From dd95fc281c81ee0f7193131302a3fc97277b1154 Mon Sep 17 00:00:00 2001 From: Mustafa Saber Date: Tue, 31 Oct 2023 14:42:04 +0100 Subject: [PATCH] Add some more goldenfile tests (#614) * Add more golden file tests - patch 1 Signed-off-by: Mustafa Abdelrahman * remove `resourcesType` field which is unnecessary Signed-off-by: Mustafa Abdelrahman * Fix existing Golden file tests Signed-off-by: Lucas Thiesen * Fix remaining goldenfile tests Signed-off-by: Lucas Thiesen * Fix ingress sharing parameter in test fixtures Signed-off-by: Lucas Thiesen * Add ability to check multiple input/output to golden files tests Signed-off-by: Lucas Thiesen * Sync annotation and improve naming in golden file tests Signed-off-by: Lucas Thiesen * Add issue link to TODO comment in CF mocks Signed-off-by: Lucas Thiesen * Fix identation Signed-off-by: Lucas Thiesen --------- Signed-off-by: Mustafa Abdelrahman Signed-off-by: Lucas Thiesen Co-authored-by: Lucas Thiesen --- aws/fake/cf.go | 38 +- .../input/k8s/01-ing.yaml | 18 + .../input/k8s/02-rg.yaml | 18 + .../output/params/01-ing.json} | 0 .../output/params/02-rg.json | 54 +++ .../output/tags/01-ing.json} | 0 .../output/tags/02-rg.json | 15 + .../output/templates/01-ing.cf} | 0 .../output/templates/02-rg.cf | 219 ++++++++++ .../input/k8s}/ing.yaml | 0 testdata/ingress_alb/output/params/ing.json | 54 +++ .../output/tags/ing.json} | 0 testdata/ingress_alb/output/templates/ing.cf | 219 ++++++++++ .../input/k8s}/ing.yaml | 2 +- .../output/params/ing.json} | 0 testdata/ingress_nlb/output/tags/ing.json | 12 + .../output/templates/ing.cf} | 0 .../input/k8s/01-ing.yaml | 18 + .../input/k8s/02-rg.yaml | 18 + .../output/params/shared.json | 54 +++ .../output/tags/shared.json | 12 + .../output/templates/shared.cf | 219 ++++++++++ .../input/k8s/01-ing.yaml | 18 + .../input/k8s/02-rg.yaml | 18 + .../output/params/shared.json | 54 +++ .../output/tags/shared.json | 12 + .../output/templates/shared.cf | 187 +++++++++ testdata/rg_alb/input/k8s/rg.yaml | 16 + testdata/rg_alb/output/params/rg.json | 54 +++ testdata/rg_alb/output/tags/rg.json | 12 + testdata/rg_alb/output/templates/rg.cf | 219 ++++++++++ testdata/rg_nlb/input/k8s/rg.yaml | 16 + testdata/rg_nlb/output/params/rg.json | 54 +++ testdata/rg_nlb/output/tags/rg.json | 12 + testdata/rg_nlb/output/templates/rg.cf | 187 +++++++++ worker_test.go | 381 ++++++++++++++++-- 36 files changed, 2157 insertions(+), 53 deletions(-) create mode 100644 testdata/ing_shared_rg_notshared_alb/input/k8s/01-ing.yaml create mode 100644 testdata/ing_shared_rg_notshared_alb/input/k8s/02-rg.yaml rename testdata/{simple_alb/params.json => ing_shared_rg_notshared_alb/output/params/01-ing.json} (100%) create mode 100644 testdata/ing_shared_rg_notshared_alb/output/params/02-rg.json rename testdata/{simple_alb/tags.json => ing_shared_rg_notshared_alb/output/tags/01-ing.json} (100%) create mode 100644 testdata/ing_shared_rg_notshared_alb/output/tags/02-rg.json rename testdata/{simple_alb/template.cf => ing_shared_rg_notshared_alb/output/templates/01-ing.cf} (100%) create mode 100644 testdata/ing_shared_rg_notshared_alb/output/templates/02-rg.cf rename testdata/{simple_alb => ingress_alb/input/k8s}/ing.yaml (100%) create mode 100644 testdata/ingress_alb/output/params/ing.json rename testdata/{simple_nlb/tags.json => ingress_alb/output/tags/ing.json} (100%) create mode 100644 testdata/ingress_alb/output/templates/ing.cf rename testdata/{simple_nlb => ingress_nlb/input/k8s}/ing.yaml (88%) rename testdata/{simple_nlb/params.json => ingress_nlb/output/params/ing.json} (100%) create mode 100644 testdata/ingress_nlb/output/tags/ing.json rename testdata/{simple_nlb/template.cf => ingress_nlb/output/templates/ing.cf} (100%) create mode 100644 testdata/ingress_rg_shared_alb/input/k8s/01-ing.yaml create mode 100644 testdata/ingress_rg_shared_alb/input/k8s/02-rg.yaml create mode 100644 testdata/ingress_rg_shared_alb/output/params/shared.json create mode 100644 testdata/ingress_rg_shared_alb/output/tags/shared.json create mode 100644 testdata/ingress_rg_shared_alb/output/templates/shared.cf create mode 100644 testdata/ingress_rg_shared_nlb/input/k8s/01-ing.yaml create mode 100644 testdata/ingress_rg_shared_nlb/input/k8s/02-rg.yaml create mode 100644 testdata/ingress_rg_shared_nlb/output/params/shared.json create mode 100644 testdata/ingress_rg_shared_nlb/output/tags/shared.json create mode 100644 testdata/ingress_rg_shared_nlb/output/templates/shared.cf create mode 100644 testdata/rg_alb/input/k8s/rg.yaml create mode 100644 testdata/rg_alb/output/params/rg.json create mode 100644 testdata/rg_alb/output/tags/rg.json create mode 100644 testdata/rg_alb/output/templates/rg.cf create mode 100644 testdata/rg_nlb/input/k8s/rg.yaml create mode 100644 testdata/rg_nlb/output/params/rg.json create mode 100644 testdata/rg_nlb/output/tags/rg.json create mode 100644 testdata/rg_nlb/output/templates/rg.cf diff --git a/aws/fake/cf.go b/aws/fake/cf.go index 8c269def..48ed5793 100644 --- a/aws/fake/cf.go +++ b/aws/fake/cf.go @@ -17,22 +17,28 @@ type CFOutputs struct { type CFClient struct { cloudformationiface.CloudFormationAPI - lastStackTemplate string - lastStackParams []*cloudformation.Parameter - lastStackTags []*cloudformation.Tag - Outputs CFOutputs + templateCreationHistory []string + paramCreationHistory [][]*cloudformation.Parameter + tagCreationHistory [][]*cloudformation.Tag + Outputs CFOutputs } -func (m *CFClient) GetLastStackTemplate() string { - return m.lastStackTemplate +func (m *CFClient) GetTemplateCreationHistory() []string { + return m.templateCreationHistory } -func (m *CFClient) GetLastStackParams() []*cloudformation.Parameter { - return m.lastStackParams +func (m *CFClient) GetParamCreationHistory() [][]*cloudformation.Parameter { + return m.paramCreationHistory } -func (m *CFClient) GetLastStackTags() []*cloudformation.Tag { - return m.lastStackTags +func (m *CFClient) GetTagCreationHistory() [][]*cloudformation.Tag { + return m.tagCreationHistory +} + +func (m *CFClient) CleanCreationHistory() { + m.paramCreationHistory = [][]*cloudformation.Parameter{} + m.tagCreationHistory = [][]*cloudformation.Tag{} + m.templateCreationHistory = []string{} } func (m *CFClient) DescribeStacksPages(in *cloudformation.DescribeStacksInput, fn func(*cloudformation.DescribeStacksOutput, bool) bool) (err error) { @@ -62,9 +68,9 @@ func (m *CFClient) DescribeStacks(in *cloudformation.DescribeStacksInput) (*clou } func (m *CFClient) CreateStack(params *cloudformation.CreateStackInput) (*cloudformation.CreateStackOutput, error) { - m.lastStackTags = params.Tags - m.lastStackParams = params.Parameters - m.lastStackTemplate = *params.TemplateBody + m.tagCreationHistory = append(m.tagCreationHistory, params.Tags) + m.paramCreationHistory = append(m.paramCreationHistory, params.Parameters) + m.templateCreationHistory = append(m.templateCreationHistory, *params.TemplateBody) out, ok := m.Outputs.CreateStack.response.(*cloudformation.CreateStackOutput) if !ok { @@ -80,9 +86,9 @@ func MockCSOutput(stackId string) *cloudformation.CreateStackOutput { } func (m *CFClient) UpdateStack(params *cloudformation.UpdateStackInput) (*cloudformation.UpdateStackOutput, error) { - m.lastStackTags = params.Tags - m.lastStackParams = params.Parameters - m.lastStackTemplate = *params.TemplateBody + // TODO: https://github.com/zalando-incubator/kube-ingress-aws-controller/issues/653 + // Update stack needs to use different variable to register change history, + // so createStack and updateStack mocks don't mess with each other states. out, ok := m.Outputs.UpdateStack.response.(*cloudformation.UpdateStackOutput) if !ok { diff --git a/testdata/ing_shared_rg_notshared_alb/input/k8s/01-ing.yaml b/testdata/ing_shared_rg_notshared_alb/input/k8s/01-ing.yaml new file mode 100644 index 00000000..ddd37ec1 --- /dev/null +++ b/testdata/ing_shared_rg_notshared_alb/input/k8s/01-ing.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: myingress + annotations: + zalando.org/aws-load-balancer-shared: "true" +spec: + rules: + - host: foo.bar.org + http: + paths: + - backend: + service: + name: foo-bar-service + port: + name: main-port + path: / + pathType: ImplementationSpecific diff --git a/testdata/ing_shared_rg_notshared_alb/input/k8s/02-rg.yaml b/testdata/ing_shared_rg_notshared_alb/input/k8s/02-rg.yaml new file mode 100644 index 00000000..432e0b40 --- /dev/null +++ b/testdata/ing_shared_rg_notshared_alb/input/k8s/02-rg.yaml @@ -0,0 +1,18 @@ +apiVersion: zalando.org/v1 +kind: RouteGroup +metadata: + name: my-route-group + annotations: + zalando.org/aws-load-balancer-shared: "false" +spec: + hosts: + - foo.bar.org + backends: + - name: my-backend + type: service + serviceName: my-service + servicePort: 80 + routes: + - pathSubtree: / + backends: + - backendName: my-backend diff --git a/testdata/simple_alb/params.json b/testdata/ing_shared_rg_notshared_alb/output/params/01-ing.json similarity index 100% rename from testdata/simple_alb/params.json rename to testdata/ing_shared_rg_notshared_alb/output/params/01-ing.json diff --git a/testdata/ing_shared_rg_notshared_alb/output/params/02-rg.json b/testdata/ing_shared_rg_notshared_alb/output/params/02-rg.json new file mode 100644 index 00000000..c1ecf899 --- /dev/null +++ b/testdata/ing_shared_rg_notshared_alb/output/params/02-rg.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/ing_shared_rg_notshared_alb/output/tags/01-ing.json similarity index 100% rename from testdata/simple_alb/tags.json rename to testdata/ing_shared_rg_notshared_alb/output/tags/01-ing.json diff --git a/testdata/ing_shared_rg_notshared_alb/output/tags/02-rg.json b/testdata/ing_shared_rg_notshared_alb/output/tags/02-rg.json new file mode 100644 index 00000000..04f7153a --- /dev/null +++ b/testdata/ing_shared_rg_notshared_alb/output/tags/02-rg.json @@ -0,0 +1,15 @@ +[ + { + "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" + },{ + "key": "ingress:owner", + "value": "/my-route-group" + } +] diff --git a/testdata/simple_alb/template.cf b/testdata/ing_shared_rg_notshared_alb/output/templates/01-ing.cf similarity index 100% rename from testdata/simple_alb/template.cf rename to testdata/ing_shared_rg_notshared_alb/output/templates/01-ing.cf diff --git a/testdata/ing_shared_rg_notshared_alb/output/templates/02-rg.cf b/testdata/ing_shared_rg_notshared_alb/output/templates/02-rg.cf new file mode 100644 index 00000000..7e9378df --- /dev/null +++ b/testdata/ing_shared_rg_notshared_alb/output/templates/02-rg.cf @@ -0,0 +1,219 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "0" + }, + { + "Key": "routing.http2.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "SecurityGroups": { + "Ref": "LoadBalancerSecurityGroupParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": { + "Ref": "TargetGroupHealthCheckTimeoutParameter" + }, + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/testdata/simple_alb/ing.yaml b/testdata/ingress_alb/input/k8s/ing.yaml similarity index 100% rename from testdata/simple_alb/ing.yaml rename to testdata/ingress_alb/input/k8s/ing.yaml diff --git a/testdata/ingress_alb/output/params/ing.json b/testdata/ingress_alb/output/params/ing.json new file mode 100644 index 00000000..c1ecf899 --- /dev/null +++ b/testdata/ingress_alb/output/params/ing.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_nlb/tags.json b/testdata/ingress_alb/output/tags/ing.json similarity index 100% rename from testdata/simple_nlb/tags.json rename to testdata/ingress_alb/output/tags/ing.json diff --git a/testdata/ingress_alb/output/templates/ing.cf b/testdata/ingress_alb/output/templates/ing.cf new file mode 100644 index 00000000..7e9378df --- /dev/null +++ b/testdata/ingress_alb/output/templates/ing.cf @@ -0,0 +1,219 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "0" + }, + { + "Key": "routing.http2.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "SecurityGroups": { + "Ref": "LoadBalancerSecurityGroupParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": { + "Ref": "TargetGroupHealthCheckTimeoutParameter" + }, + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/testdata/simple_nlb/ing.yaml b/testdata/ingress_nlb/input/k8s/ing.yaml similarity index 88% rename from testdata/simple_nlb/ing.yaml rename to testdata/ingress_nlb/input/k8s/ing.yaml index 21b2e452..1f21110d 100644 --- a/testdata/simple_nlb/ing.yaml +++ b/testdata/ingress_nlb/input/k8s/ing.yaml @@ -15,4 +15,4 @@ spec: port: name: main-port path: / - pathType: ImplementationSpecific \ No newline at end of file + pathType: ImplementationSpecific diff --git a/testdata/simple_nlb/params.json b/testdata/ingress_nlb/output/params/ing.json similarity index 100% rename from testdata/simple_nlb/params.json rename to testdata/ingress_nlb/output/params/ing.json diff --git a/testdata/ingress_nlb/output/tags/ing.json b/testdata/ingress_nlb/output/tags/ing.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/ingress_nlb/output/tags/ing.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/template.cf b/testdata/ingress_nlb/output/templates/ing.cf similarity index 100% rename from testdata/simple_nlb/template.cf rename to testdata/ingress_nlb/output/templates/ing.cf diff --git a/testdata/ingress_rg_shared_alb/input/k8s/01-ing.yaml b/testdata/ingress_rg_shared_alb/input/k8s/01-ing.yaml new file mode 100644 index 00000000..ddd37ec1 --- /dev/null +++ b/testdata/ingress_rg_shared_alb/input/k8s/01-ing.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: myingress + annotations: + zalando.org/aws-load-balancer-shared: "true" +spec: + rules: + - host: foo.bar.org + http: + paths: + - backend: + service: + name: foo-bar-service + port: + name: main-port + path: / + pathType: ImplementationSpecific diff --git a/testdata/ingress_rg_shared_alb/input/k8s/02-rg.yaml b/testdata/ingress_rg_shared_alb/input/k8s/02-rg.yaml new file mode 100644 index 00000000..01acc2e2 --- /dev/null +++ b/testdata/ingress_rg_shared_alb/input/k8s/02-rg.yaml @@ -0,0 +1,18 @@ +apiVersion: zalando.org/v1 +kind: RouteGroup +metadata: + name: my-route-group + annotations: + zalando.org/aws-load-balancer-shared: "true" +spec: + hosts: + - foo.bar.org + backends: + - name: my-backend + type: service + serviceName: my-service + servicePort: 80 + routes: + - pathSubtree: / + backends: + - backendName: my-backend diff --git a/testdata/ingress_rg_shared_alb/output/params/shared.json b/testdata/ingress_rg_shared_alb/output/params/shared.json new file mode 100644 index 00000000..c1ecf899 --- /dev/null +++ b/testdata/ingress_rg_shared_alb/output/params/shared.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/ingress_rg_shared_alb/output/tags/shared.json b/testdata/ingress_rg_shared_alb/output/tags/shared.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/ingress_rg_shared_alb/output/tags/shared.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/ingress_rg_shared_alb/output/templates/shared.cf b/testdata/ingress_rg_shared_alb/output/templates/shared.cf new file mode 100644 index 00000000..7e9378df --- /dev/null +++ b/testdata/ingress_rg_shared_alb/output/templates/shared.cf @@ -0,0 +1,219 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "0" + }, + { + "Key": "routing.http2.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "SecurityGroups": { + "Ref": "LoadBalancerSecurityGroupParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": { + "Ref": "TargetGroupHealthCheckTimeoutParameter" + }, + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/testdata/ingress_rg_shared_nlb/input/k8s/01-ing.yaml b/testdata/ingress_rg_shared_nlb/input/k8s/01-ing.yaml new file mode 100644 index 00000000..ddd37ec1 --- /dev/null +++ b/testdata/ingress_rg_shared_nlb/input/k8s/01-ing.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: myingress + annotations: + zalando.org/aws-load-balancer-shared: "true" +spec: + rules: + - host: foo.bar.org + http: + paths: + - backend: + service: + name: foo-bar-service + port: + name: main-port + path: / + pathType: ImplementationSpecific diff --git a/testdata/ingress_rg_shared_nlb/input/k8s/02-rg.yaml b/testdata/ingress_rg_shared_nlb/input/k8s/02-rg.yaml new file mode 100644 index 00000000..01acc2e2 --- /dev/null +++ b/testdata/ingress_rg_shared_nlb/input/k8s/02-rg.yaml @@ -0,0 +1,18 @@ +apiVersion: zalando.org/v1 +kind: RouteGroup +metadata: + name: my-route-group + annotations: + zalando.org/aws-load-balancer-shared: "true" +spec: + hosts: + - foo.bar.org + backends: + - name: my-backend + type: service + serviceName: my-service + servicePort: 80 + routes: + - pathSubtree: / + backends: + - backendName: my-backend diff --git a/testdata/ingress_rg_shared_nlb/output/params/shared.json b/testdata/ingress_rg_shared_nlb/output/params/shared.json new file mode 100644 index 00000000..adec04c7 --- /dev/null +++ b/testdata/ingress_rg_shared_nlb/output/params/shared.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/ingress_rg_shared_nlb/output/tags/shared.json b/testdata/ingress_rg_shared_nlb/output/tags/shared.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/ingress_rg_shared_nlb/output/tags/shared.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/ingress_rg_shared_nlb/output/templates/shared.cf b/testdata/ingress_rg_shared_nlb/output/templates/shared.cf new file mode 100644 index 00000000..ac57a010 --- /dev/null +++ b/testdata/ingress_rg_shared_nlb/output/templates/shared.cf @@ -0,0 +1,187 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "TLS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "TCP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/testdata/rg_alb/input/k8s/rg.yaml b/testdata/rg_alb/input/k8s/rg.yaml new file mode 100644 index 00000000..ed9a90f5 --- /dev/null +++ b/testdata/rg_alb/input/k8s/rg.yaml @@ -0,0 +1,16 @@ +apiVersion: zalando.org/v1 +kind: RouteGroup +metadata: + name: my-route-group +spec: + hosts: + - foo.bar.org + backends: + - name: my-backend + type: service + serviceName: my-service + servicePort: 80 + routes: + - pathSubtree: / + backends: + - backendName: my-backend diff --git a/testdata/rg_alb/output/params/rg.json b/testdata/rg_alb/output/params/rg.json new file mode 100644 index 00000000..c1ecf899 --- /dev/null +++ b/testdata/rg_alb/output/params/rg.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/rg_alb/output/tags/rg.json b/testdata/rg_alb/output/tags/rg.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/rg_alb/output/tags/rg.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/rg_alb/output/templates/rg.cf b/testdata/rg_alb/output/templates/rg.cf new file mode 100644 index 00000000..7e9378df --- /dev/null +++ b/testdata/rg_alb/output/templates/rg.cf @@ -0,0 +1,219 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "0" + }, + { + "Key": "routing.http2.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "SecurityGroups": { + "Ref": "LoadBalancerSecurityGroupParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": { + "Ref": "TargetGroupHealthCheckTimeoutParameter" + }, + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/testdata/rg_nlb/input/k8s/rg.yaml b/testdata/rg_nlb/input/k8s/rg.yaml new file mode 100644 index 00000000..ed9a90f5 --- /dev/null +++ b/testdata/rg_nlb/input/k8s/rg.yaml @@ -0,0 +1,16 @@ +apiVersion: zalando.org/v1 +kind: RouteGroup +metadata: + name: my-route-group +spec: + hosts: + - foo.bar.org + backends: + - name: my-backend + type: service + serviceName: my-service + servicePort: 80 + routes: + - pathSubtree: / + backends: + - backendName: my-backend diff --git a/testdata/rg_nlb/output/params/rg.json b/testdata/rg_nlb/output/params/rg.json new file mode 100644 index 00000000..adec04c7 --- /dev/null +++ b/testdata/rg_nlb/output/params/rg.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/rg_nlb/output/tags/rg.json b/testdata/rg_nlb/output/tags/rg.json new file mode 100644 index 00000000..d64eed43 --- /dev/null +++ b/testdata/rg_nlb/output/tags/rg.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/rg_nlb/output/templates/rg.cf b/testdata/rg_nlb/output/templates/rg.cf new file mode 100644 index 00000000..ac57a010 --- /dev/null +++ b/testdata/rg_nlb/output/templates/rg.cf @@ -0,0 +1,187 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Load Balancer for Kubernetes Ingress", + "Parameters": { + "HTTP2": { + "Type": "String", + "Default": "true", + "Description": "H2 Enabled" + }, + "IpAddressType": { + "Type": "String", + "Default": "ipv4", + "Description": "IP Address Type, 'ipv4' or 'dualstack'" + }, + "ListenerSslPolicyParameter": { + "Type": "String", + "Default": "ELBSecurityPolicy-2016-08", + "Description": "The HTTPS SSL Security Policy Name" + }, + "LoadBalancerSchemeParameter": { + "Type": "String", + "Default": "internet-facing", + "Description": "The Load Balancer scheme - 'internal' or 'internet-facing'" + }, + "LoadBalancerSecurityGroupParameter": { + "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e", + "Description": "The security group ID for the Load Balancer" + }, + "LoadBalancerSubnetsParameter": { + "Type": "List\u003cAWS::EC2::Subnet::Id\u003e", + "Description": "The list of subnets IDs for the Load Balancer" + }, + "TargetGroupHealthCheckIntervalParameter": { + "Type": "Number", + "Default": "10", + "Description": "The healthcheck interval" + }, + "TargetGroupHealthCheckPathParameter": { + "Type": "String", + "Default": "/kube-system/healthz", + "Description": "The healthcheck path" + }, + "TargetGroupHealthCheckPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The healthcheck port" + }, + "TargetGroupHealthCheckTimeoutParameter": { + "Type": "Number", + "Default": "5", + "Description": "The healthcheck timeout" + }, + "TargetGroupTargetPortParameter": { + "Type": "Number", + "Default": "9999", + "Description": "The target port" + }, + "TargetGroupVPCIDParameter": { + "Type": "AWS::EC2::VPC::Id", + "Description": "The VPCID for the TargetGroup" + }, + "Type": { + "Type": "String", + "Default": "application", + "Description": "Loadbalancer Type, 'application' or 'network'" + } + }, + "Resources": { + "HTTPSListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TG" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB" + }, + "Port": 443, + "Protocol": "TLS", + "SslPolicy": { + "Ref": "ListenerSslPolicyParameter" + } + } + }, + "HTTPSListenerCertificatefc48082457b770e278fc0bd3d392d127869993166f76e8df57d19a0e662820ea": { + "Type": "AWS::ElasticLoadBalancingV2::ListenerCertificate", + "Properties": { + "Certificates": [ + { + "CertificateArn": "DUMMY" + } + ], + "ListenerArn": { + "Ref": "HTTPSListener" + } + } + }, + "LB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "IpAddressType": { + "Ref": "IpAddressType" + }, + "LoadBalancerAttributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "false" + } + ], + "Scheme": { + "Ref": "LoadBalancerSchemeParameter" + }, + "Subnets": { + "Ref": "LoadBalancerSubnetsParameter" + }, + "Tags": [ + { + "Key": "StackName", + "Value": { + "Ref": "AWS::StackName" + } + } + ], + "Type": { + "Ref": "Type" + } + } + }, + "TG": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": { + "Ref": "TargetGroupHealthCheckIntervalParameter" + }, + "HealthCheckPath": { + "Ref": "TargetGroupHealthCheckPathParameter" + }, + "HealthCheckPort": { + "Ref": "TargetGroupHealthCheckPortParameter" + }, + "HealthCheckProtocol": "HTTP", + "HealthyThresholdCount": 0, + "Port": { + "Ref": "TargetGroupTargetPortParameter" + }, + "Protocol": "TCP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "0" + } + ], + "UnhealthyThresholdCount": 0, + "VpcId": { + "Ref": "TargetGroupVPCIDParameter" + } + } + } + }, + "Outputs": { + "LoadBalancerDNSName": { + "Description": "DNS name for the LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LB", + "DNSName" + ] + } + }, + "TargetGroupARN": { + "Description": "The ARN of the TargetGroup", + "Value": { + "Ref": "TG" + } + } + } +} \ No newline at end of file diff --git a/worker_test.go b/worker_test.go index d4cf4efb..91e9ebb5 100644 --- a/worker_test.go +++ b/worker_test.go @@ -4,6 +4,7 @@ import ( "context" "crypto/x509" "encoding/json" + "io" "net/http/httptest" "os" "reflect" @@ -27,7 +28,7 @@ import ( certsfake "github.com/zalando-incubator/kube-ingress-aws-controller/certs/fake" ) -func TestResourceConversion(tt *testing.T) { +func TestResourceConversionOneToOne(tt *testing.T) { clusterIDTagPrefix := "kubernetes.io/cluster/" clusterID := "aws:123:eu-central-1:kube-1" vpcID := "1" @@ -43,7 +44,7 @@ func TestResourceConversion(tt *testing.T) { typeLB string }{ { - name: "simple_alb", + name: "ingress_alb", responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( nil, fake.TestInstance{ @@ -96,7 +97,267 @@ func TestResourceConversion(tt *testing.T) { typeLB: awsAdapter.LoadBalancerTypeApplication, }, { - name: "simple_nlb", + name: "ingress_nlb", + responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( + nil, + fake.TestInstance{ + Id: "i0", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.3", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i1", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.4", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i2", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.5", + VpcId: vpcID, + State: running, + }), + DescribeSecurityGroups: fake.R(fake.MockDescribeSecurityGroupsOutput(map[string]string{"id": securityGroupID}), nil), + DescribeSubnets: fake.R(fake.MockDescribeSubnetsOutput( + fake.TestSubnet{Id: "foo1", Name: "bar1", Az: "baz1", Tags: map[string]string{"kubernetes.io/role/elb": ""}}), nil), + DescribeRouteTables: fake.R(fake.MockDescribeRouteTableOutput( + fake.TestRouteTable{SubnetID: "foo1", GatewayIds: []string{"igw-foo1"}}, + fake.TestRouteTable{SubnetID: "mismatch", GatewayIds: []string{"igw-foo2"}, Main: true}, + ), nil), + }, + responsesASG: fake.ASGOutputs{ + DescribeAutoScalingGroups: fake.R(fake.MockDescribeAutoScalingGroupOutput(map[string]fake.ASGtags{"asg1": { + clusterIDTagPrefix + clusterID: "owned", + }}), nil), + DescribeLoadBalancerTargetGroups: fake.R(&autoscaling.DescribeLoadBalancerTargetGroupsOutput{ + LoadBalancerTargetGroups: []*autoscaling.LoadBalancerTargetGroupState{}, + }, nil), + AttachLoadBalancerTargetGroups: fake.R(nil, nil), + }, + responsesELBv2: fake.ELBv2Outputs{ + DescribeTargetGroups: fake.R(nil, nil), + DescribeTags: fake.R(nil, nil), + }, + responsesCF: fake.CFOutputs{ + DescribeStackPages: fake.R(nil, nil), + DescribeStacks: fake.R(nil, nil), + CreateStack: fake.R(fake.MockCSOutput("42"), nil), + }, + typeLB: awsAdapter.LoadBalancerTypeNetwork, + }, { + name: "rg_alb", + responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( + nil, + fake.TestInstance{ + Id: "i0", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.3", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i1", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.4", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i2", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.5", + VpcId: vpcID, + State: running, + }), + DescribeSecurityGroups: fake.R(fake.MockDescribeSecurityGroupsOutput(map[string]string{"id": securityGroupID}), nil), + DescribeSubnets: fake.R(fake.MockDescribeSubnetsOutput( + fake.TestSubnet{Id: "foo1", Name: "bar1", Az: "baz1", Tags: map[string]string{"kubernetes.io/role/elb": ""}}), nil), + DescribeRouteTables: fake.R(fake.MockDescribeRouteTableOutput( + fake.TestRouteTable{SubnetID: "foo1", GatewayIds: []string{"igw-foo1"}}, + fake.TestRouteTable{SubnetID: "mismatch", GatewayIds: []string{"igw-foo2"}, Main: true}, + ), nil), + }, + responsesASG: fake.ASGOutputs{ + DescribeAutoScalingGroups: fake.R(fake.MockDescribeAutoScalingGroupOutput(map[string]fake.ASGtags{"asg1": { + clusterIDTagPrefix + clusterID: "owned", + }}), nil), + DescribeLoadBalancerTargetGroups: fake.R(&autoscaling.DescribeLoadBalancerTargetGroupsOutput{ + LoadBalancerTargetGroups: []*autoscaling.LoadBalancerTargetGroupState{}, + }, nil), + AttachLoadBalancerTargetGroups: fake.R(nil, nil), + }, + responsesELBv2: fake.ELBv2Outputs{ + DescribeTargetGroups: fake.R(nil, nil), + DescribeTags: fake.R(nil, nil), + }, + responsesCF: fake.CFOutputs{ + DescribeStackPages: fake.R(nil, nil), + DescribeStacks: fake.R(nil, nil), + CreateStack: fake.R(fake.MockCSOutput("42"), nil), + }, + typeLB: awsAdapter.LoadBalancerTypeApplication, + }, { + name: "rg_nlb", + responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( + nil, + fake.TestInstance{ + Id: "i0", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.3", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i1", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.4", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i2", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.5", + VpcId: vpcID, + State: running, + }), + DescribeSecurityGroups: fake.R(fake.MockDescribeSecurityGroupsOutput(map[string]string{"id": securityGroupID}), nil), + DescribeSubnets: fake.R(fake.MockDescribeSubnetsOutput( + fake.TestSubnet{Id: "foo1", Name: "bar1", Az: "baz1", Tags: map[string]string{"kubernetes.io/role/elb": ""}}), nil), + DescribeRouteTables: fake.R(fake.MockDescribeRouteTableOutput( + fake.TestRouteTable{SubnetID: "foo1", GatewayIds: []string{"igw-foo1"}}, + fake.TestRouteTable{SubnetID: "mismatch", GatewayIds: []string{"igw-foo2"}, Main: true}, + ), nil), + }, + responsesASG: fake.ASGOutputs{ + DescribeAutoScalingGroups: fake.R(fake.MockDescribeAutoScalingGroupOutput(map[string]fake.ASGtags{"asg1": { + clusterIDTagPrefix + clusterID: "owned", + }}), nil), + DescribeLoadBalancerTargetGroups: fake.R(&autoscaling.DescribeLoadBalancerTargetGroupsOutput{ + LoadBalancerTargetGroups: []*autoscaling.LoadBalancerTargetGroupState{}, + }, nil), + AttachLoadBalancerTargetGroups: fake.R(nil, nil), + }, + responsesELBv2: fake.ELBv2Outputs{ + DescribeTargetGroups: fake.R(nil, nil), + DescribeTags: fake.R(nil, nil), + }, + responsesCF: fake.CFOutputs{ + DescribeStackPages: fake.R(nil, nil), + DescribeStacks: fake.R(nil, nil), + CreateStack: fake.R(fake.MockCSOutput("42"), nil), + }, + typeLB: awsAdapter.LoadBalancerTypeNetwork, + }, { + name: "ing_shared_rg_notshared_alb", + responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( + nil, + fake.TestInstance{ + Id: "i0", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.3", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i1", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.4", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i2", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.5", + VpcId: vpcID, + State: running, + }), + DescribeSecurityGroups: fake.R(fake.MockDescribeSecurityGroupsOutput(map[string]string{"id": securityGroupID}), nil), + DescribeSubnets: fake.R(fake.MockDescribeSubnetsOutput( + fake.TestSubnet{Id: "foo1", Name: "bar1", Az: "baz1", Tags: map[string]string{"kubernetes.io/role/elb": ""}}), nil), + DescribeRouteTables: fake.R(fake.MockDescribeRouteTableOutput( + fake.TestRouteTable{SubnetID: "foo1", GatewayIds: []string{"igw-foo1"}}, + fake.TestRouteTable{SubnetID: "mismatch", GatewayIds: []string{"igw-foo2"}, Main: true}, + ), nil), + }, + responsesASG: fake.ASGOutputs{ + DescribeAutoScalingGroups: fake.R(fake.MockDescribeAutoScalingGroupOutput(map[string]fake.ASGtags{"asg1": { + clusterIDTagPrefix + clusterID: "owned", + }}), nil), + DescribeLoadBalancerTargetGroups: fake.R(&autoscaling.DescribeLoadBalancerTargetGroupsOutput{ + LoadBalancerTargetGroups: []*autoscaling.LoadBalancerTargetGroupState{}, + }, nil), + AttachLoadBalancerTargetGroups: fake.R(nil, nil), + }, + responsesELBv2: fake.ELBv2Outputs{ + DescribeTargetGroups: fake.R(nil, nil), + DescribeTags: fake.R(nil, nil), + }, + responsesCF: fake.CFOutputs{ + DescribeStackPages: fake.R(nil, nil), + DescribeStacks: fake.R(nil, nil), + CreateStack: fake.R(fake.MockCSOutput("42"), nil), + }, + typeLB: awsAdapter.LoadBalancerTypeApplication, + }, { + name: "ingress_rg_shared_alb", + responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( + nil, + fake.TestInstance{ + Id: "i0", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.3", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i1", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.4", + VpcId: vpcID, + State: running, + }, + fake.TestInstance{ + Id: "i2", + Tags: fake.Tags{"aws:autoscaling:groupName": "asg1", clusterIDTagPrefix + clusterID: "owned"}, + PrivateIp: "1.2.3.5", + VpcId: vpcID, + State: running, + }), + DescribeSecurityGroups: fake.R(fake.MockDescribeSecurityGroupsOutput(map[string]string{"id": securityGroupID}), nil), + DescribeSubnets: fake.R(fake.MockDescribeSubnetsOutput( + fake.TestSubnet{Id: "foo1", Name: "bar1", Az: "baz1", Tags: map[string]string{"kubernetes.io/role/elb": ""}}), nil), + DescribeRouteTables: fake.R(fake.MockDescribeRouteTableOutput( + fake.TestRouteTable{SubnetID: "foo1", GatewayIds: []string{"igw-foo1"}}, + fake.TestRouteTable{SubnetID: "mismatch", GatewayIds: []string{"igw-foo2"}, Main: true}, + ), nil), + }, + responsesASG: fake.ASGOutputs{ + DescribeAutoScalingGroups: fake.R(fake.MockDescribeAutoScalingGroupOutput(map[string]fake.ASGtags{"asg1": { + clusterIDTagPrefix + clusterID: "owned", + }}), nil), + DescribeLoadBalancerTargetGroups: fake.R(&autoscaling.DescribeLoadBalancerTargetGroupsOutput{ + LoadBalancerTargetGroups: []*autoscaling.LoadBalancerTargetGroupState{}, + }, nil), + AttachLoadBalancerTargetGroups: fake.R(nil, nil), + }, + responsesELBv2: fake.ELBv2Outputs{ + DescribeTargetGroups: fake.R(nil, nil), + DescribeTags: fake.R(nil, nil), + }, + responsesCF: fake.CFOutputs{ + DescribeStackPages: fake.R(nil, nil), + DescribeStacks: fake.R(nil, nil), + CreateStack: fake.R(fake.MockCSOutput("42"), nil), + }, + typeLB: awsAdapter.LoadBalancerTypeApplication, + }, { + name: "ingress_rg_shared_nlb", responsesEC2: fake.EC2Outputs{DescribeInstancesPages: fake.MockDescribeInstancesPagesOutput( nil, fake.TestInstance{ @@ -151,7 +412,7 @@ func TestResourceConversion(tt *testing.T) { } { tt.Run(scenario.name, func(t *testing.T) { readFile := func(fileName string) []byte { - b, err := os.ReadFile("./testdata/" + scenario.name + "/" + fileName) + b, err := os.ReadFile("./testdata/" + scenario.name + "/output/" + fileName) if err != nil { t.Fatal(err) } @@ -159,20 +420,46 @@ func TestResourceConversion(tt *testing.T) { return b } - template := string(readFile("template.cf")) + var templates []string + templateFiles, err := os.ReadDir("./testdata/" + scenario.name + "/output/templates/") + if err != nil { + t.Fatal(err) + } + + for _, file := range templateFiles { + templates = append(templates, string(readFile("templates/"+file.Name()))) + } - var tags []*cf.Tag - err := json.Unmarshal(readFile("tags.json"), &tags) + paramFiles, err := os.ReadDir("./testdata/" + scenario.name + "/output/params/") if err != nil { t.Fatal(err) } - var params []*cf.Parameter - err = json.Unmarshal(readFile("params.json"), ¶ms) + var params [][]*cf.Parameter + for _, file := range paramFiles { + var content []*cf.Parameter + err := json.Unmarshal(readFile("params/"+file.Name()), &content) + if err != nil { + t.Fatal(err) + } + params = append(params, content) + } + + tagFiles, err := os.ReadDir("./testdata/" + scenario.name + "/output/tags/") if err != nil { t.Fatal(err) } + var tags [][]*cf.Tag + for _, file := range tagFiles { + var content []*cf.Tag + err := json.Unmarshal(readFile("tags/"+file.Name()), &content) + if err != nil { + t.Fatal(err) + } + tags = append(tags, content) + } + clientEC2 := &fake.EC2Client{Outputs: scenario.responsesEC2} clientASG := &fake.ASGClient{Outputs: scenario.responsesASG} clientELBv2 := &fake.ELBv2Client{Outputs: scenario.responsesELBv2} @@ -188,15 +475,25 @@ func TestResourceConversion(tt *testing.T) { a, err = a.UpdateManifest(clusterID, vpcID) if err != nil { - t.Error(err) + t.Fatal(err) } - f, err := os.Open("./testdata/" + scenario.name + "/ing.yaml") + readers := make([]io.Reader, 0) + files, err := os.ReadDir("./testdata/" + scenario.name + "/input/k8s/") if err != nil { t.Fatal(err) } - api, err := kubernetestest.NewAPI(kubernetestest.TestAPIOptions{}, f) + for _, file := range files { + f, err := os.Open("./testdata/" + scenario.name + "/input/k8s/" + file.Name()) + if err != nil { + t.Fatal(err) + } + readers = append(readers, f) + defer f.Close() + } + + api, err := kubernetestest.NewAPI(kubernetestest.TestAPIOptions{}, readers...) if err != nil { t.Fatal(err) } @@ -223,36 +520,48 @@ func TestResourceConversion(tt *testing.T) { if err != nil { t.Fatal(err) } + log.SetLevel(log.DebugLevel) problems := doWork(&certsfake.CertificateProvider{}, 10, time.Hour, a, k, "") if len(problems.Errors()) > 0 { 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.ElementsMatch( - t, - tags, - clientCF.GetLastStackTags(), - ) - - assert.ElementsMatch( - t, - params, - clientCF.GetLastStackParams(), - ) + assert.Equal(t, len(clientCF.GetTagCreationHistory()), len(tags)) + assert.Equal(t, len(clientCF.GetParamCreationHistory()), len(params)) + assert.Equal(t, len(clientCF.GetTemplateCreationHistory()), len(templates)) + + // This loop is necessary because assert.ElementsMatch only do set-style comparison + // for the first level of the array. So for nested arrays it would not behave like expected. + // The order is important when loading the files, because of this its necessary to use numbers + // before the file name to make them in the order you want. + for i := range templates { + // 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, + templates[i], + clientCF.GetTemplateCreationHistory()[i], + ) + + assert.ElementsMatch( + t, + tags[i], + clientCF.GetTagCreationHistory()[i], + ) + + assert.ElementsMatch( + t, + params[i], + clientCF.GetParamCreationHistory()[i], + ) + } + clientCF.CleanCreationHistory() }) } }