Skip to content

Commit 0a4f032

Browse files
akshaysnguptacmendibleShuanglu
authored
Merge master into release/1.5 (#1349)
* fixed subscriptionId description (#1345) * k8s: Add retry logic to get server version (#1344) * add retry logic to get server version * add output of server version Co-authored-by: Akshay Gupta <[email protected]> * networking/v1: add support for ingress path type (#1346) * add support for ingress path type * add test for / * fix: don't initialize ingress class when k8s doesn't support v1/ingress (#1347) * fix: panic when ingress class is not supported on k8s * add test * docs: add changelog 1.5 (#1348) * add changelog 1.5 * add retry fix * fix reference Co-authored-by: Carlos Mendible <[email protected]> Co-authored-by: Shuanglu <[email protected]>
1 parent cba7004 commit 0a4f032

File tree

12 files changed

+666
-20
lines changed

12 files changed

+666
-20
lines changed

CHANGELOG/CHANGELOG-1.5.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
- [How to try](#how-to-try)
2+
- [v1.5.1](#v151)
3+
- [Features](#features)
4+
- [Fixes](#fixes)
5+
- [v1.5.0](#v150)
6+
- [Features](#features-1)
7+
- [Fixes](#fixes-1)
8+
- [v1.5.0-rc1](#v150-rc1)
9+
- [Features](#features-2)
10+
- [Fixes](#fixes-2)
11+
12+
# v1.5.1
13+
14+
## Features
15+
* [[#1122](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1346) Add support for ingress.rules.path.pathType property
16+
17+
## Fixes
18+
* [#1347](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1347) fix(v1/ingress): fix panic due to ingress class when k8s <= 1.19
19+
* [#1344](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1344) fix(v1/ingress): retry getting server version to get past transient issues
20+
21+
# v1.5.0
22+
23+
## Features
24+
* [#1329](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1329) Support for ingress class resource in v1/ingress
25+
* [#1280](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1280) Add cookie-based-affinity-distinct-name annotation
26+
* [#1287](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1287) Add rewrite rule set annotation to reference an existing rewrite rule on Application Gateway
27+
28+
## Fixes
29+
* [#1322](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1322) fix(port): port reference by name in ingress
30+
31+
# v1.5.0-rc1
32+
33+
## Features
34+
* [#1197](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1197) Support for v1/ingress (maintaining compatibility with v1beta1/ingress for clsuters <= 1.22)
35+
* [#1324](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1324) Support for multi-arch images: amd64/arm64
36+
* [#1169](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1169) Resource quota exposed through helm chart
37+
> Note:
38+
> * Support for ingress class resource will added in a future release
39+
> * Support for ingress.rules.path.pathType property will added in a future release
40+
41+
## Fixes
42+
* [#1282](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1282) fix(ingress): Modify cloned ingress instead of original ingress
43+
* [#1271](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1271) fix(private clouds): Use correct endpoints for AAD and Azure in private clouds
44+
* [#1273](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1273) fix(config): panic when processing duplicate paths in urlpathmap
45+
* [#1220](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1220) fix(crd): Upgrade prohibited target CRD api-version and add tests
46+
* [#1278](https://github.com/Azure/application-gateway-kubernetes-ingress/pull/1278) fix(prohibited target): incorrect merge when rules being merged reference the same path map
47+
48+
## How to try:
49+
```bash
50+
# Add helm repo / update AGIC repo
51+
helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
52+
helm repo update
53+
54+
# Install
55+
helm install \
56+
<release-name> \
57+
-f helm-config.yaml \
58+
application-gateway-kubernetes-ingress/ingress-azure \
59+
60+
# or
61+
62+
# Upgrade
63+
# https://github.com/Azure/application-gateway-kubernetes-ingress/blob/master/docs/how-tos/helm-upgrade.md
64+
# --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored
65+
helm upgrade \
66+
<release-name> \
67+
application-gateway-kubernetes-ingress/ingress-azure \
68+
--reuse-values
69+
```

docs/developers/build.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ The file will contain a JSON blob with the following shape:
3333
{
3434
"clientId": "...",
3535
"clientSecret": "...",
36-
"subscriptionId": "<your-azure-resource-group>",
36+
"subscriptionId": "<your-azure-subscription-id>",
3737
"tenantId": "...",
3838
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
3939
"resourceManagerEndpointUrl": "https://management.azure.com/",

pkg/appgw/configbuilder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ func generateListenerID(ingress *networking.Ingress, rule *networking.IngressRul
217217
if overridePort != nil {
218218
if *overridePort > 0 && *overridePort < 65000 {
219219
frontendPort = *overridePort
220+
klog.V(5).Infof("Using custom port specified in the override annotation: %d", *overridePort)
220221
} else {
221-
klog.V(5).Infof("Invalid custom port configuration (%d). Setting listener port to default : %d", *overridePort, frontendPort)
222+
klog.V(5).Infof("Derived listener port from ingress: %d", frontendPort)
222223
}
223224

224225
}

pkg/appgw/ingress_rules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (c *appGwConfigBuilder) applyToListener(rule *networking.IngressRule) bool
5252
for pathIdx := range rule.HTTP.Paths {
5353
path := &rule.HTTP.Paths[pathIdx]
5454
// if there is path that is /, /* , empty string, then apply the waf policy to the listener.
55-
if len(path.Path) == 0 || path.Path == "/" || path.Path == "/*" {
55+
if isPathCatchAll(path.Path, path.PathType) {
5656
return true
5757
}
5858
}

pkg/appgw/requestroutingrules.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func (c *appGwConfigBuilder) getDefaultFromRule(cbCtx *ConfigBuilderContext, lis
269269
defBackend := ingress.Spec.DefaultBackend
270270
for pathIdx := range rule.HTTP.Paths {
271271
path := &rule.HTTP.Paths[pathIdx]
272-
if path.Path == "" || path.Path == "/*" || path.Path == "/" {
272+
if isPathCatchAll(path.Path, path.PathType) {
273273
defBackend = &path.Backend
274274
defPath = path
275275
defRule = rule
@@ -303,7 +303,7 @@ func (c *appGwConfigBuilder) getPathRules(cbCtx *ConfigBuilderContext, listenerI
303303
pathRules := make([]n.ApplicationGatewayPathRule, 0)
304304
for pathIdx := range rule.HTTP.Paths {
305305
path := &rule.HTTP.Paths[pathIdx]
306-
if len(path.Path) == 0 || path.Path == "/*" || path.Path == "/" {
306+
if isPathCatchAll(path.Path, path.PathType) {
307307
continue
308308
}
309309

@@ -314,7 +314,7 @@ func (c *appGwConfigBuilder) getPathRules(cbCtx *ConfigBuilderContext, listenerI
314314
Name: to.StringPtr(pathRuleName),
315315
ID: to.StringPtr(c.appGwIdentifier.pathRuleID(pathMapName, pathRuleName)),
316316
ApplicationGatewayPathRulePropertiesFormat: &n.ApplicationGatewayPathRulePropertiesFormat{
317-
Paths: &[]string{path.Path},
317+
Paths: &[]string{preparePathFromPathType(path.Path, path.PathType)},
318318
},
319319
}
320320

@@ -439,3 +439,27 @@ func printPathRule(pathRule n.ApplicationGatewayPathRule) string {
439439

440440
return s
441441
}
442+
443+
// preparePathFromPathType uses pathType property to modify ingress.Path to append/remove "*"
444+
// if pathType == Prefix, "*" is appended if not provided by the user
445+
// if pathType == Exact, "*" is trimmed
446+
func preparePathFromPathType(path string, pathType *networking.PathType) string {
447+
if pathType != nil {
448+
if *pathType == networking.PathTypeExact {
449+
return strings.TrimSuffix(path, "*")
450+
}
451+
452+
if *pathType == networking.PathTypePrefix && !strings.HasSuffix(path, "*") {
453+
return path + "*"
454+
}
455+
}
456+
return path
457+
}
458+
459+
// Application Gateway doesn't allow exact path for "/"
460+
// Code="ApplicationGatewayPathRulePathShouldHaveNonEmptyMatchValue" Message="Path / should have a nonempty match value followed by '/' in PathRule xxxx
461+
// So, Path "/" with pathType:Exact cannot be added into the path rule. Thus, we don't support it.
462+
// "/" for any path type will be treated as a prefix match.
463+
func isPathCatchAll(path string, pathType *networking.PathType) bool {
464+
return len(path) == 0 || path == "/*" || path == "/"
465+
}

pkg/appgw/requestroutingrules_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,4 +937,121 @@ var _ = Describe("Test routing rules generations", func() {
937937
})
938938

939939
})
940+
941+
Context("test pathType in ingress", func() {
942+
configBuilder := newConfigBuilderFixture(nil)
943+
endpoint := tests.NewEndpointsFixture()
944+
service := tests.NewServiceFixture(*tests.NewServicePortsFixture()...)
945+
ingress := tests.NewIngressTestWithVariousPathTypeFixture(tests.Namespace, "ingress-with-path-type")
946+
947+
_ = configBuilder.k8sContext.Caches.Endpoints.Add(endpoint)
948+
_ = configBuilder.k8sContext.Caches.Service.Add(service)
949+
_ = configBuilder.k8sContext.Caches.Ingress.Add(ingress)
950+
951+
cbCtx := &ConfigBuilderContext{
952+
IngressList: []*networking.Ingress{&ingress},
953+
ServiceList: []*v1.Service{service},
954+
DefaultAddressPoolID: to.StringPtr("xx"),
955+
DefaultHTTPSettingsID: to.StringPtr("yy"),
956+
}
957+
958+
_, urlPathMaps := configBuilder.getRules(cbCtx)
959+
urlPathMap := urlPathMaps[0]
960+
pathRules := *urlPathMaps[0].PathRules
961+
962+
It("should have 8 paths", func() {
963+
Expect(len(pathRules)).To(Equal(8))
964+
})
965+
966+
It("should add * to paths with pathType:prefix", func() {
967+
paths := *(pathRules[0].Paths)
968+
Expect(paths[0]).To(Equal("/prefix0*"))
969+
970+
paths = *(pathRules[1].Paths)
971+
Expect(paths[0]).To(Equal("/prefix1*"))
972+
})
973+
974+
It("should trim * from paths with pathType:exact", func() {
975+
paths := *(pathRules[2].Paths)
976+
Expect(paths[0]).To(Equal("/exact2"))
977+
978+
paths = *(pathRules[3].Paths)
979+
Expect(paths[0]).To(Equal("/exact3"))
980+
})
981+
982+
It("should not modify paths with pathType:implementationSpecific", func() {
983+
paths := *(pathRules[4].Paths)
984+
Expect(paths[0]).To(Equal("/ims4*"))
985+
986+
paths = *(pathRules[5].Paths)
987+
Expect(paths[0]).To(Equal("/ims5"))
988+
})
989+
990+
It("should not modify paths with pathType:nil", func() {
991+
paths := *(pathRules[6].Paths)
992+
Expect(paths[0]).To(Equal("/nil6*"))
993+
994+
paths = *(pathRules[7].Paths)
995+
Expect(paths[0]).To(Equal("/nil7"))
996+
})
997+
998+
It("should have default matching /*", func() {
999+
Expect(*urlPathMap.DefaultBackendAddressPool.ID).To(HaveSuffix("pool---namespace-----service-name---80-bp-9876"))
1000+
Expect(*urlPathMap.DefaultBackendHTTPSettings.ID).To(HaveSuffix("bp---namespace-----service-name---80-9876-ingress-with-path-type"))
1001+
})
1002+
})
1003+
1004+
Context("test preparePathFromPathType", func() {
1005+
It("should append * when pathType is Prefix", func() {
1006+
pathType := networking.PathTypePrefix
1007+
1008+
Expect(preparePathFromPathType("/path", &pathType)).To(Equal("/path*"))
1009+
Expect(preparePathFromPathType("/path*", &pathType)).To(Equal("/path*"))
1010+
})
1011+
1012+
It("should trim when pathType is Exact", func() {
1013+
pathType := networking.PathTypeExact
1014+
1015+
Expect(preparePathFromPathType("/path", &pathType)).To(Equal("/path"))
1016+
Expect(preparePathFromPathType("/path*", &pathType)).To(Equal("/path"))
1017+
})
1018+
1019+
It("should not modify when pathType is ImplementationSpecific", func() {
1020+
pathType := networking.PathTypeImplementationSpecific
1021+
1022+
Expect(preparePathFromPathType("/path", &pathType)).To(Equal("/path"))
1023+
Expect(preparePathFromPathType("/path*", &pathType)).To(Equal("/path*"))
1024+
})
1025+
1026+
It("should not modify when pathType is nil", func() {
1027+
Expect(preparePathFromPathType("/path", nil)).To(Equal("/path"))
1028+
Expect(preparePathFromPathType("/path*", nil)).To(Equal("/path*"))
1029+
})
1030+
})
1031+
1032+
Context("test isPathCatchAll", func() {
1033+
// Application Gateway doesn't allow exact path for "/"
1034+
It("should be false if / and pathType:exact", func() {
1035+
pathTypeExact := networking.PathTypeExact
1036+
Expect(isPathCatchAll("/", &pathTypeExact)).To(BeTrue())
1037+
Expect(isPathCatchAll("/*", &pathTypeExact)).To(BeTrue())
1038+
})
1039+
1040+
It("should be true if / and pathType:nil", func() {
1041+
Expect(isPathCatchAll("/", nil)).To(BeTrue())
1042+
Expect(isPathCatchAll("/*", nil)).To(BeTrue())
1043+
})
1044+
1045+
It("should be true if / and pathType:prefix", func() {
1046+
pathTypePrefix := networking.PathTypePrefix
1047+
Expect(isPathCatchAll("/", &pathTypePrefix)).To(BeTrue())
1048+
Expect(isPathCatchAll("/*", &pathTypePrefix)).To(BeTrue())
1049+
})
1050+
1051+
It("should be true if / and pathType:implementationSpecific", func() {
1052+
pathTypeIMS := networking.PathTypeImplementationSpecific
1053+
Expect(isPathCatchAll("/", &pathTypeIMS)).To(BeTrue())
1054+
Expect(isPathCatchAll("/*", &pathTypeIMS)).To(BeTrue())
1055+
})
1056+
})
9401057
})

pkg/k8scontext/context.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,13 @@ func NewContext(kubeClient kubernetes.Interface, crdClient versioned.Interface,
7676

7777
if IsNetworkingV1PackageSupported {
7878
informerCollection.Ingress = informerFactory.Networking().V1().Ingresses().Informer()
79-
informerCollection.IngressClass = informerFactory.Networking().V1().IngressClasses().Informer()
8079
} else {
8180
informerCollection.Ingress = informerFactory.Extensions().V1beta1().Ingresses().Informer()
8281
}
8382

8483
cacheCollection := CacheCollection{
8584
Endpoints: informerCollection.Endpoints.GetStore(),
8685
Ingress: informerCollection.Ingress.GetStore(),
87-
IngressClass: informerCollection.IngressClass.GetStore(),
8886
Pods: informerCollection.Pods.GetStore(),
8987
Secret: informerCollection.Secret.GetStore(),
9088
Service: informerCollection.Service.GetStore(),
@@ -146,7 +144,6 @@ func NewContext(kubeClient kubernetes.Interface, crdClient versioned.Interface,
146144
// Register event handlers.
147145
informerCollection.Endpoints.AddEventHandler(resourceHandler)
148146
informerCollection.Ingress.AddEventHandler(ingressResourceHandler)
149-
informerCollection.IngressClass.AddEventHandler(resourceHandler)
150147
informerCollection.Pods.AddEventHandler(resourceHandler)
151148
informerCollection.Secret.AddEventHandler(secretResourceHandler)
152149
informerCollection.Service.AddEventHandler(resourceHandler)
@@ -156,6 +153,12 @@ func NewContext(kubeClient kubernetes.Interface, crdClient versioned.Interface,
156153
informerCollection.MultiClusterService.AddEventHandler(resourceHandler)
157154
informerCollection.MultiClusterIngress.AddEventHandler(resourceHandler)
158155

156+
if IsNetworkingV1PackageSupported {
157+
informerCollection.IngressClass = informerFactory.Networking().V1().IngressClasses().Informer()
158+
informerCollection.IngressClass.AddEventHandler(resourceHandler)
159+
cacheCollection.IngressClass = informerCollection.IngressClass.GetStore()
160+
}
161+
159162
return context
160163
}
161164

@@ -188,13 +191,16 @@ func (c *Context) Run(stopChannel chan struct{}, omitCRDs bool, envVariables env
188191
c.informers.Service,
189192
c.informers.Secret,
190193
c.informers.Ingress,
191-
c.informers.IngressClass,
192194

193195
//TODO: enabled by ccp feature flag
194196
// c.informers.AzureApplicationGatewayBackendPool,
195197
// c.informers.AzureApplicationGatewayInstanceUpdateStatus,
196198
}
197199

200+
if IsNetworkingV1PackageSupported {
201+
sharedInformers = append(sharedInformers, c.informers.IngressClass)
202+
}
203+
198204
// For AGIC to watch for these CRDs the EnableBrownfieldDeploymentVarName env variable must be set to true
199205
if envVariables.EnableBrownfieldDeployment {
200206
sharedInformers = append(sharedInformers, c.informers.AzureIngressProhibitedTarget)
@@ -870,6 +876,10 @@ func (c *Context) isServiceReferencedByAnyIngress(service *v1.Service) bool {
870876

871877
// getIngressClassResource gets ingress class object with specified name
872878
func (c *Context) getIngressClassResource(ingressClassName string) *networking.IngressClass {
879+
if c.Caches.IngressClass == nil {
880+
return nil
881+
}
882+
873883
ingressClassInterface, exist, err := c.Caches.IngressClass.GetByKey(ingressClassName)
874884
if err != nil {
875885
return nil

0 commit comments

Comments
 (0)