Skip to content

Commit ad0a7a8

Browse files
authored
Merge pull request #1887 from k8s-infra-cherrypick-robot/cherry-pick-1882-to-release-1.0
[release-1.0] Fix AAD pod identity integration for sovereign clouds
2 parents 662cf0a + b8a8160 commit ad0a7a8

File tree

2 files changed

+136
-2
lines changed

2 files changed

+136
-2
lines changed

azure/scope/identity.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (p *AzureCredentialsProvider) GetAuthorizer(ctx context.Context, resourceMa
148148
var spt *adal.ServicePrincipalToken
149149
switch p.Identity.Spec.Type {
150150
case infrav1.ServicePrincipal:
151-
if err := createAzureIdentityWithBindings(ctx, p.Identity, clusterMeta, p.Client); err != nil {
151+
if err := createAzureIdentityWithBindings(ctx, p.Identity, resourceManagerEndpoint, activeDirectoryEndpoint, clusterMeta, p.Client); err != nil {
152152
return nil, err
153153
}
154154

@@ -212,7 +212,7 @@ func (p *AzureCredentialsProvider) GetTenantID() string {
212212
return p.Identity.Spec.TenantID
213213
}
214214

215-
func createAzureIdentityWithBindings(ctx context.Context, azureIdentity *infrav1.AzureClusterIdentity, clusterMeta metav1.ObjectMeta,
215+
func createAzureIdentityWithBindings(ctx context.Context, azureIdentity *infrav1.AzureClusterIdentity, resourceManagerEndpoint, activeDirectoryEndpoint string, clusterMeta metav1.ObjectMeta,
216216
kubeClient client.Client) error {
217217
azureIdentityType, err := getAzureIdentityType(azureIdentity)
218218
if err != nil {
@@ -247,6 +247,8 @@ func createAzureIdentityWithBindings(ctx context.Context, azureIdentity *infrav1
247247
ClientID: azureIdentity.Spec.ClientID,
248248
ClientPassword: azureIdentity.Spec.ClientSecret,
249249
ResourceID: azureIdentity.Spec.ResourceID,
250+
ADResourceID: resourceManagerEndpoint,
251+
ADEndpoint: activeDirectoryEndpoint,
250252
},
251253
}
252254
err = kubeClient.Create(ctx, copiedIdentity)

azure/scope/identity_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ import (
2020
"context"
2121
"testing"
2222

23+
aadpodv1 "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
2324
. "github.com/onsi/gomega"
2425

2526
"k8s.io/apimachinery/pkg/runtime"
2627
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
2728

2829
corev1 "k8s.io/api/core/v1"
2930
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
"sigs.k8s.io/controller-runtime/pkg/client"
3032
"sigs.k8s.io/controller-runtime/pkg/client/fake"
3133
)
3234

@@ -133,3 +135,133 @@ func TestAllowedNamespaces(t *testing.T) {
133135
})
134136
}
135137
}
138+
139+
func TestCreateAzureIdentityWithBindings(t *testing.T) {
140+
g := NewWithT(t)
141+
scheme := runtime.NewScheme()
142+
_ = infrav1.AddToScheme(scheme)
143+
_ = corev1.AddToScheme(scheme)
144+
_ = aadpodv1.AddToScheme(scheme)
145+
146+
tests := []struct {
147+
name string
148+
identity *infrav1.AzureClusterIdentity
149+
identityType aadpodv1.IdentityType
150+
resourceManagerEndpoint string
151+
activeDirectoryEndpoint string
152+
clusterMeta metav1.ObjectMeta
153+
copiedIdentity metav1.ObjectMeta
154+
binding metav1.ObjectMeta
155+
expectedErr bool
156+
}{
157+
{
158+
name: "create service principal identity",
159+
identity: &infrav1.AzureClusterIdentity{
160+
ObjectMeta: metav1.ObjectMeta{
161+
Name: "test-identity",
162+
},
163+
Spec: infrav1.AzureClusterIdentitySpec{
164+
Type: infrav1.ServicePrincipal,
165+
ResourceID: "my-resource-id",
166+
ClientID: "my-client-id",
167+
ClientSecret: corev1.SecretReference{Name: "my-client-secret"},
168+
TenantID: "my-tenant-id",
169+
},
170+
},
171+
identityType: aadpodv1.ServicePrincipal,
172+
resourceManagerEndpoint: "public-cloud-endpoint",
173+
activeDirectoryEndpoint: "active-directory-endpoint",
174+
clusterMeta: metav1.ObjectMeta{
175+
Name: "cluster-name",
176+
Namespace: "my-namespace",
177+
},
178+
copiedIdentity: metav1.ObjectMeta{
179+
Name: "cluster-name-my-namespace-test-identity",
180+
Namespace: "capz-system",
181+
},
182+
binding: metav1.ObjectMeta{
183+
Name: "cluster-name-my-namespace-test-identity-binding",
184+
Namespace: "capz-system",
185+
},
186+
},
187+
{
188+
name: "create UAMI identity",
189+
identity: &infrav1.AzureClusterIdentity{
190+
ObjectMeta: metav1.ObjectMeta{
191+
Name: "test-identity",
192+
},
193+
Spec: infrav1.AzureClusterIdentitySpec{
194+
Type: infrav1.UserAssignedMSI,
195+
ResourceID: "my-resource-id",
196+
ClientID: "my-client-id",
197+
ClientSecret: corev1.SecretReference{Name: "my-client-secret"},
198+
TenantID: "my-tenant-id",
199+
},
200+
},
201+
identityType: aadpodv1.UserAssignedMSI,
202+
resourceManagerEndpoint: "public-cloud-endpoint",
203+
activeDirectoryEndpoint: "active-directory-endpoint",
204+
clusterMeta: metav1.ObjectMeta{
205+
Name: "cluster-name",
206+
Namespace: "my-namespace",
207+
},
208+
copiedIdentity: metav1.ObjectMeta{
209+
Name: "cluster-name-my-namespace-test-identity",
210+
Namespace: "capz-system",
211+
},
212+
binding: metav1.ObjectMeta{
213+
Name: "cluster-name-my-namespace-test-identity-binding",
214+
Namespace: "capz-system",
215+
},
216+
},
217+
{
218+
name: "invalid identity type",
219+
identity: &infrav1.AzureClusterIdentity{
220+
ObjectMeta: metav1.ObjectMeta{
221+
Name: "test-identity",
222+
},
223+
Spec: infrav1.AzureClusterIdentitySpec{
224+
Type: "fooIdentity",
225+
ResourceID: "my-resource-id",
226+
ClientID: "my-client-id",
227+
ClientSecret: corev1.SecretReference{Name: "my-client-secret"},
228+
TenantID: "my-tenant-id",
229+
},
230+
},
231+
identityType: 0,
232+
expectedErr: true,
233+
},
234+
}
235+
for _, tc := range tests {
236+
t.Run(tc.name, func(t *testing.T) {
237+
initObjects := []runtime.Object{tc.identity}
238+
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build()
239+
240+
err := createAzureIdentityWithBindings(context.TODO(), tc.identity, tc.resourceManagerEndpoint, tc.activeDirectoryEndpoint, tc.clusterMeta, fakeClient)
241+
if !tc.expectedErr {
242+
g.Expect(err).To(BeNil())
243+
244+
resultIdentity := &aadpodv1.AzureIdentity{}
245+
key := client.ObjectKey{Name: tc.copiedIdentity.Name, Namespace: tc.copiedIdentity.Namespace}
246+
g.Expect(fakeClient.Get(context.TODO(), key, resultIdentity)).To(Succeed())
247+
g.Expect(resultIdentity.Spec.Type).To(Equal(tc.identityType))
248+
g.Expect(resultIdentity.Spec.ResourceID).To(Equal(tc.identity.Spec.ResourceID))
249+
g.Expect(resultIdentity.Spec.ClientID).To(Equal(tc.identity.Spec.ClientID))
250+
g.Expect(resultIdentity.Spec.ClientPassword).To(Equal(tc.identity.Spec.ClientSecret))
251+
g.Expect(resultIdentity.Spec.TenantID).To(Equal(tc.identity.Spec.TenantID))
252+
g.Expect(resultIdentity.Spec.ADResourceID).To(Equal(tc.resourceManagerEndpoint))
253+
g.Expect(resultIdentity.Spec.ADEndpoint).To(Equal(tc.activeDirectoryEndpoint))
254+
255+
resultIdentityBinding := &aadpodv1.AzureIdentityBinding{}
256+
key = client.ObjectKey{Name: tc.binding.Name, Namespace: tc.binding.Namespace}
257+
g.Expect(fakeClient.Get(context.TODO(), key, resultIdentityBinding)).To(Succeed())
258+
259+
// no error if identity already exists
260+
err = createAzureIdentityWithBindings(context.TODO(), tc.identity, tc.resourceManagerEndpoint, tc.activeDirectoryEndpoint, tc.clusterMeta, fakeClient)
261+
g.Expect(err).To(BeNil())
262+
} else {
263+
g.Expect(err).ToNot(BeNil())
264+
}
265+
})
266+
}
267+
}

0 commit comments

Comments
 (0)