sigs.k8s.io/cluster-api-provider-aws@v1.5.5/cmd/clusterawsadm/cloudformation/bootstrap/template_test.go (about) 1 /* 2 Copyright 2020 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 bootstrap 18 19 import ( 20 "fmt" 21 "os" 22 "path" 23 "testing" 24 25 "github.com/awslabs/goformation/v4/cloudformation" 26 "github.com/sergi/go-diff/diffmatchpatch" 27 "k8s.io/utils/pointer" 28 "sigs.k8s.io/yaml" 29 30 infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" 31 iamv1 "sigs.k8s.io/cluster-api-provider-aws/iam/api/v1beta1" 32 ) 33 34 func Test_RenderCloudformation(t *testing.T) { 35 cases := []struct { 36 fixture string 37 template func() Template 38 }{ 39 { 40 fixture: "default", 41 template: NewTemplate, 42 }, 43 { 44 fixture: "with_ssm_secret_backend", 45 template: func() Template { 46 t := NewTemplate() 47 t.Spec.SecureSecretsBackends = []infrav1.SecretBackend{ 48 infrav1.SecretBackendSSMParameterStore, 49 } 50 return t 51 }, 52 }, 53 { 54 fixture: "with_all_secret_backends", 55 template: func() Template { 56 t := NewTemplate() 57 t.Spec.SecureSecretsBackends = []infrav1.SecretBackend{ 58 infrav1.SecretBackendSecretsManager, 59 infrav1.SecretBackendSSMParameterStore, 60 } 61 return t 62 }, 63 }, 64 { 65 fixture: "with_s3_bucket", 66 template: func() Template { 67 t := NewTemplate() 68 t.Spec.S3Buckets.Enable = true 69 return t 70 }, 71 }, 72 { 73 fixture: "customsuffix", 74 template: func() Template { 75 t := NewTemplate() 76 t.Spec.NameSuffix = pointer.StringPtr(".custom-suffix.com") 77 return t 78 }, 79 }, 80 { 81 fixture: "with_bootstrap_user", 82 template: func() Template { 83 t := NewTemplate() 84 t.Spec.BootstrapUser.Enable = true 85 return t 86 }, 87 }, 88 { 89 fixture: "with_custom_bootstrap_user", 90 template: func() Template { 91 t := NewTemplate() 92 t.Spec.BootstrapUser.Enable = true 93 t.Spec.BootstrapUser.UserName = "custom-bootstrapper.cluster-api-provider-aws.sigs.k8s.io" 94 return t 95 }, 96 }, 97 { 98 fixture: "with_different_instance_profiles", 99 template: func() Template { 100 t := NewTemplate() 101 t.Spec.ClusterAPIControllers.AllowedEC2InstanceProfiles = []string{"customrole"} 102 return t 103 }, 104 }, 105 { 106 fixture: "with_eks_default_roles", 107 template: func() Template { 108 t := NewTemplate() 109 t.Spec.Nodes.EC2ContainerRegistryReadOnly = true 110 t.Spec.EKS.DefaultControlPlaneRole.Disable = false 111 t.Spec.EKS.ManagedMachinePool.Disable = false 112 t.Spec.EKS.Fargate.Disable = false 113 return t 114 }, 115 }, 116 { 117 fixture: "with_eks_kms_prefix", 118 template: func() Template { 119 t := NewTemplate() 120 t.Spec.Nodes.EC2ContainerRegistryReadOnly = true 121 t.Spec.EKS.KMSAliasPrefix = "custom-prefix-*" 122 return t 123 }, 124 }, 125 { 126 fixture: "with_extra_statements", 127 template: func() Template { 128 t := NewTemplate() 129 t.Spec.BootstrapUser.Enable = true 130 t.Spec.ControlPlane.ExtraStatements = iamv1.Statements{ 131 { 132 Effect: iamv1.EffectAllow, 133 Resource: iamv1.Resources{iamv1.Any}, 134 Action: iamv1.Actions{"test:action"}, 135 }, 136 } 137 t.Spec.Nodes.ExtraStatements = iamv1.Statements{ 138 { 139 Effect: iamv1.EffectAllow, 140 Resource: iamv1.Resources{iamv1.Any}, 141 Action: iamv1.Actions{"test:node-action"}, 142 }, 143 } 144 t.Spec.BootstrapUser.ExtraStatements = iamv1.Statements{ 145 { 146 Effect: iamv1.EffectAllow, 147 Resource: iamv1.Resources{iamv1.Any}, 148 Action: iamv1.Actions{"test:user-action"}, 149 }, 150 } 151 t.Spec.ClusterAPIControllers.ExtraStatements = iamv1.Statements{ 152 { 153 Effect: iamv1.EffectAllow, 154 Resource: iamv1.Resources{iamv1.Any}, 155 Action: iamv1.Actions{"test:controller-action"}, 156 }, 157 } 158 return t 159 }, 160 }, 161 { 162 fixture: "with_eks_disable", 163 template: func() Template { 164 t := NewTemplate() 165 t.Spec.EKS.Disable = true 166 return t 167 }, 168 }, 169 { 170 fixture: "with_eks_console", 171 template: func() Template { 172 t := NewTemplate() 173 t.Spec.EKS.EnableUserEKSConsolePolicy = true 174 return t 175 }, 176 }, 177 } 178 179 for _, c := range cases { 180 t.Run(c.fixture, func(t *testing.T) { 181 cfn := cloudformation.Template{} 182 data, err := os.ReadFile(path.Join("fixtures", c.fixture+".yaml")) 183 if err != nil { 184 t.Fatal(err) 185 } 186 err = yaml.Unmarshal(data, cfn) 187 if err != nil { 188 t.Fatal(err) 189 } 190 191 tData, err := c.template().RenderCloudFormation().YAML() 192 if err != nil { 193 t.Fatal(err) 194 } 195 196 if string(tData) != string(data) { 197 dmp := diffmatchpatch.New() 198 diffs := dmp.DiffMain(string(tData), string(data), false) 199 out := dmp.DiffPrettyText(diffs) 200 t.Fatalf(fmt.Sprintf("Differing output (%s):\n%s", c.fixture, out)) 201 } 202 }) 203 } 204 }