Skip to content

Commit

Permalink
Add support to enable single ingress check
Browse files Browse the repository at this point in the history
  • Loading branch information
ruixiansong committed Jun 28, 2023
1 parent 60e62ab commit 2dab557
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 60 deletions.
9 changes: 8 additions & 1 deletion cmd/check-gke-ingress/app/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ var rootCmd = &cobra.Command{
fmt.Fprintf(os.Stderr, "Error connecting to Kubernetes: %v", err)
os.Exit(1)
}
output := ingress.CheckAllIngresses(namespace, client, beconfigClient, feConfigClient)

var output report.Report
if len(args) == 0 {
output = ingress.CheckAllIngresses(namespace, client, beconfigClient, feConfigClient)
} else {
output = ingress.CheckIngress(args[0], namespace, client, beconfigClient, feConfigClient)
}

res, err := report.JsonReport(&output)
if err != nil {
fmt.Fprintf(os.Stderr, "Error processing results: %v", err)
Expand Down
23 changes: 18 additions & 5 deletions cmd/check-gke-ingress/app/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"reflect"
"runtime"

networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/ingress-gce/cmd/check-gke-ingress/app/report"
Expand All @@ -31,15 +32,27 @@ import (
)

func CheckAllIngresses(namespace string, client kubernetes.Interface, beconfigClient beconfigclient.Interface, feConfigClient feconfigclient.Interface) report.Report {
output := report.Report{
Resources: []*report.Resource{},
}

ingressList, err := client.NetworkingV1().Ingresses(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
fmt.Fprintf(os.Stderr, "Error listing ingresses: %v", err)
os.Exit(1)
}
return RunChecks(ingressList.Items, client, beconfigClient, feConfigClient)
}

func CheckIngress(ingressName, namespace string, client kubernetes.Interface, beconfigClient beconfigclient.Interface, feConfigClient feconfigclient.Interface) report.Report {
ingress, err := client.NetworkingV1().Ingresses(namespace).Get(context.TODO(), ingressName, metav1.GetOptions{})
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting ingress %s/%s: %v", namespace, ingressName, err)
os.Exit(1)
}
return RunChecks([]networkingv1.Ingress{*ingress}, client, beconfigClient, feConfigClient)
}

func RunChecks(ingresses []networkingv1.Ingress, client kubernetes.Interface, beconfigClient beconfigclient.Interface, feConfigClient feconfigclient.Interface) report.Report {
output := report.Report{
Resources: []*report.Resource{},
}

ingressChecks := []ingressCheckFunc{
CheckIngressRule,
Expand All @@ -61,7 +74,7 @@ func CheckAllIngresses(namespace string, client kubernetes.Interface, beconfigCl
CheckHealthCheckTimeout,
}

for _, ingress := range ingressList.Items {
for _, ingress := range ingresses {

// Ingress related checks
ingressRes := &report.Resource{
Expand Down
157 changes: 103 additions & 54 deletions cmd/check-gke-ingress/app/ingress/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,8 @@ func TestCheckL7ILBNegAnnotation(t *testing.T) {
}
}

// TestCheckAllIngresses tests whether all the checks are triggered.
func TestCheckAllIngresses(t *testing.T) {

// TestCheckFunctions tests CheckAllIngresses and CheckIngress.
func TestCheckFunctions(t *testing.T) {
client := fake.NewSimpleClientset()
beClient := fakebeconfig.NewSimpleClientset()
feClient := fakefeconfig.NewSimpleClientset()
Expand Down Expand Up @@ -749,11 +748,107 @@ func TestCheckAllIngresses(t *testing.T) {
},
}, metav1.CreateOptions{})

result := CheckAllIngresses("test", client, beClient, feClient)
checkSet := make(map[string]struct{})
for _, resource := range result.Resources {
for _, check := range resource.Checks {
checkSet[check.Name] = struct{}{}

for _, tc := range []struct {
desc string
namespace string
ingressName string
expect report.Report
}{
{
desc: "No ingress name specified",
namespace: "test",
ingressName: "",
expect: report.Report{
Resources: []*report.Resource{
{
Kind: "Ingress",
Namespace: "test",
Name: "ingress1",
Checks: []*report.Check{
{Name: "IngressRuleCheck", Result: "PASSED"},
{Name: "L7ILBFrontendConfigCheck", Result: "FAILED"},
{Name: "RuleHostOverwriteCheck", Result: "PASSED"},
{Name: "FrontenådConfigExistenceCheck", Result: "FAILED"},
{Name: "ServiceExistenceCheck", Result: "PASSED"},
{Name: "BackendConfigAnnotationCheck", Result: "PASSED"},
{Name: "AppProtocolAnnotationCheck", Result: "FAILED"},
{Name: "L7ILBNegAnnotationCheck", Result: "FAILED"},
{Name: "BackendConfigExistenceCheck", Result: "PASSED"},
{Name: "HealthCheckTimeoutCheck", Result: "SKIPPED"},
},
},
{
Kind: "Ingress",
Namespace: "test",
Name: "ingress2",
Checks: []*report.Check{
{Name: "IngressRuleCheck", Result: "FAILED"},
{Name: "L7ILBFrontendConfigCheck", Result: "SKIPPED"},
{Name: "RuleHostOverwriteCheck", Result: "FAILED"},
{Name: "FrontendConfigExistenceCheck", Result: "PASSED"},
{Name: "ServiceExistenceCheck", Result: "PASSED"},
{Name: "BackendConfigAnnotationCheck", Result: "PASSED"},
{Name: "AppProtocolAnnotationCheck", Result: "SKIPPED"},
{Name: "L7ILBNegAnnotationCheck", Result: "SKIPPED"},
{Name: "BackendConfigExistenceCheck", Result: "PASSED"},
{Name: "HealthCheckTimeoutCheck", Result: "FAILED"},
},
},
},
},
},
{
desc: "namespace and ingress name specified",
namespace: "test",
ingressName: "ingress2",
expect: report.Report{
Resources: []*report.Resource{
{
Kind: "Ingress",
Namespace: "test",
Name: "ingress2",
Checks: []*report.Check{
{Name: "IngressRuleCheck", Result: "FAILED"},
{Name: "L7ILBFrontendConfigCheck", Result: "SKIPPED"},
{Name: "RuleHostOverwriteCheck", Result: "FAILED"},
{Name: "FrontendConfigExistenceCheck", Result: "PASSED"},
{Name: "ServiceExistenceCheck", Result: "PASSED"},
{Name: "BackendConfigAnnotationCheck", Result: "PASSED"},
{Name: "AppProtocolAnnotationCheck", Result: "SKIPPED"},
{Name: "L7ILBNegAnnotationCheck", Result: "SKIPPED"},
{Name: "BackendConfigExistenceCheck", Result: "PASSED"},
{Name: "HealthCheckTimeoutCheck", Result: "FAILED"},
},
},
},
},
},
} {
var result report.Report
if tc.ingressName == "" {
result = CheckAllIngresses(tc.namespace, client, beClient, feClient)
} else {
result = CheckIngress(tc.ingressName, tc.namespace, client, beClient, feClient)
}

for _, resource := range result.Resources {
for _, check := range resource.Checks {
checkSet[check.Name] = struct{}{}
}
}

if len(tc.expect.Resources) != len(result.Resources) {
t.Errorf("The number of ingress to be checked is not correct, want: %d, got: %d", len(tc.expect.Resources), len(result.Resources))
}

for i, resource := range result.Resources {
for j, check := range resource.Checks {
if diff := cmp.Diff(tc.expect.Resources[i].Checks[j].Result, check.Result); diff != "" {
t.Errorf("For ingress check %s for ingress %s/%s, (-want +got):\n%s", check.Name, resource.Namespace, resource.Name, diff)
}
}
}
}

Expand All @@ -770,53 +865,7 @@ func TestCheckAllIngresses(t *testing.T) {
L7ILBNegAnnotationCheck,
} {
if _, ok := checkSet[check]; !ok {
t.Errorf("Missing check %s in CheckAllIngresses", check)
}
}

expect := report.Report{
Resources: []*report.Resource{
{
Kind: "Ingress",
Namespace: "test",
Name: "ingress1",
Checks: []*report.Check{
{Name: "IngressRuleCheck", Result: "PASSED"},
{Name: "L7ILBFrontendConfigCheck", Result: "FAILED"},
{Name: "RuleHostOverwriteCheck", Result: "PASSED"},
{Name: "FrontendConfigExistenceCheck", Result: "FAILED"},
{Name: "ServiceExistenceCheck", Result: "PASSED"},
{Name: "BackendConfigAnnotationCheck", Result: "PASSED"},
{Name: "AppProtocolAnnotationCheck", Result: "FAILED"},
{Name: "L7ILBNegAnnotationCheck", Result: "FAILED"},
{Name: "BackendConfigExistenceCheck", Result: "PASSED"},
{Name: "HealthCheckTimeoutCheck", Result: "SKIPPED"},
},
},
{
Kind: "Ingress",
Namespace: "test",
Name: "ingress2",
Checks: []*report.Check{
{Name: "IngressRuleCheck", Result: "FAILED"},
{Name: "L7ILBFrontendConfigCheck", Result: "SKIPPED"},
{Name: "RuleHostOverwriteCheck", Result: "FAILED"},
{Name: "FrontendConfigExistenceCheck", Result: "PASSED"},
{Name: "ServiceExistenceCheck", Result: "PASSED"},
{Name: "BackendConfigAnnotationCheck", Result: "PASSED"},
{Name: "AppProtocolAnnotationCheck", Result: "SKIPPED"},
{Name: "L7ILBNegAnnotationCheck", Result: "SKIPPED"},
{Name: "BackendConfigExistenceCheck", Result: "PASSED"},
{Name: "HealthCheckTimeoutCheck", Result: "FAILED"},
},
},
},
}
for i, resource := range result.Resources {
for j, check := range resource.Checks {
if diff := cmp.Diff(expect.Resources[i].Checks[j].Result, check.Result); diff != "" {
t.Errorf("For ingress check %s for ingress %s/%s, (-want +got):\n%s", check.Name, resource.Namespace, resource.Name, diff)
}
t.Errorf("Missing check %s in check functions", check)
}
}
}

0 comments on commit 2dab557

Please sign in to comment.