Skip to content

Commit 337a278

Browse files
authored
Merge pull request #4316 from willie-yao/aks-fleets-member
Add support for joining clusters to AKS Fleet
2 parents 47ba1ce + ad60a09 commit 337a278

28 files changed

+1018
-3
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ WEBHOOK_ROOT ?= $(MANIFEST_ROOT)/webhook
158158
RBAC_ROOT ?= $(MANIFEST_ROOT)/rbac
159159
ASO_CRDS_PATH := $(MANIFEST_ROOT)/aso/crds.yaml
160160
ASO_VERSION := v2.5.0
161-
ASO_CRDS := resourcegroups.resources.azure.com natgateways.network.azure.com managedclusters.containerservice.azure.com managedclustersagentpools.containerservice.azure.com bastionhosts.network.azure.com virtualnetworks.network.azure.com virtualnetworkssubnets.network.azure.com privateendpoints.network.azure.com
161+
ASO_CRDS := resourcegroups.resources.azure.com natgateways.network.azure.com managedclusters.containerservice.azure.com managedclustersagentpools.containerservice.azure.com bastionhosts.network.azure.com virtualnetworks.network.azure.com virtualnetworkssubnets.network.azure.com privateendpoints.network.azure.com fleetsmembers.containerservice.azure.com
162162

163163
# Allow overriding the imagePullPolicy
164164
PULL_POLICY ?= Always

api/v1beta1/azuremanagedcontrolplane_default.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ func (m *AzureManagedControlPlane) setDefaultSubnet() {
9898
}
9999
}
100100

101+
// setDefaultFleetsMember sets the default FleetsMember for an AzureManagedControlPlane.
102+
func setDefaultFleetsMember(fleetsMember *FleetsMember, labels map[string]string) *FleetsMember {
103+
result := fleetsMember.DeepCopy()
104+
if clusterName, ok := labels[clusterv1.ClusterNameLabel]; ok && fleetsMember != nil && fleetsMember.Name == "" {
105+
result.Name = clusterName
106+
}
107+
return result
108+
}
109+
101110
func setDefaultSku(sku *AKSSku) *AKSSku {
102111
result := sku.DeepCopy()
103112
if sku == nil {

api/v1beta1/azuremanagedcontrolplane_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ type AzureManagedControlPlaneSpec struct {
110110
// Immutable.
111111
// +optional
112112
DNSPrefix *string `json:"dnsPrefix,omitempty"`
113+
114+
// FleetsMember is the spec for the fleet this cluster is a member of.
115+
// See also [AKS doc].
116+
//
117+
// [AKS doc]: https://learn.microsoft.com/en-us/azure/templates/microsoft.containerservice/2023-03-15-preview/fleets/members
118+
// +optional
119+
FleetsMember *FleetsMember `json:"fleetsMember,omitempty"`
113120
}
114121

115122
// HTTPProxyConfig is the HTTP proxy configuration for the cluster.

api/v1beta1/azuremanagedcontrolplane_webhook.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func (mw *azureManagedControlPlaneWebhook) Default(ctx context.Context, obj runt
8383
m.Spec.Version = setDefaultVersion(m.Spec.Version)
8484
m.Spec.SKU = setDefaultSku(m.Spec.SKU)
8585
m.Spec.AutoScalerProfile = setDefaultAutoScalerProfile(m.Spec.AutoScalerProfile)
86+
m.Spec.FleetsMember = setDefaultFleetsMember(m.Spec.FleetsMember, m.Labels)
8687

8788
if err := m.setDefaultSSHPublicKey(); err != nil {
8889
ctrl.Log.WithName("AzureManagedControlPlaneWebHookLogger").Error(err, "setDefaultSSHPublicKey failed")
@@ -260,6 +261,10 @@ func (mw *azureManagedControlPlaneWebhook) ValidateUpdate(ctx context.Context, o
260261
allErrs = append(allErrs, errs...)
261262
}
262263

264+
if errs := m.validateFleetsMember(old); len(errs) > 0 {
265+
allErrs = append(allErrs, errs...)
266+
}
267+
263268
if len(allErrs) == 0 {
264269
return nil, m.Validate(mw.Client)
265270
}
@@ -687,6 +692,25 @@ func (m *AzureManagedControlPlane) validateOIDCIssuerProfileUpdate(old *AzureMan
687692
return allErrs
688693
}
689694

695+
// validateFleetsMember validates a FleetsMember.
696+
func (m *AzureManagedControlPlane) validateFleetsMember(old *AzureManagedControlPlane) field.ErrorList {
697+
var allErrs field.ErrorList
698+
699+
if old.Spec.FleetsMember == nil || m.Spec.FleetsMember == nil {
700+
return allErrs
701+
}
702+
if old.Spec.FleetsMember.Name != "" && old.Spec.FleetsMember.Name != m.Spec.FleetsMember.Name {
703+
allErrs = append(allErrs,
704+
field.Forbidden(
705+
field.NewPath("Spec", "FleetsMember", "Name"),
706+
"Name is immutable",
707+
),
708+
)
709+
}
710+
711+
return allErrs
712+
}
713+
690714
func validateName(name string, fldPath *field.Path) field.ErrorList {
691715
var allErrs field.ErrorList
692716
if lName := strings.ToLower(name); strings.Contains(lName, "microsoft") ||

api/v1beta1/azuremanagedcontrolplane_webhook_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func TestDefaultingWebhook(t *testing.T) {
3737
amcp := &AzureManagedControlPlane{
3838
ObjectMeta: metav1.ObjectMeta{
3939
Name: "fooName",
40+
Labels: map[string]string{
41+
clusterv1.ClusterNameLabel: "fooCluster",
42+
},
4043
},
4144
Spec: AzureManagedControlPlaneSpec{
4245
AzureManagedControlPlaneClassSpec: AzureManagedControlPlaneClassSpec{
@@ -80,6 +83,7 @@ func TestDefaultingWebhook(t *testing.T) {
8083
Enabled: ptr.To(true),
8184
}
8285
amcp.Spec.DNSPrefix = ptr.To("test-prefix")
86+
amcp.Spec.FleetsMember = &FleetsMember{}
8387

8488
err = mcpw.Default(context.Background(), amcp)
8589
g.Expect(err).NotTo(HaveOccurred())
@@ -94,6 +98,8 @@ func TestDefaultingWebhook(t *testing.T) {
9498
g.Expect(*amcp.Spec.OIDCIssuerProfile.Enabled).To(BeTrue())
9599
g.Expect(amcp.Spec.DNSPrefix).ToNot(BeNil())
96100
g.Expect(*amcp.Spec.DNSPrefix).To(Equal("test-prefix"))
101+
g.Expect(amcp.Spec.FleetsMember.Name).To(Equal("fooCluster"))
102+
97103
t.Logf("Testing amcp defaulting webhook with overlay")
98104
amcp = &AzureManagedControlPlane{
99105
ObjectMeta: metav1.ObjectMeta{

api/v1beta1/consts.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ const (
130130
NetworkInterfaceReadyCondition clusterv1.ConditionType = "NetworkInterfacesReady"
131131
// PrivateEndpointsReadyCondition means the private endpoints exist and are ready to be used.
132132
PrivateEndpointsReadyCondition clusterv1.ConditionType = "PrivateEndpointsReady"
133+
// FleetReadyCondition means the Fleet exists and is ready to be used.
134+
FleetReadyCondition clusterv1.ConditionType = "FleetReady"
133135

134136
// CreatingReason means the resource is being created.
135137
CreatingReason = "Creating"

api/v1beta1/types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,18 @@ type AzureBastion struct {
10001000
EnableTunneling bool `json:"enableTunneling,omitempty"`
10011001
}
10021002

1003+
// FleetsMember defines the fleets member configuration.
1004+
// See also [AKS doc].
1005+
//
1006+
// [AKS doc]: https://learn.microsoft.com/en-us/azure/templates/microsoft.containerservice/2023-03-15-preview/fleets/members
1007+
type FleetsMember struct {
1008+
// Name is the name of the member.
1009+
// +optional
1010+
Name string `json:"name,omitempty"`
1011+
1012+
FleetsMemberClassSpec `json:",inline"`
1013+
}
1014+
10031015
// BackendPool describes the backend pool of the load balancer.
10041016
type BackendPool struct {
10051017
// Name specifies the name of backend pool for the load balancer. If not specified, the default name will

api/v1beta1/types_class.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,13 @@ type AzureManagedControlPlaneClassSpec struct {
211211
// DisableLocalAccounts disables getting static credentials for this cluster when set. Expected to only be used for AAD clusters.
212212
// +optional
213213
DisableLocalAccounts *bool `json:"disableLocalAccounts,omitempty"`
214+
215+
// FleetsMember is the spec for the fleet this cluster is a member of.
216+
// See also [AKS doc].
217+
//
218+
// [AKS doc]: https://learn.microsoft.com/en-us/azure/templates/microsoft.containerservice/2023-03-15-preview/fleets/members
219+
// +optional
220+
FleetsMember *FleetsMemberClassSpec `json:"fleetsMember,omitempty"`
214221
}
215222

216223
// AzureManagedMachinePoolClassSpec defines the AzureManagedMachinePool properties that may be shared across several Azure managed machinepools.
@@ -448,6 +455,19 @@ type LoadBalancerClassSpec struct {
448455
IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"`
449456
}
450457

458+
// FleetsMemberClassSpec defines the FleetsMemberSpec properties that may be shared across several Azure clusters.
459+
type FleetsMemberClassSpec struct {
460+
// Group is the group this member belongs to for multi-cluster update management.
461+
// +optional
462+
Group string `json:"group,omitempty"`
463+
464+
// ManagerName is the name of the fleet manager.
465+
ManagerName string `json:"managerName"`
466+
467+
// ManagerResourceGroup is the resource group of the fleet manager.
468+
ManagerResourceGroup string `json:"managerResourceGroup"`
469+
}
470+
451471
// SecurityGroupClass defines the SecurityGroup properties that may be shared across several Azure clusters.
452472
type SecurityGroupClass struct {
453473
// +optional

api/v1beta1/zz_generated.deepcopy.go

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

azure/defaults.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ func ManagedClusterID(subscriptionID, resourceGroup, managedClusterName string)
295295
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ContainerService/managedClusters/%s", subscriptionID, resourceGroup, managedClusterName)
296296
}
297297

298+
// FleetID returns the azure resource ID for a given fleet manager.
299+
func FleetID(subscriptionID, resourceGroup, fleetName string) string {
300+
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ContainerService/fleets/%s", subscriptionID, resourceGroup, fleetName)
301+
}
302+
298303
// GetBootstrappingVMExtension returns the CAPZ Bootstrapping VM extension.
299304
// The CAPZ Bootstrapping extension is a simple clone of https://github.com/Azure/custom-script-extension-linux for Linux or
300305
// https://learn.microsoft.com/azure/virtual-machines/extensions/custom-script-windows for Windows.

0 commit comments

Comments
 (0)