Skip to content

Commit 217c1d7

Browse files
committed
make control plane lb configurable
1 parent 7344eb9 commit 217c1d7

File tree

8 files changed

+283
-48
lines changed

8 files changed

+283
-48
lines changed

api/v1alpha3/azurecluster_conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
5454
dst.Spec.NetworkSpec.APIServerLB.FrontendIPsCount = restored.Spec.NetworkSpec.APIServerLB.FrontendIPsCount
5555
dst.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes = restored.Spec.NetworkSpec.APIServerLB.IdleTimeoutInMinutes
5656
dst.Spec.NetworkSpec.NodeOutboundLB = restored.Spec.NetworkSpec.NodeOutboundLB
57+
dst.Spec.NetworkSpec.ControlPlaneOutboundLB = restored.Spec.NetworkSpec.ControlPlaneOutboundLB
5758
dst.Spec.CloudProviderConfigOverrides = restored.Spec.CloudProviderConfigOverrides
5859
dst.Spec.BastionSpec = restored.Spec.BastionSpec
5960

api/v1alpha3/zz_generated.conversion.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha4/azurecluster_default.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func (c *AzureCluster) setNetworkSpecDefaults() {
5353
c.setSubnetDefaults()
5454
c.setAPIServerLBDefaults()
5555
c.setNodeOutboundLBDefaults()
56+
c.setControlPlaneOutboundLBDefaults()
5657
}
5758

5859
func (c *AzureCluster) setResourceGroupDefault() {
@@ -196,6 +197,42 @@ func (c *AzureCluster) setNodeOutboundLBDefaults() {
196197
lb.FrontendIPsCount = pointer.Int32Ptr(1)
197198
}
198199

200+
c.setOutboundLBFrontendIPs(lb, generateNodeOutboundIPName)
201+
}
202+
203+
func (c *AzureCluster) setControlPlaneOutboundLBDefaults() {
204+
// public clusters don't need control plane outbound lb
205+
if c.Spec.NetworkSpec.APIServerLB.Type == Public {
206+
return
207+
}
208+
209+
// private clusters can disable control plane outbound lb by setting it to nil.
210+
if c.Spec.NetworkSpec.ControlPlaneOutboundLB == nil {
211+
return
212+
}
213+
214+
lb := c.Spec.NetworkSpec.ControlPlaneOutboundLB
215+
lb.Type = Public
216+
lb.SKU = SKUStandard
217+
218+
if lb.Name == "" {
219+
lb.Name = generateControlPlaneOutboundLBName(c.ObjectMeta.Name)
220+
}
221+
222+
if lb.IdleTimeoutInMinutes == nil {
223+
lb.IdleTimeoutInMinutes = pointer.Int32Ptr(DefaultOutboundRuleIdleTimeoutInMinutes)
224+
}
225+
226+
if lb.FrontendIPsCount == nil {
227+
lb.FrontendIPsCount = pointer.Int32Ptr(1)
228+
}
229+
230+
c.setOutboundLBFrontendIPs(lb, generateControlPlaneOutboundIPName)
231+
}
232+
233+
// setOutboundLBFrontendIPs sets the frontend ips for the given load balancer.
234+
// The name of the frontend ip is generated using generatePublicIPName function.
235+
func (c *AzureCluster) setOutboundLBFrontendIPs(lb *LoadBalancerSpec, generatePublicIPName func(string) string) {
199236
switch *lb.FrontendIPsCount {
200237
case 0:
201238
lb.FrontendIPs = []FrontendIP{}
@@ -204,7 +241,7 @@ func (c *AzureCluster) setNodeOutboundLBDefaults() {
204241
{
205242
Name: generateFrontendIPConfigName(lb.Name),
206243
PublicIP: &PublicIPSpec{
207-
Name: generateNodeOutboundIPName(c.ObjectMeta.Name),
244+
Name: generatePublicIPName(c.ObjectMeta.Name),
208245
},
209246
},
210247
}
@@ -214,7 +251,7 @@ func (c *AzureCluster) setNodeOutboundLBDefaults() {
214251
lb.FrontendIPs[i] = FrontendIP{
215252
Name: withIndex(generateFrontendIPConfigName(lb.Name), i+1),
216253
PublicIP: &PublicIPSpec{
217-
Name: withIndex(generateNodeOutboundIPName(c.ObjectMeta.Name), i+1),
254+
Name: withIndex(generatePublicIPName(c.ObjectMeta.Name), i+1),
218255
},
219256
}
220257
}
@@ -294,6 +331,11 @@ func generatePublicLBName(clusterName string) string {
294331
return fmt.Sprintf("%s-%s", clusterName, "public-lb")
295332
}
296333

334+
// generateControlPlaneOutboundLBName generates the name of the control plane outbound LB.
335+
func generateControlPlaneOutboundLBName(clusterName string) string {
336+
return fmt.Sprintf("%s-outbound-lb", clusterName)
337+
}
338+
297339
// generatePublicIPName generates a public IP name, based on the cluster name and a hash.
298340
func generatePublicIPName(clusterName string) string {
299341
return fmt.Sprintf("pip-%s-apiserver", clusterName)
@@ -309,6 +351,11 @@ func generateNodeOutboundIPName(clusterName string) string {
309351
return fmt.Sprintf("pip-%s-node-outbound", clusterName)
310352
}
311353

354+
// generateControlPlaneOutboundIPName generates a public IP name, based on the cluster name.
355+
func generateControlPlaneOutboundIPName(clusterName string) string {
356+
return fmt.Sprintf("pip-%s-controlplane-outbound", clusterName)
357+
}
358+
312359
// withIndex appends the index as suffix to a generated name.
313360
func withIndex(name string, n int) string {
314361
return fmt.Sprintf("%s-%d", name, n)

api/v1alpha4/azurecluster_default_test.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,128 @@ func TestNodeOutboundLBDefaults(t *testing.T) {
916916
}
917917
}
918918

919+
func TestControlPlaneOutboundLBDefaults(t *testing.T) {
920+
cases := []struct {
921+
name string
922+
cluster *AzureCluster
923+
output *AzureCluster
924+
}{
925+
{
926+
name: "no cp lb for public clusters",
927+
cluster: &AzureCluster{
928+
ObjectMeta: v1.ObjectMeta{
929+
Name: "cluster-test",
930+
},
931+
Spec: AzureClusterSpec{
932+
NetworkSpec: NetworkSpec{
933+
APIServerLB: LoadBalancerSpec{Type: Public},
934+
},
935+
},
936+
},
937+
output: &AzureCluster{
938+
ObjectMeta: v1.ObjectMeta{
939+
Name: "cluster-test",
940+
},
941+
Spec: AzureClusterSpec{
942+
NetworkSpec: NetworkSpec{
943+
APIServerLB: LoadBalancerSpec{
944+
Type: Public,
945+
},
946+
},
947+
},
948+
},
949+
},
950+
{
951+
name: "no cp lb for private clusters",
952+
cluster: &AzureCluster{
953+
ObjectMeta: v1.ObjectMeta{
954+
Name: "cluster-test",
955+
},
956+
Spec: AzureClusterSpec{
957+
NetworkSpec: NetworkSpec{
958+
APIServerLB: LoadBalancerSpec{Type: Internal},
959+
},
960+
},
961+
},
962+
output: &AzureCluster{
963+
ObjectMeta: v1.ObjectMeta{
964+
Name: "cluster-test",
965+
},
966+
Spec: AzureClusterSpec{
967+
NetworkSpec: NetworkSpec{
968+
APIServerLB: LoadBalancerSpec{
969+
Type: Internal,
970+
},
971+
},
972+
},
973+
},
974+
},
975+
{
976+
name: "frontendIPsCount > 1",
977+
cluster: &AzureCluster{
978+
ObjectMeta: v1.ObjectMeta{
979+
Name: "cluster-test",
980+
},
981+
Spec: AzureClusterSpec{
982+
NetworkSpec: NetworkSpec{
983+
APIServerLB: LoadBalancerSpec{Type: Internal},
984+
ControlPlaneOutboundLB: &LoadBalancerSpec{
985+
FrontendIPsCount: to.Int32Ptr(2),
986+
IdleTimeoutInMinutes: to.Int32Ptr(15),
987+
},
988+
},
989+
},
990+
},
991+
output: &AzureCluster{
992+
ObjectMeta: v1.ObjectMeta{
993+
Name: "cluster-test",
994+
},
995+
Spec: AzureClusterSpec{
996+
NetworkSpec: NetworkSpec{
997+
APIServerLB: LoadBalancerSpec{
998+
Type: Internal,
999+
},
1000+
ControlPlaneOutboundLB: &LoadBalancerSpec{
1001+
Name: "cluster-test-outbound-lb",
1002+
SKU: SKUStandard,
1003+
FrontendIPs: []FrontendIP{
1004+
{
1005+
Name: "cluster-test-outbound-lb-frontEnd-1",
1006+
PublicIP: &PublicIPSpec{
1007+
Name: "pip-cluster-test-controlplane-outbound-1",
1008+
},
1009+
},
1010+
{
1011+
Name: "cluster-test-outbound-lb-frontEnd-2",
1012+
PublicIP: &PublicIPSpec{
1013+
Name: "pip-cluster-test-controlplane-outbound-2",
1014+
},
1015+
},
1016+
},
1017+
Type: Public,
1018+
FrontendIPsCount: to.Int32Ptr(2),
1019+
IdleTimeoutInMinutes: to.Int32Ptr(15),
1020+
},
1021+
},
1022+
},
1023+
},
1024+
},
1025+
}
1026+
1027+
for _, c := range cases {
1028+
tc := c
1029+
t.Run(tc.name, func(t *testing.T) {
1030+
t.Parallel()
1031+
tc.cluster.setControlPlaneOutboundLBDefaults()
1032+
if !reflect.DeepEqual(tc.cluster, tc.output) {
1033+
expected, _ := json.MarshalIndent(tc.output, "", "\t")
1034+
actual, _ := json.MarshalIndent(tc.cluster, "", "\t")
1035+
t.Errorf("Expected %s, got %s", string(expected), string(actual))
1036+
}
1037+
})
1038+
}
1039+
}
1040+
9191041
func TestBastionDefault(t *testing.T) {
9201042
cases := map[string]struct {
9211043
cluster *AzureCluster

api/v1alpha4/types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ type NetworkSpec struct {
6464
// +optional
6565
NodeOutboundLB *LoadBalancerSpec `json:"nodeOutboundLB,omitempty"`
6666

67+
// ControlPlaneOutboundLB is the configuration for the control-plane outbound load balancer.
68+
// This is different from APIServerLB, and is used only in private clusters (optionally) for enabling outbound traffic.
69+
// +optional
70+
ControlPlaneOutboundLB *LoadBalancerSpec `json:"controlPlaneOutboundLB,omitempty"`
71+
6772
// PrivateDNSZoneName defines the zone name for the Azure Private DNS.
6873
// +optional
6974
PrivateDNSZoneName string `json:"privateDNSZoneName,omitempty"`

api/v1alpha4/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)