@@ -21,8 +21,9 @@ import (
21
21
)
22
22
23
23
const (
24
- TGAttrsProxyProtocolV2Enabled = "proxy_protocol_v2.enabled"
25
- healthCheckPortTrafficPort = "traffic-port"
24
+ TGAttrsProxyProtocolV2Enabled = "proxy_protocol_v2.enabled"
25
+ TGAttrsPreserveClientIPEnabled = "preserve_client_ip.enabled"
26
+ healthCheckPortTrafficPort = "traffic-port"
26
27
)
27
28
28
29
func (t * defaultModelBuildTask ) buildTargetGroup (ctx context.Context , port corev1.ServicePort , tgProtocol elbv2model.Protocol ) (* elbv2model.TargetGroup , error ) {
@@ -39,13 +40,17 @@ func (t *defaultModelBuildTask) buildTargetGroup(ctx context.Context, port corev
39
40
if err != nil {
40
41
return nil , err
41
42
}
43
+ preserveClientIP , err := t .buildPreserveClientIPFlag (ctx , targetType )
44
+ if err != nil {
45
+ return nil , err
46
+ }
42
47
tgSpec , err := t .buildTargetGroupSpec (ctx , tgProtocol , targetType , port , healthCheckConfig )
43
48
if err != nil {
44
49
return nil , err
45
50
}
46
51
targetGroup := elbv2model .NewTargetGroup (t .stack , tgResourceID , tgSpec )
47
52
t .tgByResID [tgResourceID ] = targetGroup
48
- _ = t .buildTargetGroupBinding (ctx , targetGroup , port , healthCheckConfig )
53
+ _ = t .buildTargetGroupBinding (ctx , targetGroup , preserveClientIP , port , healthCheckConfig )
49
54
return targetGroup , nil
50
55
}
51
56
@@ -141,20 +146,53 @@ func (t *defaultModelBuildTask) buildTargetGroupName(_ context.Context, svcPort
141
146
}
142
147
143
148
func (t * defaultModelBuildTask ) buildTargetGroupAttributes (_ context.Context ) ([]elbv2model.TargetGroupAttribute , error ) {
144
- var attrs []elbv2model.TargetGroupAttribute
145
- proxyV2Enabled := t .defaultProxyProtocolV2Enabled
149
+ var rawAttributes map [string ]string
150
+ if _ , err := t .annotationParser .ParseStringMapAnnotation (annotations .SvcLBSuffixTargetGroupAttributes , & rawAttributes , t .service .Annotations ); err != nil {
151
+ return nil , err
152
+ }
153
+ if rawAttributes == nil {
154
+ rawAttributes = make (map [string ]string )
155
+ }
156
+ if _ , ok := rawAttributes [TGAttrsProxyProtocolV2Enabled ]; ! ok {
157
+ rawAttributes [TGAttrsProxyProtocolV2Enabled ] = strconv .FormatBool (t .defaultProxyProtocolV2Enabled )
158
+ }
146
159
proxyV2Annotation := ""
147
- if t .annotationParser .ParseStringAnnotation (annotations .SvcLBSuffixProxyProtocol , & proxyV2Annotation , t .service .Annotations ) {
160
+ exists := t .annotationParser .ParseStringAnnotation (annotations .SvcLBSuffixProxyProtocol , & proxyV2Annotation , t .service .Annotations )
161
+ if exists {
148
162
if proxyV2Annotation != "*" {
149
- return []elbv2model.TargetGroupAttribute {}, errors .Errorf ("Invalid value %v for Load Balancer proxy protocol v2 annotation, only value currently supported is *" , proxyV2Annotation )
163
+ return []elbv2model.TargetGroupAttribute {}, errors .Errorf ("invalid value %v for Load Balancer proxy protocol v2 annotation, only value currently supported is *" , proxyV2Annotation )
150
164
}
151
- proxyV2Enabled = true
165
+ rawAttributes [TGAttrsProxyProtocolV2Enabled ] = "true"
166
+ }
167
+ attributes := make ([]elbv2model.TargetGroupAttribute , 0 , len (rawAttributes ))
168
+ for attrKey , attrValue := range rawAttributes {
169
+ attributes = append (attributes , elbv2model.TargetGroupAttribute {
170
+ Key : attrKey ,
171
+ Value : attrValue ,
172
+ })
173
+ }
174
+ return attributes , nil
175
+ }
176
+
177
+ func (t * defaultModelBuildTask ) buildPreserveClientIPFlag (_ context.Context , targetType elbv2model.TargetType ) (bool , error ) {
178
+ var rawAttributes map [string ]string
179
+ if _ , err := t .annotationParser .ParseStringMapAnnotation (annotations .SvcLBSuffixTargetGroupAttributes , & rawAttributes , t .service .Annotations ); err != nil {
180
+ return false , err
181
+ }
182
+ if rawVal , ok := rawAttributes [TGAttrsPreserveClientIPEnabled ]; ok {
183
+ val , err := strconv .ParseBool (rawVal )
184
+ if err != nil {
185
+ return false , errors .Wrapf (err , "failed to parse attribute %v=%v" , TGAttrsPreserveClientIPEnabled , rawVal )
186
+ }
187
+ return val , nil
188
+ }
189
+ switch targetType {
190
+ case elbv2model .TargetTypeIP :
191
+ return false , nil
192
+ case elbv2model .TargetTypeInstance :
193
+ return true , nil
152
194
}
153
- attrs = append (attrs , elbv2model.TargetGroupAttribute {
154
- Key : TGAttrsProxyProtocolV2Enabled ,
155
- Value : strconv .FormatBool (proxyV2Enabled ),
156
- })
157
- return attrs , nil
195
+ return false , nil
158
196
}
159
197
160
198
func (t * defaultModelBuildTask ) buildTargetGroupHealthCheckPort (_ context.Context ) (intstr.IntOrString , error ) {
@@ -251,15 +289,15 @@ func (t *defaultModelBuildTask) buildTargetGroupTags(ctx context.Context) (map[s
251
289
return t .buildAdditionalResourceTags (ctx )
252
290
}
253
291
254
- func (t * defaultModelBuildTask ) buildTargetGroupBinding (ctx context.Context , targetGroup * elbv2model.TargetGroup ,
292
+ func (t * defaultModelBuildTask ) buildTargetGroupBinding (ctx context.Context , targetGroup * elbv2model.TargetGroup , preserveClientIP bool ,
255
293
port corev1.ServicePort , hc * elbv2model.TargetGroupHealthCheckConfig ) * elbv2model.TargetGroupBindingResource {
256
- tgbSpec := t .buildTargetGroupBindingSpec (ctx , targetGroup , port , hc )
294
+ tgbSpec := t .buildTargetGroupBindingSpec (ctx , targetGroup , preserveClientIP , port , hc )
257
295
return elbv2model .NewTargetGroupBindingResource (t .stack , targetGroup .ID (), tgbSpec )
258
296
}
259
297
260
- func (t * defaultModelBuildTask ) buildTargetGroupBindingSpec (ctx context.Context , targetGroup * elbv2model.TargetGroup ,
298
+ func (t * defaultModelBuildTask ) buildTargetGroupBindingSpec (ctx context.Context , targetGroup * elbv2model.TargetGroup , preserveClientIP bool ,
261
299
port corev1.ServicePort , hc * elbv2model.TargetGroupHealthCheckConfig ) elbv2model.TargetGroupBindingResourceSpec {
262
- tgbNetworking := t .buildTargetGroupBindingNetworking (ctx , port .TargetPort , * hc .Port , port .Protocol )
300
+ tgbNetworking := t .buildTargetGroupBindingNetworking (ctx , port .TargetPort , preserveClientIP , * hc .Port , port .Protocol )
263
301
targetType := elbv2api .TargetType (targetGroup .Spec .TargetType )
264
302
return elbv2model.TargetGroupBindingResourceSpec {
265
303
Template : elbv2model.TargetGroupBindingTemplate {
@@ -302,7 +340,7 @@ func (t *defaultModelBuildTask) buildPeersFromSourceRanges(_ context.Context) []
302
340
return peers
303
341
}
304
342
305
- func (t * defaultModelBuildTask ) buildTargetGroupBindingNetworking (ctx context.Context , tgPort intstr.IntOrString ,
343
+ func (t * defaultModelBuildTask ) buildTargetGroupBindingNetworking (ctx context.Context , tgPort intstr.IntOrString , preserveClientIP bool ,
306
344
hcPort intstr.IntOrString , tgProtocol corev1.Protocol ) * elbv2model.TargetGroupBindingNetworking {
307
345
var fromVPC []elbv2model.NetworkingPeer
308
346
for _ , subnet := range t .ec2Subnets {
@@ -323,7 +361,7 @@ func (t *defaultModelBuildTask) buildTargetGroupBindingNetworking(ctx context.Co
323
361
},
324
362
}
325
363
trafficSource := fromVPC
326
- if networkingProtocol == elbv2api .NetworkingProtocolUDP {
364
+ if networkingProtocol == elbv2api .NetworkingProtocolUDP || preserveClientIP {
327
365
trafficSource = t .buildPeersFromSourceRanges (ctx )
328
366
}
329
367
tgbNetworking := & elbv2model.TargetGroupBindingNetworking {
0 commit comments