diff --git a/functional_tests/functional_test.go b/functional_tests/functional_test.go index 9f412fe03..683c792dd 100644 --- a/functional_tests/functional_test.go +++ b/functional_tests/functional_test.go @@ -701,6 +701,49 @@ var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() { }, } + ingressSlashNothingSlashSomething := &v1beta1.Ingress{ + Spec: v1beta1.IngressSpec{ + Rules: []v1beta1.IngressRule{ + { + // This one has no host + IngressRuleValue: v1beta1.IngressRuleValue{ + HTTP: &v1beta1.HTTPIngressRuleValue{ + Paths: []v1beta1.HTTPIngressPath{ + { + Path: "/", + Backend: v1beta1.IngressBackend{ + ServiceName: serviceNameB, + ServicePort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + }, + }, + { + Path: "/A", + Backend: v1beta1.IngressBackend{ + ServiceName: serviceNameA, + ServicePort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + annotations.IngressClassKey: annotations.ApplicationGatewayIngressClass, + }, + Namespace: tests.Namespace, + Name: tests.Name, + }, + } + ginkgo.It("THREE Ingress Resources", func() { cbCtx := &ConfigBuilderContext{ IngressList: []*v1beta1.Ingress{ @@ -851,7 +894,7 @@ var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() { }) ginkgo.It("WAF Annotation", func() { - annotatedIngress := ingressB + annotatedIngress := ingressSlashNothingSlashSomething annotatedIngress.Annotations[annotations.FirewallPolicy] = "/some/policy/here" cbCtx := &ConfigBuilderContext{ @@ -863,6 +906,8 @@ var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() { ExistingPortsByNumber: map[Port]n.ApplicationGatewayFrontendPort{ Port(80): fixtures.GetDefaultPort(), }, + DefaultAddressPoolID: to.StringPtr("xx"), + DefaultHTTPSettingsID: to.StringPtr("yy"), } check(cbCtx, "waf_annotation.json", stopChannel, ctxt, configBuilder) }) diff --git a/functional_tests/waf_annotation.json b/functional_tests/waf_annotation.json index 7758ca5ee..2efe9edf7 100644 --- a/functional_tests/waf_annotation.json +++ b/functional_tests/waf_annotation.json @@ -8,6 +8,23 @@ "backendAddresses": [] } }, + { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-a-80-bp-80", + "name": "pool---namespace---hello-world-a-80-bp-80", + "properties": { + "backendAddresses": [ + { + "ipAddress": "1.1.1.1" + }, + { + "ipAddress": "1.1.1.2" + }, + { + "ipAddress": "1.1.1.3" + } + ] + } + }, { "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-b-80-bp-80", "name": "pool---namespace---hello-world-b-80-bp-80", @@ -27,6 +44,20 @@ } ], "backendHttpSettingsCollection": [ + { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-a-80-80---name--", + "name": "bp---namespace---hello-world-a-80-80---name--", + "properties": { + "cookieBasedAffinity": "Disabled", + "pickHostNameFromBackendAddress": false, + "port": 80, + "probe": { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/pb---namespace---hello-world-a-80---name--" + }, + "protocol": "Http", + "requestTimeout": 30 + } + }, { "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-b-80-80---name--", "name": "bp---namespace---hello-world-b-80-80---name--", @@ -88,6 +119,9 @@ "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-e1903c8aa3446b7b3207aec6d6ecba8a", "name": "fl-e1903c8aa3446b7b3207aec6d6ecba8a", "properties": { + "firewallPolicy": { + "id": "/some/policy/here" + }, "frontendIPConfiguration": { "id": "--front-end-ip-id-1--" }, @@ -131,6 +165,21 @@ "unhealthyThreshold": 3 } }, + { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/pb---namespace---hello-world-a-80---name--", + "name": "pb---namespace---hello-world-a-80---name--", + "properties": { + "host": "localhost", + "interval": 30, + "match": {}, + "minServers": 0, + "path": "/A", + "pickHostNameFromBackendHttpSettings": false, + "protocol": "Http", + "timeout": 30, + "unhealthyThreshold": 3 + } + }, { "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/pb---namespace---hello-world-b-80---name--", "name": "pb---namespace---hello-world-b-80---name--", @@ -139,7 +188,7 @@ "interval": 30, "match": {}, "minServers": 0, - "path": "/B/", + "path": "/", "pickHostNameFromBackendHttpSettings": false, "protocol": "Http", "timeout": 30, @@ -174,24 +223,28 @@ "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/urlPathMaps/url-e1903c8aa3446b7b3207aec6d6ecba8a", "name": "url-e1903c8aa3446b7b3207aec6d6ecba8a", "properties": { - "defaultBackendAddressPool": {}, - "defaultBackendHttpSettings": {}, + "defaultBackendAddressPool": { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-b-80-bp-80" + }, + "defaultBackendHttpSettings": { + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-b-80-80---name--" + }, "pathRules": [ { - "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/urlPathMaps/url-e1903c8aa3446b7b3207aec6d6ecba8a/pathRules/pr---namespace-----name---0", - "name": "pr---namespace-----name---0", + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/urlPathMaps/url-e1903c8aa3446b7b3207aec6d6ecba8a/pathRules/pr---namespace-----name---1", + "name": "pr---namespace-----name---1", "properties": { "backendAddressPool": { - "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-b-80-bp-80" + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-a-80-bp-80" }, "backendHttpSettings": { - "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-b-80-80---name--" + "id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-a-80-80---name--" }, "firewallPolicy": { "id": "/some/policy/here" }, "paths": [ - "/B/" + "/A" ] } } diff --git a/pkg/appgw/ingress_rules.go b/pkg/appgw/ingress_rules.go index 36d218e57..065cac936 100644 --- a/pkg/appgw/ingress_rules.go +++ b/pkg/appgw/ingress_rules.go @@ -51,13 +51,12 @@ func (c *appGwConfigBuilder) getListenersFromIngress(ingress *v1beta1.Ingress, e func (c *appGwConfigBuilder) applyToListener(rule *v1beta1.IngressRule) bool { for pathIdx := range rule.HTTP.Paths { path := &rule.HTTP.Paths[pathIdx] - // if path is specified, apply waf policy to the pathRule, otherwise apply to a listener, listener is per ingress host - if len(path.Path) != 0 && path.Path != "/" && path.Path != "/*" { - // apply to path rule instead of listener - return false + // if there is path that is /, /* , empty string, then apply the waf policy to the listener. + if len(path.Path) == 0 || path.Path == "/" || path.Path == "/*" { + return true } } - return true + return false } func (c *appGwConfigBuilder) processIngressRuleWithTLS(rule *v1beta1.IngressRule, ingress *v1beta1.Ingress, env environment.EnvVariables) (map[Port]interface{}, map[listenerIdentifier]listenerAzConfig) { diff --git a/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/ssl-e2e-redirect/app.yaml b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/ssl-e2e-redirect/app.yaml index a5c287cb3..2a28120b5 100644 --- a/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/ssl-e2e-redirect/app.yaml +++ b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/ssl-e2e-redirect/app.yaml @@ -70,12 +70,10 @@ metadata: appgw.ingress.kubernetes.io/ssl-redirect: "true" appgw.ingress.kubernetes.io/backend-hostname: "test" appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "test" + appgw.ingress.kubernetes.io/waf-policy-for-path : "/subscriptions/2ce9a29e-219e-422b-b9f8-5c5e54d5439e/resourceGroups/agic-e2e/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/waf-policy" spec: tls: - secretName: testsecret-tls - backend: - serviceName: ssl-redirect-service - servicePort: 443 rules: - http: paths: @@ -83,6 +81,10 @@ spec: backend: serviceName: ssl-redirect-service servicePort: 443 + - path: /* + backend: + serviceName: ssl-redirect-service + servicePort: 443 --- apiVersion: v1 kind: Secret