Skip to content

Commit ef4e54c

Browse files
Fix for create podidentityassociation bug in auto-mode clusters (#8358)
Added auto-mode checks for IsPodIdentityAgentInstalled to allow for creation of podidentityassociations in auto-mode clusters as pod-identity-agent comes in-built in auto-mode clusters and doesn't need explicit installs.
1 parent 922c13b commit ef4e54c

File tree

5 files changed

+139
-10
lines changed

5 files changed

+139
-10
lines changed

pkg/actions/podidentityassociation/migrator.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ func (m *Migrator) MigrateToPodIdentity(ctx context.Context, options PodIdentity
215215
}
216216

217217
func IsPodIdentityAgentInstalled(ctx context.Context, eksAPI awsapi.EKS, clusterName string) (bool, error) {
218+
219+
if autoMode, _ := IsAutoModeEnabled(ctx, eksAPI, clusterName); autoMode {
220+
return true, nil
221+
}
222+
218223
if _, err := eksAPI.DescribeAddon(ctx, &awseks.DescribeAddonInput{
219224
AddonName: aws.String(api.PodIdentityAgentAddon),
220225
ClusterName: &clusterName,
@@ -228,6 +233,22 @@ func IsPodIdentityAgentInstalled(ctx context.Context, eksAPI awsapi.EKS, cluster
228233
return true, nil
229234
}
230235

236+
func IsAutoModeEnabled(ctx context.Context, eksAPI awsapi.EKS, clusterName string) (bool, error) {
237+
clstrDescribeResponse, err := eksAPI.DescribeCluster(ctx, &awseks.DescribeClusterInput{
238+
Name: aws.String(clusterName),
239+
})
240+
241+
if err != nil {
242+
return false, fmt.Errorf("calling EKS::DescribeCluster: %w", err)
243+
}
244+
245+
if *clstrDescribeResponse.Cluster.ComputeConfig.Enabled {
246+
return true, nil
247+
}
248+
249+
return false, nil
250+
}
251+
231252
type IRSAv1StackNameResolver map[string]IRSAv1StackSummary
232253

233254
type IRSAv1StackSummary struct {

pkg/actions/podidentityassociation/migrator_test.go

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,24 @@ var _ = Describe("Create", func() {
6666
genericErr = fmt.Errorf("ERR")
6767
)
6868

69-
mockDescribeAddon := func(provider *mockprovider.MockProvider, err error) {
69+
mockDescribeAddon := func(provider *mockprovider.MockProvider, err error, autoMode bool) {
7070
mockProvider.MockEKS().
71-
On("DescribeAddon", mock.Anything, mock.Anything).
72-
Return(nil, err).
71+
On("DescribeCluster", mock.Anything, mock.Anything).
72+
Return(&awseks.DescribeClusterOutput{
73+
Cluster: &ekstypes.Cluster{
74+
ComputeConfig: &ekstypes.ComputeConfigResponse{
75+
Enabled: aws.Bool(autoMode),
76+
},
77+
},
78+
}, nil).
7379
Once()
80+
if !autoMode {
81+
mockProvider.MockEKS().
82+
On("DescribeAddon", mock.Anything, mock.Anything).
83+
Return(nil, err).
84+
Once()
85+
86+
}
7487
}
7588

7689
createFakeServiceAccount := func(clientSet *fake.Clientset, namespace, serviceAccountName, roleARN string) {
@@ -139,14 +152,14 @@ var _ = Describe("Create", func() {
139152
},
140153
Entry("[API errors] describing pod identity agent addon fails", migrateToPodIdentityAssociationEntry{
141154
mockEKS: func(provider *mockprovider.MockProvider) {
142-
mockDescribeAddon(provider, genericErr)
155+
mockDescribeAddon(provider, genericErr, false)
143156
},
144157
expectedErr: fmt.Sprintf("calling %q", fmt.Sprintf("EKS::DescribeAddon::%s", api.PodIdentityAgentAddon)),
145158
}),
146159

147160
Entry("[API errors] fetching iamserviceaccounts fails", migrateToPodIdentityAssociationEntry{
148161
mockEKS: func(provider *mockprovider.MockProvider) {
149-
mockDescribeAddon(provider, nil)
162+
mockDescribeAddon(provider, nil, false)
150163
},
151164
mockCFN: func(stackUpdater *fakes.FakeStackUpdater) {
152165
stackUpdater.GetIAMServiceAccountsReturns(nil, genericErr)
@@ -158,7 +171,7 @@ var _ = Describe("Create", func() {
158171
mockEKS: func(provider *mockprovider.MockProvider) {
159172
mockDescribeAddon(provider, &ekstypes.ResourceNotFoundException{
160173
Message: aws.String(genericErr.Error()),
161-
})
174+
}, false)
162175
},
163176
mockCFN: func(stackUpdater *fakes.FakeStackUpdater) {
164177
stackUpdater.GetIAMServiceAccountsReturns([]*api.ClusterIAMServiceAccount{}, nil)
@@ -173,7 +186,7 @@ var _ = Describe("Create", func() {
173186

174187
Entry("[taskTree] contains tasks to remove IRSAv1 EKS Role annotation if remove trust option is specified", migrateToPodIdentityAssociationEntry{
175188
mockEKS: func(provider *mockprovider.MockProvider) {
176-
mockDescribeAddon(provider, nil)
189+
mockDescribeAddon(provider, nil, false)
177190
},
178191
mockCFN: func(stackUpdater *fakes.FakeStackUpdater) {
179192
stackUpdater.GetIAMServiceAccountsReturns([]*api.ClusterIAMServiceAccount{}, nil)
@@ -191,7 +204,7 @@ var _ = Describe("Create", func() {
191204

192205
Entry("[taskTree] contains all other expected tasks", migrateToPodIdentityAssociationEntry{
193206
mockEKS: func(provider *mockprovider.MockProvider) {
194-
mockDescribeAddon(provider, nil)
207+
mockDescribeAddon(provider, nil, false)
195208
},
196209
mockCFN: func(stackUpdater *fakes.FakeStackUpdater) {
197210
stackUpdater.GetIAMServiceAccountsReturns([]*api.ClusterIAMServiceAccount{
@@ -220,7 +233,88 @@ var _ = Describe("Create", func() {
220233

221234
Entry("completes all tasks successfully", migrateToPodIdentityAssociationEntry{
222235
mockEKS: func(provider *mockprovider.MockProvider) {
223-
mockDescribeAddon(provider, nil)
236+
mockDescribeAddon(provider, nil, false)
237+
238+
mockProvider.MockEKS().
239+
On("CreatePodIdentityAssociation", mock.Anything, mock.Anything).
240+
Run(func(args mock.Arguments) {
241+
Expect(args).To(HaveLen(2))
242+
Expect(args[1]).To(BeAssignableToTypeOf(&awseks.CreatePodIdentityAssociationInput{}))
243+
}).
244+
Return(nil, nil).
245+
Twice()
246+
247+
mockProvider.MockIAM().
248+
On("GetRole", mock.Anything, mock.Anything).
249+
Return(&awsiam.GetRoleOutput{
250+
Role: &iamtypes.Role{
251+
AssumeRolePolicyDocument: policyDocument,
252+
},
253+
}, nil).
254+
Twice()
255+
256+
mockProvider.MockIAM().
257+
On("UpdateAssumeRolePolicy", mock.Anything, mock.Anything).
258+
Run(func(args mock.Arguments) {
259+
Expect(args).To(HaveLen(2))
260+
Expect(args[1]).To(BeAssignableToTypeOf(&awsiam.UpdateAssumeRolePolicyInput{}))
261+
input := args[1].(*awsiam.UpdateAssumeRolePolicyInput)
262+
263+
var trustPolicy api.IAMPolicyDocument
264+
Expect(json.Unmarshal([]byte(*input.PolicyDocument), &trustPolicy)).NotTo(HaveOccurred())
265+
Expect(trustPolicy.Statements).To(HaveLen(1))
266+
value, exists := trustPolicy.Statements[0].Principal["Service"]
267+
Expect(exists).To(BeTrue())
268+
Expect(value).To(ConsistOf([]string{api.EKSServicePrincipal}))
269+
}).
270+
Return(nil, nil).
271+
Once()
272+
},
273+
mockCFN: func(stackUpdater *fakes.FakeStackUpdater) {
274+
stackUpdater.GetIAMServiceAccountsReturns([]*api.ClusterIAMServiceAccount{
275+
{
276+
Status: &api.ClusterIAMServiceAccountStatus{
277+
RoleARN: aws.String(roleARN1),
278+
StackName: aws.String(makeIRSAv1StackName(podidentityassociation.Identifier{
279+
Namespace: nsDefault,
280+
ServiceAccountName: sa1,
281+
})),
282+
Capabilities: []string{"CAPABILITY_IAM"},
283+
},
284+
},
285+
}, nil)
286+
287+
stackUpdater.GetStackTemplateReturnsOnCall(0, iamRoleStackTemplate(nsDefault, sa1), nil)
288+
stackUpdater.GetStackTemplateReturnsOnCall(1, iamRoleStackTemplate(nsDefault, sa2), nil)
289+
290+
stackUpdater.MustUpdateStackStub = func(ctx context.Context, options manager.UpdateStackOptions) error {
291+
Expect(options.Stack).NotTo(BeNil())
292+
Expect(options.Stack.Tags).To(ConsistOf([]cfntypes.Tag{
293+
{
294+
Key: aws.String(api.PodIdentityAssociationNameTag),
295+
Value: aws.String(nsDefault + "/" + sa1),
296+
},
297+
}))
298+
Expect(options.Stack.Capabilities).To(ConsistOf([]cfntypes.Capability{"CAPABILITY_IAM"}))
299+
template := string(options.TemplateData.(manager.TemplateBody))
300+
Expect(template).To(ContainSubstring(api.EKSServicePrincipal))
301+
Expect(template).NotTo(ContainSubstring("oidc"))
302+
return nil
303+
}
304+
},
305+
mockK8s: func(clientSet *fake.Clientset) {
306+
createFakeServiceAccount(clientSet, nsDefault, sa1, roleARN1)
307+
createFakeServiceAccount(clientSet, nsDefault, sa2, roleARN2)
308+
},
309+
options: podidentityassociation.PodIdentityMigrationOptions{
310+
RemoveOIDCProviderTrustRelationship: true,
311+
Approve: true,
312+
},
313+
}),
314+
315+
Entry("completes all tasks successfully for auto-mode", migrateToPodIdentityAssociationEntry{
316+
mockEKS: func(provider *mockprovider.MockProvider) {
317+
mockDescribeAddon(provider, nil, true)
224318

225319
mockProvider.MockEKS().
226320
On("CreatePodIdentityAssociation", mock.Anything, mock.Anything).

pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go

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

pkg/goformation/cloudformation/types/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func NewValueFromPrimitive(raw interface{}) (*Value, error) {
3232
case json.Number:
3333
i, err := p.Int64()
3434
if err == nil {
35-
if i <= int64(^uint(0) >> 1) {
35+
if i <= int64(^uint(0)>>1) {
3636
return NewInteger(int(i)), nil
3737
}
3838
return NewLong(i), nil

userdocs/src/usage/pod-identity-associations.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ As a result, IAM roles no longer need to reference an [OIDC provider](/usage/iam
1010

1111
Behind the scenes, the implementation of pod identity associations is running an agent as a daemonset on the worker nodes. To run the pre-requisite agent on the cluster, EKS provides a new add-on called EKS Pod Identity Agent. Therefore, creating pod identity associations (in general, and with `eksctl`) requires the `eks-pod-identity-agent` addon pre-installed on the cluster. This addon can be [created using `eksctl`](/usage/addons/#creating-addons) in the same fashion any other supported addon is, e.g.
1212

13+
???+ note
14+
If you are using [EKS Auto Mode](https://eksctl.io/usage/auto-mode/) cluster the `eks-pod-identity-agent` comes pre-installed and you can skip creating the addon.
15+
1316
```
1417
eksctl create addon --cluster my-cluster --name eks-pod-identity-agent
1518
```

0 commit comments

Comments
 (0)