diff --git a/Makefile b/Makefile
index 7c92e1ac..06f89cac 100644
--- a/Makefile
+++ b/Makefile
@@ -19,6 +19,7 @@ LEADER_ELECT := "true"
# If Integration Test Suite is to be run locally against clusters then export the below variable
# with MCM deployment name in the cluster
MACHINE_CONTROLLER_MANAGER_DEPLOYMENT_NAME := machine-controller-manager
+PLATFORM ?= linux/amd64
#########################################
# Tools & Cleanup
@@ -116,7 +117,6 @@ test-integration:
.PHONY: release
release: docker-image docker-push
-PLATFORM ?= linux/amd64
.PHONY: docker-image
docker-image:
@docker buildx build --platform $(PLATFORM) -t $(IMAGE_NAME):$(VERSION) -t $(IMAGE_NAME):latest .
diff --git a/hack/api-reference/api.md b/hack/api-reference/api.md
index bdb43a3f..8c98dc70 100644
--- a/hack/api-reference/api.md
+++ b/hack/api-reference/api.md
@@ -156,7 +156,21 @@ string
- PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+(Optional)
+PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+Deprecated: use PodNetworkCIDRs instead
+ |
+
+
+
+podNetworkCIDRs
+
+[]string
+
+ |
+
+(Optional)
+ PodNetworkCIDRs is the CIDR ranges for the pods assigned to this instance.
|
@@ -360,7 +374,21 @@ string
- PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+(Optional)
+PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+Deprecated: use PodNetworkCIDRs instead
+ |
+
+
+
+podNetworkCIDRs
+
+[]string
+
+ |
+
+(Optional)
+ PodNetworkCIDRs is the CIDR ranges for the pods assigned to this instance.
|
diff --git a/pkg/apis/openstack/types.go b/pkg/apis/openstack/types.go
index c9ee233d..e6ecaac0 100644
--- a/pkg/apis/openstack/types.go
+++ b/pkg/apis/openstack/types.go
@@ -40,7 +40,10 @@ type MachineProviderConfigSpec struct {
// SubnetID is the ID of the subnet the instance should belong to. If SubnetID is not specified
SubnetID *string
// PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+ // Deprecated - use `PodNetworkCIDRs` instead.
PodNetworkCidr string
+ // PodNetworkCidr is the CIDR ranges for the pods assigned to this instance.
+ PodNetworkCIDRs []string
// The size of the root disk used for the instance.
RootDiskSize int
// The type of the root disk type used for the instance
diff --git a/pkg/apis/openstack/v1alpha1/types.go b/pkg/apis/openstack/v1alpha1/types.go
index 9c3cf699..7687f392 100644
--- a/pkg/apis/openstack/v1alpha1/types.go
+++ b/pkg/apis/openstack/v1alpha1/types.go
@@ -43,7 +43,12 @@ type MachineProviderConfigSpec struct {
// +optional
SubnetID *string `json:"subnetID,omitempty"`
// PodNetworkCidr is the CIDR range for the pods assigned to this instance.
+ // Deprecated: use PodNetworkCIDRs instead
+ // +optional
PodNetworkCidr string `json:"podNetworkCidr"`
+ // PodNetworkCIDRs is the CIDR ranges for the pods assigned to this instance.
+ // +optional
+ PodNetworkCIDRs []string `json:"podNetworkCIDRs"`
// The size of the root disk used for the instance.
RootDiskSize int `json:"rootDiskSize,omitempty"` // in GB
// The type of the root disk used for the instance.
diff --git a/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go b/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
index 53c1b6b8..52a19d1f 100644
--- a/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
+++ b/pkg/apis/openstack/v1alpha1/zz_generated.conversion.go
@@ -93,6 +93,7 @@ func autoConvert_v1alpha1_MachineProviderConfigSpec_To_openstack_MachineProvider
out.NetworkID = in.NetworkID
out.SubnetID = (*string)(unsafe.Pointer(in.SubnetID))
out.PodNetworkCidr = in.PodNetworkCidr
+ out.PodNetworkCIDRs = *(*[]string)(unsafe.Pointer(&in.PodNetworkCIDRs))
out.RootDiskSize = in.RootDiskSize
out.RootDiskType = (*string)(unsafe.Pointer(in.RootDiskType))
out.UseConfigDrive = (*bool)(unsafe.Pointer(in.UseConfigDrive))
@@ -118,6 +119,7 @@ func autoConvert_openstack_MachineProviderConfigSpec_To_v1alpha1_MachineProvider
out.NetworkID = in.NetworkID
out.SubnetID = (*string)(unsafe.Pointer(in.SubnetID))
out.PodNetworkCidr = in.PodNetworkCidr
+ out.PodNetworkCIDRs = *(*[]string)(unsafe.Pointer(&in.PodNetworkCIDRs))
out.RootDiskSize = in.RootDiskSize
out.RootDiskType = (*string)(unsafe.Pointer(in.RootDiskType))
out.UseConfigDrive = (*bool)(unsafe.Pointer(in.UseConfigDrive))
diff --git a/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/openstack/v1alpha1/zz_generated.deepcopy.go
index 5d3efb81..f6872f7c 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.PodNetworkCIDRs != nil {
+ in, out := &in.PodNetworkCIDRs, &out.PodNetworkCIDRs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.RootDiskType != nil {
in, out := &in.RootDiskType, &out.RootDiskType
*out = new(string)
diff --git a/pkg/apis/openstack/zz_generated.deepcopy.go b/pkg/apis/openstack/zz_generated.deepcopy.go
index 9d78e6df..cd076d08 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.PodNetworkCIDRs != nil {
+ in, out := &in.PodNetworkCIDRs, &out.PodNetworkCIDRs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.RootDiskType != nil {
in, out := &in.RootDiskType, &out.RootDiskType
*out = new(string)
diff --git a/pkg/apis/validation/validation.go b/pkg/apis/validation/validation.go
index 5714db12..1a6e6327 100644
--- a/pkg/apis/validation/validation.go
+++ b/pkg/apis/validation/validation.go
@@ -57,20 +57,20 @@ func validateMachineProviderConfig(providerConfig *openstack.MachineProviderConf
if "" == providerConfig.Spec.NetworkID && len(providerConfig.Spec.Networks) == 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("networkID"), "both \"networks\" and \"networkID\" should not be empty"))
}
- if "" == providerConfig.Spec.PodNetworkCidr {
- allErrs = append(allErrs, field.Required(fldPath.Child("podNetworkCidr"), "PodNetworkCidr is required"))
+ if len(providerConfig.Spec.PodNetworkCIDRs) == 0 && len(providerConfig.Spec.PodNetworkCidr) == 0 {
+ allErrs = append(allErrs, field.Required(fldPath.Child("PodNetworkCIDRs"), "PodNetworkCIDRs is required"))
}
if providerConfig.Spec.RootDiskSize < 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("rootDiskSize"), "RootDiskSize can not be negative"))
}
- allErrs = append(allErrs, validateNetworks(providerConfig.Spec.Networks, providerConfig.Spec.PodNetworkCidr, field.NewPath("spec.networks"))...)
+ allErrs = append(allErrs, validateNetworks(providerConfig.Spec.Networks, providerConfig.Spec.PodNetworkCidr, providerConfig.Spec.PodNetworkCIDRs, field.NewPath("spec.networks"))...)
allErrs = append(allErrs, validateClassSpecTags(providerConfig.Spec.Tags, field.NewPath("spec.tags"))...)
return allErrs
}
-func validateNetworks(networks []openstack.OpenStackNetwork, podNetworkCidr string, fldPath *field.Path) field.ErrorList {
+func validateNetworks(networks []openstack.OpenStackNetwork, podNetworkCidr string, podNetworkCIDRs []string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for index, network := range networks {
@@ -81,7 +81,7 @@ func validateNetworks(networks []openstack.OpenStackNetwork, podNetworkCidr stri
if "" != network.Id && "" != network.Name {
allErrs = append(allErrs, field.Forbidden(fldPath, "simultaneous use of network \"id\" and \"name\" is forbidden"))
}
- if "" == podNetworkCidr && network.PodNetwork {
+ if len(podNetworkCIDRs) == 0 && len(podNetworkCidr) == 0 && network.PodNetwork {
allErrs = append(allErrs, field.Required(fldPath.Child("podNetwork"), "\"podNetwork\" switch should not be used in absence of \"spec.podNetworkCidr\""))
}
}
diff --git a/pkg/apis/validation/validation_test.go b/pkg/apis/validation/validation_test.go
index 6af9c414..81426531 100644
--- a/pkg/apis/validation/validation_test.go
+++ b/pkg/apis/validation/validation_test.go
@@ -36,13 +36,13 @@ var _ = Describe("Validation", func() {
fmt.Sprintf("%s-foo", ServerTagRolePrefix): "1",
fmt.Sprintf("%s-foo", ServerTagClusterPrefix): "1",
},
- NetworkID: "networkID",
- SubnetID: nil,
- PodNetworkCidr: "10.0.0.1/8",
- RootDiskSize: 0,
- UseConfigDrive: nil,
- ServerGroupID: nil,
- Networks: nil,
+ NetworkID: "networkID",
+ SubnetID: nil,
+ PodNetworkCIDRs: []string{"10.0.0.1/8"},
+ RootDiskSize: 0,
+ UseConfigDrive: nil,
+ ServerGroupID: nil,
+ Networks: nil,
},
}
})
@@ -59,7 +59,7 @@ var _ = Describe("Validation", func() {
spec.FlavorName = ""
spec.AvailabilityZone = ""
spec.KeyName = ""
- spec.PodNetworkCidr = ""
+ spec.PodNetworkCIDRs = nil
err := validateMachineProviderConfig(machineProviderConfig)
Expect(err).To(ConsistOf(
@@ -81,7 +81,7 @@ var _ = Describe("Validation", func() {
})),
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": BeEquivalentTo("FieldValueRequired"),
- "Field": Equal("spec.podNetworkCidr"),
+ "Field": Equal("spec.PodNetworkCIDRs"),
})),
))
})
diff --git a/pkg/driver/executor/executor.go b/pkg/driver/executor/executor.go
index 99cec5db..c2c5be9a 100644
--- a/pkg/driver/executor/executor.go
+++ b/pkg/driver/executor/executor.go
@@ -19,7 +19,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog/v2"
- "k8s.io/utils/pointer"
+ "k8s.io/utils/ptr"
api "github.com/gardener/machine-controller-manager-provider-openstack/pkg/apis/openstack"
"github.com/gardener/machine-controller-manager-provider-openstack/pkg/client"
@@ -134,7 +134,7 @@ func (ex *Executor) resolveServerNetworks(ctx context.Context, machineName strin
return serverNetworks, nil
}
- if !isEmptyString(pointer.StringPtr(networkID)) {
+ if !isEmptyString(ptr.To(networkID)) {
klog.V(3).Infof("deploying in network [ID=%q]", networkID)
serverNetworks = append(serverNetworks, servers.Network{UUID: ex.Config.Spec.NetworkID})
return serverNetworks, nil
@@ -145,7 +145,7 @@ func (ex *Executor) resolveServerNetworks(ctx context.Context, machineName strin
resolvedNetworkID string
err error
)
- if isEmptyString(pointer.StringPtr(network.Id)) {
+ if isEmptyString(ptr.To(network.Id)) {
resolvedNetworkID, err = ex.Network.NetworkIDFromName(network.Name)
if err != nil {
return nil, err
@@ -383,27 +383,34 @@ func (ex *Executor) patchServerPortsForPodNetwork(serverID string) error {
return fmt.Errorf("failed to resolve network IDs for the pod network %v", err)
}
+ // coalesce all pod network CIDRs into a single slice.
+ podCIDRs := sets.NewString(ex.Config.Spec.PodNetworkCIDRs...)
+ if ex.Config.Spec.PodNetworkCidr != "" {
+ podCIDRs.Insert(ex.Config.Spec.PodNetworkCidr)
+ }
+
for _, port := range allPorts {
- if podNetworkIDs.Has(port.NetworkID) {
- addressPairFound := false
-
- for _, pair := range port.AllowedAddressPairs {
- if pair.IPAddress == ex.Config.Spec.PodNetworkCidr {
- klog.V(3).Infof("port [ID=%q] already allows pod network CIDR range. Skipping update...", port.ID)
- addressPairFound = true
- // break inner loop if target found
- break
- }
- }
- // continue outer loop if target found
- if addressPairFound {
- continue
- }
+ // if the port is not part of the networks we care about, continue.
+ if !podNetworkIDs.Has(port.NetworkID) {
+ continue
+ }
- if err := ex.Network.UpdatePort(port.ID, ports.UpdateOpts{
- AllowedAddressPairs: &[]ports.AddressPair{{IPAddress: ex.Config.Spec.PodNetworkCidr}},
- }); err != nil {
- return fmt.Errorf("failed to update allowed address pair for port [ID=%q]: %v", port.ID, err)
+ for _, cidr := range podCIDRs.List() {
+ if err := func() error {
+ for _, pair := range port.AllowedAddressPairs {
+ if pair.IPAddress == cidr {
+ klog.V(3).Infof("port [ID=%q] already allows pod network CIDR range. Skipping update...", port.ID)
+ return nil
+ }
+ }
+ if err := ex.Network.UpdatePort(port.ID, ports.UpdateOpts{
+ AllowedAddressPairs: &[]ports.AddressPair{{IPAddress: cidr}},
+ }); err != nil {
+ return fmt.Errorf("failed to update allowed address pair for port [ID=%q]: %v", port.ID, err)
+ }
+ return nil
+ }(); err != nil {
+ return err
}
}
}
@@ -411,14 +418,14 @@ func (ex *Executor) patchServerPortsForPodNetwork(serverID string) error {
}
// resolveNetworkIDsForPodNetwork resolves the networks that accept traffic from the pod CIDR range.
-func (ex *Executor) resolveNetworkIDsForPodNetwork() (sets.String, error) {
+func (ex *Executor) resolveNetworkIDsForPodNetwork() (sets.Set[string], error) {
var (
networkID = ex.Config.Spec.NetworkID
networks = ex.Config.Spec.Networks
- podNetworkIDs = sets.NewString()
+ podNetworkIDs = sets.New[string]()
)
- if !isEmptyString(pointer.StringPtr(networkID)) {
+ if !isEmptyString(ptr.To(networkID)) {
podNetworkIDs.Insert(networkID)
return podNetworkIDs, nil
}
@@ -428,7 +435,7 @@ func (ex *Executor) resolveNetworkIDsForPodNetwork() (sets.String, error) {
resolvedNetworkID string
err error
)
- if isEmptyString(pointer.StringPtr(network.Id)) {
+ if isEmptyString(ptr.To(network.Id)) {
resolvedNetworkID, err = ex.Network.NetworkIDFromName(network.Name)
if err != nil {
return nil, err
@@ -451,7 +458,7 @@ func (ex *Executor) DeleteMachine(ctx context.Context, machineName, providerID s
err error
)
- if !isEmptyString(pointer.StringPtr(providerID)) {
+ if !isEmptyString(ptr.To(providerID)) {
serverID := decodeProviderID(providerID)
server, err = ex.getMachineByID(ctx, serverID)
} else {
@@ -514,11 +521,10 @@ func (ex *Executor) getOrCreatePort(_ context.Context, machineName string) (stri
}
port, err := ex.Network.CreatePort(&ports.CreateOpts{
- Name: machineName,
- NetworkID: ex.Config.Spec.NetworkID,
- FixedIPs: []ports.IP{{SubnetID: *ex.Config.Spec.SubnetID}},
- AllowedAddressPairs: []ports.AddressPair{{IPAddress: ex.Config.Spec.PodNetworkCidr}},
- SecurityGroups: &securityGroupIDs,
+ Name: machineName,
+ NetworkID: ex.Config.Spec.NetworkID,
+ FixedIPs: []ports.IP{{SubnetID: *ex.Config.Spec.SubnetID}},
+ SecurityGroups: &securityGroupIDs,
})
if err != nil {
return "", err
@@ -695,5 +701,5 @@ func (ex *Executor) listServers(_ 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(pointer.StringPtr(ex.Config.Spec.NetworkID)) && !isEmptyString(ex.Config.Spec.SubnetID)
+ return !isEmptyString(ptr.To(ex.Config.Spec.NetworkID)) && !isEmptyString(ex.Config.Spec.SubnetID)
}