diff --git a/azure/scope/managedcontrolplane.go b/azure/scope/managedcontrolplane.go index 5a4ad4eb956..23c302f105e 100644 --- a/azure/scope/managedcontrolplane.go +++ b/azure/scope/managedcontrolplane.go @@ -625,6 +625,13 @@ func (s *ManagedControlPlaneScope) SetKubeConfigData(kubeConfigData []byte) { s.kubeConfigData = kubeConfigData } +// SetKubeletIdentity sets the ID of the user-assigned identity for kubelet if not already set. +func (s *ManagedControlPlaneScope) SetKubeletIdentity(id string) { + if s.ControlPlane.Spec.KubeletUserAssignedIdentity == "" { + s.ControlPlane.Spec.KubeletUserAssignedIdentity = id + } +} + // SetLongRunningOperationState will set the future on the AzureManagedControlPlane status to allow the resource to continue // in the next reconciliation. func (s *ManagedControlPlaneScope) SetLongRunningOperationState(future *infrav1.Future) { diff --git a/azure/services/managedclusters/managedclusters.go b/azure/services/managedclusters/managedclusters.go index f0b24ffcbb9..288da7e5ec5 100644 --- a/azure/services/managedclusters/managedclusters.go +++ b/azure/services/managedclusters/managedclusters.go @@ -33,12 +33,15 @@ import ( const serviceName = "managedcluster" +const kubeletIdentityKey = "kubeletidentity" + // ManagedClusterScope defines the scope interface for a managed cluster. type ManagedClusterScope interface { azure.Authorizer azure.AsyncStatusUpdater ManagedClusterSpec() azure.ResourceSpecGetter SetControlPlaneEndpoint(clusterv1.APIEndpoint) + SetKubeletIdentity(string) MakeEmptyKubeConfigSecret() corev1.Secret GetKubeConfigData() []byte SetKubeConfigData([]byte) @@ -99,6 +102,12 @@ func (s *Service) Reconcile(ctx context.Context) error { return errors.Wrap(err, "failed to get credentials for managed cluster") } s.Scope.SetKubeConfigData(kubeConfigData) + + // This field gets populated by AKS when not set by the user. Persist AKS's value so for future diffs, + // the "before" reflects the correct value. + if id := managedCluster.ManagedClusterProperties.IdentityProfile[kubeletIdentityKey]; id != nil && id.ResourceID != nil { + s.Scope.SetKubeletIdentity(*id.ResourceID) + } } s.Scope.UpdatePutStatus(infrav1.ManagedClusterRunningCondition, serviceName, resultErr) return resultErr diff --git a/azure/services/managedclusters/managedclusters_test.go b/azure/services/managedclusters/managedclusters_test.go index 366e76ddf0f..54b192e1e4f 100644 --- a/azure/services/managedclusters/managedclusters_test.go +++ b/azure/services/managedclusters/managedclusters_test.go @@ -65,6 +65,11 @@ func TestReconcile(t *testing.T) { ManagedClusterProperties: &containerservice.ManagedClusterProperties{ Fqdn: pointer.String("my-managedcluster-fqdn"), ProvisioningState: pointer.String("Succeeded"), + IdentityProfile: map[string]*containerservice.UserAssignedIdentity{ + kubeletIdentityKey: { + ResourceID: pointer.String("kubelet-id"), + }, + }, }, }, nil) s.SetControlPlaneEndpoint(clusterv1.APIEndpoint{ @@ -73,6 +78,7 @@ func TestReconcile(t *testing.T) { }) m.GetCredentials(gomockinternal.AContext(), "my-rg", "my-managedcluster").Return([]byte("credentials"), nil) s.SetKubeConfigData([]byte("credentials")) + s.SetKubeletIdentity("kubelet-id") s.UpdatePutStatus(infrav1.ManagedClusterRunningCondition, serviceName, nil) }, }, diff --git a/azure/services/managedclusters/mock_managedclusters/managedclusters_mock.go b/azure/services/managedclusters/mock_managedclusters/managedclusters_mock.go index 1b50cf73be4..2bbade80d8a 100644 --- a/azure/services/managedclusters/mock_managedclusters/managedclusters_mock.go +++ b/azure/services/managedclusters/mock_managedclusters/managedclusters_mock.go @@ -230,6 +230,18 @@ func (mr *MockManagedClusterScopeMockRecorder) SetKubeConfigData(arg0 interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetKubeConfigData", reflect.TypeOf((*MockManagedClusterScope)(nil).SetKubeConfigData), arg0) } +// SetKubeletIdentity mocks base method. +func (m *MockManagedClusterScope) SetKubeletIdentity(arg0 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetKubeletIdentity", arg0) +} + +// SetKubeletIdentity indicates an expected call of SetKubeletIdentity. +func (mr *MockManagedClusterScopeMockRecorder) SetKubeletIdentity(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetKubeletIdentity", reflect.TypeOf((*MockManagedClusterScope)(nil).SetKubeletIdentity), arg0) +} + // SetLongRunningOperationState mocks base method. func (m *MockManagedClusterScope) SetLongRunningOperationState(arg0 *v1beta1.Future) { m.ctrl.T.Helper() diff --git a/azure/services/managedclusters/spec.go b/azure/services/managedclusters/spec.go index b263c960a09..9af11d372b5 100644 --- a/azure/services/managedclusters/spec.go +++ b/azure/services/managedclusters/spec.go @@ -397,7 +397,7 @@ func (s *ManagedClusterSpec) Parameters(ctx context.Context, existing interface{ if s.KubeletUserAssignedIdentity != "" { managedCluster.ManagedClusterProperties.IdentityProfile = map[string]*containerservice.UserAssignedIdentity{ - "kubeletidentity": { + kubeletIdentityKey: { ResourceID: pointer.String(s.KubeletUserAssignedIdentity), }, } @@ -590,16 +590,16 @@ func computeDiffOfNormalizedClusters(managedCluster containerservice.ManagedClus if managedCluster.IdentityProfile != nil { propertiesNormalized.IdentityProfile = map[string]*containerservice.UserAssignedIdentity{ - "kubeletidentity": { - ResourceID: managedCluster.IdentityProfile["kubeletidentity"].ResourceID, + kubeletIdentityKey: { + ResourceID: managedCluster.IdentityProfile[kubeletIdentityKey].ResourceID, }, } } if existingMC.IdentityProfile != nil { existingMCPropertiesNormalized.IdentityProfile = map[string]*containerservice.UserAssignedIdentity{ - "kubeletidentity": { - ResourceID: existingMC.IdentityProfile["kubeletidentity"].ResourceID, + kubeletIdentityKey: { + ResourceID: existingMC.IdentityProfile[kubeletIdentityKey].ResourceID, }, } } diff --git a/azure/services/managedclusters/spec_test.go b/azure/services/managedclusters/spec_test.go index 86aef8a0a18..940098da93f 100644 --- a/azure/services/managedclusters/spec_test.go +++ b/azure/services/managedclusters/spec_test.go @@ -143,7 +143,7 @@ func TestParameters(t *testing.T) { g.Expect(result.(containerservice.ManagedCluster).KubernetesVersion).To(Equal(pointer.String("v1.22.99"))) g.Expect(result.(containerservice.ManagedCluster).Identity.Type).To(Equal(containerservice.ResourceIdentityType("UserAssigned"))) g.Expect(result.(containerservice.ManagedCluster).Identity.UserAssignedIdentities).To(Equal(map[string]*containerservice.ManagedClusterIdentityUserAssignedIdentitiesValue{"/resource/ID": {}})) - g.Expect(result.(containerservice.ManagedCluster).IdentityProfile).To(Equal(map[string]*containerservice.UserAssignedIdentity{"kubeletidentity": {ResourceID: pointer.String("/resource/ID")}})) + g.Expect(result.(containerservice.ManagedCluster).IdentityProfile).To(Equal(map[string]*containerservice.UserAssignedIdentity{kubeletIdentityKey: {ResourceID: pointer.String("/resource/ID")}})) }, }, {