diff --git a/api/v1beta1/azurecluster_default.go b/api/v1beta1/azurecluster_default.go index bcbe32bbfd0..341c47826e3 100644 --- a/api/v1beta1/azurecluster_default.go +++ b/api/v1beta1/azurecluster_default.go @@ -18,6 +18,7 @@ package v1beta1 import ( "fmt" + "sigs.k8s.io/cluster-api-provider-azure/feature" "k8s.io/utils/ptr" ) @@ -245,6 +246,29 @@ func (c *AzureCluster) setAPIServerLBDefaults() { }, } } + // if the API Server ILB feature is enabled, we should create a default internal LB IP + if feature.Gates.Enabled(feature.APIServerILB) { + privateIPFound := false + for i := range lb.FrontendIPs { + if lb.FrontendIPs[i].FrontendIPClass.PrivateIPAddress != "" { + if lb.FrontendIPs[i].Name == "" { + lb.FrontendIPs[i].Name = generateFrontendIPConfigName(lb.Name) + "-internal-ip" + } + privateIPFound = true + break + } + } + // if no private IP is found, we should create a default internal LB IP + if !privateIPFound { + privateIP := FrontendIP{ + Name: generateFrontendIPConfigName(lb.Name) + "-internal-ip", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: DefaultInternalLBIPAddress, + }, + } + lb.FrontendIPs = append(lb.FrontendIPs, privateIP) + } + } } else if lb.Type == Internal { if lb.Name == "" { lb.Name = generateInternalLBName(c.ObjectMeta.Name) diff --git a/api/v1beta1/azurecluster_default_test.go b/api/v1beta1/azurecluster_default_test.go index 507bb86f139..b434d76da50 100644 --- a/api/v1beta1/azurecluster_default_test.go +++ b/api/v1beta1/azurecluster_default_test.go @@ -18,7 +18,10 @@ package v1beta1 import ( "encoding/json" + "k8s.io/component-base/featuregate" + featuregatetesting "k8s.io/component-base/featuregate/testing" "reflect" + "sigs.k8s.io/cluster-api-provider-azure/feature" "testing" corev1 "k8s.io/api/core/v1" @@ -1236,9 +1239,10 @@ func TestVnetPeeringDefaults(t *testing.T) { func TestAPIServerLBDefaults(t *testing.T) { cases := []struct { - name string - cluster *AzureCluster - output *AzureCluster + name string + featureGates map[featuregate.Feature]bool + cluster *AzureCluster + output *AzureCluster }{ { name: "no lb", @@ -1375,16 +1379,243 @@ func TestAPIServerLBDefaults(t *testing.T) { }, }, }, + { + name: "no lb with APIServerILB feature gate enabled", + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + cluster: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + ControlPlaneEnabled: true, + NetworkSpec: NetworkSpec{}, + }, + }, + output: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + ControlPlaneEnabled: true, + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + Name: "cluster-test-public-lb", + FrontendIPs: []FrontendIP{ + { + Name: "cluster-test-public-lb-frontEnd", + PublicIP: &PublicIPSpec{ + Name: "pip-cluster-test-apiserver", + DNSName: "", + }, + }, + { + Name: "cluster-test-public-lb-frontEnd-internal-ip", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: DefaultInternalLBIPAddress, + }, + }, + }, + BackendPool: BackendPool{ + Name: "cluster-test-public-lb-backendPool", + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + SKU: SKUStandard, + Type: Public, + IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes), + }, + }, + }, + }, + }, + }, + { + name: "internal lb with APIServerILB feature gate enabled", + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + cluster: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Internal, + }, + }, + }, + }, + }, + output: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "cluster-test-internal-lb-frontEnd", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: DefaultInternalLBIPAddress, + }, + }, + }, + BackendPool: BackendPool{ + Name: "cluster-test-internal-lb-backendPool", + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + SKU: SKUStandard, + Type: Internal, + IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes), + }, + Name: "cluster-test-internal-lb", + }, + }, + }, + }, + }, + { + name: "with custom backend pool name with APIServerILB feature gate enabled", + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + cluster: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Internal, + }, + BackendPool: BackendPool{ + Name: "custom-backend-pool", + }, + }, + }, + }, + }, + output: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "cluster-test-internal-lb-frontEnd", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: DefaultInternalLBIPAddress, + }, + }, + }, + BackendPool: BackendPool{ + Name: "custom-backend-pool", + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + SKU: SKUStandard, + Type: Internal, + IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes), + }, + Name: "cluster-test-internal-lb", + }, + }, + }, + }, + }, + { + name: "public lb with APIServerILB feature gate enabled and custom private IP belonging to default control plane CIDR", + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + cluster: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + ControlPlaneEnabled: true, + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + Name: "cluster-test-public-lb", + FrontendIPs: []FrontendIP{ + { + Name: "cluster-test-public-lb-frontEnd", + PublicIP: &PublicIPSpec{ + Name: "pip-cluster-test-apiserver", + DNSName: "", + }, + }, + { + Name: "my-internal-ip", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "10.0.0.111", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + SKU: SKUStandard, + }, + }, + }, + }, + }, + output: &AzureCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-test", + }, + Spec: AzureClusterSpec{ + ControlPlaneEnabled: true, + NetworkSpec: NetworkSpec{ + APIServerLB: &LoadBalancerSpec{ + Name: "cluster-test-public-lb", + FrontendIPs: []FrontendIP{ + { + Name: "cluster-test-public-lb-frontEnd", + PublicIP: &PublicIPSpec{ + Name: "pip-cluster-test-apiserver", + DNSName: "", + }, + }, + { + Name: "my-internal-ip", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "10.0.0.111", + }, + }, + }, + BackendPool: BackendPool{ + Name: "cluster-test-public-lb-backendPool", + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + SKU: SKUStandard, + Type: Public, + IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes), + }, + }, + }, + }, + }, + }, } - for _, c := range cases { - tc := c - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - tc.cluster.setAPIServerLBDefaults() - if !reflect.DeepEqual(tc.cluster, tc.output) { - expected, _ := json.MarshalIndent(tc.output, "", "\t") - actual, _ := json.MarshalIndent(tc.cluster, "", "\t") + for _, testcase := range cases { + t.Run(testcase.name, func(t *testing.T) { + if testcase.featureGates != nil { + for featureKey, featureValue := range testcase.featureGates { + defer featuregatetesting.SetFeatureGateDuringTest(t, feature.Gates, featureKey, featureValue)() + } + } + testcase.cluster.setAPIServerLBDefaults() + if !reflect.DeepEqual(testcase.cluster, testcase.output) { + expected, _ := json.MarshalIndent(testcase.output, "", "\t") + actual, _ := json.MarshalIndent(testcase.cluster, "", "\t") t.Errorf("Expected %s, got %s", string(expected), string(actual)) } }) diff --git a/api/v1beta1/azurecluster_validation.go b/api/v1beta1/azurecluster_validation.go index 667065c3a34..88f4f95fc23 100644 --- a/api/v1beta1/azurecluster_validation.go +++ b/api/v1beta1/azurecluster_validation.go @@ -412,37 +412,62 @@ func validateAPIServerLB(lb *LoadBalancerSpec, old *LoadBalancerSpec, cidrs []st allErrs = append(allErrs, field.Forbidden(fldPath.Child("name"), "API Server load balancer name should not be modified after AzureCluster creation.")) } - // There should only be one IP config. - if len(lb.FrontendIPs) != 1 || ptr.Deref[int32](lb.FrontendIPsCount, 1) != 1 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("frontendIPConfigs"), lb.FrontendIPs, - "API Server Load balancer should have 1 Frontend IP")) - } else { - // if Internal, IP config should not have a public IP. - if lb.Type == Internal { - if lb.FrontendIPs[0].PublicIP != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("frontendIPConfigs").Index(0).Child("publicIP"), - "Internal Load Balancers cannot have a Public IP")) - } - if lb.FrontendIPs[0].PrivateIPAddress != "" { - if err := validateInternalLBIPAddress(lb.FrontendIPs[0].PrivateIPAddress, cidrs, - fldPath.Child("frontendIPConfigs").Index(0).Child("privateIP")); err != nil { - allErrs = append(allErrs, err) - } - if len(old.FrontendIPs) != 0 && old.FrontendIPs[0].PrivateIPAddress != lb.FrontendIPs[0].PrivateIPAddress { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("name"), "API Server load balancer private IP should not be modified after AzureCluster creation.")) - } - } + publicIPCount := 0 + privateIPCount := 0 + privateIP := "" + for i := range lb.FrontendIPs { + if lb.FrontendIPs[i].PublicIP != nil { + publicIPCount++ + } + if lb.FrontendIPs[i].PrivateIPAddress != "" { + privateIPCount++ + privateIP = lb.FrontendIPs[i].PrivateIPAddress + } + } + + if lb.Type == Public { + // public IP count should be 1 for public LB. + if publicIPCount != 1 || ptr.Deref[int32](lb.FrontendIPsCount, 1) != 1 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("frontendIPConfigs"), lb.FrontendIPs, + "API Server Load balancer should have 1 Frontend IP")) } - // if Public, IP config should not have a private IP. - if lb.Type == Public { - if lb.FrontendIPs[0].PrivateIPAddress != "" { + if feature.Gates.Enabled(feature.APIServerILB) { + if err := validateInternalLBIPAddress(privateIP, cidrs, + fldPath.Child("frontendIPConfigs").Index(0).Child("privateIP")); err != nil { + allErrs = append(allErrs, err) + } + } else { + // API Server LB should not have a Private IP if APIServerILB feature is disabled. + if privateIPCount > 0 { allErrs = append(allErrs, field.Forbidden(fldPath.Child("frontendIPConfigs").Index(0).Child("privateIP"), "Public Load Balancers cannot have a Private IP")) } } } + // if Internal, IP config should not have a public IP. + if lb.Type == Internal { + if publicIPCount != 0 { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("frontendIPConfigs").Index(0).Child("publicIP"), + "Internal Load Balancers cannot have a Public IP")) + } + + if privateIPCount != 1 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("frontendIPConfigs"), lb.FrontendIPs, + "API Server Load balancer of type private should have 1 frontend private IP")) + } else { + if err := validateInternalLBIPAddress(lb.FrontendIPs[0].PrivateIPAddress, cidrs, + fldPath.Child("frontendIPConfigs").Index(0).Child("privateIP")); err != nil { + allErrs = append(allErrs, err) + } + + if len(old.FrontendIPs) != 0 && old.FrontendIPs[0].PrivateIPAddress != lb.FrontendIPs[0].PrivateIPAddress { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("name"), "API Server load balancer private IP should not be modified after AzureCluster creation.")) + } + } + } + return allErrs } diff --git a/api/v1beta1/azurecluster_validation_test.go b/api/v1beta1/azurecluster_validation_test.go index f9a169e83e0..19d7c4c0b9b 100644 --- a/api/v1beta1/azurecluster_validation_test.go +++ b/api/v1beta1/azurecluster_validation_test.go @@ -17,6 +17,9 @@ limitations under the License. package v1beta1 import ( + "k8s.io/component-base/featuregate" + featuregatetesting "k8s.io/component-base/featuregate/testing" + "sigs.k8s.io/cluster-api-provider-azure/feature" "testing" . "github.com/onsi/gomega" @@ -887,12 +890,13 @@ func TestValidateSecurityRule(t *testing.T) { func TestValidateAPIServerLB(t *testing.T) { testcases := []struct { - name string - lb LoadBalancerSpec - old LoadBalancerSpec - cpCIDRS []string - wantErr bool - expectedErr field.Error + name string + lb LoadBalancerSpec + old LoadBalancerSpec + cpCIDRS []string + featureGates map[featuregate.Feature]bool + wantErr bool + expectedErr field.Error }{ { name: "invalid SKU", @@ -947,6 +951,9 @@ func TestValidateAPIServerLB(t *testing.T) { { name: "too many IP configs", lb: LoadBalancerSpec{ + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + }, FrontendIPs: []FrontendIP{ { Name: "ip-1", @@ -971,6 +978,39 @@ func TestValidateAPIServerLB(t *testing.T) { Detail: "API Server Load balancer should have 1 Frontend IP", }, }, + { + name: "too many IP configs with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + }, + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + }, + { + Name: "ip-2", + }, + }, + }, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: true, + expectedErr: field.Error{ + Type: "FieldValueInvalid", + Field: "apiServerLB.frontendIPConfigs", + BadValue: []FrontendIP{ + { + Name: "ip-1", + }, + { + Name: "ip-2", + }, + }, + Detail: "API Server Load balancer should have 1 Frontend IP", + }, + }, { name: "public LB with private IP", lb: LoadBalancerSpec{ @@ -993,6 +1033,36 @@ func TestValidateAPIServerLB(t *testing.T) { Detail: "Public Load Balancers cannot have a Private IP", }, }, + { + name: "public LB with private IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + Name: "my-awesome-lb", + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + PublicIP: &PublicIPSpec{ + Name: "my-valid-frontend-ip", + DNSName: "my-valid-frontend-ip", + }, + }, + { + Name: "ip-2", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "10.0.0.111", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + SKU: SKUStandard, + }, + }, + cpCIDRS: []string{"10.0.0.0/24"}, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: false, + }, { name: "internal LB with public IP", lb: LoadBalancerSpec{ @@ -1015,6 +1085,31 @@ func TestValidateAPIServerLB(t *testing.T) { Detail: "Internal Load Balancers cannot have a Public IP", }, }, + { + name: "internal LB with public IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + PublicIP: &PublicIPSpec{ + Name: "my-invalid-ip", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Internal, + }, + }, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: true, + expectedErr: field.Error{ + Type: "FieldValueForbidden", + Field: "apiServerLB.frontendIPConfigs[0].publicIP", + Detail: "Internal Load Balancers cannot have a Public IP", + }, + }, { name: "internal LB with invalid private IP", lb: LoadBalancerSpec{ @@ -1038,6 +1133,32 @@ func TestValidateAPIServerLB(t *testing.T) { Detail: "Internal LB IP address isn't a valid IPv4 or IPv6 address", }, }, + { + name: "internal LB with invalid private IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "NAIP", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Internal, + }, + }, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: true, + expectedErr: field.Error{ + Type: "FieldValueInvalid", + Field: "apiServerLB.frontendIPConfigs[0].privateIP", + BadValue: "NAIP", + Detail: "Internal LB IP address isn't a valid IPv4 or IPv6 address", + }, + }, { name: "internal LB with out of range private IP", lb: LoadBalancerSpec{ @@ -1062,6 +1183,33 @@ func TestValidateAPIServerLB(t *testing.T) { Detail: "Internal LB IP address needs to be in control plane subnet range ([10.0.0.0/24 10.1.0.0/24])", }, }, + { + name: "internal LB with out of range private IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "20.1.2.3", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Internal, + }, + }, + cpCIDRS: []string{"10.0.0.0/24", "10.1.0.0/24"}, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: true, + expectedErr: field.Error{ + Type: "FieldValueInvalid", + Field: "apiServerLB.frontendIPConfigs[0].privateIP", + BadValue: "20.1.2.3", + Detail: "Internal LB IP address needs to be in control plane subnet range ([10.0.0.0/24 10.1.0.0/24])", + }, + }, { name: "internal LB with in range private IP", lb: LoadBalancerSpec{ @@ -1082,11 +1230,72 @@ func TestValidateAPIServerLB(t *testing.T) { cpCIDRS: []string{"10.0.0.0/24", "10.1.0.0/24"}, wantErr: false, }, + { + name: "public LB with in-range private IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "10.0.0.123", + }, + }, + { + Name: "ip-2", + PublicIP: &PublicIPSpec{ + Name: "my-valid-ip", + DNSName: "my-valid-ip", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + SKU: SKUStandard, + }, + Name: "my-private-lb", + }, + cpCIDRS: []string{"10.0.0.0/24"}, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: false, + }, + { + name: "public LB with out of range private IP with feature flag APIServerILB enabled", + lb: LoadBalancerSpec{ + FrontendIPs: []FrontendIP{ + { + Name: "ip-1", + FrontendIPClass: FrontendIPClass{ + PrivateIPAddress: "20.1.2.3", + }, + }, + }, + LoadBalancerClassSpec: LoadBalancerClassSpec{ + Type: Public, + }, + }, + cpCIDRS: []string{"10.0.0.0/24", "10.1.0.0/24"}, + featureGates: map[featuregate.Feature]bool{ + feature.APIServerILB: true, + }, + wantErr: true, + expectedErr: field.Error{ + Type: "FieldValueInvalid", + Field: "apiServerLB.frontendIPConfigs[0].privateIP", + BadValue: "20.1.2.3", + Detail: "Internal LB IP address needs to be in control plane subnet range ([10.0.0.0/24 10.1.0.0/24])", + }, + }, } for _, test := range testcases { t.Run(test.name, func(t *testing.T) { - t.Parallel() + if test.featureGates != nil { + for featureKey, featureValue := range test.featureGates { + defer featuregatetesting.SetFeatureGateDuringTest(t, feature.Gates, featureKey, featureValue)() + } + } g := NewWithT(t) err := validateAPIServerLB(&test.lb, &test.old, test.cpCIDRS, field.NewPath("apiServerLB")) if test.wantErr { diff --git a/azure/scope/cluster.go b/azure/scope/cluster.go index 58ae9a885a1..0fed0ac8396 100644 --- a/azure/scope/cluster.go +++ b/azure/scope/cluster.go @@ -269,7 +269,7 @@ func (s *ClusterScope) LBSpecs() []azure.ResourceSpecGetter { } // get the internal LB IP and the public LB IP - // apiServerLBInternalIP := infrav1.FrontendIP{} + apiServerInternalLBIP := infrav1.FrontendIP{} apiServerFrontendLBIP := make([]infrav1.FrontendIP, 0) if s.APIServerLB().FrontendIPs != nil { for _, frontendIP := range s.APIServerLB().FrontendIPs { @@ -279,9 +279,9 @@ func (s *ClusterScope) LBSpecs() []azure.ResourceSpecGetter { apiServerFrontendLBIP = append(apiServerFrontendLBIP, frontendIP) } - //if frontendIP.PrivateIPAddress != "" { - // apiServerLBInternalIP = frontendIP - //} + if frontendIP.PrivateIPAddress != "" { + apiServerInternalLBIP = frontendIP + } } } @@ -311,15 +311,7 @@ func (s *ClusterScope) LBSpecs() []azure.ResourceSpecGetter { } // set the internal IP for the internal LB - // internalLB.FrontendIPConfigs = []infrav1.FrontendIP{apiServerInternalLBIP} - internalLB.FrontendIPConfigs = []infrav1.FrontendIP{ - { - Name: s.APIServerLB().Name + "-internal-frontEnd", - FrontendIPClass: infrav1.FrontendIPClass{ - PrivateIPAddress: infrav1.DefaultInternalLBIPAddress, - }, - }, - } + internalLB.FrontendIPConfigs = []infrav1.FrontendIP{apiServerInternalLBIP} specs = append(specs, internalLB) } }