From 5dc73186f20a47e1b91edf10a86f75e2c57aad29 Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Sat, 23 Nov 2024 13:28:28 +0900 Subject: [PATCH 1/3] Add TargetType field to IngressClassParams --- apis/elbv2/v1beta1/ingressclassparams_types.go | 4 ++++ docs/guide/ingress/ingress_class.md | 9 ++++++++- pkg/ingress/model_build_target_group.go | 10 +++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apis/elbv2/v1beta1/ingressclassparams_types.go b/apis/elbv2/v1beta1/ingressclassparams_types.go index 23479ff8f1..5791171355 100644 --- a/apis/elbv2/v1beta1/ingressclassparams_types.go +++ b/apis/elbv2/v1beta1/ingressclassparams_types.go @@ -139,6 +139,10 @@ type IngressClassParamsSpec struct { // Tags defines list of Tags on AWS resources provisioned for Ingresses that belong to IngressClass with this IngressClassParams. Tags []Tag `json:"tags,omitempty"` + // TargetType defines the target type of target groups for all Ingresses that belong to IngressClass with this IngressClassParams. + // +optional + TargetType TargetType `json:"targetType,omitempty"` + // LoadBalancerAttributes define the custom attributes to LoadBalancers for all Ingress that that belong to IngressClass with this IngressClassParams. // +optional LoadBalancerAttributes []Attribute `json:"loadBalancerAttributes,omitempty"` diff --git a/docs/guide/ingress/ingress_class.md b/docs/guide/ingress/ingress_class.md index 3322cc7cfb..4fec55677a 100644 --- a/docs/guide/ingress/ingress_class.md +++ b/docs/guide/ingress/ingress_class.md @@ -178,7 +178,7 @@ If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/inboun #### spec.certificateArn Cluster administrators can use the optional `certificateARN` field to specify the ARN of the certificates for all Ingresses that belong to IngressClass with this IngressClassParams. - + If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/certificate-arn` annotation. #### spec.sslPolicy @@ -225,6 +225,13 @@ Cluster administrators can use `tags` field to specify the custom tags for AWS r 2. `spec.tags` in IngressClassParams will have the middle priority. 3. `alb.ingress.kubernetes.io/tags` annotation will have the lowest priority. +#### spec.targetType + +`targetType` is an optional setting. The available options are `instance` or `ip`. + +This defines the target type of target groups for all Ingresses that belong to IngressClass with this IngressClassParams. +If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/target-type` annotation. + #### spec.loadBalancerAttributes `loadBalancerAttributes` is an optional setting. diff --git a/pkg/ingress/model_build_target_group.go b/pkg/ingress/model_build_target_group.go index 381fd39721..0aa049dd5c 100644 --- a/pkg/ingress/model_build_target_group.go +++ b/pkg/ingress/model_build_target_group.go @@ -5,10 +5,11 @@ import ( "crypto/sha256" "encoding/hex" "fmt" - awssdk "github.com/aws/aws-sdk-go-v2/aws" "regexp" "strconv" + awssdk "github.com/aws/aws-sdk-go-v2/aws" + "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -153,7 +154,7 @@ func (t *defaultModelBuildTask) buildTargetGroupBindingNetworking(ctx context.Co func (t *defaultModelBuildTask) buildTargetGroupSpec(ctx context.Context, ing ClassifiedIngress, svc *corev1.Service, port intstr.IntOrString, svcPort corev1.ServicePort) (elbv2model.TargetGroupSpec, error) { svcAndIngAnnotations := algorithm.MergeStringMap(svc.Annotations, ing.Ing.Annotations) - targetType, err := t.buildTargetGroupTargetType(ctx, svcAndIngAnnotations) + targetType, err := t.buildTargetGroupTargetType(ctx, svcAndIngAnnotations, ing.IngClassConfig) if err != nil { return elbv2model.TargetGroupSpec{}, err } @@ -220,9 +221,12 @@ func (t *defaultModelBuildTask) buildTargetGroupName(_ context.Context, return fmt.Sprintf("k8s-%.8s-%.8s-%.10s", sanitizedNamespace, sanitizedName, uuid) } -func (t *defaultModelBuildTask) buildTargetGroupTargetType(_ context.Context, svcAndIngAnnotations map[string]string) (elbv2model.TargetType, error) { +func (t *defaultModelBuildTask) buildTargetGroupTargetType(_ context.Context, svcAndIngAnnotations map[string]string, classCfg ClassConfiguration) (elbv2model.TargetType, error) { rawTargetType := string(t.defaultTargetType) _ = t.annotationParser.ParseStringAnnotation(annotations.IngressSuffixTargetType, &rawTargetType, svcAndIngAnnotations) + if classCfg.IngClassParams != nil && classCfg.IngClassParams.Spec.TargetType != "" { + rawTargetType = string(classCfg.IngClassParams.Spec.TargetType) + } switch rawTargetType { case string(elbv2model.TargetTypeInstance): return elbv2model.TargetTypeInstance, nil From ca79e92d52f7f4d6aca19a3d299bf8221d795dc9 Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Sat, 23 Nov 2024 16:40:54 +0900 Subject: [PATCH 2/3] add a test --- pkg/ingress/model_builder_test.go | 312 +++++++++++++++++++++++++++++- 1 file changed, 310 insertions(+), 2 deletions(-) diff --git a/pkg/ingress/model_builder_test.go b/pkg/ingress/model_builder_test.go index 99d9fb066d..80b1cf116b 100644 --- a/pkg/ingress/model_builder_test.go +++ b/pkg/ingress/model_builder_test.go @@ -3,11 +3,12 @@ package ingress import ( "context" "encoding/json" - ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" - elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "testing" "time" + ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" + awssdk "github.com/aws/aws-sdk-go-v2/aws" jsonpatch "github.com/evanphx/json-patch" "github.com/go-logr/logr" @@ -2140,6 +2141,313 @@ func Test_defaultModelBuilder_Build(t *testing.T) { "80:3": null } } +}`, + }, + { + name: "Ingress - target-type in IngressClassParams", + env: env{ + svcs: []*corev1.Service{ns_1_svc_1, ns_1_svc_2, ns_1_svc_3}, + }, + fields: fields{ + resolveViaDiscoveryCalls: []resolveViaDiscoveryCall{resolveViaDiscoveryCallForInternalLB}, + listLoadBalancersCalls: []listLoadBalancersCall{listLoadBalancerCallForEmptyLB}, + enableBackendSG: true, + }, + args: args{ + ingGroup: Group{ + ID: GroupID{Namespace: "ns-1", Name: "ing-1"}, + Members: []ClassifiedIngress{ + { + IngClassConfig: ClassConfiguration{ + IngClassParams: &v1beta1.IngressClassParams{ + Spec: v1beta1.IngressClassParamsSpec{ + TargetType: v1beta1.TargetTypeIP, + }, + }, + }, + Ing: &networking.Ingress{ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-1", + Name: "ing-1", + Annotations: map[string]string{ + "alb.ingress.kubernetes.io/target-type": string(v1beta1.TargetTypeInstance), + }, + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "app-1.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-1", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_1.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + { + Path: "/svc-2", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_2.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + }, + }, + }, + }, + { + Host: "app-2.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-3", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_3.Name, + Port: networking.ServiceBackendPort{ + Name: "https", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + defaultTargetType: "instance", + wantStackPatch: ` +{ + "resources": { + "AWS::ElasticLoadBalancingV2::TargetGroup":{ + "ns-1/ing-1-svc-1:http":{ + "spec":{ + "name":"k8s-ns1-svc1-6350990f3a", + "targetType":"ip", + "ipAddressType":"ipv4", + "port":8080, + "protocol":"HTTP", + "protocolVersion":"HTTP1", + "healthCheckConfig":{ + "port":"traffic-port", + "protocol":"HTTP", + "path":"/", + "matcher":{ + "httpCode":"200" + }, + "intervalSeconds":15, + "timeoutSeconds":5, + "healthyThresholdCount":2, + "unhealthyThresholdCount":2 + } + } + }, + "ns-1/ing-1-svc-2:http":{ + "spec":{ + "name":"k8s-ns1-svc2-6350990f3a", + "targetType":"ip", + "ipAddressType":"ipv4", + "port":8080, + "protocol":"HTTP", + "protocolVersion":"HTTP1", + "healthCheckConfig":{ + "port":"traffic-port", + "protocol":"HTTP", + "path":"/", + "matcher":{ + "httpCode":"200" + }, + "intervalSeconds":15, + "timeoutSeconds":5, + "healthyThresholdCount":2, + "unhealthyThresholdCount":2 + } + } + }, + "ns-1/ing-1-svc-3:https":{ + "spec":{ + "name":"k8s-ns1-svc3-bf42870fba", + "targetType":"ip", + "ipAddressType":"ipv4", + "port":8443, + "protocol":"HTTPS", + "protocolVersion":"HTTP1", + "healthCheckConfig":{ + "port":9090, + "protocol":"HTTPS", + "path":"/health-check", + "matcher":{ + "httpCode":"200-300" + }, + "intervalSeconds":20, + "timeoutSeconds":10, + "healthyThresholdCount":7, + "unhealthyThresholdCount":5 + } + } + } + }, + "K8S::ElasticLoadBalancingV2::TargetGroupBinding":{ + "ns-1/ing-1-svc-1:http":{ + "spec":{ + "template":{ + "metadata":{ + "name":"k8s-ns1-svc1-6350990f3a", + "namespace":"ns-1", + "creationTimestamp":null + }, + "spec":{ + "targetGroupARN":{ + "$ref":"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/ns-1/ing-1-svc-1:http/status/targetGroupARN" + }, + "targetType":"ip", + "vpcID": "vpc-dummy", + "ipAddressType":"ipv4", + "serviceRef":{ + "name":"svc-1", + "port":"http" + }, + "networking":{ + "ingress":[ + { + "from":[ + { + "securityGroup":{ + "groupID": "sg-auto" + } + } + ], + "ports":[ + { + "port":8080, + "protocol":"TCP" + } + ] + } + ] + } + } + } + } + }, + "ns-1/ing-1-svc-2:http":{ + "spec":{ + "template":{ + "metadata":{ + "name":"k8s-ns1-svc2-6350990f3a", + "namespace":"ns-1", + "creationTimestamp":null + }, + "spec":{ + "targetGroupARN":{ + "$ref":"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/ns-1/ing-1-svc-2:http/status/targetGroupARN" + }, + "targetType":"ip", + "ipAddressType":"ipv4", + "vpcID": "vpc-dummy", + "serviceRef":{ + "name":"svc-2", + "port":"http" + }, + "networking":{ + "ingress":[ + { + "from":[ + { + "securityGroup":{ + "groupID": "sg-auto" + } + } + ], + "ports":[ + { + "port":8080, + "protocol":"TCP" + } + ] + } + ] + } + } + } + } + }, + "ns-1/ing-1-svc-3:https":{ + "spec":{ + "template":{ + "metadata":{ + "name":"k8s-ns1-svc3-bf42870fba", + "namespace":"ns-1", + "creationTimestamp":null + }, + "spec":{ + "targetGroupARN":{ + "$ref":"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/ns-1/ing-1-svc-3:https/status/targetGroupARN" + }, + "targetType":"ip", + "vpcID": "vpc-dummy", + "ipAddressType":"ipv4", + "serviceRef":{ + "name":"svc-3", + "port":"https" + }, + "networking":{ + "ingress":[ + { + "from":[ + { + "securityGroup":{ + "groupID": "sg-auto" + } + } + ], + "ports":[ + { + "port": 8443, + "protocol":"TCP" + } + ] + }, + { + "from":[ + { + "securityGroup":{ + "groupID": "sg-auto" + } + } + ], + "ports":[ + { + "port": 9090, + "protocol":"TCP" + } + ] + } + ] + } + } + } + } + } + } + } }`, }, { From 3bec091a864d59b1df56becc6e85e6924a0e60a3 Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Sat, 23 Nov 2024 16:50:26 +0900 Subject: [PATCH 3/3] make crds --- config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml | 7 +++++++ config/webhook/manifests.yaml | 1 - helm/aws-load-balancer-controller/crds/crds.yaml | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml index 26b39f0e8c..fd694a7d1d 100644 --- a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml +++ b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml @@ -234,6 +234,13 @@ spec: - value type: object type: array + targetType: + description: TargetType defines the target type of target groups for + all Ingresses that belong to IngressClass with this IngressClassParams. + enum: + - instance + - ip + type: string type: object type: object served: true diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 0b1a24bfed..1493d5386a 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,4 +1,3 @@ ---- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: diff --git a/helm/aws-load-balancer-controller/crds/crds.yaml b/helm/aws-load-balancer-controller/crds/crds.yaml index 048d51e841..db06e40029 100644 --- a/helm/aws-load-balancer-controller/crds/crds.yaml +++ b/helm/aws-load-balancer-controller/crds/crds.yaml @@ -233,6 +233,13 @@ spec: - value type: object type: array + targetType: + description: TargetType defines the target type of target groups for + all Ingresses that belong to IngressClass with this IngressClassParams. + enum: + - instance + - ip + type: string type: object type: object served: true