Skip to content

Commit 5bc6482

Browse files
committed
e2e tests for access entries
1 parent 6489f1f commit 5bc6482

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
apiVersion: cluster.x-k8s.io/v1beta1
3+
kind: Cluster
4+
metadata:
5+
name: "${CLUSTER_NAME}"
6+
spec:
7+
clusterNetwork:
8+
pods:
9+
cidrBlocks: ["192.168.0.0/16"]
10+
infrastructureRef:
11+
kind: AWSManagedControlPlane
12+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
13+
name: "${CLUSTER_NAME}-control-plane"
14+
controlPlaneRef:
15+
kind: AWSManagedControlPlane
16+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
17+
name: "${CLUSTER_NAME}-control-plane"
18+
---
19+
kind: AWSManagedControlPlane
20+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
21+
metadata:
22+
name: "${CLUSTER_NAME}-control-plane"
23+
spec:
24+
region: "${AWS_REGION}"
25+
sshKeyName: "${AWS_SSH_KEY_NAME}"
26+
version: "${KUBERNETES_VERSION}"
27+
accessConfig:
28+
authenticationMode: API
29+
accessEntries:
30+
- principalARN: "arn:aws:iam::123456789012:role/KubernetesAdmin"
31+
type: STANDARD
32+
username: kubernetes-admin
33+
kubernetesGroups:
34+
- system:masters
35+
accessPolicies:
36+
- policyARN: "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
37+
accessScope:
38+
type: "cluster"
39+
- principalARN: "arn:aws:iam::123456789012:role/DeveloperRole"
40+
type: STANDARD
41+
username: developer
42+
kubernetesGroups:
43+
- developers
44+
accessPolicies:
45+
- policyARN: "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
46+
accessScope:
47+
type: "namespace"
48+
namespaces: ["default"]
49+
identityRef:
50+
kind: AWSClusterStaticIdentity
51+
name: e2e-account

test/e2e/suites/managed/eks_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,56 @@ var _ = ginkgo.Describe("[managed] [general] EKS cluster tests", func() {
161161
}
162162
})
163163

164+
ginkgo.By("should create a cluster with access entries")
165+
ManagedClusterSpec(ctx, func() ManagedClusterSpecInput {
166+
return ManagedClusterSpecInput{
167+
E2EConfig: e2eCtx.E2EConfig,
168+
ConfigClusterFn: defaultConfigCluster,
169+
BootstrapClusterProxy: e2eCtx.Environment.BootstrapClusterProxy,
170+
AWSSession: e2eCtx.BootstrapUserAWSSession,
171+
AWSSessionV2: e2eCtx.BootstrapUserAWSSessionV2,
172+
Namespace: namespace,
173+
ClusterName: clusterName,
174+
Flavour: EKSControlPlaneOnlyWithAccessEntriesFlavor,
175+
ControlPlaneMachineCount: 1, // NOTE: this cannot be zero as clusterctl returns an error
176+
WorkerMachineCount: 0,
177+
}
178+
})
179+
180+
ginkgo.By("should have created the expected access entries")
181+
expectedEntries := []ekscontrolplanev1.AccessEntry{
182+
{
183+
PrincipalARN: "arn:aws:iam::123456789012:role/KubernetesAdmin",
184+
Type: "STANDARD",
185+
Username: "kubernetes-admin",
186+
KubernetesGroups: []string{"system:masters"},
187+
AccessPolicies: []ekscontrolplanev1.AccessPolicyReference{
188+
{
189+
PolicyARN: "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
190+
AccessScope: ekscontrolplanev1.AccessScope{
191+
Type: "cluster",
192+
},
193+
},
194+
},
195+
},
196+
{
197+
PrincipalARN: "arn:aws:iam::123456789012:role/DeveloperRole",
198+
Type: "STANDARD",
199+
Username: "developer",
200+
KubernetesGroups: []string{"developers"},
201+
AccessPolicies: []ekscontrolplanev1.AccessPolicyReference{
202+
{
203+
PolicyARN: "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy",
204+
AccessScope: ekscontrolplanev1.AccessScope{
205+
Type: "namespace",
206+
Namespaces: []string{"default"},
207+
},
208+
},
209+
},
210+
},
211+
}
212+
verifyAccessEntries(ctx, eksClusterName, expectedEntries, e2eCtx.BootstrapUserAWSSessionV2)
213+
164214
ginkgo.By(fmt.Sprintf("getting cluster with name %s", clusterName))
165215
cluster := framework.GetClusterByName(ctx, framework.GetClusterByNameInput{
166216
Getter: e2eCtx.Environment.BootstrapClusterProxy.GetClient(),

test/e2e/suites/managed/helpers.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package managed
2222
import (
2323
"context"
2424
"fmt"
25+
"slices"
2526
"time"
2627

2728
"github.com/aws/aws-sdk-go-v2/aws"
@@ -35,6 +36,7 @@ import (
3536
crclient "sigs.k8s.io/controller-runtime/pkg/client"
3637

3738
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
39+
ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/eks/api/v1beta2"
3840
"sigs.k8s.io/cluster-api/test/framework/clusterctl"
3941
)
4042

@@ -52,6 +54,7 @@ const (
5254
EKSClusterClassFlavor = "eks-clusterclass"
5355
EKSAuthAPIAndConfigMapFlavor = "eks-auth-api-and-config-map"
5456
EKSAuthBootstrapDisabledFlavor = "eks-auth-bootstrap-disabled"
57+
EKSControlPlaneOnlyWithAccessEntriesFlavor = "eks-control-plane-only-with-accessentries"
5558
)
5659

5760
const (
@@ -249,3 +252,68 @@ func verifyASG(eksClusterName, asgName string, checkOwned bool, cfg *aws.Config)
249252
Expect(found).To(BeTrue(), "expecting the cluster owned tag to exist")
250253
}
251254
}
255+
256+
func verifyAccessEntries(ctx context.Context, eksClusterName string, expectedEntries []ekscontrolplanev1.AccessEntry, cfg *aws.Config) {
257+
eksClient := eks.NewFromConfig(*cfg)
258+
259+
listOutput, err := eksClient.ListAccessEntries(ctx, &eks.ListAccessEntriesInput{
260+
ClusterName: &eksClusterName,
261+
})
262+
Expect(err).ToNot(HaveOccurred(), "failed to list access entries")
263+
264+
expectedEntriesMap := make(map[string]ekscontrolplanev1.AccessEntry, len(expectedEntries))
265+
for _, entry := range expectedEntries {
266+
expectedEntriesMap[entry.PrincipalARN] = entry
267+
}
268+
269+
for _, principalARN := range listOutput.AccessEntries {
270+
expectedEntry, exists := expectedEntriesMap[principalARN]
271+
Expect(exists).To(BeTrue(), fmt.Sprintf("unexpected access entry: %s", principalARN))
272+
273+
describeOutput, err := eksClient.DescribeAccessEntry(ctx, &eks.DescribeAccessEntryInput{
274+
ClusterName: &eksClusterName,
275+
PrincipalArn: &principalARN,
276+
})
277+
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to describe access entry: %s", principalARN))
278+
279+
Expect(describeOutput.AccessEntry.Type).To(Equal(expectedEntry.Type), "access entry type does not match")
280+
Expect(describeOutput.AccessEntry.Username).To(Equal(expectedEntry.Username), "access entry username does not match")
281+
282+
if len(expectedEntry.KubernetesGroups) > 0 {
283+
slices.Sort(expectedEntry.KubernetesGroups)
284+
slices.Sort(describeOutput.AccessEntry.KubernetesGroups)
285+
Expect(describeOutput.AccessEntry.KubernetesGroups).To(Equal(expectedEntry.KubernetesGroups), "access entry kubernetes groups do not match")
286+
}
287+
288+
if len(expectedEntry.AccessPolicies) > 0 {
289+
listOutput, err := eksClient.ListAssociatedAccessPolicies(ctx, &eks.ListAssociatedAccessPoliciesInput{
290+
ClusterName: &eksClusterName,
291+
PrincipalArn: &principalARN,
292+
})
293+
Expect(err).ToNot(HaveOccurred(), "failed to list access policies")
294+
295+
expectedPolicies := make(map[string]ekscontrolplanev1.AccessPolicyReference, len(expectedEntry.AccessPolicies))
296+
for _, policy := range expectedEntry.AccessPolicies {
297+
expectedPolicies[policy.PolicyARN] = policy
298+
}
299+
300+
for _, policy := range listOutput.AssociatedAccessPolicies {
301+
expectedPolicy, exists := expectedPolicies[*policy.PolicyArn]
302+
Expect(exists).To(BeTrue(), fmt.Sprintf("unexpected access policy: %s", *policy.PolicyArn))
303+
304+
Expect(policy.AccessScope.Type).To(Equal(expectedPolicy.AccessScope.Type), "access policy scope type does not match")
305+
306+
if expectedPolicy.AccessScope.Type == "namespace" {
307+
slices.Sort(expectedPolicy.AccessScope.Namespaces)
308+
slices.Sort(policy.AccessScope.Namespaces)
309+
Expect(policy.AccessScope.Namespaces).To(Equal(expectedPolicy.AccessScope.Namespaces), "access policy scope namespaces do not match")
310+
}
311+
312+
delete(expectedPolicies, *policy.PolicyArn)
313+
}
314+
Expect(expectedPolicies).To(BeEmpty(), "not all expected access policies were found")
315+
}
316+
delete(expectedEntriesMap, principalARN)
317+
}
318+
Expect(expectedEntriesMap).To(BeEmpty(), "not all expected access entries were found")
319+
}

0 commit comments

Comments
 (0)