@@ -266,3 +266,193 @@ func TestValidateServiceAnnotationTargetGroupAttributes(t *testing.T) {
266266 })
267267 }
268268}
269+
270+ func TestValidateServiceAnnotations (t * testing.T ) {
271+ const byoSecurityGroupID = "sg-123456789"
272+
273+ tests := []struct {
274+ name string
275+ annotations map [string ]string
276+ servicePorts []v1.ServicePort
277+ expectedError string
278+ }{
279+ // Valid cases - CLB (Classic Load Balancer) should allow BYO security groups
280+ {
281+ name : "CLB with BYO SG annotation - success" ,
282+ annotations : map [string ]string {
283+ ServiceAnnotationLoadBalancerSecurityGroups : byoSecurityGroupID ,
284+ },
285+ expectedError : "" ,
286+ },
287+ {
288+ name : "CLB with BYO extra SG annotation - success" ,
289+ annotations : map [string ]string {
290+ ServiceAnnotationLoadBalancerExtraSecurityGroups : byoSecurityGroupID ,
291+ },
292+ expectedError : "" ,
293+ },
294+ {
295+ name : "CLB with both BYO SG annotations - success" ,
296+ annotations : map [string ]string {
297+ ServiceAnnotationLoadBalancerSecurityGroups : byoSecurityGroupID ,
298+ ServiceAnnotationLoadBalancerExtraSecurityGroups : "sg-extra123" ,
299+ },
300+ expectedError : "" ,
301+ },
302+
303+ // Error cases - NLB should reject BYO security group annotations
304+ {
305+ name : "NLB with BYO SG annotation - error (not supported)" ,
306+ annotations : map [string ]string {
307+ ServiceAnnotationLoadBalancerType : "nlb" ,
308+ ServiceAnnotationLoadBalancerSecurityGroups : byoSecurityGroupID ,
309+ },
310+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
311+ },
312+ {
313+ name : "NLB with BYO extra SG annotation - error (not supported)" ,
314+ annotations : map [string ]string {
315+ ServiceAnnotationLoadBalancerType : "nlb" ,
316+ ServiceAnnotationLoadBalancerExtraSecurityGroups : byoSecurityGroupID ,
317+ },
318+ expectedError : "BYO extra security group annotation \" service.beta.kubernetes.io/aws-load-balancer-extra-security-groups\" is not supported by NLB" ,
319+ },
320+ {
321+ name : "NLB with both BYO SG annotations - error (not supported)" ,
322+ annotations : map [string ]string {
323+ ServiceAnnotationLoadBalancerType : "nlb" ,
324+ ServiceAnnotationLoadBalancerSecurityGroups : byoSecurityGroupID ,
325+ ServiceAnnotationLoadBalancerExtraSecurityGroups : "sg-extra123" ,
326+ },
327+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
328+ },
329+ {
330+ name : "NLB with BYO SG with empty value - error (not supported)" ,
331+ annotations : map [string ]string {
332+ ServiceAnnotationLoadBalancerType : "nlb" ,
333+ ServiceAnnotationLoadBalancerSecurityGroups : "" ,
334+ },
335+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
336+ },
337+ {
338+ name : "NLB with BYO SG with multiple values - error (not supported)" ,
339+ annotations : map [string ]string {
340+ ServiceAnnotationLoadBalancerType : "nlb" ,
341+ ServiceAnnotationLoadBalancerSecurityGroups : "sg-123,sg-456" ,
342+ },
343+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
344+ },
345+ {
346+ name : "NLB with single BYO SG - error (not supported)" ,
347+ annotations : map [string ]string {
348+ ServiceAnnotationLoadBalancerType : "nlb" ,
349+ ServiceAnnotationLoadBalancerSecurityGroups : "sg-123456789" ,
350+ },
351+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
352+ },
353+ {
354+ name : "NLB with multiple BYO SGs - error (not supported)" ,
355+ annotations : map [string ]string {
356+ ServiceAnnotationLoadBalancerType : "nlb" ,
357+ ServiceAnnotationLoadBalancerSecurityGroups : "sg-123456789,sg-987654321" ,
358+ },
359+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
360+ },
361+ {
362+ name : "NLB with invalid BYO SG format - error (not supported)" ,
363+ annotations : map [string ]string {
364+ ServiceAnnotationLoadBalancerType : "nlb" ,
365+ ServiceAnnotationLoadBalancerSecurityGroups : "invalid-sg-format" ,
366+ },
367+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
368+ },
369+ {
370+ name : "NLB case sensitivity - BYO SG annotation with different casing should still be rejected" ,
371+ annotations : map [string ]string {
372+ ServiceAnnotationLoadBalancerType : "nlb" ,
373+ ServiceAnnotationLoadBalancerSecurityGroups : "SG-123ABC" ,
374+ },
375+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
376+ },
377+ {
378+ name : "NLB mixed annotations - BYO and other annotations" ,
379+ annotations : map [string ]string {
380+ ServiceAnnotationLoadBalancerSecurityGroups : "sg-123456" ,
381+ ServiceAnnotationLoadBalancerType : "nlb" ,
382+ ServiceAnnotationLoadBalancerInternal : "true" ,
383+ },
384+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
385+ },
386+ {
387+ name : "NLB whitespace in BYO SG values - should still be rejected" ,
388+ annotations : map [string ]string {
389+ ServiceAnnotationLoadBalancerType : "nlb" ,
390+ ServiceAnnotationLoadBalancerSecurityGroups : " sg-123456 " ,
391+ },
392+ expectedError : "BYO security group annotation \" service.beta.kubernetes.io/aws-load-balancer-security-groups\" is not supported by NLB" ,
393+ },
394+
395+ // Target group attributes validation for NLB (should succeed)
396+ {
397+ name : "NLB with target group attributes - success" ,
398+ annotations : map [string ]string {
399+ ServiceAnnotationLoadBalancerType : "nlb" ,
400+ ServiceAnnotationLoadBalancerTargetGroupAttributes : "preserve_client_ip.enabled=true" ,
401+ },
402+ servicePorts : []v1.ServicePort {
403+ {Port : 80 , Protocol : v1 .ProtocolTCP },
404+ },
405+ expectedError : "" ,
406+ },
407+
408+ // Target group attributes validation for CLB (should fail)
409+ {
410+ name : "CLB with target group attributes - error (only supported for NLB)" ,
411+ annotations : map [string ]string {
412+ ServiceAnnotationLoadBalancerTargetGroupAttributes : "preserve_client_ip.enabled=true" ,
413+ },
414+ expectedError : "target group attributes annotation is only supported for NLB" ,
415+ },
416+
417+ // No annotations (should succeed)
418+ {
419+ name : "no annotations - success" ,
420+ annotations : map [string ]string {},
421+ expectedError : "" ,
422+ },
423+ }
424+
425+ for _ , tt := range tests {
426+ t .Run (tt .name , func (t * testing.T ) {
427+ // Create a test service with the specified ports and annotations
428+ service := & v1.Service {
429+ ObjectMeta : metav1.ObjectMeta {
430+ Name : "test-service" ,
431+ Namespace : "test-namespace" ,
432+ Annotations : tt .annotations ,
433+ },
434+ Spec : v1.ServiceSpec {
435+ Type : v1 .ServiceTypeLoadBalancer ,
436+ Ports : tt .servicePorts ,
437+ },
438+ }
439+
440+ // Create validation input
441+ input := & awsValidationInput {
442+ apiService : service ,
443+ annotations : tt .annotations ,
444+ }
445+
446+ // Execute the validation
447+ err := validateServiceAnnotations (input )
448+
449+ // Verify the result
450+ if tt .expectedError == "" {
451+ assert .NoError (t , err , "Expected no error for test case: %s" , tt .name )
452+ } else {
453+ assert .Error (t , err , "Expected error for test case: %s" , tt .name )
454+ assert .Contains (t , err .Error (), tt .expectedError , "Error message should contain expected text for test case: %s" , tt .name )
455+ }
456+ })
457+ }
458+ }
0 commit comments