Skip to content

Commit

Permalink
enable/disable AKS cluster add-ons
Browse files Browse the repository at this point in the history
  • Loading branch information
michalno1 committed Feb 23, 2022
1 parent 0a254d8 commit 127f2dd
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 12 deletions.
10 changes: 10 additions & 0 deletions azure/scope/managedcontrolplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,16 @@ func (s *ManagedControlPlaneScope) ManagedClusterSpec() (azure.ManagedClusterSpe
}
}

if s.ControlPlane.Spec.AddonProfiles != nil {
for _, profile := range s.ControlPlane.Spec.AddonProfiles {
managedClusterSpec.AddonProfiles = append(managedClusterSpec.AddonProfiles, azure.AddonProfile{
Name: profile.Name,
Enabled: profile.Enabled,
Config: profile.Config,
})
}
}

if s.ControlPlane.Spec.SKU != nil {
managedClusterSpec.SKU = &azure.SKU{
Tier: string(s.ControlPlane.Spec.SKU.Tier),
Expand Down
95 changes: 95 additions & 0 deletions azure/scope/managedcontrolplane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,101 @@ func TestManagedControlPlaneScope_OSDiskType(t *testing.T) {
}
}

func TestManagedControlPlaneScope_AddonProfiles(t *testing.T) {
scheme := runtime.NewScheme()
_ = capiv1exp.AddToScheme(scheme)
_ = infrav1.AddToScheme(scheme)

cases := []struct {
Name string
Input ManagedControlPlaneScopeParams
Expected azure.ManagedClusterSpec
}{
{
Name: "Without add-ons",
Input: ManagedControlPlaneScopeParams{
AzureClients: AzureClients{
Authorizer: autorest.NullAuthorizer{},
},
Cluster: &clusterv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1",
Namespace: "default",
},
},
ControlPlane: &infrav1.AzureManagedControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1",
Namespace: "default",
},
Spec: infrav1.AzureManagedControlPlaneSpec{
SubscriptionID: "00000000-0000-0000-0000-000000000000",
},
},
MachinePool: getMachinePool("pool0"),
InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem),
PatchTarget: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem),
},
Expected: azure.ManagedClusterSpec{
Name: "cluster1",
VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/",
},
},
{
Name: "With add-ons",
Input: ManagedControlPlaneScopeParams{
AzureClients: AzureClients{
Authorizer: autorest.NullAuthorizer{},
},
Cluster: &clusterv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1",
Namespace: "default",
},
},
ControlPlane: &infrav1.AzureManagedControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1",
Namespace: "default",
},
Spec: infrav1.AzureManagedControlPlaneSpec{
SubscriptionID: "00000000-0000-0000-0000-000000000000",
AddonProfiles: []infrav1.AddonProfile{
{Name: "addon1", Config: nil, Enabled: false},
{Name: "addon2", Config: map[string]string{"k1": "v1", "k2": "v2"}, Enabled: true},
},
},
},
MachinePool: getMachinePool("pool0"),
InfraMachinePool: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem),
PatchTarget: getAzureMachinePool("pool0", infrav1.NodePoolModeSystem),
},
Expected: azure.ManagedClusterSpec{
Name: "cluster1",
VnetSubnetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/",
AddonProfiles: []azure.AddonProfile{
{Name: "addon1", Config: nil, Enabled: false},
{Name: "addon2", Config: map[string]string{"k1": "v1", "k2": "v2"}, Enabled: true},
},
},
},
}

for _, c := range cases {
c := c
t.Run(c.Name, func(t *testing.T) {
g := NewWithT(t)
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(c.Input.MachinePool, c.Input.InfraMachinePool, c.Input.ControlPlane).Build()
c.Input.Client = fakeClient
s, err := NewManagedControlPlaneScope(context.TODO(), c.Input)
g.Expect(err).To(Succeed())
managedCluster, err := s.ManagedClusterSpec()
g.Expect(err).To(Succeed())
g.Expect(managedCluster).To(Equal(c.Expected))
})
}
}

func getAzureMachinePool(name string, mode infrav1.NodePoolMode) *infrav1.AzureManagedMachinePool {
return &infrav1.AzureManagedMachinePool{
ObjectMeta: metav1.ObjectMeta{
Expand Down
35 changes: 35 additions & 0 deletions azure/services/managedclusters/managedclusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,26 @@ func computeDiffOfNormalizedClusters(managedCluster containerservice.ManagedClus
}
}

if managedCluster.AddonProfiles != nil {
propertiesNormalized.AddonProfiles = map[string]*containerservice.ManagedClusterAddonProfile{}
for k, v := range managedCluster.AddonProfiles {
propertiesNormalized.AddonProfiles[k] = &containerservice.ManagedClusterAddonProfile{
Enabled: v.Enabled,
Config: v.Config,
}
}
}

if existingMC.AddonProfiles != nil {
existingMCPropertiesNormalized.AddonProfiles = map[string]*containerservice.ManagedClusterAddonProfile{}
for k, v := range existingMC.AddonProfiles {
existingMCPropertiesNormalized.AddonProfiles[k] = &containerservice.ManagedClusterAddonProfile{
Enabled: v.Enabled,
Config: v.Config,
}
}
}

if managedCluster.NetworkProfile != nil {
propertiesNormalized.NetworkProfile.LoadBalancerProfile = managedCluster.NetworkProfile.LoadBalancerProfile
}
Expand Down Expand Up @@ -255,6 +275,8 @@ func (s *Service) Reconcile(ctx context.Context) error {
}
}

handleAddonProfiles(managedCluster, managedClusterSpec)

if managedClusterSpec.SKU != nil {
tierName := containerservice.ManagedClusterSKUTier(managedClusterSpec.SKU.Tier)
managedCluster.Sku = &containerservice.ManagedClusterSKU{
Expand Down Expand Up @@ -349,6 +371,19 @@ func (s *Service) Reconcile(ctx context.Context) error {
return nil
}

func handleAddonProfiles(managedCluster containerservice.ManagedCluster, spec azure.ManagedClusterSpec) {
for i := range spec.AddonProfiles {
if managedCluster.AddonProfiles == nil {
managedCluster.AddonProfiles = map[string]*containerservice.ManagedClusterAddonProfile{}
}
addonProfile := spec.AddonProfiles[i]
managedCluster.AddonProfiles[addonProfile.Name] = &containerservice.ManagedClusterAddonProfile{
Enabled: &addonProfile.Enabled,
Config: *to.StringMapPtr(addonProfile.Config),
}
}
}

// Delete deletes the managed cluster.
func (s *Service) Delete(ctx context.Context) error {
ctx, _, done := tele.StartSpanWithLogger(ctx, "managedclusters.Service.Delete")
Expand Down
10 changes: 10 additions & 0 deletions azure/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ type ManagedClusterSpec struct {
// AADProfile is Azure Active Directory configuration to integrate with AKS, for aad authentication.
AADProfile *AADProfile

// AddonProfiles are the profiles of managed cluster add-on.
AddonProfiles []AddonProfile

// SKU is the SKU of the AKS to be provisioned.
SKU *SKU

Expand All @@ -267,6 +270,13 @@ type AADProfile struct {
AdminGroupObjectIDs []string
}

// AddonProfile - Profile of managed cluster add-on.
type AddonProfile struct {
Name string
Config map[string]string
Enabled bool
}

// SKU - AKS SKU.
type SKU struct {
// Tier - Tier of a managed cluster SKU.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ spec:
AzureManagedControlPlane.
properties:
aadProfile:
description: AadProfile is Azure Active Directory configuration to
description: AADProfile is Azure Active Directory configuration to
integrate with AKS for aad authentication.
properties:
adminGroupObjectIDs:
Expand All @@ -530,6 +530,26 @@ spec:
resources managed by the Azure provider, in addition to the ones
added by default.
type: object
addonProfiles:
description: AddonProfiles are the profiles of managed cluster add-on.
items:
properties:
config:
additionalProperties:
type: string
description: Config - Key-value pairs for configuring an add-on.
type: object
enabled:
description: Enabled - Whether the add-on is enabled or not.
type: boolean
name:
description: Name- The name of managed cluster add-on.
type: string
required:
- enabled
- name
type: object
type: array
apiServerAccessProfile:
description: APIServerAccessProfile is the access profile for AKS
API server.
Expand Down
1 change: 1 addition & 0 deletions exp/api/v1alpha3/azuremanagedcontrolplane_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (src *AzureManagedControlPlane) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.SKU = restored.Spec.SKU
dst.Spec.LoadBalancerProfile = restored.Spec.LoadBalancerProfile
dst.Spec.APIServerAccessProfile = restored.Spec.APIServerAccessProfile
dst.Spec.AddonProfiles = restored.Spec.AddonProfiles

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates
dst.Status.Conditions = restored.Status.Conditions
Expand Down
1 change: 1 addition & 0 deletions exp/api/v1alpha3/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions exp/api/v1alpha4/azuremanagedcontrolplane_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (src *AzureManagedControlPlane) ConvertTo(dstRaw conversion.Hub) error {
return err
}

dst.Spec.AddonProfiles = restored.Spec.AddonProfiles
dst.Status.Conditions = restored.Status.Conditions

return nil
Expand All @@ -52,6 +53,11 @@ func (dst *AzureManagedControlPlane) ConvertFrom(srcRaw conversion.Hub) error {
return utilconversion.MarshalData(src, dst)
}

// Convert_v1beta1_AzureManagedControlPlaneSpec_To_v1alpha4_AzureManagedControlPlaneSpec is an autogenerated conversion function.
func Convert_v1beta1_AzureManagedControlPlaneSpec_To_v1alpha4_AzureManagedControlPlaneSpec(in *expv1beta1.AzureManagedControlPlaneSpec, out *AzureManagedControlPlaneSpec, s apiconversion.Scope) error {
return autoConvert_v1beta1_AzureManagedControlPlaneSpec_To_v1alpha4_AzureManagedControlPlaneSpec(in, out, s)
}

// Convert_v1beta1_AzureManagedControlPlaneStatus_To_v1alpha4_AzureManagedControlPlaneStatus is an autogenerated conversion function.
func Convert_v1beta1_AzureManagedControlPlaneStatus_To_v1alpha4_AzureManagedControlPlaneStatus(in *expv1beta1.AzureManagedControlPlaneStatus, out *AzureManagedControlPlaneStatus, s apiconversion.Scope) error {
return autoConvert_v1beta1_AzureManagedControlPlaneStatus_To_v1alpha4_AzureManagedControlPlaneStatus(in, out, s)
Expand Down
16 changes: 6 additions & 10 deletions exp/api/v1alpha4/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion exp/api/v1beta1/azuremanagedcontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,14 @@ type AzureManagedControlPlaneSpec struct {
// +optional
IdentityRef *corev1.ObjectReference `json:"identityRef,omitempty"`

// AadProfile is Azure Active Directory configuration to integrate with AKS for aad authentication.
// AADProfile is Azure Active Directory configuration to integrate with AKS for aad authentication.
// +optional
AADProfile *AADProfile `json:"aadProfile,omitempty"`

// AddonProfiles are the profiles of managed cluster add-on.
// +optional
AddonProfiles []AddonProfile `json:"addonProfiles,omitempty"`

// SKU is the SKU of the AKS to be provisioned.
// +optional
SKU *SKU `json:"sku,omitempty"`
Expand All @@ -121,6 +125,18 @@ type AADProfile struct {
AdminGroupObjectIDs []string `json:"adminGroupObjectIDs"`
}

type AddonProfile struct {
// Name- The name of managed cluster add-on.
Name string `json:"name"`

// Config - Key-value pairs for configuring an add-on.
// +optional
Config map[string]string `json:"config,omitempty"`

// Enabled - Whether the add-on is enabled or not.
Enabled bool `json:"enabled"`
}

// AzureManagedControlPlaneSkuTier - Tier of a managed cluster SKU.
// +kubebuilder:validation:Enum=Free;Paid
type AzureManagedControlPlaneSkuTier string
Expand Down
29 changes: 29 additions & 0 deletions exp/api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 127f2dd

Please sign in to comment.