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  }