diff --git a/Makefile b/Makefile index 2896aeef5..6587c96ce 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ ifeq (, $(shell which controller-gen)) CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.1 ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(GOBIN)/controller-gen diff --git a/apis/elbv2/v1alpha1/zz_generated.deepcopy.go b/apis/elbv2/v1alpha1/zz_generated.deepcopy.go index 0ce767338..ce91abd84 100644 --- a/apis/elbv2/v1alpha1/zz_generated.deepcopy.go +++ b/apis/elbv2/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* diff --git a/apis/elbv2/v1beta1/zz_generated.deepcopy.go b/apis/elbv2/v1beta1/zz_generated.deepcopy.go index 32aeab3fe..b85ca0a8f 100644 --- a/apis/elbv2/v1beta1/zz_generated.deepcopy.go +++ b/apis/elbv2/v1beta1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* @@ -311,7 +310,8 @@ func (in *SubnetSelector) DeepCopyInto(out *SubnetSelector) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } diff --git a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml index 051aa25f5..8663e4f79 100644 --- a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml +++ b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: ingressclassparams.elbv2.k8s.aws spec: group: elbv2.k8s.aws @@ -37,14 +36,19 @@ spec: description: IngressClassParams is the Schema for the IngressClassParams API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -93,32 +97,32 @@ spec: type: object type: array namespaceSelector: - description: NamespaceSelector restrict the namespaces of Ingresses - that are allowed to specify the IngressClass with this IngressClassParams. + description: |- + NamespaceSelector restrict the namespaces of Ingresses that are allowed to specify the IngressClass with this IngressClassParams. * if absent or present but empty, it selects all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -131,11 +135,10 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic @@ -168,10 +171,11 @@ spec: items: type: string type: array - description: Tags specifies subnets in the load balancer's VPC - where each tag specified in the map key contains one of the - values in the corresponding value list. Exactly one of this - or `ids` must be specified. + description: |- + Tags specifies subnets in the load balancer's VPC where each + tag specified in the map key contains one of the values in the corresponding + value list. + Exactly one of this or `ids` must be specified. type: object type: object tags: diff --git a/config/crd/bases/elbv2.k8s.aws_targetgroupbindings.yaml b/config/crd/bases/elbv2.k8s.aws_targetgroupbindings.yaml index e515c56aa..f079fedb2 100644 --- a/config/crd/bases/elbv2.k8s.aws_targetgroupbindings.yaml +++ b/config/crd/bases/elbv2.k8s.aws_targetgroupbindings.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: targetgroupbindings.elbv2.k8s.aws spec: group: elbv2.k8s.aws @@ -42,14 +41,19 @@ spec: description: TargetGroupBinding is the Schema for the TargetGroupBinding API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -66,28 +70,30 @@ spec: items: properties: from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. + description: |- + List of peers which should be able to access the targets in TargetGroup. + At least one NetworkingPeer should be specified. items: description: NetworkingPeer defines the source/destination peer for networking rules. properties: ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. + description: |- + IPBlock defines an IPBlock peer. + If specified, none of the other fields can be set. properties: cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. + description: |- + CIDR is the network CIDR. + Both IPV4 or IPV6 CIDR are accepted. type: string required: - cidr type: object securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. + description: |- + SecurityGroup defines a SecurityGroup peer. + If specified, none of the other fields can be set. properties: groupID: description: GroupID is the EC2 SecurityGroupID. @@ -98,24 +104,24 @@ spec: type: object type: array ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. + description: |- + List of ports which should be made accessible on the targets in TargetGroup. + If ports is empty or unspecified, it defaults to all ports with TCP. items: properties: port: anyOf: - type: integer - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. + description: |- + The port which traffic must match. + When NodePort endpoints(instance TargetType) is used, this must be a numerical port. + When Port endpoints(ip TargetType) is used, this can be either numerical or named port on pods. + if port is unspecified, it defaults to all ports. x-kubernetes-int-or-string: true protocol: - description: The protocol which traffic must match. + description: |- + The protocol which traffic must match. If protocol is unspecified, it defaults to TCP. enum: - TCP @@ -201,14 +207,19 @@ spec: description: TargetGroupBinding is the Schema for the TargetGroupBinding API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -234,28 +245,30 @@ spec: of traffic that is allowed to access TargetGroup's targets. properties: from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. + description: |- + List of peers which should be able to access the targets in TargetGroup. + At least one NetworkingPeer should be specified. items: description: NetworkingPeer defines the source/destination peer for networking rules. properties: ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. + description: |- + IPBlock defines an IPBlock peer. + If specified, none of the other fields can be set. properties: cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. + description: |- + CIDR is the network CIDR. + Both IPV4 or IPV6 CIDR are accepted. type: string required: - cidr type: object securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. + description: |- + SecurityGroup defines a SecurityGroup peer. + If specified, none of the other fields can be set. properties: groupID: description: GroupID is the EC2 SecurityGroupID. @@ -266,9 +279,9 @@ spec: type: object type: array ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. + description: |- + List of ports which should be made accessible on the targets in TargetGroup. + If ports is empty or unspecified, it defaults to all ports with TCP. items: description: NetworkingPort defines the port and protocol for networking rules. @@ -277,15 +290,15 @@ spec: anyOf: - type: integer - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. + description: |- + The port which traffic must match. + When NodePort endpoints(instance TargetType) is used, this must be a numerical port. + When Port endpoints(ip TargetType) is used, this can be either numerical or named port on pods. + if port is unspecified, it defaults to all ports. x-kubernetes-int-or-string: true protocol: - description: The protocol which traffic must match. + description: |- + The protocol which traffic must match. If protocol is unspecified, it defaults to TCP. enum: - TCP @@ -307,24 +320,24 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -337,11 +350,10 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 9acadc472..c9d2abe92 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,7 +2,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: controller-role rules: - apiGroups: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 7dc0bd430..0b1a24bfe 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -2,7 +2,6 @@ apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - creationTimestamp: null name: webhook webhooks: - admissionReviewVersions: @@ -67,7 +66,6 @@ webhooks: apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - creationTimestamp: null name: webhook webhooks: - admissionReviewVersions: diff --git a/controllers/ingress/group_controller.go b/controllers/ingress/group_controller.go index 4fb14b341..a064c3b25 100644 --- a/controllers/ingress/group_controller.go +++ b/controllers/ingress/group_controller.go @@ -60,7 +60,7 @@ func NewGroupReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder authConfigBuilder, enhancedBackendBuilder, trackingProvider, elbv2TaggingManager, controllerConfig.FeatureGates, cloud.VpcID(), controllerConfig.ClusterName, controllerConfig.DefaultTags, controllerConfig.ExternalManagedTags, controllerConfig.DefaultSSLPolicy, controllerConfig.DefaultTargetType, backendSGProvider, sgResolver, - controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), logger) + controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules, controllerConfig.IngressConfig.AllowedCertificateAuthorityARNs, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), logger) stackMarshaller := deploy.NewDefaultStackMarshaller() stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager, controllerConfig, ingressTagPrefix, logger) diff --git a/docs/deploy/configurations.md b/docs/deploy/configurations.md index 2374a8fe4..3974f127a 100644 --- a/docs/deploy/configurations.md +++ b/docs/deploy/configurations.md @@ -71,6 +71,7 @@ Currently, you can set only 1 namespace to watch in this flag. See [this Kuberne |aws-max-retries | int | 10 | Maximum retries for AWS APIs | |aws-region | string | [instance metadata](#instance-metadata) | AWS Region for the kubernetes cluster | |aws-vpc-id | string | [instance metadata](#instance-metadata) | AWS VPC ID for the Kubernetes cluster | +|allowed-certificate-authority-arns | stringList | [] | Specify an optional list of CA ARNs to filter on in cert discovery (empty means all CAs are allowed) | |backend-security-group | string | | Backend security group id to use for the ingress rules on the worker node SG| |cluster-name | string | | Kubernetes cluster name| |default-ssl-policy | string | ELBSecurityPolicy-2016-08 | Default SSL Policy that will be applied to all Ingresses or Services that do not have the SSL Policy annotation | diff --git a/docs/guide/ingress/annotations.md b/docs/guide/ingress/annotations.md index ff8a893f0..6f2f421c6 100644 --- a/docs/guide/ingress/annotations.md +++ b/docs/guide/ingress/annotations.md @@ -226,7 +226,10 @@ Traffic Routing can be controlled with following annotations: - `alb.ingress.kubernetes.io/subnets` specifies the [Availability Zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html)s that the ALB will route traffic to. See [Load Balancer subnets](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-subnets.html) for more details. !!!note "" - You must specify at least two subnets in different AZs. Either subnetID or subnetName(Name tag on subnets) can be used. + You must specify at least two subnets in different AZs unless utilizing the outpost locale, in which case a single subnet suffices. Either subnetID or subnetName(Name tag on subnets) can be used. + + !!!note "" + You must not mix subnets from different locales: availability-zone, local-zone, wavelength-zone, outpost. !!!tip You can enable subnet auto discovery to avoid specifying this annotation on every Ingress. See [Subnet Discovery](../../deploy/subnet_discovery.md) for instructions. diff --git a/docs/guide/service/annotations.md b/docs/guide/service/annotations.md index e3a9bfe76..cdab12199 100644 --- a/docs/guide/service/annotations.md +++ b/docs/guide/service/annotations.md @@ -229,6 +229,10 @@ for proxy protocol v2 configuration. ``` service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true ``` + - disable immediate [connection termination for unhealthy targets](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-health.html#unhealthy-target-connection-termination) and configure a 30s draining interval (available range is 0-360000 seconds) + ``` + service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: target_health_state.unhealthy.connection_termination.enabled=false,target_health_state.unhealthy.draining_interval_seconds=30 + ``` - `service.beta.kubernetes.io/aws-load-balancer-attributes` specifies [Load Balancer Attributes](http://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_LoadBalancerAttribute.html) that should be applied to the NLB. diff --git a/helm/aws-load-balancer-controller/crds/crds.yaml b/helm/aws-load-balancer-controller/crds/crds.yaml index 78c226660..4a7a24f40 100644 --- a/helm/aws-load-balancer-controller/crds/crds.yaml +++ b/helm/aws-load-balancer-controller/crds/crds.yaml @@ -2,8 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: ingressclassparams.elbv2.k8s.aws spec: group: elbv2.k8s.aws @@ -36,14 +35,19 @@ spec: description: IngressClassParams is the Schema for the IngressClassParams API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -92,32 +96,32 @@ spec: type: object type: array namespaceSelector: - description: NamespaceSelector restrict the namespaces of Ingresses - that are allowed to specify the IngressClass with this IngressClassParams. + description: |- + NamespaceSelector restrict the namespaces of Ingresses that are allowed to specify the IngressClass with this IngressClassParams. * if absent or present but empty, it selects all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -130,11 +134,10 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic @@ -167,10 +170,11 @@ spec: items: type: string type: array - description: Tags specifies subnets in the load balancer's VPC - where each tag specified in the map key contains one of the - values in the corresponding value list. Exactly one of this - or `ids` must be specified. + description: |- + Tags specifies subnets in the load balancer's VPC where each + tag specified in the map key contains one of the values in the corresponding + value list. + Exactly one of this or `ids` must be specified. type: object type: object tags: @@ -200,8 +204,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: targetgroupbindings.elbv2.k8s.aws spec: group: elbv2.k8s.aws @@ -239,14 +242,19 @@ spec: description: TargetGroupBinding is the Schema for the TargetGroupBinding API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -263,28 +271,30 @@ spec: items: properties: from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. + description: |- + List of peers which should be able to access the targets in TargetGroup. + At least one NetworkingPeer should be specified. items: description: NetworkingPeer defines the source/destination peer for networking rules. properties: ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. + description: |- + IPBlock defines an IPBlock peer. + If specified, none of the other fields can be set. properties: cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. + description: |- + CIDR is the network CIDR. + Both IPV4 or IPV6 CIDR are accepted. type: string required: - cidr type: object securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. + description: |- + SecurityGroup defines a SecurityGroup peer. + If specified, none of the other fields can be set. properties: groupID: description: GroupID is the EC2 SecurityGroupID. @@ -295,24 +305,24 @@ spec: type: object type: array ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. + description: |- + List of ports which should be made accessible on the targets in TargetGroup. + If ports is empty or unspecified, it defaults to all ports with TCP. items: properties: port: anyOf: - type: integer - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. + description: |- + The port which traffic must match. + When NodePort endpoints(instance TargetType) is used, this must be a numerical port. + When Port endpoints(ip TargetType) is used, this can be either numerical or named port on pods. + if port is unspecified, it defaults to all ports. x-kubernetes-int-or-string: true protocol: - description: The protocol which traffic must match. + description: |- + The protocol which traffic must match. If protocol is unspecified, it defaults to TCP. enum: - TCP @@ -398,14 +408,19 @@ spec: description: TargetGroupBinding is the Schema for the TargetGroupBinding API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -431,28 +446,30 @@ spec: of traffic that is allowed to access TargetGroup's targets. properties: from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. + description: |- + List of peers which should be able to access the targets in TargetGroup. + At least one NetworkingPeer should be specified. items: description: NetworkingPeer defines the source/destination peer for networking rules. properties: ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. + description: |- + IPBlock defines an IPBlock peer. + If specified, none of the other fields can be set. properties: cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. + description: |- + CIDR is the network CIDR. + Both IPV4 or IPV6 CIDR are accepted. type: string required: - cidr type: object securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. + description: |- + SecurityGroup defines a SecurityGroup peer. + If specified, none of the other fields can be set. properties: groupID: description: GroupID is the EC2 SecurityGroupID. @@ -463,9 +480,9 @@ spec: type: object type: array ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. + description: |- + List of ports which should be made accessible on the targets in TargetGroup. + If ports is empty or unspecified, it defaults to all ports with TCP. items: description: NetworkingPort defines the port and protocol for networking rules. @@ -474,15 +491,15 @@ spec: anyOf: - type: integer - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. + description: |- + The port which traffic must match. + When NodePort endpoints(instance TargetType) is used, this must be a numerical port. + When Port endpoints(ip TargetType) is used, this can be either numerical or named port on pods. + if port is unspecified, it defaults to all ports. x-kubernetes-int-or-string: true protocol: - description: The protocol which traffic must match. + description: |- + The protocol which traffic must match. If protocol is unspecified, it defaults to TCP. enum: - TCP @@ -504,24 +521,24 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -534,11 +551,10 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic diff --git a/helm/aws-load-balancer-controller/templates/deployment.yaml b/helm/aws-load-balancer-controller/templates/deployment.yaml index c1bed7b86..fb646ea6f 100644 --- a/helm/aws-load-balancer-controller/templates/deployment.yaml +++ b/helm/aws-load-balancer-controller/templates/deployment.yaml @@ -159,6 +159,9 @@ spec: {{- if .Values.serviceTargetENISGTags }} - --service-target-eni-security-group-tags={{ .Values.serviceTargetENISGTags }} {{- end }} + {{- if .Values.certDiscovery.allowedCertificateAuthorityARNs }} + - --allowed-certificate-authority-arns={{ .Values.certDiscovery.allowedCertificateAuthorityARNs }} + {{- end }} {{- if or .Values.env .Values.envSecretName }} env: {{- if .Values.env}} diff --git a/helm/aws-load-balancer-controller/values.yaml b/helm/aws-load-balancer-controller/values.yaml index 03d45e7b9..6b776ce5d 100644 --- a/helm/aws-load-balancer-controller/values.yaml +++ b/helm/aws-load-balancer-controller/values.yaml @@ -350,6 +350,9 @@ controllerConfig: # NLBHealthCheckAdvancedConfig: true # ALBSingleSubnet: false +certDiscovery: + allowedCertificateAuthorityARNs: "" # empty means all CAs are in scope + # objectSelector for webhook objectSelector: matchExpressions: diff --git a/pkg/config/ingress_config.go b/pkg/config/ingress_config.go index 6e08af602..b735164cf 100644 --- a/pkg/config/ingress_config.go +++ b/pkg/config/ingress_config.go @@ -9,6 +9,7 @@ const ( flagIngressMaxConcurrentReconciles = "ingress-max-concurrent-reconciles" flagTolerateNonExistentBackendService = "tolerate-non-existent-backend-service" flagTolerateNonExistentBackendAction = "tolerate-non-existent-backend-action" + flagAllowedCAArns = "allowed-certificate-authority-arns" defaultIngressClass = "alb" defaultDisableIngressClassAnnotation = false defaultDisableIngressGroupNameAnnotation = false @@ -42,6 +43,9 @@ type IngressConfig struct { // TolerateNonExistentBackendAction specifies whether to allow rules that reference a backend action that does not // exist. In this case, requests to that rule will result in a 503 error. TolerateNonExistentBackendAction bool + + // AllowedCertificateAuthoritiyARNs contains a list of all CAs to consider when discovering certificates for ingress resources + AllowedCertificateAuthorityARNs []string } // BindFlags binds the command line flags to the fields in the config object @@ -58,4 +62,5 @@ func (cfg *IngressConfig) BindFlags(fs *pflag.FlagSet) { "Tolerate rules that specify a non-existent backend service") fs.BoolVar(&cfg.TolerateNonExistentBackendAction, flagTolerateNonExistentBackendAction, defaultTolerateNonExistentBackendAction, "Tolerate rules that specify a non-existent backend action") + fs.StringSliceVar(&cfg.AllowedCertificateAuthorityARNs, flagAllowedCAArns, []string{}, "Specify an optional list of CA ARNs to filter on in cert discovery") } diff --git a/pkg/ingress/cert_discovery.go b/pkg/ingress/cert_discovery.go index 8f0952c65..80fb9c743 100644 --- a/pkg/ingress/cert_discovery.go +++ b/pkg/ingress/cert_discovery.go @@ -2,7 +2,13 @@ package ingress import ( "context" + "slices" + "strings" + "sync" + "time" + "github.com/aws/aws-sdk-go/aws" + awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/acm" "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" @@ -11,9 +17,6 @@ import ( "k8s.io/apimachinery/pkg/util/cache" "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services" - "strings" - "sync" - "time" ) const ( @@ -33,7 +36,7 @@ type CertDiscovery interface { } // NewACMCertDiscovery constructs new acmCertDiscovery -func NewACMCertDiscovery(acmClient services.ACM, logger logr.Logger) *acmCertDiscovery { +func NewACMCertDiscovery(acmClient services.ACM, allowedCAARNs []string, logger logr.Logger) *acmCertDiscovery { return &acmCertDiscovery{ acmClient: acmClient, logger: logger, @@ -44,6 +47,7 @@ func NewACMCertDiscovery(acmClient services.ACM, logger logr.Logger) *acmCertDis certDomainsCache: cache.NewExpiring(), importedCertDomainsCacheTTL: defaultImportedCertDomainsCacheTTL, privateCertDomainsCacheTTL: defaultPrivateCertDomainsCacheTTL, + allowedCAARNs: allowedCAARNs, } } @@ -59,6 +63,7 @@ type acmCertDiscovery struct { certARNsCache *cache.Expiring certARNsCacheTTL time.Duration certDomainsCache *cache.Expiring + allowedCAARNs []string importedCertDomainsCacheTTL time.Duration privateCertDomainsCacheTTL time.Duration } @@ -102,7 +107,10 @@ func (d *acmCertDiscovery) loadDomainsForAllCertificates(ctx context.Context) (m if err != nil { return nil, err } - domainsByCertARN[certARN] = certDomains + if len(certDomains) > 0 { + domainsByCertARN[certARN] = certDomains + } + } return domainsByCertARN, nil } @@ -143,14 +151,20 @@ func (d *acmCertDiscovery) loadDomainsForCertificate(ctx context.Context, certAR return nil, err } certDetail := resp.Certificate - domains := sets.NewString(aws.StringValueSlice(certDetail.SubjectAlternativeNames)...) - switch aws.StringValue(certDetail.Type) { - case acm.CertificateTypeImported: - d.certDomainsCache.Set(certARN, domains, d.importedCertDomainsCacheTTL) - case acm.CertificateTypeAmazonIssued, acm.CertificateTypePrivate: - d.certDomainsCache.Set(certARN, domains, d.privateCertDomainsCacheTTL) + + // check if cert is issued from an allowed CA + if len(d.allowedCAARNs) == 0 || slices.Contains(d.allowedCAARNs, awssdk.StringValue(certDetail.CertificateAuthorityArn)) { + domains := sets.NewString(aws.StringValueSlice(certDetail.SubjectAlternativeNames)...) + switch aws.StringValue(certDetail.Type) { + case acm.CertificateTypeImported: + d.certDomainsCache.Set(certARN, domains, d.importedCertDomainsCacheTTL) + case acm.CertificateTypeAmazonIssued, acm.CertificateTypePrivate: + d.certDomainsCache.Set(certARN, domains, d.privateCertDomainsCacheTTL) + } + return domains, nil } - return domains, nil + return sets.String{}, nil + } func (d *acmCertDiscovery) domainMatchesHost(domainName string, tlsHost string) bool { diff --git a/pkg/ingress/model_builder.go b/pkg/ingress/model_builder.go index 17939f5bf..31b6d4319 100644 --- a/pkg/ingress/model_builder.go +++ b/pkg/ingress/model_builder.go @@ -44,8 +44,8 @@ func NewDefaultModelBuilder(k8sClient client.Client, eventRecorder record.EventR trackingProvider tracking.Provider, elbv2TaggingManager elbv2deploy.TaggingManager, featureGates config.FeatureGates, vpcID string, clusterName string, defaultTags map[string]string, externalManagedTags []string, defaultSSLPolicy string, defaultTargetType string, backendSGProvider networkingpkg.BackendSGProvider, sgResolver networkingpkg.SecurityGroupResolver, - enableBackendSG bool, disableRestrictedSGRules bool, enableIPTargetType bool, logger logr.Logger) *defaultModelBuilder { - certDiscovery := NewACMCertDiscovery(acmClient, logger) + enableBackendSG bool, disableRestrictedSGRules bool, allowedCAARNs []string, enableIPTargetType bool, logger logr.Logger) *defaultModelBuilder { + certDiscovery := NewACMCertDiscovery(acmClient, allowedCAARNs, logger) ruleOptimizer := NewDefaultRuleOptimizer(logger) return &defaultModelBuilder{ k8sClient: k8sClient,