Skip to content

Commit cb4f483

Browse files
author
Thejas N
authored
Added EnableIPTargetType flag to controller (#2587)
* added EnableIPTargetType feature to controller Signed-off-by: thejasn <[email protected]> * review: fixed package alias Signed-off-by: thejasn <[email protected]>
1 parent 1edccda commit cb4f483

11 files changed

+173
-30
lines changed

controllers/ingress/group_controller.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,26 @@ const (
4444
func NewGroupReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder record.EventRecorder,
4545
finalizerManager k8s.FinalizerManager, networkingSGManager networkingpkg.SecurityGroupManager,
4646
networkingSGReconciler networkingpkg.SecurityGroupReconciler, subnetsResolver networkingpkg.SubnetsResolver,
47-
config config.ControllerConfig, backendSGProvider networkingpkg.BackendSGProvider, logger logr.Logger) *groupReconciler {
47+
controllerConfig config.ControllerConfig, backendSGProvider networkingpkg.BackendSGProvider, logger logr.Logger) *groupReconciler {
4848

4949
annotationParser := annotations.NewSuffixAnnotationParser(annotations.AnnotationPrefixIngress)
5050
authConfigBuilder := ingress.NewDefaultAuthConfigBuilder(annotationParser)
5151
enhancedBackendBuilder := ingress.NewDefaultEnhancedBackendBuilder(k8sClient, annotationParser, authConfigBuilder)
5252
referenceIndexer := ingress.NewDefaultReferenceIndexer(enhancedBackendBuilder, authConfigBuilder, logger)
53-
trackingProvider := tracking.NewDefaultProvider(ingressTagPrefix, config.ClusterName)
54-
elbv2TaggingManager := elbv2deploy.NewDefaultTaggingManager(cloud.ELBV2(), cloud.VpcID(), config.FeatureGates, logger)
53+
trackingProvider := tracking.NewDefaultProvider(ingressTagPrefix, controllerConfig.ClusterName)
54+
elbv2TaggingManager := elbv2deploy.NewDefaultTaggingManager(cloud.ELBV2(), cloud.VpcID(), controllerConfig.FeatureGates, logger)
5555
modelBuilder := ingress.NewDefaultModelBuilder(k8sClient, eventRecorder,
5656
cloud.EC2(), cloud.ACM(),
5757
annotationParser, subnetsResolver,
5858
authConfigBuilder, enhancedBackendBuilder, trackingProvider, elbv2TaggingManager,
59-
cloud.VpcID(), config.ClusterName, config.DefaultTags, config.ExternalManagedTags,
60-
config.DefaultSSLPolicy, backendSGProvider, config.EnableBackendSecurityGroup, config.DisableRestrictedSGRules, logger)
59+
cloud.VpcID(), controllerConfig.ClusterName, controllerConfig.DefaultTags, controllerConfig.ExternalManagedTags,
60+
controllerConfig.DefaultSSLPolicy, backendSGProvider, controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), logger)
6161
stackMarshaller := deploy.NewDefaultStackMarshaller()
6262
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler,
63-
config, ingressTagPrefix, logger)
63+
controllerConfig, ingressTagPrefix, logger)
6464
classLoader := ingress.NewDefaultClassLoader(k8sClient)
65-
classAnnotationMatcher := ingress.NewDefaultClassAnnotationMatcher(config.IngressConfig.IngressClass)
66-
manageIngressesWithoutIngressClass := config.IngressConfig.IngressClass == ""
65+
classAnnotationMatcher := ingress.NewDefaultClassAnnotationMatcher(controllerConfig.IngressConfig.IngressClass)
66+
manageIngressesWithoutIngressClass := controllerConfig.IngressConfig.IngressClass == ""
6767
groupLoader := ingress.NewDefaultGroupLoader(k8sClient, eventRecorder, annotationParser, classLoader, classAnnotationMatcher, manageIngressesWithoutIngressClass)
6868
groupFinalizerManager := ingress.NewDefaultFinalizerManager(finalizerManager)
6969

@@ -80,7 +80,7 @@ func NewGroupReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder
8080
groupFinalizerManager: groupFinalizerManager,
8181
logger: logger,
8282

83-
maxConcurrentReconciles: config.IngressConfig.MaxConcurrentReconciles,
83+
maxConcurrentReconciles: controllerConfig.IngressConfig.MaxConcurrentReconciles,
8484
}
8585
}
8686

controllers/service/service_controller.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,30 @@ const (
3636
func NewServiceReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder record.EventRecorder,
3737
finalizerManager k8s.FinalizerManager, networkingSGManager networking.SecurityGroupManager,
3838
networkingSGReconciler networking.SecurityGroupReconciler, subnetsResolver networking.SubnetsResolver,
39-
vpcInfoProvider networking.VPCInfoProvider, config config.ControllerConfig, logger logr.Logger) *serviceReconciler {
39+
vpcInfoProvider networking.VPCInfoProvider, controllerConfig config.ControllerConfig, logger logr.Logger) *serviceReconciler {
4040

4141
annotationParser := annotations.NewSuffixAnnotationParser(serviceAnnotationPrefix)
42-
trackingProvider := tracking.NewDefaultProvider(serviceTagPrefix, config.ClusterName)
43-
elbv2TaggingManager := elbv2.NewDefaultTaggingManager(cloud.ELBV2(), cloud.VpcID(), config.FeatureGates, logger)
44-
serviceUtils := service.NewServiceUtils(annotationParser, serviceFinalizer, config.ServiceConfig.LoadBalancerClass, config.FeatureGates)
42+
trackingProvider := tracking.NewDefaultProvider(serviceTagPrefix, controllerConfig.ClusterName)
43+
elbv2TaggingManager := elbv2.NewDefaultTaggingManager(cloud.ELBV2(), cloud.VpcID(), controllerConfig.FeatureGates, logger)
44+
serviceUtils := service.NewServiceUtils(annotationParser, serviceFinalizer, controllerConfig.ServiceConfig.LoadBalancerClass, controllerConfig.FeatureGates)
4545
modelBuilder := service.NewDefaultModelBuilder(annotationParser, subnetsResolver, vpcInfoProvider, cloud.VpcID(), trackingProvider,
46-
elbv2TaggingManager, config.ClusterName, config.DefaultTags, config.ExternalManagedTags, config.DefaultSSLPolicy, serviceUtils)
46+
elbv2TaggingManager, controllerConfig.ClusterName, controllerConfig.DefaultTags, controllerConfig.ExternalManagedTags, controllerConfig.DefaultSSLPolicy, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), serviceUtils)
4747
stackMarshaller := deploy.NewDefaultStackMarshaller()
48-
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, config, serviceTagPrefix, logger)
48+
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, controllerConfig, serviceTagPrefix, logger)
4949
return &serviceReconciler{
5050
k8sClient: k8sClient,
5151
eventRecorder: eventRecorder,
5252
finalizerManager: finalizerManager,
5353
annotationParser: annotationParser,
54-
loadBalancerClass: config.ServiceConfig.LoadBalancerClass,
54+
loadBalancerClass: controllerConfig.ServiceConfig.LoadBalancerClass,
5555
serviceUtils: serviceUtils,
5656

5757
modelBuilder: modelBuilder,
5858
stackMarshaller: stackMarshaller,
5959
stackDeployer: stackDeployer,
6060
logger: logger,
6161

62-
maxConcurrentReconciles: config.ServiceMaxConcurrentReconciles,
62+
maxConcurrentReconciles: controllerConfig.ServiceMaxConcurrentReconciles,
6363
}
6464
}
6565

docs/deploy/configurations.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,4 @@ They are a set of kye=value pairs that describe AWS load balance controller feat
146146
| ServiceTypeLoadBalancerOnly | string | false | If enabled, controller will be limited to reconciling service of type `LoadBalancer`|
147147
| EndpointsFailOpen | string | false | Enable or disable allowing endpoints with `ready:unknown` state in the target groups. |
148148
| EnableServiceController | string | true | Toggles support for `Service` type resources. |
149+
| EnableIPTargetType | string | true | Used to toggle support for target-type `ip` across `Ingress` and `Service` type resources. |

pkg/config/feature_gates.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const (
1515
ServiceTypeLoadBalancerOnly Feature = "ServiceTypeLoadBalancerOnly"
1616
EndpointsFailOpen Feature = "EndpointsFailOpen"
1717
EnableServiceController Feature = "EnableServiceController"
18+
EnableIPTargetType Feature = "EnableIPTargetType"
1819
)
1920

2021
type FeatureGates interface {
@@ -47,6 +48,7 @@ func NewFeatureGates() FeatureGates {
4748
ServiceTypeLoadBalancerOnly: false,
4849
EndpointsFailOpen: false,
4950
EnableServiceController: true,
51+
EnableIPTargetType: true,
5052
},
5153
}
5254
}

pkg/ingress/model_build_target_group.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ func (t *defaultModelBuildTask) buildTargetGroupTargetType(_ context.Context, sv
214214
case string(elbv2model.TargetTypeInstance):
215215
return elbv2model.TargetTypeInstance, nil
216216
case string(elbv2model.TargetTypeIP):
217+
if !t.enableIPTargetType {
218+
return "", errors.Errorf("unsupported targetType: %v when EnableIPTargetType is %v", rawTargetType, t.enableIPTargetType)
219+
}
217220
return elbv2model.TargetTypeIP, nil
218221
default:
219222
return "", errors.Errorf("unknown targetType: %v", rawTargetType)

pkg/ingress/model_builder.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func NewDefaultModelBuilder(k8sClient client.Client, eventRecorder record.EventR
4040
authConfigBuilder AuthConfigBuilder, enhancedBackendBuilder EnhancedBackendBuilder,
4141
trackingProvider tracking.Provider, elbv2TaggingManager elbv2deploy.TaggingManager,
4242
vpcID string, clusterName string, defaultTags map[string]string, externalManagedTags []string, defaultSSLPolicy string,
43-
backendSGProvider networkingpkg.BackendSGProvider, enableBackendSG bool, disableRestrictedSGRules bool, logger logr.Logger) *defaultModelBuilder {
43+
backendSGProvider networkingpkg.BackendSGProvider, enableBackendSG bool, disableRestrictedSGRules bool, enableIPTargetType bool, logger logr.Logger) *defaultModelBuilder {
4444
certDiscovery := NewACMCertDiscovery(acmClient, logger)
4545
ruleOptimizer := NewDefaultRuleOptimizer(logger)
4646
return &defaultModelBuilder{
@@ -63,6 +63,7 @@ func NewDefaultModelBuilder(k8sClient client.Client, eventRecorder record.EventR
6363
defaultSSLPolicy: defaultSSLPolicy,
6464
enableBackendSG: enableBackendSG,
6565
disableRestrictedSGRules: disableRestrictedSGRules,
66+
enableIPTargetType: enableIPTargetType,
6667
logger: logger,
6768
}
6869
}
@@ -92,6 +93,7 @@ type defaultModelBuilder struct {
9293
defaultSSLPolicy string
9394
enableBackendSG bool
9495
disableRestrictedSGRules bool
96+
enableIPTargetType bool
9597

9698
logger logr.Logger
9799
}
@@ -117,6 +119,7 @@ func (b *defaultModelBuilder) Build(ctx context.Context, ingGroup Group) (core.S
117119
logger: b.logger,
118120
enableBackendSG: b.enableBackendSG,
119121
disableRestrictedSGRules: b.disableRestrictedSGRules,
122+
enableIPTargetType: b.enableIPTargetType,
120123

121124
ingGroup: ingGroup,
122125
stack: stack,
@@ -172,6 +175,7 @@ type defaultModelBuildTask struct {
172175
backendSGIDToken core.StringToken
173176
enableBackendSG bool
174177
disableRestrictedSGRules bool
178+
enableIPTargetType bool
175179

176180
defaultTags map[string]string
177181
externalManagedTags sets.String

pkg/ingress/model_builder_test.go

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,13 @@ func Test_defaultModelBuilder_Build(t *testing.T) {
194194
}
195195

196196
tests := []struct {
197-
name string
198-
env env
199-
args args
200-
fields fields
201-
wantStackJSON string
202-
wantErr error
197+
name string
198+
env env
199+
enableIPTargetType *bool
200+
args args
201+
fields fields
202+
wantStackJSON string
203+
wantErr error
203204
}{
204205
{
205206
name: "Ingress - vanilla internal",
@@ -3611,6 +3612,59 @@ func Test_defaultModelBuilder_Build(t *testing.T) {
36113612
},
36123613
wantErr: errors.New("ingress: ns-1/ing-1: unsupported IPv6 configuration, lb not dual-stack"),
36133614
},
3615+
{
3616+
name: "target type IP with enableIPTargetType set to false",
3617+
env: env{
3618+
svcs: []*corev1.Service{svcWithNamedTargetPort},
3619+
},
3620+
enableIPTargetType: awssdk.Bool(false),
3621+
fields: fields{
3622+
resolveViaDiscoveryCalls: []resolveViaDiscoveryCall{resolveViaDiscoveryCallForInternalLB},
3623+
listLoadBalancersCalls: []listLoadBalancersCall{listLoadBalancerCallForEmptyLB},
3624+
enableBackendSG: true,
3625+
},
3626+
args: args{
3627+
ingGroup: Group{
3628+
ID: GroupID{Namespace: "ns-1", Name: "ing-1"},
3629+
Members: []ClassifiedIngress{
3630+
{
3631+
Ing: &networking.Ingress{ObjectMeta: metav1.ObjectMeta{
3632+
Namespace: "ns-1",
3633+
Name: "ing-1",
3634+
Annotations: map[string]string{
3635+
"alb.ingress.kubernetes.io/target-type": "ip",
3636+
},
3637+
},
3638+
Spec: networking.IngressSpec{
3639+
Rules: []networking.IngressRule{
3640+
{
3641+
IngressRuleValue: networking.IngressRuleValue{
3642+
HTTP: &networking.HTTPIngressRuleValue{
3643+
Paths: []networking.HTTPIngressPath{
3644+
{
3645+
Path: "/",
3646+
Backend: networking.IngressBackend{
3647+
Service: &networking.IngressServiceBackend{
3648+
Name: svcWithNamedTargetPort.Name,
3649+
Port: networking.ServiceBackendPort{
3650+
Name: "https",
3651+
},
3652+
},
3653+
},
3654+
},
3655+
},
3656+
},
3657+
},
3658+
},
3659+
},
3660+
},
3661+
},
3662+
},
3663+
},
3664+
},
3665+
},
3666+
wantErr: errors.New("ingress: ns-1/ing-1: unsupported targetType: ip when EnableIPTargetType is false"),
3667+
},
36143668
{
36153669
name: "target type IP with named target port",
36163670
env: env{
@@ -3900,6 +3954,12 @@ func Test_defaultModelBuilder_Build(t *testing.T) {
39003954
defaultSSLPolicy: "ELBSecurityPolicy-2016-08",
39013955
}
39023956

3957+
if tt.enableIPTargetType == nil {
3958+
b.enableIPTargetType = true
3959+
} else {
3960+
b.enableIPTargetType = *tt.enableIPTargetType
3961+
}
3962+
39033963
gotStack, _, _, err := b.Build(context.Background(), tt.args.ingGroup)
39043964
if tt.wantErr != nil {
39053965
assert.EqualError(t, err, tt.wantErr.Error())

pkg/service/model_build_target_group.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ func (t *defaultModelBuildTask) buildTargetType(_ context.Context, port corev1.S
339339
var lbTargetType string
340340
lbTargetType = string(t.defaultTargetType)
341341
_ = t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixTargetType, &lbTargetType, t.service.Annotations)
342+
if lbTargetType == LoadBalancerTargetTypeIP && !t.enableIPTargetType {
343+
return "", errors.Errorf("unsupported targetType: %v when EnableIPTargetType is %v", lbTargetType, t.enableIPTargetType)
344+
}
342345
if lbType == LoadBalancerTypeNLBIP || lbTargetType == LoadBalancerTargetTypeIP {
343346
return elbv2model.TargetTypeIP, nil
344347
}

pkg/service/model_build_target_group_test.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,10 +1161,11 @@ func Test_defaultModelBuilder_buildPreserveClientIPFlag(t *testing.T) {
11611161
func Test_defaultModelBuilder_buildTargetType(t *testing.T) {
11621162

11631163
tests := []struct {
1164-
testName string
1165-
svc *corev1.Service
1166-
want elbv2.TargetType
1167-
wantErr error
1164+
testName string
1165+
svc *corev1.Service
1166+
want elbv2.TargetType
1167+
enableIPTargetType *bool
1168+
wantErr error
11681169
}{
11691170
{
11701171
testName: "empty annotation",
@@ -1247,6 +1248,29 @@ func Test_defaultModelBuilder_buildTargetType(t *testing.T) {
12471248
},
12481249
want: elbv2.TargetTypeIP,
12491250
},
1251+
{
1252+
testName: "enableIPTargetType is false, target ip",
1253+
svc: &corev1.Service{
1254+
ObjectMeta: metav1.ObjectMeta{
1255+
Annotations: map[string]string{
1256+
"service.beta.kubernetes.io/aws-load-balancer-type": "external",
1257+
"service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "ip",
1258+
},
1259+
},
1260+
Spec: corev1.ServiceSpec{
1261+
Ports: []corev1.ServicePort{
1262+
{
1263+
Name: "http",
1264+
Port: 80,
1265+
TargetPort: intstr.FromInt(80),
1266+
Protocol: corev1.ProtocolTCP,
1267+
},
1268+
},
1269+
},
1270+
},
1271+
enableIPTargetType: aws.Bool(false),
1272+
wantErr: errors.New("unsupported targetType: ip when EnableIPTargetType is false"),
1273+
},
12501274
{
12511275
testName: "external, ClusterIP with target type instance",
12521276
svc: &corev1.Service{
@@ -1337,6 +1361,11 @@ func Test_defaultModelBuilder_buildTargetType(t *testing.T) {
13371361
service: tt.svc,
13381362
defaultTargetType: LoadBalancerTargetTypeInstance,
13391363
}
1364+
if tt.enableIPTargetType == nil {
1365+
builder.enableIPTargetType = true
1366+
} else {
1367+
builder.enableIPTargetType = *tt.enableIPTargetType
1368+
}
13401369
got, err := builder.buildTargetType(context.Background(), tt.svc.Spec.Ports[0])
13411370
if tt.wantErr != nil {
13421371
assert.EqualError(t, err, tt.wantErr.Error())

pkg/service/model_builder.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type ModelBuilder interface {
3636
func NewDefaultModelBuilder(annotationParser annotations.Parser, subnetsResolver networking.SubnetsResolver,
3737
vpcInfoProvider networking.VPCInfoProvider, vpcID string, trackingProvider tracking.Provider,
3838
elbv2TaggingManager elbv2deploy.TaggingManager, clusterName string, defaultTags map[string]string,
39-
externalManagedTags []string, defaultSSLPolicy string, serviceUtils ServiceUtils) *defaultModelBuilder {
39+
externalManagedTags []string, defaultSSLPolicy string, enableIPTargetType bool, serviceUtils ServiceUtils) *defaultModelBuilder {
4040
return &defaultModelBuilder{
4141
annotationParser: annotationParser,
4242
subnetsResolver: subnetsResolver,
@@ -49,6 +49,7 @@ func NewDefaultModelBuilder(annotationParser annotations.Parser, subnetsResolver
4949
defaultTags: defaultTags,
5050
externalManagedTags: sets.NewString(externalManagedTags...),
5151
defaultSSLPolicy: defaultSSLPolicy,
52+
enableIPTargetType: enableIPTargetType,
5253
}
5354
}
5455

@@ -67,6 +68,7 @@ type defaultModelBuilder struct {
6768
defaultTags map[string]string
6869
externalManagedTags sets.String
6970
defaultSSLPolicy string
71+
enableIPTargetType bool
7072
}
7173

7274
func (b *defaultModelBuilder) Build(ctx context.Context, service *corev1.Service) (core.Stack, *elbv2model.LoadBalancer, error) {
@@ -80,6 +82,7 @@ func (b *defaultModelBuilder) Build(ctx context.Context, service *corev1.Service
8082
trackingProvider: b.trackingProvider,
8183
elbv2TaggingManager: b.elbv2TaggingManager,
8284
serviceUtils: b.serviceUtils,
85+
enableIPTargetType: b.enableIPTargetType,
8386

8487
service: service,
8588
stack: stack,
@@ -129,6 +132,7 @@ type defaultModelBuildTask struct {
129132
trackingProvider tracking.Provider
130133
elbv2TaggingManager elbv2deploy.TaggingManager
131134
serviceUtils ServiceUtils
135+
enableIPTargetType bool
132136

133137
service *corev1.Service
134138

0 commit comments

Comments
 (0)