diff --git a/cmd/check-gke-ingress/app/ingress/rule.go b/cmd/check-gke-ingress/app/ingress/rule.go index b659d60e8e..5b238b8819 100644 --- a/cmd/check-gke-ingress/app/ingress/rule.go +++ b/cmd/check-gke-ingress/app/ingress/rule.go @@ -156,6 +156,23 @@ func CheckL7ILBFrontendConfig(ing *networkingv1.Ingress) (string, string) { return report.Passed, fmt.Sprintf("Ingress %s/%s for L7 internal load balancing does not have a frontendConfig annotation", ing.Namespace, ing.Name) } +// CheckL7ILBNegAnnotation check whether a service which belongs to an internal +// ingress has a correct NEG annotation. +func CheckL7ILBNegAnnotation(svc *corev1.Service) (string, string) { + val, ok := getNegAnnotation(svc) + if !ok { + return report.Failed, fmt.Sprintf("No Neg annotation found in service %s/%s for internal HTTP(S) load balancing", svc.Namespace, svc.Name) + } + var res annotations.NegAnnotation + if err := json.Unmarshal([]byte(val), &res); err != nil { + return report.Failed, fmt.Sprintf("Invalid Neg annotation found in service %s/%s for internal HTTP(S) load balancing", svc.Namespace, svc.Name) + } + if !res.Ingress { + return report.Failed, fmt.Sprintf("Neg annotation ingress field is not true in service %s/%s for internal HTTP(S) load balancing", svc.Namespace, svc.Name) + } + return report.Passed, fmt.Sprintf("Neg annotation is set correctly in service %s/%s for internal HTTP(S) load balancing", svc.Namespace, svc.Name) +} + // getBackendConfigAnnotation gets the BackendConfig annotation from a service. func getBackendConfigAnnotation(svc *corev1.Service) (string, bool) { for _, bcKey := range []string{annotations.BackendConfigKey, annotations.BetaBackendConfigKey} { @@ -199,3 +216,12 @@ func getFrontendConfigAnnotation(ing *networkingv1.Ingress) (string, bool) { } return val, true } + +// getNegAnnotation gets the NEG annotation from a service object. +func getNegAnnotation(svc *corev1.Service) (string, bool) { + val, ok := svc.Annotations[annotations.NEGAnnotationKey] + if !ok { + return "", false + } + return val, true +} diff --git a/cmd/check-gke-ingress/app/ingress/rule_test.go b/cmd/check-gke-ingress/app/ingress/rule_test.go index dba0fe5670..c936a4f25f 100644 --- a/cmd/check-gke-ingress/app/ingress/rule_test.go +++ b/cmd/check-gke-ingress/app/ingress/rule_test.go @@ -527,3 +527,66 @@ func TestCheckL7ILBFrontendConfig(t *testing.T) { } } } + +func TestCheckL7ILBNegAnnotation(t *testing.T) { + for _, tc := range []struct { + desc string + svc corev1.Service + expect string + }{ + { + desc: "Service without NEG annotation", + svc: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "svc-1", + Namespace: "test", + }, + }, + expect: report.Failed, + }, + { + desc: "Service with invalid NEG annotation json", + svc: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "svc-1", + Namespace: "test", + Annotations: map[string]string{ + annotations.NEGAnnotationKey: `{"ingress": true,}`, + }, + }, + }, + expect: report.Failed, + }, + { + desc: "Service with NEG annotation which does not have ingress key", + svc: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "svc-1", + Namespace: "test", + Annotations: map[string]string{ + annotations.NEGAnnotationKey: `{"exposed_ports": {"80":{"name": "neg1"}}}`, + }, + }, + }, + expect: report.Failed, + }, + { + desc: "Service with correct NEG annotation", + svc: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "svc-1", + Namespace: "test", + Annotations: map[string]string{ + annotations.NEGAnnotationKey: `{"ingress": true}`, + }, + }, + }, + expect: report.Passed, + }, + } { + res, _ := CheckL7ILBNegAnnotation(&tc.svc) + if res != tc.expect { + t.Errorf("For test case %q, expect check result = %s, but got %s", tc.desc, tc.expect, res) + } + } +}