diff --git a/pkg/harvester/components/settings/storage-network.vue b/pkg/harvester/components/settings/storage-network.vue index c843480d..57ffc017 100644 --- a/pkg/harvester/components/settings/storage-network.vue +++ b/pkg/harvester/components/settings/storage-network.vue @@ -12,6 +12,9 @@ import { NODE } from '@shell/config/types'; import { HCI } from '../../types'; import { DOC } from '../../config/doc-links'; import { docLink } from '../../utils/feature-flags'; +import { NETWORK_TYPE } from '../../config/types'; + +const { L2VLAN, UNTAGGED } = NETWORK_TYPE; export default { name: 'HarvesterEditStorageNetwork', @@ -57,11 +60,14 @@ export default { data() { let parsedDefaultValue = {}; let openVlan = false; + let networkType = L2VLAN; try { parsedDefaultValue = JSON.parse(this.value.value); + networkType = 'vlan' in parsedDefaultValue ? L2VLAN : UNTAGGED; // backend doesn't provide networkType, so we check if vlan is provided instead openVlan = true; } catch (error) { + networkType = L2VLAN; parsedDefaultValue = { vlan: '', clusterNetwork: '', @@ -73,6 +79,7 @@ export default { return { openVlan, + networkType, errors: [], exclude, parsedDefaultValue, @@ -87,16 +94,35 @@ export default { }, computed: { + showVlan() { + return this.networkType === L2VLAN; + }, + networkTypes() { + const types = [L2VLAN]; + + if (this.untaggedNetworkSettingEnabled) { + types.push(UNTAGGED); + } + + return types; + }, storageNetworkExampleLink() { const version = this.$store.getters['harvester-common/getServerVersion'](); return docLink(DOC.STORAGE_NETWORK_EXAMPLE, version); }, + + untaggedNetworkSettingEnabled() { + return this.$store.getters['harvester-common/getFeatureEnabled']('untaggedNetworkSetting'); + }, + clusterNetworkOptions() { const inStore = this.$store.getters['currentProduct'].inStore; const clusterNetworks = this.$store.getters[`${ inStore }/all`](HCI.CLUSTER_NETWORK) || []; + // untaggedNetwork filter out mgmt cluster network + const clusterNetworksOptions = this.networkType === UNTAGGED ? clusterNetworks.filter((net) => net.id !== 'mgmt') : clusterNetworks; - return clusterNetworks.map((n) => { + return clusterNetworksOptions.map((n) => { const disabled = !n.isReadyForStorageNetwork; return { @@ -108,7 +134,50 @@ export default { }, }, + watch: { + networkType: { + handler(neu) { + this.parsedDefaultValue.clusterNetwork = ''; + + if (neu === L2VLAN) { + this.parsedDefaultValue.vlan = ''; + } else { + delete this.parsedDefaultValue.vlan; + } + }, + deep: true + } + }, + methods: { + inputVlan(neu) { + if (neu === '') { + this.parsedDefaultValue.vlan = ''; + + return; + } + const newValue = Number(neu); + + if (newValue > 4094) { + this.parsedDefaultValue.vlan = 4094; + } else if (newValue < 1) { + this.parsedDefaultValue.vlan = 1; + } else { + this.parsedDefaultValue.vlan = newValue; + } + }, + + useDefault() { + this.openVlan = false; + this.networkType = L2VLAN; + this.parsedDefaultValue = { + vlan: '', + clusterNetwork: '', + range: '', + exclude: [] + }; + }, + update() { const exclude = this.exclude.filter((ip) => ip); @@ -138,7 +207,7 @@ export default { errors.push(this.t('harvester.setting.storageNetwork.range.invalid', null, true)); } - if (!this.parsedDefaultValue.vlan) { + if (this.networkType === L2VLAN && !this.parsedDefaultValue.vlan) { errors.push(this.t('validation.required', { key: this.t('harvester.setting.storageNetwork.vlan') }, true)); } @@ -191,13 +260,25 @@ export default { />
+ + Any change to storage-network requires shutting down all virtual machines before applying this setting.
Users have to ensure the cluster network is configured and VLAN Configuration will cover all nodes and ensure the network connectivity is working and expected in all nodes.' - tip: 'Specify an IP range in the IPv4 CIDR format. Number of IPs Required = Number of Nodes * 4 + Number of Disks * 2 + Number of Images to Download/Upload . For more information about storage network settings, see the documentation.' + tip: 'Specify an IP range in the IPv4 CIDR format. Number of IPs Required = Number of Nodes * 2 + Number of Disks * 2 + Number of Images to Download/Upload . For more information about storage network settings, see the documentation.' vmForceDeletionPolicy: period: Period ratio : Ratio diff --git a/pkg/harvester/models/k8s.cni.cncf.io.networkattachmentdefinition.js b/pkg/harvester/models/k8s.cni.cncf.io.networkattachmentdefinition.js index a916386c..351e6017 100644 --- a/pkg/harvester/models/k8s.cni.cncf.io.networkattachmentdefinition.js +++ b/pkg/harvester/models/k8s.cni.cncf.io.networkattachmentdefinition.js @@ -1,5 +1,8 @@ import SteveModel from '@shell/plugins/steve/steve-class'; import { HCI } from '@shell/config/labels-annotations'; +import { NETWORK_TYPE } from '../config/types'; + +const { UNTAGGED } = NETWORK_TYPE; export default class NetworkAttachmentDef extends SteveModel { applyDefaults() { @@ -42,7 +45,7 @@ export default class NetworkAttachmentDef extends SteveModel { } get vlanId() { - return this.vlanType === 'UntaggedNetwork' ? 'N/A' : this.parseConfig.vlan; + return this.vlanType === UNTAGGED ? 'N/A' : this.parseConfig.vlan; } get customValidationRules() { @@ -65,7 +68,7 @@ export default class NetworkAttachmentDef extends SteveModel { const route = annotations[HCI.NETWORK_ROUTE]; let config = {}; - if (this.vlanType === 'UntaggedNetwork') { + if (this.vlanType === UNTAGGED) { return 'N/A'; }