diff --git a/README.md b/README.md index 76630d7b..44e3013a 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,12 @@ yawolFloatingID: # Placed in LoadBalancer.spec.infrastructure.networkID yawolNetworkID: +# OpenStack subnetwork ID in which the Load Balancer is placed. +# If not set, the subnetwork is chosen automatically. +# +# Placed in LoadBalancer.spec.infrastructure.subnetworkID +yawolSubnetworkID: + # default value for flavor that yawol Load Balancer instances should use # can be overridden by annotation # diff --git a/api/v1beta1/loadbalancer_types.go b/api/v1beta1/loadbalancer_types.go index 162314dd..add16b82 100644 --- a/api/v1beta1/loadbalancer_types.go +++ b/api/v1beta1/loadbalancer_types.go @@ -15,6 +15,8 @@ const ( // If this is set to a different network ID than defined as default in the yawol-cloud-controller // the default from the yawol-cloud-controller will be added to the additionalNetworks ServiceDefaultNetworkID = "yawol.stackit.cloud/defaultNetworkID" + // ServiceDefaultSubnetworkID overwrites the default openstack subnetwork for the loadbalancer + ServiceDefaultSubnetworkID = "yawol.stackit.cloud/defaultSubnetworkID" // ServiceSkipCloudControllerDefaultNetworkID if set to true it do not add the default network ID from // the yawol-cloud-controller to the additionalNetworks ServiceSkipCloudControllerDefaultNetworkID = "yawol.stackit.cloud/skipCloudControllerDefaultNetworkID" @@ -236,6 +238,9 @@ type LoadBalancerDefaultNetwork struct { FloatingNetID *string `json:"floatingNetID,omitempty"` // NetworkID defines an openstack ID for the network. NetworkID string `json:"networkID"` + // SubnetworkID defines an openstack ID for the subnetwork. + // +optional + SubnetworkID *string `json:"subnetworkID,omitempty"` } // OpenstackImageRef defines a reference to a Openstack image. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 838df928..d82fff47 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -75,6 +75,11 @@ func (in *LoadBalancerDefaultNetwork) DeepCopyInto(out *LoadBalancerDefaultNetwo *out = new(string) **out = **in } + if in.SubnetworkID != nil { + in, out := &in.SubnetworkID, &out.SubnetworkID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerDefaultNetwork. diff --git a/charts/yawol-controller/README.md b/charts/yawol-controller/README.md index 43a44e84..a4e7ec25 100644 --- a/charts/yawol-controller/README.md +++ b/charts/yawol-controller/README.md @@ -51,5 +51,6 @@ Helm chart for yawol-controller | yawolFloatingID | string | `nil` | | | yawolImageID | string | `nil` | | | yawolNetworkID | string | `nil` | | +| yawolSubnetworkID | string | `nil` | | | yawolOSSecretName | string | `nil` | | diff --git a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancermachines.yaml b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancermachines.yaml index f221a033..33e8052c 100644 --- a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancermachines.yaml +++ b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancermachines.yaml @@ -100,6 +100,10 @@ spec: networkID: description: NetworkID defines an openstack ID for the network. type: string + subnetworkID: + description: SubnetworkID defines an openstack ID for the + subnetwork. + type: string required: - networkID type: object diff --git a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancers.yaml b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancers.yaml index 71109279..1d18db00 100644 --- a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancers.yaml +++ b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancers.yaml @@ -131,6 +131,10 @@ spec: networkID: description: NetworkID defines an openstack ID for the network. type: string + subnetworkID: + description: SubnetworkID defines an openstack ID for the + subnetwork. + type: string required: - networkID type: object diff --git a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancersets.yaml b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancersets.yaml index 73121874..9d8bea50 100644 --- a/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancersets.yaml +++ b/charts/yawol-controller/crds/yawol.stackit.cloud_loadbalancersets.yaml @@ -165,6 +165,10 @@ spec: description: NetworkID defines an openstack ID for the network. type: string + subnetworkID: + description: SubnetworkID defines an openstack ID + for the subnetwork. + type: string required: - networkID type: object diff --git a/charts/yawol-controller/templates/yawol-cloud-controller.yaml b/charts/yawol-controller/templates/yawol-cloud-controller.yaml index 303a77ac..496349bd 100644 --- a/charts/yawol-controller/templates/yawol-cloud-controller.yaml +++ b/charts/yawol-controller/templates/yawol-cloud-controller.yaml @@ -61,6 +61,10 @@ spec: - name: NETWORK_ID value: {{ .Values.yawolNetworkID }} {{- end }} + {{- if .Values.yawolSubnetworkID }} + - name: SUBNETWORK_ID + value: {{ .Values.yawolSubnetworkID }} + {{- end }} {{- if .Values.yawolFlavorID }} - name: FLAVOR_ID value: {{ .Values.yawolFlavorID }} diff --git a/charts/yawol-controller/values.yaml b/charts/yawol-controller/values.yaml index 02bbb32c..07eba3d8 100644 --- a/charts/yawol-controller/values.yaml +++ b/charts/yawol-controller/values.yaml @@ -86,6 +86,12 @@ yawolFloatingID: # Placed in LoadBalancer.spec.infrastructure.networkID yawolNetworkID: +# OpenStack subnetwork ID in which the Load Balancer is placed. +# If not set, the subnetwork is chosen automatically. +# +# Placed in LoadBalancer.spec.infrastructure.subnetworkID +yawolSubnetworkID: + # default value for flavor that yawol Load Balancer instances should use # can be overridden by annotation # diff --git a/cmd/yawol-cloud-controller/main.go b/cmd/yawol-cloud-controller/main.go index 4c019d32..1319abc4 100644 --- a/cmd/yawol-cloud-controller/main.go +++ b/cmd/yawol-cloud-controller/main.go @@ -47,6 +47,8 @@ const ( EnvFloatingNetID = "FLOATING_NET_ID" // Openstack NetworkID for LB EnvNetworkID = "NETWORK_ID" + // OpenStack SubnetworkID for LB + EnvSubnetworkID = "SUBNETWORK_ID" // Flavor Information // one must be set EnvFlavorID = "FLAVOR_ID" @@ -300,6 +302,7 @@ func getInfrastructureDefaultsFromEnvOrDie() targetcontroller.InfrastructureDefa if networkID = os.Getenv(EnvNetworkID); networkID == "" { panic("could not read env " + EnvNetworkID) } + subnetworkID := os.Getenv(EnvSubnetworkID) var clusterNamespace string if clusterNamespace = os.Getenv(EnvClusterNamespace); clusterNamespace == "" { @@ -358,6 +361,7 @@ func getInfrastructureDefaultsFromEnvOrDie() targetcontroller.InfrastructureDefa AuthSecretName: ptr.To(authSecretName), FloatingNetworkID: ptr.To(floatingNetworkID), NetworkID: ptr.To(networkID), + SubnetworkID: ptr.To(subnetworkID), Namespace: ptr.To(clusterNamespace), FlavorRef: &yawolv1beta1.OpenstackFlavorRef{ FlavorID: flavorID, diff --git a/controllers/yawol-cloud-controller/targetcontroller/infrastructure_defaults.go b/controllers/yawol-cloud-controller/targetcontroller/infrastructure_defaults.go index 28b63e3b..16c14654 100644 --- a/controllers/yawol-cloud-controller/targetcontroller/infrastructure_defaults.go +++ b/controllers/yawol-cloud-controller/targetcontroller/infrastructure_defaults.go @@ -12,6 +12,7 @@ type InfrastructureDefaults struct { AuthSecretName *string FloatingNetworkID *string NetworkID *string + SubnetworkID *string Namespace *string FlavorRef *yawolv1beta1.OpenstackFlavorRef ImageRef *yawolv1beta1.OpenstackImageRef diff --git a/controllers/yawol-cloud-controller/targetcontroller/service_controller.go b/controllers/yawol-cloud-controller/targetcontroller/service_controller.go index 801e33e3..bb95d13b 100644 --- a/controllers/yawol-cloud-controller/targetcontroller/service_controller.go +++ b/controllers/yawol-cloud-controller/targetcontroller/service_controller.go @@ -634,6 +634,7 @@ func getDefaultNetwork( defaultNetwork := yawolv1beta1.LoadBalancerDefaultNetwork{ FloatingNetID: infraConfig.FloatingNetworkID, NetworkID: *infraConfig.NetworkID, + SubnetworkID: infraConfig.SubnetworkID, } if networkID, ok := svc.Annotations[yawolv1beta1.ServiceDefaultNetworkID]; ok { @@ -643,6 +644,10 @@ func getDefaultNetwork( if floatingID, ok := svc.Annotations[yawolv1beta1.ServiceFloatingNetworkID]; ok { defaultNetwork.FloatingNetID = &floatingID } + + if subnetworkID, ok := svc.Annotations[yawolv1beta1.ServiceDefaultSubnetworkID]; ok { + defaultNetwork.SubnetworkID = &subnetworkID + } return defaultNetwork } diff --git a/controllers/yawol-controller/loadbalancer/loadbalancer_controller.go b/controllers/yawol-controller/loadbalancer/loadbalancer_controller.go index f9ad39a6..e39cf313 100644 --- a/controllers/yawol-controller/loadbalancer/loadbalancer_controller.go +++ b/controllers/yawol-controller/loadbalancer/loadbalancer_controller.go @@ -560,11 +560,17 @@ func (r *Reconciler) reconcilePort( //nolint: gocyclo // TODO reduce complexity networkID = lb.Spec.Infrastructure.DefaultNetwork.NetworkID } + var subnetworkID string + if lb.Spec.Infrastructure.DefaultNetwork.SubnetworkID != nil { + subnetworkID = *lb.Spec.Infrastructure.DefaultNetwork.SubnetworkID + } + port, err = openstackhelper.CreatePort( ctx, portClient, *lb.Status.PortName, networkID, + subnetworkID, ) if err != nil { r.Log.Info("unexpected error occurred claiming a port", "lb", req.NamespacedName) diff --git a/controllers/yawol-controller/loadbalancermachine/loadbalancermachine_controller.go b/controllers/yawol-controller/loadbalancermachine/loadbalancermachine_controller.go index dbdd972a..0cd602e2 100644 --- a/controllers/yawol-controller/loadbalancermachine/loadbalancermachine_controller.go +++ b/controllers/yawol-controller/loadbalancermachine/loadbalancermachine_controller.go @@ -471,6 +471,11 @@ func (r *LoadBalancerMachineReconciler) reconcilePort( //nolint: gocyclo // TODO return helper.ErrNoNetworkID } + var subnetworkID string + if lbm.Spec.Infrastructure.DefaultNetwork.SubnetworkID != nil { + subnetworkID = *lbm.Spec.Infrastructure.DefaultNetwork.SubnetworkID + } + var portClient os.PortClient portClient, err = osClient.PortClient(ctx) if err != nil { @@ -509,7 +514,8 @@ func (r *LoadBalancerMachineReconciler) reconcilePort( //nolint: gocyclo // TODO ctx, portClient, *lbm.Status.DefaultPortName, - networkID) + networkID, + subnetworkID) if err != nil { r.Log.Info("unexpected error occurred claiming a port", "lbm", lbm.Name) return kubernetes.SendErrorAsEvent(r.RecorderLB, err, lbm) diff --git a/internal/helper/openstack/port.go b/internal/helper/openstack/port.go index 3081ae93..350c0acc 100644 --- a/internal/helper/openstack/port.go +++ b/internal/helper/openstack/port.go @@ -38,11 +38,17 @@ func CreatePort( portClient openstack.PortClient, portName string, networkID string, + subnetworkID string, ) (*ports.Port, error) { opts := ports.CreateOpts{ Name: portName, NetworkID: networkID, } + if subnetworkID != "" { + opts.FixedIPs = []ports.IP{ + {SubnetID: subnetworkID}, + } + } port, err := portClient.Create(ctx, opts) if err != nil { return nil, err