Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions aws/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type Adapter struct {
controllerID string
sslPolicy string
ipAddressType string
targetIpAddressType string
albLogsS3Bucket string
albLogsS3Prefix string
nlbZoneAffinity string
Expand Down Expand Up @@ -118,6 +119,8 @@ const (
DefaultSslPolicy = "ELBSecurityPolicy-2016-08"
// DefaultIpAddressType sets IpAddressType to "ipv4", it is either ipv4 or dualstack
DefaultIpAddressType = "ipv4"
// DefaultTargetIpAddressType sets TargetIpAddressType to "ipv4", it is either ipv4 or ipv6
DefaultTargetIpAddressType = "ipv4"
// DefaultAlbS3LogsBucket is a blank string, and must be set if enabled
DefaultAlbS3LogsBucket = ""
// DefaultAlbS3LogsPrefix is a blank string, and optionally set if desired
Expand All @@ -139,6 +142,7 @@ const (
LoadBalancerTypeNetwork = "network"
IPAddressTypeIPV4 = "ipv4"
IPAddressTypeDualstack = "dualstack"
IPAddressTypeIPV6 = "ipv6"

TargetAccessModeAWSCNI = "AWSCNI"
TargetAccessModeHostPort = "HostPort"
Expand Down Expand Up @@ -263,6 +267,7 @@ func NewAdapter(ctx context.Context, clusterID, newControllerID, vpcID string, d
controllerID: newControllerID,
sslPolicy: DefaultSslPolicy,
ipAddressType: DefaultIpAddressType,
targetIpAddressType: DefaultTargetIpAddressType,
albLogsS3Bucket: DefaultAlbS3LogsBucket,
albLogsS3Prefix: DefaultAlbS3LogsPrefix,
nlbCrossZone: DefaultNLBCrossZone,
Expand Down Expand Up @@ -442,6 +447,14 @@ func (a *Adapter) WithIpAddressType(ipAddressType string) *Adapter {
return a
}

// WithTargetIpAddressType returns the receiver with ipv4 or ipv6 configuration, defaults to ipv4.
func (a *Adapter) WithTargetIpAddressType(targetIpAddressType string) *Adapter {
if targetIpAddressType == IPAddressTypeIPV6 {
a.targetIpAddressType = targetIpAddressType
}
return a
}

// WithAlbLogsS3Bucket returns the receiver adapter after changing the S3 bucket for logging
func (a *Adapter) WithAlbLogsS3Bucket(bucket string) *Adapter {
a.albLogsS3Bucket = bucket
Expand Down Expand Up @@ -770,7 +783,7 @@ func (a *Adapter) UpdateTargetGroupsAndAutoScalingGroups(ctx context.Context, st
// All the required resources (listeners and target group) are created in a
// transactional fashion.
// Failure to create the stack causes it to be deleted automatically.
func (a *Adapter) CreateStack(ctx context.Context, certificateARNs []string, scheme, securityGroup, owner, sslPolicy, ipAddressType, wafWebACLID string, cwAlarms CloudWatchAlarmList, loadBalancerType string, http2 bool) (string, error) {
func (a *Adapter) CreateStack(ctx context.Context, certificateARNs []string, scheme, securityGroup, owner, sslPolicy, ipAddressType, wafWebACLID string, cwAlarms CloudWatchAlarmList, loadBalancerType string, http2 bool, targetIpAddressType string) (string, error) {
certARNs := make(map[string]time.Time, len(certificateARNs))
for _, arn := range certificateARNs {
certARNs[arn] = time.Time{}
Expand All @@ -780,6 +793,10 @@ func (a *Adapter) CreateStack(ctx context.Context, certificateARNs []string, sch
sslPolicy = a.sslPolicy
}

if targetIpAddressType == "" {
targetIpAddressType = a.targetIpAddressType
}

if _, ok := SSLPolicies[sslPolicy]; !ok {
return "", fmt.Errorf("invalid SSLPolicy '%s' defined", sslPolicy)
}
Expand Down Expand Up @@ -814,6 +831,7 @@ func (a *Adapter) CreateStack(ctx context.Context, certificateARNs []string, sch
controllerID: a.controllerID,
sslPolicy: sslPolicy,
ipAddressType: ipAddressType,
targetIpAddressType: targetIpAddressType,
loadbalancerType: loadBalancerType,
albLogsS3Bucket: a.albLogsS3Bucket,
albLogsS3Prefix: a.albLogsS3Prefix,
Expand All @@ -836,7 +854,7 @@ func (a *Adapter) CreateStack(ctx context.Context, certificateARNs []string, sch
return createStack(ctx, a.cloudformation, spec)
}

func (a *Adapter) UpdateStack(ctx context.Context, stackName string, certificateARNs map[string]time.Time, scheme, securityGroup, owner, sslPolicy, ipAddressType, wafWebACLID string, cwAlarms CloudWatchAlarmList, loadBalancerType string, http2 bool) (string, error) {
func (a *Adapter) UpdateStack(ctx context.Context, stackName string, certificateARNs map[string]time.Time, scheme, securityGroup, owner, sslPolicy, ipAddressType, wafWebACLID string, cwAlarms CloudWatchAlarmList, loadBalancerType string, http2 bool, targetIpAddressType string) (string, error) {
if _, ok := SSLPolicies[sslPolicy]; !ok {
return "", fmt.Errorf("invalid SSLPolicy '%s' defined", sslPolicy)
}
Expand Down Expand Up @@ -871,6 +889,7 @@ func (a *Adapter) UpdateStack(ctx context.Context, stackName string, certificate
controllerID: a.controllerID,
sslPolicy: sslPolicy,
ipAddressType: ipAddressType,
targetIpAddressType: targetIpAddressType,
loadbalancerType: loadBalancerType,
albLogsS3Bucket: a.albLogsS3Bucket,
albLogsS3Prefix: a.albLogsS3Prefix,
Expand Down
79 changes: 45 additions & 34 deletions aws/cf.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,24 @@ const (

// Stack is a simple wrapper around a CloudFormation Stack.
type Stack struct {
Name string
status types.StackStatus
statusReason string
LoadBalancerARN string
DNSName string
Scheme string
SecurityGroup string
SSLPolicy string
IpAddressType string
LoadBalancerType string
HTTP2 bool
OwnerIngress string
CWAlarmConfigHash string
TargetGroupARNs []string
WAFWebACLID string
CertificateARNs map[string]time.Time
tags map[string]string
Name string
status types.StackStatus
statusReason string
LoadBalancerARN string
DNSName string
Scheme string
SecurityGroup string
SSLPolicy string
IpAddressType string
LoadBalancerType string
HTTP2 bool
OwnerIngress string
CWAlarmConfigHash string
TargetGroupARNs []string
WAFWebACLID string
CertificateARNs map[string]time.Time
tags map[string]string
TargetIPAddressType string
}

// IsComplete returns true if the stack status is a complete state.
Expand Down Expand Up @@ -150,6 +151,7 @@ const (
parameterTargetGroupHealthCheckTimeoutParameter = "TargetGroupHealthCheckTimeoutParameter"
parameterTargetGroupTargetPortParameter = "TargetGroupTargetPortParameter"
parameterTargetGroupHTTPTargetPortParameter = "TargetGroupHTTPTargetPortParameter"
parameterTargetGroupIpAddressTypeParameter = "TargetGroupIpAddressTypeParameter"
parameterTargetGroupVPCIDParameter = "TargetGroupVPCIDParameter"
parameterListenerSslPolicyParameter = "ListenerSslPolicyParameter"
parameterIpAddressTypeParameter = "IpAddressType"
Expand Down Expand Up @@ -183,6 +185,7 @@ type stackSpec struct {
controllerID string
sslPolicy string
ipAddressType string
targetIpAddressType string
loadbalancerType string
albLogsS3Bucket string
albLogsS3Prefix string
Expand Down Expand Up @@ -241,6 +244,7 @@ func createStack(ctx context.Context, svc CloudFormationAPI, spec *stackSpec) (s
cfParam(parameterLoadBalancerSubnetsParameter, strings.Join(spec.subnets, ",")),
cfParam(parameterTargetGroupVPCIDParameter, spec.vpcID),
cfParam(parameterTargetGroupTargetPortParameter, fmt.Sprintf("%d", spec.targetPort)),
cfParam(parameterTargetGroupIpAddressTypeParameter, spec.targetIpAddressType),
cfParam(parameterListenerSslPolicyParameter, spec.sslPolicy),
cfParam(parameterIpAddressTypeParameter, spec.ipAddressType),
cfParam(parameterLoadBalancerTypeParameter, spec.loadbalancerType),
Expand Down Expand Up @@ -316,6 +320,7 @@ func updateStack(ctx context.Context, svc CloudFormationAPI, spec *stackSpec) (s
cfParam(parameterLoadBalancerSubnetsParameter, strings.Join(spec.subnets, ",")),
cfParam(parameterTargetGroupVPCIDParameter, spec.vpcID),
cfParam(parameterTargetGroupTargetPortParameter, fmt.Sprintf("%d", spec.targetPort)),
cfParam(parameterTargetGroupIpAddressTypeParameter, spec.targetIpAddressType),
cfParam(parameterListenerSslPolicyParameter, spec.sslPolicy),
cfParam(parameterIpAddressTypeParameter, spec.ipAddressType),
cfParam(parameterLoadBalancerTypeParameter, spec.loadbalancerType),
Expand Down Expand Up @@ -490,24 +495,30 @@ func mapToManagedStack(stack *types.Stack) *Stack {
http2 = false
}

targetGroupIpAddressType := parameters[parameterTargetGroupIpAddressTypeParameter]
if targetGroupIpAddressType == "" {
targetGroupIpAddressType = DefaultTargetIpAddressType
}

return &Stack{
Name: aws.ToString(stack.StackName),
LoadBalancerARN: outputs.loadBalancerARN(),
DNSName: outputs.dnsName(),
TargetGroupARNs: outputs.targetGroupARNs(),
Scheme: parameters[parameterLoadBalancerSchemeParameter],
SecurityGroup: parameters[parameterLoadBalancerSecurityGroupParameter],
SSLPolicy: parameters[parameterListenerSslPolicyParameter],
IpAddressType: parameters[parameterIpAddressTypeParameter],
LoadBalancerType: parameters[parameterLoadBalancerTypeParameter],
HTTP2: http2,
CertificateARNs: certificateARNs,
tags: tags,
OwnerIngress: ownerIngress,
status: stack.StackStatus,
statusReason: aws.ToString(stack.StackStatusReason),
CWAlarmConfigHash: tags[cwAlarmConfigHashTag],
WAFWebACLID: parameters[parameterLoadBalancerWAFWebACLIDParameter],
Name: aws.ToString(stack.StackName),
LoadBalancerARN: outputs.loadBalancerARN(),
DNSName: outputs.dnsName(),
TargetGroupARNs: outputs.targetGroupARNs(),
Scheme: parameters[parameterLoadBalancerSchemeParameter],
SecurityGroup: parameters[parameterLoadBalancerSecurityGroupParameter],
SSLPolicy: parameters[parameterListenerSslPolicyParameter],
IpAddressType: parameters[parameterIpAddressTypeParameter],
LoadBalancerType: parameters[parameterLoadBalancerTypeParameter],
HTTP2: http2,
CertificateARNs: certificateARNs,
tags: tags,
OwnerIngress: ownerIngress,
status: stack.StackStatus,
statusReason: aws.ToString(stack.StackStatusReason),
CWAlarmConfigHash: tags[cwAlarmConfigHashTag],
WAFWebACLID: parameters[parameterLoadBalancerWAFWebACLIDParameter],
TargetIPAddressType: targetGroupIpAddressType,
}
}

Expand Down
6 changes: 6 additions & 0 deletions aws/cf_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ func generateTemplate(spec *stackSpec) (string, error) {
Type: "AWS::EC2::VPC::Id",
Description: "The VPCID for the TargetGroup",
},
parameterTargetGroupIpAddressTypeParameter: {
Type: "String",
Description: "The IP Address Type for the TargetGroup, 'ipv4' or 'ipv6'",
Default: IPAddressTypeIPV4,
},
parameterListenerSslPolicyParameter: {
Type: "String",
Description: "The HTTPS SSL Security Policy Name",
Expand Down Expand Up @@ -495,6 +500,7 @@ func newTargetGroup(spec *stackSpec, targetPortParameter string) *cloudformation
HealthCheckProtocol: cloudformation.String(healthCheckProtocol),
HealthyThresholdCount: cloudformation.Integer(int64(healthyThresholdCount)),
UnhealthyThresholdCount: cloudformation.Integer(int64(unhealthyThresholdCount)),
IPAddressType: cloudformation.Ref(parameterTargetGroupIpAddressTypeParameter).String(),
Port: cloudformation.Ref(targetPortParameter).Integer(),
Protocol: cloudformation.String(protocol),
TargetType: targetType,
Expand Down
4 changes: 4 additions & 0 deletions controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ var (
blacklistCertARNs []string
blacklistCertArnMap map[string]bool
ipAddressType string
targetIpAddressType string
albLogsS3Bucket string
albLogsS3Prefix string
wafWebAclId string
Expand Down Expand Up @@ -162,6 +163,8 @@ func loadSettings() error {
kingpin.Flag("blacklist-certificate-arns", "Certificate ARNs to not consider by the controller.").StringsVar(&blacklistCertARNs)
kingpin.Flag("ip-addr-type", "IP Address type to use.").
Default(aws.DefaultIpAddressType).EnumVar(&ipAddressType, aws.IPAddressTypeIPV4, aws.IPAddressTypeDualstack)
kingpin.Flag("target-ip-addr-type", "Target IP Address type to use. Defaults to ipv4, can be set to ipv6.").
Default(aws.DefaultTargetIpAddressType).EnumVar(&targetIpAddressType, aws.IPAddressTypeIPV4, aws.IPAddressTypeIPV6)
kingpin.Flag("logs-s3-bucket", "S3 bucket to be used for ALB logging").
Default(aws.DefaultAlbS3LogsBucket).StringVar(&albLogsS3Bucket)
kingpin.Flag("logs-s3-prefix", "Prefix within S3 bucket to be used for ALB logging").
Expand Down Expand Up @@ -336,6 +339,7 @@ func main() {
WithControllerID(controllerID).
WithSslPolicy(sslPolicy).
WithIpAddressType(ipAddressType).
WithTargetIpAddressType(targetIpAddressType).
WithAlbLogsS3Bucket(albLogsS3Bucket).
WithAlbLogsS3Prefix(albLogsS3Prefix).
WithHTTPRedirectToHTTPS(httpRedirectToHTTPS).
Expand Down
23 changes: 5 additions & 18 deletions delivery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,15 @@ pipeline:
- ~/.cache/go-build # Go build cache
type: script
commands:
- desc: test
cmd: |
make test
- desc: Build docker image
cmd: |
make build.docker
git diff --exit-code || exit 1
- desc: Push docker image
cmd: |
if [ -n "$CDP_PULL_REQUEST_NUMBER" ]; then
IMAGE=registry-write.opensource.zalan.do/teapot/kube-ingress-aws-controller-test
VERSION=$CDP_BUILD_VERSION
IMAGE=$IMAGE VERSION=$VERSION make build.push

# multi-arch image
IMAGE=container-registry-test.zalando.net/teapot/kube-ingress-aws-controller
# multi-arch image
IMAGE=container-registry-test.zalando.net/teapot/kube-ingress-aws-controller

make build.linux.amd64 build.linux.arm64
make build.linux.amd64 build.linux.arm64

docker buildx create --config /etc/cdp-buildkitd.toml --driver-opt network=host --bootstrap --use
docker buildx build --rm --build-arg BASE_IMAGE=container-registry.zalando.net/library/static:latest -t "${IMAGE}:${CDP_BUILD_VERSION}" --platform linux/amd64,linux/arm64 --push .
fi
docker buildx create --config /etc/cdp-buildkitd.toml --driver-opt network=host --bootstrap --use
docker buildx build --rm --build-arg BASE_IMAGE=container-registry.zalando.net/library/static:latest -t "${IMAGE}:${CDP_BUILD_VERSION}" --platform linux/amd64,linux/arm64 --push .

- id: buildprod
when:
Expand Down
9 changes: 6 additions & 3 deletions internal/aws/cloudformation/schema.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package cloudformation

// RESOURCE SPECIFICATION VERSION: 206.0.0
import "time"
import "encoding/json"
import _ "gopkg.in/go-playground/validator.v9" // Used for struct level validation tags
import (
"encoding/json"
"time"

_ "gopkg.in/go-playground/validator.v9"
) // Used for struct level validation tags

const ResourceSpecificationVersion = "206.0.0"

Expand Down
11 changes: 3 additions & 8 deletions kubernetes/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ func (a *Adapter) newIngress(typ IngressType, metadata kubeItemMetadata, host st
shared = false
}

ipAddressType := aws.IPAddressTypeIPV4
if getAnnotationsString(annotations, ingressALBIPAddressType, "") == aws.IPAddressTypeDualstack {
ipAddressType = aws.IPAddressTypeDualstack
ipAddressType := aws.IPAddressTypeDualstack
if getAnnotationsString(annotations, ingressALBIPAddressType, "") == aws.IPAddressTypeIPV4 {
ipAddressType = aws.IPAddressTypeIPV4
}

sslPolicy := getAnnotationsString(annotations, ingressSSLPolicyAnnotation, a.ingressDefaultSSLPolicy)
Expand Down Expand Up @@ -243,11 +243,6 @@ func (a *Adapter) newIngress(typ IngressType, metadata kubeItemMetadata, host st
// convert to the internal naming e.g. nlb -> network
loadBalancerType = loadBalancerTypesIngressToAWS[loadBalancerType]

if loadBalancerType == aws.LoadBalancerTypeNetwork {
// ensure ipv4 for network load balancers
ipAddressType = aws.IPAddressTypeIPV4
}

http2 := true
if getAnnotationsString(annotations, ingressHTTP2Annotation, "") == "false" {
http2 = false
Expand Down
9 changes: 7 additions & 2 deletions worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,12 @@ func (w *worker) createStack(ctx context.Context, lb *loadBalancer, problems *pr

log.Infof("Creating stack for certificates %q / ingress %q", certificates, lb.ingresses)

stackId, err := w.awsAdapter.CreateStack(ctx, certificates, lb.scheme, lb.securityGroup, lb.Owner(), lb.sslPolicy, lb.ipAddressType, lb.wafWebACLID, lb.cwAlarms, lb.loadBalancerType, lb.http2)
targetIpAddressType := ""
if lb.stack != nil {
targetIpAddressType = lb.stack.TargetIPAddressType
}

stackId, err := w.awsAdapter.CreateStack(ctx, certificates, lb.scheme, lb.securityGroup, lb.Owner(), lb.sslPolicy, lb.ipAddressType, lb.wafWebACLID, lb.cwAlarms, lb.loadBalancerType, lb.http2, targetIpAddressType)
if err != nil {
if isAlreadyExistsError(err) {
lb.stack, err = w.awsAdapter.GetStack(ctx, stackId)
Expand All @@ -565,7 +570,7 @@ func (w *worker) updateStack(ctx context.Context, lb *loadBalancer, problems *pr

log.Infof("Updating %q stack for %d certificates / %d ingresses", lb.scheme, len(certificates), len(lb.ingresses))

stackId, err := w.awsAdapter.UpdateStack(ctx, lb.stack.Name, certificates, lb.scheme, lb.securityGroup, lb.Owner(), lb.sslPolicy, lb.ipAddressType, lb.wafWebACLID, lb.cwAlarms, lb.loadBalancerType, lb.http2)
stackId, err := w.awsAdapter.UpdateStack(ctx, lb.stack.Name, certificates, lb.scheme, lb.securityGroup, lb.Owner(), lb.sslPolicy, lb.ipAddressType, lb.wafWebACLID, lb.cwAlarms, lb.loadBalancerType, lb.http2, lb.stack.TargetIPAddressType)
if isNoUpdatesToBePerformedError(err) {
log.Debugf("Stack(%q) is already up to date", certificates)
} else if err != nil {
Expand Down
Loading