diff --git a/aws/fake/cf.go b/aws/fake/cf.go index 3b367f79..8c269def 100644 --- a/aws/fake/cf.go +++ b/aws/fake/cf.go @@ -17,12 +17,22 @@ type CFOutputs struct { type CFClient struct { cloudformationiface.CloudFormationAPI - lastGeneratedTemplate string - Outputs CFOutputs + lastStackTemplate string + lastStackParams []*cloudformation.Parameter + lastStackTags []*cloudformation.Tag + Outputs CFOutputs } -func (m *CFClient) GetLastGeneratedTemplate() string { - return m.lastGeneratedTemplate +func (m *CFClient) GetLastStackTemplate() string { + return m.lastStackTemplate +} + +func (m *CFClient) GetLastStackParams() []*cloudformation.Parameter { + return m.lastStackParams +} + +func (m *CFClient) GetLastStackTags() []*cloudformation.Tag { + return m.lastStackTags } func (m *CFClient) DescribeStacksPages(in *cloudformation.DescribeStacksInput, fn func(*cloudformation.DescribeStacksOutput, bool) bool) (err error) { @@ -52,7 +62,10 @@ func (m *CFClient) DescribeStacks(in *cloudformation.DescribeStacksInput) (*clou } func (m *CFClient) CreateStack(params *cloudformation.CreateStackInput) (*cloudformation.CreateStackOutput, error) { - m.lastGeneratedTemplate = *params.TemplateBody + m.lastStackTags = params.Tags + m.lastStackParams = params.Parameters + m.lastStackTemplate = *params.TemplateBody + out, ok := m.Outputs.CreateStack.response.(*cloudformation.CreateStackOutput) if !ok { return nil, m.Outputs.CreateStack.err @@ -67,7 +80,10 @@ func MockCSOutput(stackId string) *cloudformation.CreateStackOutput { } func (m *CFClient) UpdateStack(params *cloudformation.UpdateStackInput) (*cloudformation.UpdateStackOutput, error) { - m.lastGeneratedTemplate = *params.TemplateBody + m.lastStackTags = params.Tags + m.lastStackParams = params.Parameters + m.lastStackTemplate = *params.TemplateBody + out, ok := m.Outputs.UpdateStack.response.(*cloudformation.UpdateStackOutput) if !ok { return nil, m.Outputs.UpdateStack.err diff --git a/testdata/simple_alb/params.json b/testdata/simple_alb/params.json new file mode 100644 index 00000000..c1ecf899 --- /dev/null +++ b/testdata/simple_alb/params.json @@ -0,0 +1,54 @@ +[ + { + "parameterKey": "LoadBalancerSchemeParameter", + "parameterValue": "internet-facing" + }, + { + "parameterKey": "LoadBalancerSecurityGroupParameter", + "parameterValue": "42" + }, + { + "parameterKey": "LoadBalancerSubnetsParameter", + "parameterValue": "foo1" + }, + { + "parameterKey": "TargetGroupVPCIDParameter", + "parameterValue": "1" + }, + { + "parameterKey": "TargetGroupTargetPortParameter", + "parameterValue": "0" + }, + { + "parameterKey": "ListenerSslPolicyParameter", + "parameterValue": "ELBSecurityPolicy-2016-08" + }, + { + "parameterKey": "IpAddressType", + "parameterValue": "ipv4" + }, + { + "parameterKey": "Type", + "parameterValue": "application" + }, + { + "parameterKey": "HTTP2", + "parameterValue": "true" + }, + { + "parameterKey": "TargetGroupHealthCheckPathParameter", + "parameterValue": "" + }, + { + "parameterKey": "TargetGroupHealthCheckPortParameter", + "parameterValue": "0" + }, + { + "parameterKey": "TargetGroupHealthCheckIntervalParameter", + "parameterValue": "0" + }, + { + "parameterKey": "TargetGroupHealthCheckTimeoutParameter", + "parameterValue": "0" + } +] diff --git a/testdata/simple_alb/tags.json b/testdata/simple_alb/tags.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/simple_alb/tags.json @@ -0,0 +1,12 @@ +[ + { + "key": "kubernetes:application", + "value": "" + },{ + "key": "kubernetes.io/cluster/aws:123:eu-central-1:kube-1", + "value": "owned" + },{ + "key": "ingress:certificate-arn/DUMMY", + "value": "0001-01-01T00:00:00Z" + } +] diff --git a/testdata/simple_alb/expected.cf b/testdata/simple_alb/template.cf similarity index 100% rename from testdata/simple_alb/expected.cf rename to testdata/simple_alb/template.cf diff --git a/testdata/simple_nlb/params.json b/testdata/simple_nlb/params.json new file mode 100644 index 00000000..adec04c7 --- /dev/null +++ b/testdata/simple_nlb/params.json @@ -0,0 +1,54 @@ +[ + { + "parameterKey": "LoadBalancerSchemeParameter", + "parameterValue": "internet-facing" + }, + { + "parameterKey": "LoadBalancerSecurityGroupParameter", + "parameterValue": "42" + }, + { + "parameterKey": "LoadBalancerSubnetsParameter", + "parameterValue": "foo1" + }, + { + "parameterKey": "TargetGroupVPCIDParameter", + "parameterValue": "1" + }, + { + "parameterKey": "TargetGroupTargetPortParameter", + "parameterValue": "0" + }, + { + "parameterKey": "ListenerSslPolicyParameter", + "parameterValue": "ELBSecurityPolicy-2016-08" + }, + { + "parameterKey": "IpAddressType", + "parameterValue": "ipv4" + }, + { + "parameterKey": "Type", + "parameterValue": "network" + }, + { + "parameterKey": "HTTP2", + "parameterValue": "true" + }, + { + "parameterKey": "TargetGroupHealthCheckPathParameter", + "parameterValue": "" + }, + { + "parameterKey": "TargetGroupHealthCheckPortParameter", + "parameterValue": "0" + }, + { + "parameterKey": "TargetGroupHealthCheckIntervalParameter", + "parameterValue": "0" + }, + { + "parameterKey": "TargetGroupHealthCheckTimeoutParameter", + "parameterValue": "0" + } +] diff --git a/testdata/simple_nlb/tags.json b/testdata/simple_nlb/tags.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/simple_nlb/tags.json @@ -0,0 +1,12 @@ +[ + { + "key": "kubernetes:application", + "value": "" + },{ + "key": "kubernetes.io/cluster/aws:123:eu-central-1:kube-1", + "value": "owned" + },{ + "key": "ingress:certificate-arn/DUMMY", + "value": "0001-01-01T00:00:00Z" + } +] diff --git a/testdata/simple_nlb/expected.cf b/testdata/simple_nlb/template.cf similarity index 100% rename from testdata/simple_nlb/expected.cf rename to testdata/simple_nlb/template.cf diff --git a/worker_test.go b/worker_test.go index dccda0f8..6524dec0 100644 --- a/worker_test.go +++ b/worker_test.go @@ -3,6 +3,7 @@ package main import ( "context" "crypto/x509" + "encoding/json" "net/http/httptest" "os" "reflect" @@ -11,6 +12,7 @@ import ( "time" "github.com/aws/aws-sdk-go/service/autoscaling" + cf "github.com/aws/aws-sdk-go/service/cloudformation" cloudformation "github.com/mweagle/go-cloudformation" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -148,11 +150,28 @@ func TestResourceConversion(tt *testing.T) { }, } { tt.Run(scenario.name, func(t *testing.T) { - b, err := os.ReadFile("./testdata/" + scenario.name + "/expected.cf") + readFile := func(fileName string) []byte { + b, err := os.ReadFile("./testdata/" + scenario.name + "/" + fileName) + if err != nil { + t.Fatal(err) + } + + return b + } + + template := string(readFile("template.cf")) + + var tags []*cf.Tag + err := json.Unmarshal(readFile("tags.json"), &tags) + if err != nil { + t.Fatal(err) + } + + var params []*cf.Parameter + err = json.Unmarshal(readFile("params.json"), ¶ms) if err != nil { t.Fatal(err) } - expected := string(b) clientEC2 := &fake.EC2Client{Outputs: scenario.responsesEC2} clientASG := &fake.ASGClient{Outputs: scenario.responsesASG} @@ -210,10 +229,29 @@ func TestResourceConversion(tt *testing.T) { t.Error(problems.Errors()) } + // When a stack is created using cloud formation API the stack information is sent in a split way. + // There is a template with the description of the stack, but this template references parameters + // and tags that are not defined in this template. These parameters and tags are sent as different + // fields in the request. + // That is why when we validate the content of the template we also need to check the parameters + // and tags and this is why this check is split in three parts, we check the template, + // the parameters and tags generated by the ingress controller and not only the template. + assert.Equal( + t, + template, + clientCF.GetLastStackTemplate(), + ) + + assert.Equal( + t, + tags, + clientCF.GetLastStackTags(), + ) + assert.Equal( t, - expected, - clientCF.GetLastGeneratedTemplate(), + params, + clientCF.GetLastStackParams(), ) }) }