@@ -311,3 +311,245 @@ func BenchmarkMergeMasterAnnotationsIntoMinion(b *testing.B) {
311311 mergeMasterAnnotationsIntoMinion (minionAnnotations , masterAnnotations )
312312 }
313313}
314+
315+ // TestSSLCipherAnnotationParsing tests the parsing of SSL cipher annotations
316+ func TestSSLCipherAnnotationParsing (t * testing.T ) {
317+ t .Parallel ()
318+
319+ tests := []struct {
320+ name string
321+ annotations map [string ]string
322+ expected ConfigParams
323+ }{
324+ {
325+ name : "SSL ciphers annotation only" ,
326+ annotations : map [string ]string {
327+ "nginx.org/ssl-ciphers" : "HIGH:!aNULL:!MD5" ,
328+ },
329+ expected : ConfigParams {
330+ ServerSSLCiphers : "HIGH:!aNULL:!MD5" ,
331+ ServerSSLPreferServerCiphers : false ,
332+ },
333+ },
334+ {
335+ name : "SSL prefer server ciphers annotation only - true" ,
336+ annotations : map [string ]string {
337+ "nginx.org/ssl-prefer-server-ciphers" : "true" ,
338+ },
339+ expected : ConfigParams {
340+ ServerSSLCiphers : "" ,
341+ ServerSSLPreferServerCiphers : true ,
342+ },
343+ },
344+ {
345+ name : "SSL prefer server ciphers annotation only - True" ,
346+ annotations : map [string ]string {
347+ "nginx.org/ssl-prefer-server-ciphers" : "True" ,
348+ },
349+ expected : ConfigParams {
350+ ServerSSLCiphers : "" ,
351+ ServerSSLPreferServerCiphers : true ,
352+ },
353+ },
354+ {
355+ name : "SSL prefer server ciphers annotation only - false" ,
356+ annotations : map [string ]string {
357+ "nginx.org/ssl-prefer-server-ciphers" : "false" ,
358+ },
359+ expected : ConfigParams {
360+ ServerSSLCiphers : "" ,
361+ ServerSSLPreferServerCiphers : false ,
362+ },
363+ },
364+ {
365+ name : "Both SSL cipher annotations" ,
366+ annotations : map [string ]string {
367+ "nginx.org/ssl-ciphers" : "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256" ,
368+ "nginx.org/ssl-prefer-server-ciphers" : "true" ,
369+ },
370+ expected : ConfigParams {
371+ ServerSSLCiphers : "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256" ,
372+ ServerSSLPreferServerCiphers : true ,
373+ },
374+ },
375+ {
376+ name : "Empty SSL ciphers annotation" ,
377+ annotations : map [string ]string {
378+ "nginx.org/ssl-ciphers" : "" ,
379+ },
380+ expected : ConfigParams {
381+ ServerSSLCiphers : "" ,
382+ ServerSSLPreferServerCiphers : false ,
383+ },
384+ },
385+ {
386+ name : "No SSL cipher annotations" ,
387+ annotations : map [string ]string {
388+ "nginx.org/proxy-connect-timeout" : "30s" ,
389+ },
390+ expected : ConfigParams {
391+ ServerSSLCiphers : "" ,
392+ ServerSSLPreferServerCiphers : false ,
393+ },
394+ },
395+ }
396+
397+ for _ , tt := range tests {
398+ t .Run (tt .name , func (t * testing.T ) {
399+ ingress := & networking.Ingress {
400+ ObjectMeta : metav1.ObjectMeta {
401+ Name : "test-ingress" ,
402+ Namespace : "default" ,
403+ Annotations : tt .annotations ,
404+ },
405+ }
406+
407+ ingEx := & IngressEx {
408+ Ingress : ingress ,
409+ }
410+
411+ baseCfgParams := NewDefaultConfigParams (context .Background (), false )
412+ result := parseAnnotations (ingEx , baseCfgParams , false , false , false , false , false )
413+
414+ if result .ServerSSLCiphers != tt .expected .ServerSSLCiphers {
415+ t .Errorf ("Expected ServerSSLCiphers %q, got %q" , tt .expected .ServerSSLCiphers , result .ServerSSLCiphers )
416+ }
417+
418+ if result .ServerSSLPreferServerCiphers != tt .expected .ServerSSLPreferServerCiphers {
419+ t .Errorf ("Expected ServerSSLPreferServerCiphers %v, got %v" , tt .expected .ServerSSLPreferServerCiphers , result .ServerSSLPreferServerCiphers )
420+ }
421+ })
422+ }
423+ }
424+
425+ // TestSSLCipherAnnotationFiltering tests that SSL cipher annotations are filtered correctly for minions
426+ func TestSSLCipherAnnotationFiltering (t * testing.T ) {
427+ t .Parallel ()
428+
429+ tests := []struct {
430+ name string
431+ annotations map [string ]string
432+ filterFunc func (map [string ]string ) []string
433+ expectedRemoved []string
434+ expectedAnnotations map [string ]string
435+ }{
436+ {
437+ name : "SSL cipher annotations removed from minions" ,
438+ annotations : map [string ]string {
439+ "nginx.org/ssl-ciphers" : "HIGH:!aNULL:!MD5" ,
440+ "nginx.org/ssl-prefer-server-ciphers" : "true" ,
441+ "nginx.org/proxy-connect-timeout" : "30s" ,
442+ "nginx.org/server-snippets" : "add_header X-Frame-Options SAMEORIGIN;" ,
443+ },
444+ filterFunc : filterMinionAnnotations ,
445+ expectedRemoved : []string {
446+ "nginx.org/ssl-ciphers" ,
447+ "nginx.org/ssl-prefer-server-ciphers" ,
448+ "nginx.org/server-snippets" ,
449+ },
450+ expectedAnnotations : map [string ]string {
451+ "nginx.org/proxy-connect-timeout" : "30s" ,
452+ },
453+ },
454+ {
455+ name : "SSL cipher annotations allowed in masters" ,
456+ annotations : map [string ]string {
457+ "nginx.org/ssl-ciphers" : "HIGH:!aNULL:!MD5" ,
458+ "nginx.org/ssl-prefer-server-ciphers" : "true" ,
459+ "nginx.org/rewrites" : "serviceName=test rewrite=/" ,
460+ "nginx.org/proxy-connect-timeout" : "30s" ,
461+ },
462+ filterFunc : filterMasterAnnotations ,
463+ expectedRemoved : []string {
464+ "nginx.org/rewrites" ,
465+ },
466+ expectedAnnotations : map [string ]string {
467+ "nginx.org/ssl-ciphers" : "HIGH:!aNULL:!MD5" ,
468+ "nginx.org/ssl-prefer-server-ciphers" : "true" ,
469+ "nginx.org/proxy-connect-timeout" : "30s" ,
470+ },
471+ },
472+ }
473+
474+ for _ , tt := range tests {
475+ t .Run (tt .name , func (t * testing.T ) {
476+ // Make a copy of annotations to avoid modifying the test data
477+ annotations := make (map [string ]string )
478+ for k , v := range tt .annotations {
479+ annotations [k ] = v
480+ }
481+
482+ removedAnnotations := tt .filterFunc (annotations )
483+
484+ // Sort slices for comparison
485+ sort .Strings (removedAnnotations )
486+ sort .Strings (tt .expectedRemoved )
487+
488+ if ! reflect .DeepEqual (removedAnnotations , tt .expectedRemoved ) {
489+ t .Errorf ("Expected removed annotations %v, got %v" , tt .expectedRemoved , removedAnnotations )
490+ }
491+
492+ if ! reflect .DeepEqual (annotations , tt .expectedAnnotations ) {
493+ t .Errorf ("Expected remaining annotations %v, got %v" , tt .expectedAnnotations , annotations )
494+ }
495+ })
496+ }
497+ }
498+
499+ // TestSSLCipherAnnotationBooleanValues tests both valid and invalid boolean values for ssl-prefer-server-ciphers
500+ func TestSSLCipherAnnotationBooleanValues (t * testing.T ) {
501+ t .Parallel ()
502+
503+ testCases := []struct {
504+ value string
505+ expected bool
506+ isValid bool
507+ }{
508+ // Valid boolean values
509+ {"true" , true , true },
510+ {"TRUE" , true , true },
511+ {"True" , true , true },
512+ {"1" , true , true },
513+ {"false" , false , true },
514+ {"FALSE" , false , true },
515+ {"False" , false , true },
516+ {"0" , false , true },
517+ // Invalid boolean values (should default to false)
518+ {"invalid" , false , false },
519+ {"yes" , false , false },
520+ {"no" , false , false },
521+ {"2" , false , false },
522+ {"" , false , false },
523+ {"maybe" , false , false },
524+ {"on" , false , false },
525+ }
526+
527+ for _ , tc := range testCases {
528+ t .Run (tc .value , func (t * testing.T ) {
529+ ingress := & networking.Ingress {
530+ ObjectMeta : metav1.ObjectMeta {
531+ Name : "test-ingress" ,
532+ Namespace : "default" ,
533+ Annotations : map [string ]string {
534+ "nginx.org/ssl-prefer-server-ciphers" : tc .value ,
535+ },
536+ },
537+ }
538+
539+ ingEx := & IngressEx {
540+ Ingress : ingress ,
541+ }
542+
543+ baseCfgParams := NewDefaultConfigParams (context .Background (), false )
544+ result := parseAnnotations (ingEx , baseCfgParams , false , false , false , false , false )
545+
546+ if result .ServerSSLPreferServerCiphers != tc .expected {
547+ validityMsg := "valid"
548+ if ! tc .isValid {
549+ validityMsg = "invalid"
550+ }
551+ t .Errorf ("Expected ServerSSLPreferServerCiphers to be %v for %s value %q, got %v" , tc .expected , validityMsg , tc .value , result .ServerSSLPreferServerCiphers )
552+ }
553+ })
554+ }
555+ }
0 commit comments