Skip to content

Commit bd37f1c

Browse files
authored
Merge pull request #2153 from k8s-infra-cherrypick-robot/cherry-pick-2134-to-release-1.2
[release-1.2] Populate ControlPlaneEndpoint when ManagedCluster update is not needed.
2 parents 07fbd76 + 7ac511f commit bd37f1c

File tree

2 files changed

+117
-4
lines changed

2 files changed

+117
-4
lines changed

azure/services/managedclusters/managedclusters.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,11 @@ func (s *Service) Reconcile(ctx context.Context) error {
295295
}
296296

297297
customHeaders := maps.FilterByKeyPrefix(s.Scope.ManagedClusterAnnotations(), azure.CustomHeaderPrefix)
298+
// Use the MC fetched from Azure if no update is needed. This is to ensure the read-only fields like Fqdn from the
299+
// existing MC are used for updating the AzureManagedCluster.
300+
result := existingMC
298301
if isCreate {
299-
managedCluster, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster, customHeaders)
302+
result, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster, customHeaders)
300303
if err != nil {
301304
return fmt.Errorf("failed to create managed cluster, %w", err)
302305
}
@@ -325,20 +328,23 @@ func (s *Service) Reconcile(ctx context.Context) error {
325328
diff := computeDiffOfNormalizedClusters(managedCluster, existingMC)
326329
if diff != "" {
327330
klog.V(2).Infof("Update required (+new -old):\n%s", diff)
328-
managedCluster, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster, customHeaders)
331+
result, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster, customHeaders)
329332
if err != nil {
330333
return fmt.Errorf("failed to update managed cluster, %w", err)
331334
}
332335
}
333336
}
334337

335338
// Update control plane endpoint.
336-
if managedCluster.ManagedClusterProperties != nil && managedCluster.ManagedClusterProperties.Fqdn != nil {
339+
if result.ManagedClusterProperties != nil && result.ManagedClusterProperties.Fqdn != nil {
337340
endpoint := clusterv1.APIEndpoint{
338-
Host: *managedCluster.ManagedClusterProperties.Fqdn,
341+
Host: *result.ManagedClusterProperties.Fqdn,
339342
Port: 443,
340343
}
341344
s.Scope.SetControlPlaneEndpoint(endpoint)
345+
} else {
346+
// Fail if cluster api endpoint is not available.
347+
return fmt.Errorf("failed to get API endpoint for managed cluster")
342348
}
343349

344350
// Update kubeconfig data

azure/services/managedclusters/managedclusters_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"sigs.k8s.io/cluster-api-provider-azure/azure"
3030
"sigs.k8s.io/cluster-api-provider-azure/azure/services/managedclusters/mock_managedclusters"
3131
gomockinternal "sigs.k8s.io/cluster-api-provider-azure/internal/test/matchers/gomock"
32+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3233
)
3334

3435
func TestReconcile(t *testing.T) {
@@ -123,16 +124,118 @@ func TestReconcile(t *testing.T) {
123124
{
124125
name: "no managedcluster exists",
125126
expectedError: "",
127+
expect: func(m *mock_managedclusters.MockClientMockRecorder, s *mock_managedclusters.MockManagedClusterScopeMockRecorder) {
128+
m.CreateOrUpdate(gomockinternal.AContext(), "my-rg", "my-managedcluster", gomock.Any(), gomock.Any()).Return(containerservice.ManagedCluster{ManagedClusterProperties: &containerservice.ManagedClusterProperties{
129+
Fqdn: pointer.String("my-managedcluster-fqdn"),
130+
ProvisioningState: pointer.String("Succeeded"),
131+
}}, nil).Times(1)
132+
m.Get(gomockinternal.AContext(), "my-rg", "my-managedcluster").Return(containerservice.ManagedCluster{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not Found"))
133+
m.GetCredentials(gomockinternal.AContext(), "my-rg", "my-managedcluster").Times(1)
134+
s.ClusterName().AnyTimes().Return("my-managedcluster")
135+
s.ResourceGroup().AnyTimes().Return("my-rg")
136+
s.ManagedClusterAnnotations().Times(1).Return(map[string]string{})
137+
s.ManagedClusterSpec().AnyTimes().Return(azure.ManagedClusterSpec{
138+
Name: "my-managedcluster",
139+
ResourceGroupName: "my-rg",
140+
}, nil)
141+
s.GetAllAgentPoolSpecs(gomockinternal.AContext()).AnyTimes().Return([]azure.AgentPoolSpec{
142+
{
143+
Name: "my-agentpool",
144+
SKU: "Standard_D4s_v3",
145+
Replicas: 1,
146+
OSDiskSizeGB: 0,
147+
},
148+
}, nil)
149+
s.SetControlPlaneEndpoint(gomock.Eq(clusterv1.APIEndpoint{
150+
Host: "my-managedcluster-fqdn",
151+
Port: 443,
152+
})).Times(1)
153+
s.SetKubeConfigData(gomock.Any()).Times(1)
154+
},
155+
},
156+
{
157+
name: "missing fqdn after create",
158+
expectedError: "failed to get API endpoint for managed cluster",
126159
expect: func(m *mock_managedclusters.MockClientMockRecorder, s *mock_managedclusters.MockManagedClusterScopeMockRecorder) {
127160
m.CreateOrUpdate(gomockinternal.AContext(), "my-rg", "my-managedcluster", gomock.Any(), gomock.Any()).Return(containerservice.ManagedCluster{ManagedClusterProperties: &containerservice.ManagedClusterProperties{}}, nil)
128161
m.Get(gomockinternal.AContext(), "my-rg", "my-managedcluster").Return(containerservice.ManagedCluster{}, autorest.NewErrorWithResponse("", "", &http.Response{StatusCode: 404}, "Not Found"))
162+
s.ClusterName().AnyTimes().Return("my-managedcluster")
163+
s.ResourceGroup().AnyTimes().Return("my-rg")
164+
s.ManagedClusterAnnotations().Times(1).Return(map[string]string{})
165+
s.ManagedClusterSpec().AnyTimes().Return(azure.ManagedClusterSpec{
166+
Name: "my-managedcluster",
167+
ResourceGroupName: "my-rg",
168+
}, nil)
169+
s.GetAllAgentPoolSpecs(gomockinternal.AContext()).AnyTimes().Return([]azure.AgentPoolSpec{
170+
{
171+
Name: "my-agentpool",
172+
SKU: "Standard_D4s_v3",
173+
Replicas: 1,
174+
OSDiskSizeGB: 0,
175+
},
176+
}, nil)
177+
},
178+
},
179+
{
180+
name: "set correct ControlPlaneEndpoint using fqdn from existing MC after update",
181+
expectedError: "",
182+
expect: func(m *mock_managedclusters.MockClientMockRecorder, s *mock_managedclusters.MockManagedClusterScopeMockRecorder) {
183+
m.CreateOrUpdate(gomockinternal.AContext(), "my-rg", "my-managedcluster", gomock.Any(), gomock.Any()).Return(containerservice.ManagedCluster{
184+
ManagedClusterProperties: &containerservice.ManagedClusterProperties{
185+
Fqdn: pointer.String("my-managedcluster-fqdn"),
186+
ProvisioningState: pointer.String("Succeeded"),
187+
},
188+
}, nil)
189+
m.Get(gomockinternal.AContext(), "my-rg", "my-managedcluster").Return(containerservice.ManagedCluster{
190+
ManagedClusterProperties: &containerservice.ManagedClusterProperties{
191+
Fqdn: pointer.String("my-managedcluster-fqdn"),
192+
ProvisioningState: pointer.String("Succeeded"),
193+
NetworkProfile: &containerservice.NetworkProfile{},
194+
},
195+
}, nil).Times(1)
196+
m.GetCredentials(gomockinternal.AContext(), "my-rg", "my-managedcluster").Times(1)
197+
s.ClusterName().AnyTimes().Return("my-managedcluster")
198+
s.ResourceGroup().AnyTimes().Return("my-rg")
199+
s.ManagedClusterAnnotations().Times(1).Return(map[string]string{})
200+
s.ManagedClusterSpec().AnyTimes().Return(azure.ManagedClusterSpec{
201+
Name: "my-managedcluster",
202+
ResourceGroupName: "my-rg",
203+
}, nil)
204+
s.GetAllAgentPoolSpecs(gomockinternal.AContext()).AnyTimes().Return([]azure.AgentPoolSpec{
205+
{
206+
Name: "my-agentpool",
207+
SKU: "Standard_D4s_v3",
208+
Replicas: 1,
209+
OSDiskSizeGB: 0,
210+
},
211+
}, nil)
212+
s.SetControlPlaneEndpoint(gomock.Eq(clusterv1.APIEndpoint{
213+
Host: "my-managedcluster-fqdn",
214+
Port: 443,
215+
})).Times(1)
216+
s.SetKubeConfigData(gomock.Any()).Times(1)
217+
},
218+
},
219+
{
220+
name: "no update needed - set correct ControlPlaneEndpoint using fqdn from existing MC",
221+
expectedError: "",
222+
expect: func(m *mock_managedclusters.MockClientMockRecorder, s *mock_managedclusters.MockManagedClusterScopeMockRecorder) {
223+
m.Get(gomockinternal.AContext(), "my-rg", "my-managedcluster").Return(containerservice.ManagedCluster{
224+
ManagedClusterProperties: &containerservice.ManagedClusterProperties{
225+
Fqdn: pointer.String("my-managedcluster-fqdn"),
226+
ProvisioningState: pointer.String("Succeeded"),
227+
KubernetesVersion: pointer.String("1.1"),
228+
NetworkProfile: &containerservice.NetworkProfile{},
229+
},
230+
}, nil).Times(1)
129231
m.GetCredentials(gomockinternal.AContext(), "my-rg", "my-managedcluster").Times(1)
130232
s.ClusterName().AnyTimes().Return("my-managedcluster")
131233
s.ResourceGroup().AnyTimes().Return("my-rg")
132234
s.ManagedClusterAnnotations().Times(1).Return(map[string]string{})
133235
s.ManagedClusterSpec().AnyTimes().Return(azure.ManagedClusterSpec{
134236
Name: "my-managedcluster",
135237
ResourceGroupName: "my-rg",
238+
Version: "1.1",
136239
}, nil)
137240
s.GetAllAgentPoolSpecs(gomockinternal.AContext()).AnyTimes().Return([]azure.AgentPoolSpec{
138241
{
@@ -142,6 +245,10 @@ func TestReconcile(t *testing.T) {
142245
OSDiskSizeGB: 0,
143246
},
144247
}, nil)
248+
s.SetControlPlaneEndpoint(gomock.Eq(clusterv1.APIEndpoint{
249+
Host: "my-managedcluster-fqdn",
250+
Port: 443,
251+
})).Times(1)
145252
s.SetKubeConfigData(gomock.Any()).Times(1)
146253
},
147254
},

0 commit comments

Comments
 (0)