sigs.k8s.io/cluster-api-provider-aws@v1.5.5/cmd/clusterawsadm/gc/gc_test.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package gc 18 19 import ( 20 "context" 21 "testing" 22 23 . "github.com/onsi/gomega" 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/runtime" 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 "sigs.k8s.io/controller-runtime/pkg/client/fake" 29 30 infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" 31 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1" 32 expinfrav1 "sigs.k8s.io/cluster-api-provider-aws/exp/api/v1beta1" 33 "sigs.k8s.io/cluster-api-provider-aws/pkg/annotations" 34 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 35 "sigs.k8s.io/cluster-api/controllers/external" 36 ) 37 38 func TestEnableGC(t *testing.T) { 39 RegisterTestingT(t) 40 41 testClusterName := "test-cluster" 42 43 testCases := []struct { 44 name string 45 clusterName string 46 existingObjs []client.Object 47 expectError bool 48 }{ 49 { 50 name: "no capi cluster", 51 clusterName: testClusterName, 52 existingObjs: []client.Object{}, 53 expectError: true, 54 }, 55 { 56 name: "no infra cluster", 57 clusterName: testClusterName, 58 existingObjs: newManagedCluster(testClusterName, true), 59 expectError: true, 60 }, 61 { 62 name: "with managed control plane and no annotation", 63 clusterName: testClusterName, 64 existingObjs: newManagedClusterWithAnnotations(testClusterName, nil), 65 expectError: false, 66 }, 67 { 68 name: "with awscluster and no annotation", 69 clusterName: testClusterName, 70 existingObjs: newUnManagedClusterWithAnnotations(testClusterName, nil), 71 expectError: false, 72 }, 73 { 74 name: "with managed control plane and existing annotation", 75 clusterName: testClusterName, 76 existingObjs: newManagedClusterWithAnnotations(testClusterName, map[string]string{expinfrav1.ExternalResourceGCAnnotation: "false"}), 77 expectError: false, 78 }, 79 } 80 81 for _, tc := range testCases { 82 t.Run(tc.name, func(t *testing.T) { 83 g := NewWithT(t) 84 85 input := GCInput{ 86 ClusterName: tc.clusterName, 87 Namespace: "default", 88 } 89 90 fake := newFakeClient(scheme, tc.existingObjs...) 91 ctx := context.TODO() 92 93 proc, err := New(input, WithClient(fake)) 94 g.Expect(err).NotTo(HaveOccurred()) 95 96 resErr := proc.Enable(ctx) 97 if tc.expectError { 98 g.Expect(resErr).To(HaveOccurred()) 99 return 100 } 101 g.Expect(resErr).NotTo(HaveOccurred()) 102 103 cluster := tc.existingObjs[0].(*clusterv1.Cluster) 104 ref := cluster.Spec.InfrastructureRef 105 106 obj, err := external.Get(ctx, fake, ref, "default") 107 g.Expect(err).NotTo(HaveOccurred()) 108 g.Expect(obj).NotTo(BeNil()) 109 110 annotationVal, hasAnnotation := annotations.Get(obj, expinfrav1.ExternalResourceGCAnnotation) 111 g.Expect(hasAnnotation).To(BeTrue()) 112 g.Expect(annotationVal).To(Equal("true")) 113 }) 114 } 115 } 116 117 func TestDisableGC(t *testing.T) { 118 RegisterTestingT(t) 119 120 testClusterName := "test-cluster" 121 122 testCases := []struct { 123 name string 124 clusterName string 125 existingObjs []client.Object 126 expectError bool 127 }{ 128 { 129 name: "no capi cluster", 130 clusterName: testClusterName, 131 existingObjs: []client.Object{}, 132 expectError: true, 133 }, 134 { 135 name: "no infra cluster", 136 clusterName: testClusterName, 137 existingObjs: newManagedCluster(testClusterName, true), 138 expectError: true, 139 }, 140 { 141 name: "with managed control plane and with annotation", 142 clusterName: testClusterName, 143 existingObjs: newManagedClusterWithAnnotations(testClusterName, map[string]string{expinfrav1.ExternalResourceGCAnnotation: "true"}), 144 expectError: false, 145 }, 146 { 147 name: "with awscluster and with annotation", 148 clusterName: testClusterName, 149 existingObjs: newUnManagedClusterWithAnnotations(testClusterName, map[string]string{expinfrav1.ExternalResourceGCAnnotation: "true"}), 150 expectError: false, 151 }, 152 } 153 154 for _, tc := range testCases { 155 t.Run(tc.name, func(t *testing.T) { 156 g := NewWithT(t) 157 158 input := GCInput{ 159 ClusterName: tc.clusterName, 160 Namespace: "default", 161 } 162 163 fake := newFakeClient(scheme, tc.existingObjs...) 164 ctx := context.TODO() 165 166 proc, err := New(input, WithClient(fake)) 167 g.Expect(err).NotTo(HaveOccurred()) 168 169 resErr := proc.Disable(ctx) 170 if tc.expectError { 171 g.Expect(resErr).To(HaveOccurred()) 172 return 173 } 174 g.Expect(resErr).NotTo(HaveOccurred()) 175 176 cluster := tc.existingObjs[0].(*clusterv1.Cluster) 177 ref := cluster.Spec.InfrastructureRef 178 179 obj, err := external.Get(ctx, fake, ref, "default") 180 g.Expect(err).NotTo(HaveOccurred()) 181 g.Expect(obj).NotTo(BeNil()) 182 183 annotationVal, hasAnnotation := annotations.Get(obj, expinfrav1.ExternalResourceGCAnnotation) 184 g.Expect(hasAnnotation).To(BeTrue()) 185 g.Expect(annotationVal).To(Equal("false")) 186 }) 187 } 188 } 189 190 func newFakeClient(scheme *runtime.Scheme, objs ...client.Object) client.Client { 191 return fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build() 192 } 193 194 func newManagedCluster(name string, excludeInfra bool) []client.Object { 195 objs := []client.Object{ 196 &clusterv1.Cluster{ 197 TypeMeta: metav1.TypeMeta{ 198 Kind: "Cluster", 199 APIVersion: clusterv1.GroupVersion.String(), 200 }, 201 ObjectMeta: metav1.ObjectMeta{ 202 Name: name, 203 Namespace: "default", 204 }, 205 Spec: clusterv1.ClusterSpec{ 206 InfrastructureRef: &corev1.ObjectReference{ 207 Name: name, 208 Namespace: "default", 209 Kind: "AWSManagedControlPlane", 210 APIVersion: ekscontrolplanev1.GroupVersion.String(), 211 }, 212 }, 213 }, 214 } 215 216 if !excludeInfra { 217 objs = append(objs, &ekscontrolplanev1.AWSManagedControlPlane{ 218 TypeMeta: metav1.TypeMeta{ 219 Kind: "AWSManagedControlPlane", 220 APIVersion: ekscontrolplanev1.GroupVersion.String(), 221 }, 222 ObjectMeta: metav1.ObjectMeta{ 223 Name: name, 224 Namespace: "default", 225 }, 226 }) 227 } 228 229 return objs 230 } 231 232 func newManagedClusterWithAnnotations(name string, annotations map[string]string) []client.Object { 233 objs := newManagedCluster(name, false) 234 235 mcp := objs[1].(*ekscontrolplanev1.AWSManagedControlPlane) 236 mcp.ObjectMeta.Annotations = annotations 237 238 return objs 239 } 240 241 func newUnManagedCluster(name string, excludeInfra bool) []client.Object { 242 objs := []client.Object{ 243 &clusterv1.Cluster{ 244 TypeMeta: metav1.TypeMeta{ 245 Kind: "Cluster", 246 APIVersion: clusterv1.GroupVersion.String(), 247 }, 248 ObjectMeta: metav1.ObjectMeta{ 249 Name: name, 250 Namespace: "default", 251 }, 252 Spec: clusterv1.ClusterSpec{ 253 InfrastructureRef: &corev1.ObjectReference{ 254 Name: name, 255 Namespace: "default", 256 Kind: "AWSCluster", 257 APIVersion: infrav1.GroupVersion.String(), 258 }, 259 }, 260 }, 261 } 262 263 if !excludeInfra { 264 objs = append(objs, &infrav1.AWSCluster{ 265 TypeMeta: metav1.TypeMeta{ 266 Kind: "AWSCluster", 267 APIVersion: infrav1.GroupVersion.String(), 268 }, 269 ObjectMeta: metav1.ObjectMeta{ 270 Name: name, 271 Namespace: "default", 272 }, 273 }) 274 } 275 276 return objs 277 } 278 279 func newUnManagedClusterWithAnnotations(name string, annotations map[string]string) []client.Object { 280 objs := newUnManagedCluster(name, false) 281 282 awsc := objs[1].(*infrav1.AWSCluster) 283 awsc.ObjectMeta.Annotations = annotations 284 285 return objs 286 }