From a914c894bd7b1f32d4de5e09de548309c8682a43 Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Thu, 19 Sep 2024 06:34:51 +0000 Subject: [PATCH] wip --- api/bases/octavia.openstack.org_octavias.yaml | 3 +- api/v1beta1/octavia_types.go | 8 +- .../bases/octavia.openstack.org_octavias.yaml | 3 +- controllers/octavia_controller.go | 61 ++++++++---- pkg/octavia/lb_mgmt_network.go | 97 +++++++++++++++++-- pkg/octavia/network_parameters.go | 2 + 6 files changed, 137 insertions(+), 37 deletions(-) diff --git a/api/bases/octavia.openstack.org_octavias.yaml b/api/bases/octavia.openstack.org_octavias.yaml index 81ee8449..78273e6d 100644 --- a/api/bases/octavia.openstack.org_octavias.yaml +++ b/api/bases/octavia.openstack.org_octavias.yaml @@ -105,6 +105,7 @@ spec: type: object lbMgmtNetwork: default: + createDefaultLbMgmtNetwork: true manageLbMgmtNetworks: true description: OctaviaLbMgmtNetworks Settings for Octavia management networks @@ -123,7 +124,6 @@ spec: type: string type: array createDefaultLbMgmtNetwork: - default: true type: boolean lbMgmtRouterGateway: description: LbMgmtRouterGateway is the IP address of the Octavia @@ -132,7 +132,6 @@ spec: Attachment Definition type: string manageLbMgmtNetworks: - default: true type: boolean type: object nodeSelector: diff --git a/api/v1beta1/octavia_types.go b/api/v1beta1/octavia_types.go index 95fdd3e7..195a74f5 100644 --- a/api/v1beta1/octavia_types.go +++ b/api/v1beta1/octavia_types.go @@ -171,7 +171,7 @@ type OctaviaSpecBase struct { TenantName string `json:"tenantName"` // +kubebuilder:validation:Optional - // +kubebuilder:default={manageLbMgmtNetworks: true} + // +kubebuilder:default={manageLbMgmtNetworks: true, createDefaultLbMgmtNetwork: true} LbMgmtNetworks OctaviaLbMgmtNetworks `json:"lbMgmtNetwork"` // +kubebuilder:validation:Optional @@ -230,12 +230,10 @@ type PasswordSelector struct { // OctaviaLbMgmtNetworks Settings for Octavia management networks type OctaviaLbMgmtNetworks struct { // +kubebuilder:validation:Optional - // +kubebuilder:default=true - ManageLbMgmtNetworks bool `json:"manageLbMgmtNetworks,omitempty"` + ManageLbMgmtNetworks bool `json:"manageLbMgmtNetworks"` // +kubebuilder:validation:Optional - // +kubebuilder:default=true - CreateDefaultLbMgmtNetwork bool `json:"createDefaultLbMgmtNetwork,omitempty"` + CreateDefaultLbMgmtNetwork bool `json:"createDefaultLbMgmtNetwork"` // +kubebuilder:validation:Optional // LbMgmtRouterGateway is the IP address of the Octavia router on the diff --git a/config/crd/bases/octavia.openstack.org_octavias.yaml b/config/crd/bases/octavia.openstack.org_octavias.yaml index 81ee8449..78273e6d 100644 --- a/config/crd/bases/octavia.openstack.org_octavias.yaml +++ b/config/crd/bases/octavia.openstack.org_octavias.yaml @@ -105,6 +105,7 @@ spec: type: object lbMgmtNetwork: default: + createDefaultLbMgmtNetwork: true manageLbMgmtNetworks: true description: OctaviaLbMgmtNetworks Settings for Octavia management networks @@ -123,7 +124,6 @@ spec: type: string type: array createDefaultLbMgmtNetwork: - default: true type: boolean lbMgmtRouterGateway: description: LbMgmtRouterGateway is the IP address of the Octavia @@ -132,7 +132,6 @@ spec: Attachment Definition type: string manageLbMgmtNetworks: - default: true type: boolean type: object nodeSelector: diff --git a/controllers/octavia_controller.go b/controllers/octavia_controller.go index f0fe3264..a2cd0d1c 100644 --- a/controllers/octavia_controller.go +++ b/controllers/octavia_controller.go @@ -660,25 +660,48 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav return ctrl.Result{}, err } - // Create load balancer management network and get its Id (networkInfo is actually a struct and contains - // multiple details. - networkInfo, err := octavia.EnsureAmphoraManagementNetwork( - ctx, - instance.Namespace, - instance.Spec.TenantName, - &instance.Spec.LbMgmtNetworks, - networkParameters, - &Log, - helper, - ) - if err != nil { - instance.Status.Conditions.Set(condition.FalseCondition( - octaviav1.OctaviaManagementNetworkReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - octaviav1.OctaviaManagementNetworkReadyErrorMessage, - err.Error())) - return ctrl.Result{}, err + var networkInfo octavia.NetworkProvisioningSummary + + if instance.Spec.LbMgmtNetworks.ManageLbMgmtNetworks == true { + // Create load balancer management network and get its Id (networkInfo is actually a struct and contains + // multiple details. + networkInfo, err = octavia.EnsureAmphoraManagementNetwork( + ctx, + instance.Namespace, + instance.Spec.TenantName, + &instance.Spec.LbMgmtNetworks, + networkParameters, + &Log, + helper, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + octaviav1.OctaviaManagementNetworkReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + octaviav1.OctaviaManagementNetworkReadyErrorMessage, + err.Error())) + return ctrl.Result{}, err + } + } else { + networkInfo, err = octavia.HandleUnmanagedAmphoraManagementNetwork( + ctx, + instance.Namespace, + instance.Spec.TenantName, + &instance.Spec.LbMgmtNetworks, + networkParameters, + &Log, + helper, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + octaviav1.OctaviaManagementNetworkReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + octaviav1.OctaviaManagementNetworkReadyErrorMessage, + err.Error())) + return ctrl.Result{}, err + } } instance.Status.Conditions.MarkTrue(octaviav1.OctaviaManagementNetworkReadyCondition, octaviav1.OctaviaManagementNetworkReadyCompleteMessage) Log.Info(fmt.Sprintf("Using management network \"%s\"", networkInfo.TenantNetworkID)) diff --git a/pkg/octavia/lb_mgmt_network.go b/pkg/octavia/lb_mgmt_network.go index 4761a1ee..13a89e81 100644 --- a/pkg/octavia/lb_mgmt_network.go +++ b/pkg/octavia/lb_mgmt_network.go @@ -37,9 +37,6 @@ import ( // Type for conveying the results of the EnsureAmphoraManagementNetwork call. type NetworkProvisioningSummary struct { TenantNetworkID string - TenantSubnetID string - ProviderNetworkID string - RouterID string SecurityGroupID string ManagementSubnetCIDR string ManagementSubnetGateway string @@ -208,6 +205,25 @@ func getNetworkExt(client *gophercloud.ServiceClient, networkName string, servic return nil, nil } +func getSubnet(client *gophercloud.ServiceClient, subnetName string, serviceTenantID string) (*subnets.Subnet, error) { + listOpts := subnets.ListOpts{ + Name: subnetName, + TenantID: serviceTenantID, + } + allPages, err := subnets.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + allSubnets, err := subnets.ExtractSubnets(allPages) + if err != nil { + return nil, err + } + if len(allSubnets) > 0 { + return &allSubnets[0], nil + } + return nil, nil +} + func ensureNetwork(client *gophercloud.ServiceClient, createOpts networks.CreateOpts, log *logr.Logger, serviceTenantID string) (*networks.Network, error) { foundNetwork, err := getNetwork(client, createOpts.Name, serviceTenantID) @@ -805,6 +821,74 @@ func ensureSecurityGroup( return secGroup.ID, nil } +func HandleUnmanagedAmphoraManagementNetwork( + ctx context.Context, + ns string, + tenantName string, + netDetails *octaviav1.OctaviaLbMgmtNetworks, + networkParameters *NetworkParameters, + log *logr.Logger, + helper *helper.Helper, +) (NetworkProvisioningSummary, error) { + o, err := GetOpenstackClient(ctx, ns, helper) + if err != nil { + return NetworkProvisioningSummary{}, err + } + client, err := GetNetworkClient(o) + if err != nil { + return NetworkProvisioningSummary{}, err + } + adminTenant, err := GetProject(o, AdminTenant) + if err != nil { + return NetworkProvisioningSummary{}, err + } + serviceTenant, err := GetProject(o, tenantName) + if err != nil { + return NetworkProvisioningSummary{}, err + } + + // get security-group-id + // get octavia-link-router + // get lb-mgmt--subnet + tenantNetworkID := "" + network, err := getNetwork(client, LbProvNetName, adminTenant.ID) + if err == nil && network != nil { + tenantNetworkID = network.ID + } + + managementSubnetGateway := "" + router, err := findRouter(client, log) + if err == nil && router != nil { + if len(router.GatewayInfo.ExternalFixedIPs) > 0 { + managementSubnetGateway = router.GatewayInfo.ExternalFixedIPs[0].IPAddress + } else { + log.Info("No external fixedIP on router %s, skipping", router.Name) + } + } + + managementSubnetCIDR := "" + subnet, err := getSubnet(client, LbMgmtSubnetName, serviceTenant.ID) + if err == nil && subnet != nil { + managementSubnetCIDR = subnet.CIDR + } + + managementSubnetExtraCIDRs := []string{} + for _, az := range netDetails.AvailabilityZones { + subnet, err := getSubnet(client, fmt.Sprintf(LbMgmtSubnetNameAZ, az), serviceTenant.ID) + if err == nil && subnet != nil { + managementSubnetExtraCIDRs = append(managementSubnetExtraCIDRs, subnet.CIDR) + } + } + + return NetworkProvisioningSummary{ + TenantNetworkID: tenantNetworkID, + SecurityGroupID: "", // TODO(gthiemonge) + ManagementSubnetCIDR: managementSubnetCIDR, + ManagementSubnetGateway: managementSubnetGateway, + ManagementSubnetExtraCIDRs: managementSubnetExtraCIDRs, + }, nil +} + // EnsureAmphoraManagementNetwork - retrieve, create and reconcile the Octavia management network for the in cluster link to the // management tenant network. func EnsureAmphoraManagementNetwork( @@ -844,7 +928,6 @@ func EnsureAmphoraManagementNetwork( var tenantSubnet *subnets.Subnet var tenantRouterPort *ports.Port tenantNetworkID := "" - tenantSubnetID := "" if netDetails.CreateDefaultLbMgmtNetwork { tenantNetwork, err = ensureLbMgmtNetwork(client, nil, netDetails, serviceTenant.ID, log) @@ -857,7 +940,6 @@ func EnsureAmphoraManagementNetwork( if err != nil { return NetworkProvisioningSummary{}, err } - tenantSubnetID = tenantSubnet.ID tenantRouterPort, _, err = ensurePort(client, nil, tenantNetwork, &securityGroups, log) if err != nil { @@ -943,7 +1025,7 @@ func EnsureAmphoraManagementNetwork( managementSubnetAZCIDRs := []string{} for az, cidr := range netDetails.AvailabilityZoneCIDRs { // Create Management network and subnet for AZ - network, err := ensureLbMgmtNetwork(client, &az, netDetails, adminTenant.ID, log) + network, err := ensureLbMgmtNetwork(client, &az, netDetails, serviceTenant.ID, log) if err != nil { return NetworkProvisioningSummary{}, err } @@ -997,9 +1079,6 @@ func EnsureAmphoraManagementNetwork( return NetworkProvisioningSummary{ TenantNetworkID: tenantNetworkID, - TenantSubnetID: tenantSubnetID, - ProviderNetworkID: providerNetwork.ID, - RouterID: router.ID, SecurityGroupID: lbMgmtSecurityGroupID, ManagementSubnetCIDR: managementSubnetCIDR, ManagementSubnetGateway: networkParameters.ProviderGateway.String(), diff --git a/pkg/octavia/network_parameters.go b/pkg/octavia/network_parameters.go index 9e1f35f4..2bfa9224 100644 --- a/pkg/octavia/network_parameters.go +++ b/pkg/octavia/network_parameters.go @@ -124,6 +124,8 @@ func GetNetworkParametersFromNAD( if err != nil { return nil, fmt.Errorf("cannot parse gateway information: %w", err) } + } else if !instance.Spec.LbMgmtNetworks.ManageLbMgmtNetworks { + return networkParameters, nil // TODO(gthiemonge) } else { return nil, fmt.Errorf("cannot find gateway information in network attachment") }