diff --git a/hack/api-reference/api.md b/hack/api-reference/api.md
index 8c98dc70..d5e683ff 100644
--- a/hack/api-reference/api.md
+++ b/hack/api-reference/api.md
@@ -145,7 +145,20 @@ string
(Optional)
- SubnetID is the ID of the subnet the instance should belong to. If SubnetID is not specified
+SubnetID is the ID of the subnet the instance should belong to.
+Deprecated - use SubnetIDs instead.
+ |
+
+
+
+subnetIDs
+
+[]string
+
+ |
+
+(Optional)
+ SubnetIDs is a list of IDs of the subnets the instance should belong to.
|
@@ -363,7 +376,20 @@ string
|
(Optional)
- SubnetID is the ID of the subnet the instance should belong to. If SubnetID is not specified
+SubnetID is the ID of the subnet the instance should belong to.
+Deprecated - use SubnetIDs instead.
+ |
+
+
+
+subnetIDs
+
+[]string
+
+ |
+
+(Optional)
+ SubnetIDs is a list of IDs of the subnets the instance should belong to.
|
diff --git a/pkg/apis/openstack/types.go b/pkg/apis/openstack/types.go
index 6ee847c8..41f2e836 100644
--- a/pkg/apis/openstack/types.go
+++ b/pkg/apis/openstack/types.go
@@ -37,8 +37,11 @@ type MachineProviderConfigSpec struct {
Tags map[string]string
// NetworkID is the ID of the network the instance should belong to.
NetworkID string
- // SubnetID is the ID of the subnet the instance should belong to. If SubnetID is not specified
+ // SubnetID is the ID of the subnet the instance should belong to.
+ // Deprecated - use `SubnetIDs` instead.
SubnetID *string
+ // SubnetIDs is a list of IDs of the subnets the instance should belong to.
+ SubnetIDs []string
// PodNetworkCidr is the CIDR range for the pods assigned to this instance.
// Deprecated - use `PodNetworkCIDRs` instead.
PodNetworkCidr string
diff --git a/pkg/apis/openstack/v1alpha1/types.go b/pkg/apis/openstack/v1alpha1/types.go
index 31935def..cee77ba5 100644
--- a/pkg/apis/openstack/v1alpha1/types.go
+++ b/pkg/apis/openstack/v1alpha1/types.go
@@ -39,9 +39,13 @@ type MachineProviderConfigSpec struct {
Tags map[string]string `json:"tags,omitempty"`
// NetworkID is the ID of the network the instance should belong to.
NetworkID string `json:"networkID"`
- // SubnetID is the ID of the subnet the instance should belong to. If SubnetID is not specified
+ // SubnetID is the ID of the subnet the instance should belong to.
+ // Deprecated - use `SubnetIDs` instead.
// +optional
SubnetID *string `json:"subnetID,omitempty"`
+ // SubnetIDs is a list of IDs of the subnets the instance should belong to.
+ // +optional
+ SubnetIDs []string `json:"subnetIDs,omitempty"`
// PodNetworkCidr is the CIDR range for the pods assigned to this instance.
// Deprecated: use PodNetworkCIDRs instead
// +optional
diff --git a/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go b/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
index 52a19d1f..9cd84a53 100644
--- a/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
+++ b/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
@@ -92,6 +92,7 @@ func autoConvert_v1alpha1_MachineProviderConfigSpec_To_openstack_MachineProvider
out.Tags = *(*map[string]string)(unsafe.Pointer(&in.Tags))
out.NetworkID = in.NetworkID
out.SubnetID = (*string)(unsafe.Pointer(in.SubnetID))
+ out.SubnetIDs = *(*[]string)(unsafe.Pointer(&in.SubnetIDs))
out.PodNetworkCidr = in.PodNetworkCidr
out.PodNetworkCIDRs = *(*[]string)(unsafe.Pointer(&in.PodNetworkCIDRs))
out.RootDiskSize = in.RootDiskSize
@@ -118,6 +119,7 @@ func autoConvert_openstack_MachineProviderConfigSpec_To_v1alpha1_MachineProvider
out.Tags = *(*map[string]string)(unsafe.Pointer(&in.Tags))
out.NetworkID = in.NetworkID
out.SubnetID = (*string)(unsafe.Pointer(in.SubnetID))
+ out.SubnetIDs = *(*[]string)(unsafe.Pointer(&in.SubnetIDs))
out.PodNetworkCidr = in.PodNetworkCidr
out.PodNetworkCIDRs = *(*[]string)(unsafe.Pointer(&in.PodNetworkCIDRs))
out.RootDiskSize = in.RootDiskSize
diff --git a/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go
index f6872f7c..c6e0bbf8 100644
--- a/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go
@@ -59,6 +59,11 @@ func (in *MachineProviderConfigSpec) DeepCopyInto(out *MachineProviderConfigSpec
*out = new(string)
**out = **in
}
+ if in.SubnetIDs != nil {
+ in, out := &in.SubnetIDs, &out.SubnetIDs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.PodNetworkCIDRs != nil {
in, out := &in.PodNetworkCIDRs, &out.PodNetworkCIDRs
*out = make([]string, len(*in))
diff --git a/pkg/apis/openstack/zz_generated.deepcopy.go b/pkg/apis/openstack/zz_generated.deepcopy.go
index cd076d08..4a6eb7f5 100644
--- a/pkg/apis/openstack/zz_generated.deepcopy.go
+++ b/pkg/apis/openstack/zz_generated.deepcopy.go
@@ -59,6 +59,11 @@ func (in *MachineProviderConfigSpec) DeepCopyInto(out *MachineProviderConfigSpec
*out = new(string)
**out = **in
}
+ if in.SubnetIDs != nil {
+ in, out := &in.SubnetIDs, &out.SubnetIDs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.PodNetworkCIDRs != nil {
in, out := &in.PodNetworkCIDRs, &out.PodNetworkCIDRs
*out = make([]string, len(*in))
diff --git a/pkg/driver/executor/executor.go b/pkg/driver/executor/executor.go
index 5eab5efc..998b539e 100644
--- a/pkg/driver/executor/executor.go
+++ b/pkg/driver/executor/executor.go
@@ -520,7 +520,7 @@ func (ex *Executor) getOrCreatePort(ctx context.Context, machineName string) (st
port, err := ex.Network.CreatePort(ctx, &ports.CreateOpts{
Name: machineName,
NetworkID: ex.Config.Spec.NetworkID,
- FixedIPs: []ports.IP{{SubnetID: *ex.Config.Spec.SubnetID}},
+ FixedIPs: ex.buildFixedIPs(),
SecurityGroups: &securityGroupIDs,
})
if err != nil {
@@ -542,6 +542,32 @@ func (ex *Executor) getOrCreatePort(ctx context.Context, machineName string) (st
return port.ID, nil
}
+// buildFixedIPs creates a list of FixedIPs from SubnetID and SubnetIDs, avoiding duplicates
+func (ex *Executor) buildFixedIPs() []ports.IP {
+ // Use a set to track unique subnet IDs and avoid duplicates
+ subnetIDSet := sets.NewString()
+
+ // Add the single SubnetID if specified
+ if ex.Config.Spec.SubnetID != nil && *ex.Config.Spec.SubnetID != "" {
+ subnetIDSet.Insert(*ex.Config.Spec.SubnetID)
+ }
+
+ // Add all SubnetIDs if specified
+ for _, subnetID := range ex.Config.Spec.SubnetIDs {
+ if subnetID != "" {
+ subnetIDSet.Insert(subnetID)
+ }
+ }
+
+ // Convert to []ports.IP
+ var fixedIPs []ports.IP
+ for _, subnetID := range subnetIDSet.List() {
+ fixedIPs = append(fixedIPs, ports.IP{SubnetID: subnetID})
+ }
+
+ return fixedIPs
+}
+
func (ex *Executor) deletePort(ctx context.Context, machineName string) error {
portList, err := ex.Network.ListPorts(ctx, ports.ListOpts{
Name: machineName,
@@ -698,5 +724,9 @@ func (ex *Executor) listServers(ctx context.Context) ([]servers.Server, error) {
// isUserManagedNetwork returns true if the port used by the machine will be created and managed by MCM.
func (ex *Executor) isUserManagedNetwork() bool {
- return !isEmptyString(ptr.To(ex.Config.Spec.NetworkID)) && !isEmptyString(ex.Config.Spec.SubnetID)
+ hasNetworkID := !isEmptyString(ptr.To(ex.Config.Spec.NetworkID))
+ hasSubnetID := !isEmptyString(ex.Config.Spec.SubnetID)
+ hasSubnetIDs := len(ex.Config.Spec.SubnetIDs) > 0
+
+ return hasNetworkID && (hasSubnetID || hasSubnetIDs)
}