Skip to content

Commit a42ded1

Browse files
4ch3losKhizerRehan
andauthored
Add support for multiple nics with vmware cloud director in the UI (#7452)
* Add support for multiple nics with vmware cloud director Signed-off-by: Kai Fink <[email protected]> * Update modules/web/src/app/node-data/basic/provider/vmware-cloud-director/template.html Co-authored-by: Khizer Rehan <[email protected]> Signed-off-by: Kai Fink <[email protected]> * Update modules/web/src/app/node-data/basic/provider/vmware-cloud-director/component.ts Co-authored-by: Khizer Rehan <[email protected]> Signed-off-by: Kai Fink <[email protected]> * Remove unneeded file Signed-off-by: Kai Fink <[email protected]> * Updated codegen for adjusted api Signed-off-by: Kai Fink <[email protected]> * Update machine-controller and operating-system-manager Signed-off-by: Kai Fink <[email protected]> * Update api dependencies Signed-off-by: Kai Fink <[email protected]> * Update api dependencies(kube-openapi) Signed-off-by: Kai Fink <[email protected]> * Fix test method call Signed-off-by: Kai Fink <[email protected]> * Update swagger Signed-off-by: Kai Fink <[email protected]> * Update api client Signed-off-by: Kai Fink <[email protected]> * Missing file from swagger gen Signed-off-by: Kai Fink <[email protected]> --------- Signed-off-by: Kai Fink <[email protected]> Co-authored-by: Khizer Rehan <[email protected]>
1 parent 19d56c9 commit a42ded1

File tree

8 files changed

+136
-59
lines changed

8 files changed

+136
-59
lines changed

modules/api/cmd/kubermatic-api/swagger.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41488,6 +41488,13 @@
4148841488
"description": "VMwareCloudDirectorNodeSpec VMware Cloud Director node settings",
4148941489
"type": "object",
4149041490
"properties": {
41491+
"additionalNetworks": {
41492+
"type": "array",
41493+
"items": {
41494+
"type": "string"
41495+
},
41496+
"x-go-name": "AdditionalNetworks"
41497+
},
4149141498
"catalog": {
4149241499
"type": "string",
4149341500
"x-go-name": "Catalog"

modules/api/pkg/api/v1/types.go

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,19 +2575,20 @@ func (spec *OpenNebulaNodeSpec) MarshalJSON() ([]byte, error) {
25752575
// VMwareCloudDirectorNodeSpec VMware Cloud Director node settings
25762576
// swagger:model VMwareCloudDirectorNodeSpec
25772577
type VMwareCloudDirectorNodeSpec struct {
2578-
CPUs int `json:"cpus"`
2579-
CPUCores int `json:"cpuCores"`
2580-
MemoryMB int `json:"memoryMB"`
2581-
DiskSizeGB *int64 `json:"diskSizeGB,omitempty"`
2582-
DiskIOPS *int64 `json:"diskIOPS,omitempty"`
2583-
Template string `json:"template"`
2584-
Catalog string `json:"catalog"`
2585-
StorageProfile string `json:"storageProfile"`
2586-
IPAllocationMode vmwareclouddirector.IPAllocationMode `json:"ipAllocationMode,omitempty"`
2587-
VApp string `json:"vapp,omitempty"`
2588-
Network string `json:"network,omitempty"`
2589-
PlacementPolicy *string `json:"placementPolicy,omitempty"`
2590-
SizingPolicy *string `json:"sizingPolicy,omitempty"`
2578+
CPUs int `json:"cpus"`
2579+
CPUCores int `json:"cpuCores"`
2580+
MemoryMB int `json:"memoryMB"`
2581+
DiskSizeGB *int64 `json:"diskSizeGB,omitempty"`
2582+
DiskIOPS *int64 `json:"diskIOPS,omitempty"`
2583+
Template string `json:"template"`
2584+
Catalog string `json:"catalog"`
2585+
StorageProfile string `json:"storageProfile"`
2586+
IPAllocationMode vmwareclouddirector.IPAllocationMode `json:"ipAllocationMode,omitempty"`
2587+
VApp string `json:"vapp,omitempty"`
2588+
Network string `json:"network,omitempty"`
2589+
AdditionalNetworks []string `json:"additionalNetworks,omitempty"`
2590+
PlacementPolicy *string `json:"placementPolicy,omitempty"`
2591+
SizingPolicy *string `json:"sizingPolicy,omitempty"`
25912592
// Additional metadata to set
25922593
// required: false
25932594
Metadata map[string]string `json:"metadata,omitempty"`
@@ -2629,35 +2630,37 @@ func (spec *VMwareCloudDirectorNodeSpec) MarshalJSON() ([]byte, error) {
26292630
}
26302631

26312632
res := struct {
2632-
CPUs int `json:"cpus"`
2633-
CPUCores int `json:"cpuCores"`
2634-
MemoryMB int `json:"memoryMB"`
2635-
DiskSizeGB *int64 `json:"diskSizeGB,omitempty"`
2636-
DiskIOPS *int64 `json:"diskIOPS,omitempty"`
2637-
Catalog string `json:"catalog"`
2638-
Template string `json:"template"`
2639-
StorageProfile string `json:"storageProfile,omitempty"`
2640-
IPAllocationMode vmwareclouddirector.IPAllocationMode `json:"ipAllocationMode,omitempty"`
2641-
VApp string `json:"vapp,omitempty"`
2642-
Network string `json:"network,omitempty"`
2643-
Metadata map[string]string `json:"metadata,omitempty"`
2644-
PlacementPolicy *string `json:"placementPolicy,omitempty"`
2645-
SizingPolicy *string `json:"sizingPolicy,omitempty"`
2633+
CPUs int `json:"cpus"`
2634+
CPUCores int `json:"cpuCores"`
2635+
MemoryMB int `json:"memoryMB"`
2636+
DiskSizeGB *int64 `json:"diskSizeGB,omitempty"`
2637+
DiskIOPS *int64 `json:"diskIOPS,omitempty"`
2638+
Catalog string `json:"catalog"`
2639+
Template string `json:"template"`
2640+
StorageProfile string `json:"storageProfile,omitempty"`
2641+
IPAllocationMode vmwareclouddirector.IPAllocationMode `json:"ipAllocationMode,omitempty"`
2642+
VApp string `json:"vapp,omitempty"`
2643+
Network string `json:"network,omitempty"`
2644+
AdditionalNetworks []string `json:"additionalNetworks,omitempty"`
2645+
Metadata map[string]string `json:"metadata,omitempty"`
2646+
PlacementPolicy *string `json:"placementPolicy,omitempty"`
2647+
SizingPolicy *string `json:"sizingPolicy,omitempty"`
26462648
}{
2647-
CPUs: spec.CPUs,
2648-
CPUCores: spec.CPUCores,
2649-
MemoryMB: spec.MemoryMB,
2650-
DiskSizeGB: spec.DiskSizeGB,
2651-
DiskIOPS: spec.DiskIOPS,
2652-
Catalog: spec.Catalog,
2653-
Template: spec.Template,
2654-
StorageProfile: spec.StorageProfile,
2655-
IPAllocationMode: spec.IPAllocationMode,
2656-
VApp: spec.VApp,
2657-
Network: spec.Network,
2658-
Metadata: spec.Metadata,
2659-
PlacementPolicy: spec.PlacementPolicy,
2660-
SizingPolicy: spec.SizingPolicy,
2649+
CPUs: spec.CPUs,
2650+
CPUCores: spec.CPUCores,
2651+
MemoryMB: spec.MemoryMB,
2652+
DiskSizeGB: spec.DiskSizeGB,
2653+
DiskIOPS: spec.DiskIOPS,
2654+
Catalog: spec.Catalog,
2655+
Template: spec.Template,
2656+
StorageProfile: spec.StorageProfile,
2657+
IPAllocationMode: spec.IPAllocationMode,
2658+
VApp: spec.VApp,
2659+
Network: spec.Network,
2660+
AdditionalNetworks: spec.AdditionalNetworks,
2661+
Metadata: spec.Metadata,
2662+
PlacementPolicy: spec.PlacementPolicy,
2663+
SizingPolicy: spec.SizingPolicy,
26612664
}
26622665

26632666
return json.Marshal(&res)

modules/api/pkg/machine/convert.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,32 @@ func GetAPIV2NodeCloudSpec(machineSpec clusterv1alpha1.MachineSpec) (*apiv1.Node
257257
if err := json.Unmarshal(decodedProviderSpec.CloudProviderSpec.Raw, &config); err != nil {
258258
return nil, fmt.Errorf("failed to parse VMWare Cloud Director config: %w", err)
259259
}
260+
261+
var networks []string
262+
263+
for _, network := range config.Networks {
264+
networks = append(networks, network.Value)
265+
}
266+
267+
network := config.Network.Value
268+
269+
if len(networks) > 0 {
270+
network = networks[0]
271+
networks = networks[1:]
272+
}
273+
260274
cloudSpec.VMwareCloudDirector = &apiv1.VMwareCloudDirectorNodeSpec{
261-
CPUs: int(config.CPUs),
262-
CPUCores: int(config.CPUCores),
263-
MemoryMB: int(config.MemoryMB),
264-
DiskSizeGB: config.DiskSizeGB,
265-
Template: config.Template.Value,
266-
Catalog: config.Catalog.Value,
267-
DiskIOPS: config.DiskIOPS,
268-
VApp: config.VApp.Value,
269-
Network: config.Network.Value,
270-
IPAllocationMode: config.IPAllocationMode,
275+
CPUs: int(config.CPUs),
276+
CPUCores: int(config.CPUCores),
277+
MemoryMB: int(config.MemoryMB),
278+
DiskSizeGB: config.DiskSizeGB,
279+
Template: config.Template.Value,
280+
Catalog: config.Catalog.Value,
281+
DiskIOPS: config.DiskIOPS,
282+
VApp: config.VApp.Value,
283+
Network: network,
284+
AdditionalNetworks: networks,
285+
IPAllocationMode: config.IPAllocationMode,
271286
}
272287

273288
if config.StorageProfile != nil {

modules/api/pkg/resources/machine/common.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,15 +355,30 @@ func GetVMwareCloudDirectorProviderConfig(c *kubermaticv1.Cluster, nodeSpec apiv
355355
config.PlacementPolicy = nodeSpec.Cloud.VMwareCloudDirector.PlacementPolicy
356356
}
357357

358+
var networks []providerconfig.ConfigVarString
359+
358360
switch {
359361
case nodeSpec.Cloud.VMwareCloudDirector.Network != "":
360-
config.Network = providerconfig.ConfigVarString{Value: nodeSpec.Cloud.VMwareCloudDirector.Network}
362+
networks = append(networks, providerconfig.ConfigVarString{Value: nodeSpec.Cloud.VMwareCloudDirector.Network})
361363
case c.Spec.Cloud.VMwareCloudDirector.OVDCNetwork != "":
362-
config.Network = providerconfig.ConfigVarString{Value: c.Spec.Cloud.VMwareCloudDirector.OVDCNetwork}
364+
networks = append(networks, providerconfig.ConfigVarString{Value: c.Spec.Cloud.VMwareCloudDirector.OVDCNetwork})
363365
case len(c.Spec.Cloud.VMwareCloudDirector.OVDCNetworks) > 0:
364-
config.Network = providerconfig.ConfigVarString{Value: c.Spec.Cloud.VMwareCloudDirector.OVDCNetworks[0]}
366+
networks = append(networks, providerconfig.ConfigVarString{Value: c.Spec.Cloud.VMwareCloudDirector.OVDCNetworks[0]})
365367
}
366368

369+
networkLoop:
370+
for _, network := range nodeSpec.Cloud.VMwareCloudDirector.AdditionalNetworks {
371+
// Check if network is already registered in the slice
372+
for _, registered := range networks {
373+
if registered.Value == network {
374+
continue networkLoop
375+
}
376+
}
377+
networks = append(networks, providerconfig.ConfigVarString{Value: network})
378+
}
379+
380+
config.Networks = networks
381+
367382
return config, nil
368383
}
369384

modules/api/pkg/test/e2e/utils/apiclient/models/v_mware_cloud_director_node_spec.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/web/src/app/node-data/basic/provider/vmware-cloud-director/component.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum Controls {
6161
SizingPolicy = 'sizingPolicy',
6262
Template = 'template',
6363
Network = 'network',
64+
AdditionalNetworks = 'additionalNetworks',
6465
}
6566

6667
enum StorageProfileState {
@@ -201,7 +202,8 @@ export class VMwareCloudDirectorBasicNodeDataComponent
201202
this.form.get(Controls.DiskSizeGB).valueChanges,
202203
this.form.get(Controls.DiskIOPs).valueChanges,
203204
this.form.get(Controls.IPAllocationMode).valueChanges,
204-
this.form.get(Controls.Network).valueChanges
205+
this.form.get(Controls.Network).valueChanges,
206+
this.form.get(Controls.AdditionalNetworks).valueChanges
205207
)
206208
.pipe(takeUntil(this._unsubscribe))
207209
.subscribe(_ => (this._nodeDataService.nodeData = this._getNodeData()));
@@ -217,7 +219,8 @@ export class VMwareCloudDirectorBasicNodeDataComponent
217219
this.form.get(Controls.Catalog).valueChanges,
218220
this.form.get(Controls.PlacementPolicy).valueChanges,
219221
this.form.get(Controls.SizingPolicy).valueChanges,
220-
this.form.get(Controls.Network).valueChanges
222+
this.form.get(Controls.Network).valueChanges,
223+
this.form.get(Controls.AdditionalNetworks).valueChanges
221224
)
222225
.pipe(filter(_ => this.isEnterpriseEdition))
223226
.pipe(takeUntil(this._unsubscribe))
@@ -339,10 +342,21 @@ export class VMwareCloudDirectorBasicNodeDataComponent
339342
}
340343

341344
onNetworkChanged(network: string): void {
345+
const additionalNetworksControl = this.form.get(Controls.AdditionalNetworks);
346+
347+
if (additionalNetworksControl.value && additionalNetworksControl.value.includes(network)) {
348+
additionalNetworksControl.setValue(additionalNetworksControl.value.filter(n => n !== network));
349+
}
350+
342351
this._nodeDataService.nodeData.spec.cloud.vmwareclouddirector.network = network;
343352
this._nodeDataService.nodeDataChanges.next(this._nodeDataService.nodeData);
344353
}
345354

355+
onAdditionalNetworkChanged(networks: string[]): void {
356+
this._nodeDataService.nodeData.spec.cloud.vmwareclouddirector.additionalNetworks = networks;
357+
this._nodeDataService.nodeDataChanges.next(this._nodeDataService.nodeData);
358+
}
359+
346360
onTemplateChanged(template: string): void {
347361
this.selectedTemplate = template;
348362
this._nodeDataService.nodeData.spec.cloud.vmwareclouddirector.template = template;
@@ -351,6 +365,10 @@ export class VMwareCloudDirectorBasicNodeDataComponent
351365

352366
updateSelectedNetwork(): void {
353367
const networkControl = this.form.get(Controls.Network);
368+
const additionalNetworksControl = this.form.get(Controls.AdditionalNetworks);
369+
370+
additionalNetworksControl.setValue(additionalNetworksControl.value.filter(n => this.networks.includes(n)));
371+
354372
if (networkControl.value && this.networks.includes(networkControl.value)) {
355373
return;
356374
}
@@ -381,9 +399,8 @@ export class VMwareCloudDirectorBasicNodeDataComponent
381399
[Controls.Catalog]: this._builder.control(values ? values.catalog : defaults.catalog, [Validators.required]),
382400
[Controls.PlacementPolicy]: this._builder.control(values ? values.placementPolicy : defaults.placementPolicy),
383401
[Controls.SizingPolicy]: this._builder.control(values ? values.sizingPolicy : defaults.sizingPolicy),
384-
[Controls.Network]: this._builder.control(values && values.network ? values.network : this.networks[0], [
385-
Validators.required,
386-
]),
402+
[Controls.Network]: this._builder.control(values?.network ?? this.networks[0], Validators.required),
403+
[Controls.AdditionalNetworks]: this._builder.control(values?.additionalNetworks ?? defaults.additionalNetworks),
387404
});
388405
}
389406

@@ -573,6 +590,7 @@ export class VMwareCloudDirectorBasicNodeDataComponent
573590
diskIOPS: this.form.get(Controls.DiskIOPs).value,
574591
ipAllocationMode: this.form.get(Controls.IPAllocationMode).value,
575592
network: this.form.get(Controls.Network).value,
593+
additionalNetworks: this.form.get(Controls.AdditionalNetworks).value,
576594
} as VMwareCloudDirectorNodeSpec,
577595
} as NodeCloudSpec,
578596
} as NodeSpec,
@@ -595,6 +613,7 @@ export class VMwareCloudDirectorBasicNodeDataComponent
595613
[Controls.PlacementPolicy]: this.form.get(Controls.PlacementPolicy).value?.[ComboboxControls.Select],
596614
[Controls.SizingPolicy]: this.form.get(Controls.SizingPolicy).value?.[ComboboxControls.Select],
597615
[Controls.Network]: this.form.get(Controls.Network).value,
616+
[Controls.AdditionalNetworks]: this.form.get(Controls.AdditionalNetworks).value,
598617
} as VMwareCloudDirectorNodeSpec,
599618
};
600619

modules/web/src/app/node-data/basic/provider/vmware-cloud-director/template.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@
9898
</mat-select>
9999
</mat-form-field>
100100

101+
102+
<mat-form-field fxFlex *ngIf="networks.length > 1">
103+
<mat-label>Additional Networks</mat-label>
104+
<mat-select [formControlName]="Controls.AdditionalNetworks"
105+
(selectionChange)="onAdditionalNetworkChanged($event.value)"
106+
disableOptionCentering
107+
multiple
108+
kmValueChangedIndicator>
109+
<mat-option *ngFor="let network of networks"
110+
[value]="network"
111+
[disabled]="network == form.get(Controls.Network).value"> {{network}} </mat-option>
112+
</mat-select>
113+
</mat-form-field>
114+
101115
<km-combobox #placementPolicyCombobox
102116
[selected]="selectedPlacementPolicy"
103117
[options]="placementPolicies"

modules/web/src/app/shared/entity/node.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ export class VMwareCloudDirectorNodeSpec {
307307
vapp?: string;
308308
catalog: string;
309309
network?: string;
310+
additionalNetworks: string[];
310311
template: string;
311312
placementPolicy?: string;
312313
sizingPolicy?: string;

0 commit comments

Comments
 (0)