Skip to content

Commit 423ea03

Browse files
authored
Add crossplane config controller (#260)
* Add crossplane config controller * Don't fail during teardown if aws resources don't exist * Remove providerRole parameter, because it can be computed at runtime * Rename reconciler * Change managed-by label
1 parent f3b2003 commit 423ea03

File tree

12 files changed

+2062
-27
lines changed

12 files changed

+2062
-27
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Add crossplane controller to create crossplane provider cluster config.
13+
1014
## [0.18.0] - 2025-06-16
1115

1216
### Added

controllers/controllers_suite_test.go

Lines changed: 178 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"go/build"
2323
"math/rand"
24+
"os"
2425
"path/filepath"
2526
"testing"
2627

@@ -34,6 +35,7 @@ import (
3435
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3536
"k8s.io/kubectl/pkg/scheme"
3637
capa "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
38+
eks "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/eks/api/v1beta2"
3739
capi "sigs.k8s.io/cluster-api/api/v1beta1"
3840
"sigs.k8s.io/controller-runtime/pkg/client"
3941
"sigs.k8s.io/controller-runtime/pkg/envtest"
@@ -81,10 +83,14 @@ var _ = BeforeSuite(func() {
8183
Expect(err).NotTo(HaveOccurred())
8284

8385
By("bootstrapping test environment")
86+
ex, err := os.Executable()
87+
Expect(err).NotTo(HaveOccurred())
88+
crdPath := filepath.Join(filepath.Dir(ex), "..", "tests", "testdata", "crds")
8489
testEnv = &envtest.Environment{
8590
CRDDirectoryPaths: []string{
8691
filepath.Join(build.Default.GOPATH, "pkg", "mod", "sigs.k8s.io", fmt.Sprintf("cluster-api@%s", capiModule[0].Module.Version), "config", "crd", "bases"),
8792
filepath.Join(build.Default.GOPATH, "pkg", "mod", "sigs.k8s.io", "cluster-api-provider-aws", fmt.Sprintf("v2@%s", capaModule[0].Module.Version), "config", "crd", "bases"),
93+
crdPath,
8894
},
8995
ErrorIfCRDPathMissing: true,
9096
}
@@ -98,7 +104,9 @@ var _ = BeforeSuite(func() {
98104

99105
err = capi.AddToScheme(scheme.Scheme)
100106
Expect(err).NotTo(HaveOccurred())
101-
// +kubebuilder:scaffold:scheme
107+
108+
err = eks.AddToScheme(scheme.Scheme)
109+
Expect(err).NotTo(HaveOccurred())
102110

103111
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
104112
Expect(err).NotTo(HaveOccurred())
@@ -194,21 +202,6 @@ func createRandomClusterWithIdentity(annotationsKeyValues ...string) (*capa.AWSC
194202
return identity, awsCluster
195203
}
196204

197-
func newRoleIdentity() *capa.AWSClusterRoleIdentity {
198-
name := uuid.NewString()
199-
return &capa.AWSClusterRoleIdentity{
200-
ObjectMeta: metav1.ObjectMeta{
201-
Name: name,
202-
Namespace: namespace,
203-
},
204-
Spec: capa.AWSClusterRoleIdentitySpec{
205-
AWSRoleSpec: capa.AWSRoleSpec{
206-
RoleArn: uuid.NewString(),
207-
},
208-
},
209-
}
210-
}
211-
212205
func newSubnetSpec(id, availabilityZone string, transitGatewayTagged bool) capa.SubnetSpec {
213206
subnet := capa.SubnetSpec{
214207
ID: id,
@@ -224,3 +217,172 @@ func newSubnetSpec(id, availabilityZone string, transitGatewayTagged bool) capa.
224217

225218
return subnet
226219
}
220+
221+
func newCapiCluster(name string, annotationsKeyValues ...string) *capi.Cluster {
222+
if len(annotationsKeyValues)%2 != 0 {
223+
Fail("wrong number of arguments for newCluster. Expected even number of arguments for annotation key/value pairs")
224+
}
225+
226+
annotations := map[string]string{}
227+
for i := 0; i < len(annotationsKeyValues); i += 2 {
228+
annotations[annotationsKeyValues[i]] = annotationsKeyValues[i+1]
229+
}
230+
231+
awsCluster := &capi.Cluster{
232+
ObjectMeta: metav1.ObjectMeta{
233+
Name: name,
234+
Namespace: namespace,
235+
Annotations: annotations,
236+
},
237+
}
238+
239+
return awsCluster
240+
}
241+
242+
func newCapaCluster(name string, annotationsKeyValues ...string) *capa.AWSCluster {
243+
if len(annotationsKeyValues)%2 != 0 {
244+
Fail("wrong number of arguments for newCluster. Expected even number of arguments for annotation key/value pairs")
245+
}
246+
247+
annotations := map[string]string{}
248+
for i := 0; i < len(annotationsKeyValues); i += 2 {
249+
annotations[annotationsKeyValues[i]] = annotationsKeyValues[i+1]
250+
}
251+
252+
awsCluster := &capa.AWSCluster{
253+
ObjectMeta: metav1.ObjectMeta{
254+
Name: name,
255+
Namespace: namespace,
256+
Annotations: annotations,
257+
},
258+
Spec: capa.AWSClusterSpec{
259+
Region: "the-region",
260+
NetworkSpec: capa.NetworkSpec{
261+
VPC: capa.VPCSpec{
262+
ID: "vpc-1",
263+
CidrBlock: fmt.Sprintf("10.%d.0.0/24", rand.Intn(255)),
264+
},
265+
Subnets: capa.Subnets{
266+
{
267+
ID: "sub-1",
268+
IsPublic: false,
269+
},
270+
},
271+
},
272+
},
273+
}
274+
275+
return awsCluster
276+
}
277+
278+
func newEksCluster(name string, annotationsKeyValues ...string) *eks.AWSManagedControlPlane {
279+
if len(annotationsKeyValues)%2 != 0 {
280+
Fail("wrong number of arguments for newCluster. Expected even number of arguments for annotation key/value pairs")
281+
}
282+
283+
annotations := map[string]string{}
284+
for i := 0; i < len(annotationsKeyValues); i += 2 {
285+
annotations[annotationsKeyValues[i]] = annotationsKeyValues[i+1]
286+
}
287+
288+
eksCluster := &eks.AWSManagedControlPlane{
289+
ObjectMeta: metav1.ObjectMeta{
290+
Name: name,
291+
Namespace: namespace,
292+
Annotations: annotations,
293+
},
294+
Spec: eks.AWSManagedControlPlaneSpec{
295+
Region: "the-region",
296+
ControlPlaneEndpoint: capi.APIEndpoint{
297+
Host: "https://eks123clusterID.sk1.eu-west-2.eks.amazonaws.com",
298+
Port: 443,
299+
},
300+
NetworkSpec: capa.NetworkSpec{
301+
VPC: capa.VPCSpec{
302+
ID: "vpc-1",
303+
CidrBlock: fmt.Sprintf("10.%d.0.0/24", rand.Intn(255)),
304+
},
305+
Subnets: capa.Subnets{
306+
{
307+
ID: "sub-1",
308+
IsPublic: false,
309+
},
310+
},
311+
},
312+
},
313+
}
314+
315+
return eksCluster
316+
}
317+
318+
func createRandomCapaClusterWithIdentity(annotationsKeyValues ...string) (*capa.AWSClusterRoleIdentity, *capa.AWSCluster, *capi.Cluster) {
319+
name := uuid.NewString()
320+
awsCluster := newCapaCluster(name, annotationsKeyValues...)
321+
capiCluster := newCapiCluster(name, annotationsKeyValues...)
322+
identity := newRoleIdentity()
323+
324+
awsCluster.Spec.IdentityRef = &capa.AWSIdentityReference{
325+
Name: identity.Name,
326+
Kind: "AWSClusterRoleIdentity",
327+
}
328+
329+
Expect(k8sClient.Create(context.Background(), capiCluster)).To(Succeed())
330+
tests.PatchCAPIClusterStatus(k8sClient, capiCluster, capi.ClusterStatus{
331+
Phase: "Running",
332+
})
333+
334+
Expect(k8sClient.Create(context.Background(), awsCluster)).To(Succeed())
335+
Expect(k8sClient.Create(context.Background(), identity)).To(Succeed())
336+
tests.PatchAWSClusterStatus(k8sClient, awsCluster, capa.AWSClusterStatus{
337+
Ready: true,
338+
})
339+
340+
return identity, awsCluster, capiCluster
341+
}
342+
343+
func createRandomAwsManagedControlplaneWithIdentity(annotationsKeyValues ...string) (*capa.AWSClusterRoleIdentity, *eks.AWSManagedControlPlane, *capi.Cluster) {
344+
name := uuid.NewString()
345+
eksCluster := newEksCluster(name, annotationsKeyValues...)
346+
capiCluster := newCapiCluster(name, annotationsKeyValues...)
347+
identity := newRoleIdentity()
348+
349+
capiCluster.Spec.InfrastructureRef = &corev1.ObjectReference{
350+
Kind: "AWSManagedCluster",
351+
}
352+
capiCluster.Spec.ControlPlaneRef = &corev1.ObjectReference{
353+
Kind: "AWSManagedControlPlane",
354+
}
355+
356+
eksCluster.Spec.IdentityRef = &capa.AWSIdentityReference{
357+
Name: identity.Name,
358+
Kind: "AWSClusterRoleIdentity",
359+
}
360+
361+
Expect(k8sClient.Create(context.Background(), capiCluster)).To(Succeed())
362+
tests.PatchCAPIClusterStatus(k8sClient, capiCluster, capi.ClusterStatus{
363+
Phase: "Running",
364+
})
365+
366+
Expect(k8sClient.Create(context.Background(), eksCluster)).To(Succeed())
367+
Expect(k8sClient.Create(context.Background(), identity)).To(Succeed())
368+
tests.PatchEKSClusterStatus(k8sClient, eksCluster, eks.AWSManagedControlPlaneStatus{
369+
Ready: true,
370+
})
371+
372+
return identity, eksCluster, capiCluster
373+
}
374+
375+
func newRoleIdentity() *capa.AWSClusterRoleIdentity {
376+
name := uuid.NewString()
377+
return &capa.AWSClusterRoleIdentity{
378+
ObjectMeta: metav1.ObjectMeta{
379+
Name: name,
380+
Namespace: namespace,
381+
},
382+
Spec: capa.AWSClusterRoleIdentitySpec{
383+
AWSRoleSpec: capa.AWSRoleSpec{
384+
RoleArn: fmt.Sprintf("arn:aws:iam::%d:role/%s", rand.Intn(1000000), name),
385+
},
386+
},
387+
}
388+
}

0 commit comments

Comments
 (0)