Skip to content

Commit ae07003

Browse files
Relax frontend config validation and prune public ingress when public IP is not present (#1503)
* relax validation and prune public ingresses when no public IP * default logic
1 parent 732d8ae commit ae07003

21 files changed

+515
-211
lines changed

.vscode/launch.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Run Unit Test in File",
6+
"type": "go",
7+
"mode": "test",
8+
"program": "${fileDirname}",
9+
"buildFlags": "-tags 'unittest'",
10+
}
11+
]
12+
}

cmd/appgw-ingress/main.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,12 @@ func main() {
188188

189189
// fatal config validations
190190
appGw, _ := azClient.GetGateway()
191-
if err := appgw.FatalValidateOnExistingConfig(recorder, appGw.ApplicationGatewayPropertiesFormat, env); err != nil {
192-
klog.Fatal("Got a fatal validation error on existing Application Gateway config. Please update Application Gateway or the controller's helm config. Error:", err)
193-
}
194-
195191
if _, exists := allowedSkus[appGw.Sku.Tier]; !exists {
196192
errorLine := fmt.Sprintf("App Gateway SKU Tier %s is not supported by AGIC version %s; (v0.10.0 supports App Gwy v1)", appGw.Sku.Tier, appgw.GetVersion())
197193
if agicPod != nil {
198194
recorder.Event(agicPod, v1.EventTypeWarning, events.UnsupportedAppGatewaySKUTier, errorLine)
199195
}
196+
200197
// Slow down the cycling of the AGIC pod.
201198
time.Sleep(5 * time.Second)
202199
klog.Fatal(errorLine)

functional_tests/functional_test.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ func TestFunctional(t *testing.T) {
5050
ginkgo.RunSpecs(t, "Appgw Suite")
5151
}
5252

53-
var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() {
53+
var _ = ginkgo.Describe("Functional Tests", func() {
5454
var stopChannel chan struct{}
5555
var ctxt *k8scontext.Context
56+
var appGwy *n.ApplicationGateway
5657
var configBuilder ConfigBuilder
5758

5859
version.Version = "a"
@@ -537,7 +538,7 @@ var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() {
537538
_ = ctxt.CertificateSecretStore.ConvertSecret(secKey, ingressSecret)
538539
_ = ctxt.CertificateSecretStore.GetPfxCertificate(secKey)
539540

540-
appGwy := &n.ApplicationGateway{
541+
appGwy = &n.ApplicationGateway{
541542
ApplicationGatewayPropertiesFormat: NewAppGwyConfigFixture(),
542543
}
543544

@@ -1182,5 +1183,35 @@ var _ = ginkgo.Describe("Tests `appgw.ConfigBuilder`", func() {
11821183
check(cbCtx, "rewrite_rule_sets_path-based_rules_without_default_backend.json", stopChannel, ctxt, configBuilder)
11831184
})
11841185

1186+
ginkgo.It("Application Gateway has private IP only; Should use private IP for all rules", func() {
1187+
appGwy.FrontendIPConfigurations = &[]n.ApplicationGatewayFrontendIPConfiguration{
1188+
{
1189+
// Private IP
1190+
Name: to.StringPtr("yy3"),
1191+
Etag: to.StringPtr("yy2"),
1192+
Type: to.StringPtr("yy1"),
1193+
ID: to.StringPtr(tests.PrivateIPID),
1194+
ApplicationGatewayFrontendIPConfigurationPropertiesFormat: &n.ApplicationGatewayFrontendIPConfigurationPropertiesFormat{
1195+
PrivateIPAddress: to.StringPtr("abc"),
1196+
PublicIPAddress: nil,
1197+
},
1198+
},
1199+
}
1200+
1201+
configBuilder = NewConfigBuilder(ctxt, &appGwIdentifier, appGwy, record.NewFakeRecorder(100), mocks.Clock{})
1202+
1203+
privateingress := newIngress()
1204+
privateingress.Annotations[annotations.UsePrivateIPKey] = "true"
1205+
cbCtx := &ConfigBuilderContext{
1206+
IngressList: []*networking.Ingress{
1207+
privateingress,
1208+
},
1209+
ServiceList: serviceList,
1210+
EnvVariables: environment.GetFakeEnv(),
1211+
DefaultAddressPoolID: to.StringPtr("xx"),
1212+
DefaultHTTPSettingsID: to.StringPtr("yy"),
1213+
}
1214+
check(cbCtx, "private-ip-only-gateway.json", stopChannel, ctxt, configBuilder)
1215+
})
11851216
})
11861217
})

functional_tests/helpers.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"encoding/json"
1010
"fmt"
1111
"io/ioutil"
12+
"os"
1213
"strings"
1314

1415
"github.com/onsi/gomega"
@@ -47,7 +48,9 @@ func check(cbCtx *appgw.ConfigBuilderContext, expectedFilename string, stopChan
4748
actualJSONTxt := string(jsonBlob)
4849

4950
// Repair tests
50-
// ioutil.WriteFile(expectedFilename, []byte(actualJSONTxt), 0644)
51+
if os.Getenv("RENDER_SNAPSHOTS") != "" {
52+
ioutil.WriteFile(expectedFilename, []byte(actualJSONTxt), 0644)
53+
}
5154

5255
expectedBytes, err := ioutil.ReadFile(expectedFilename)
5356
expectedJSON := strings.Trim(string(expectedBytes), "\n")
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
{
2+
"properties": {
3+
"backendAddressPools": [
4+
{
5+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/defaultaddresspool",
6+
"name": "defaultaddresspool",
7+
"properties": {
8+
"backendAddresses": []
9+
}
10+
},
11+
{
12+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-80-bp-80",
13+
"name": "pool---namespace---hello-world-80-bp-80",
14+
"properties": {
15+
"backendAddresses": [
16+
{
17+
"ipAddress": "1.1.1.1"
18+
},
19+
{
20+
"ipAddress": "1.1.1.2"
21+
},
22+
{
23+
"ipAddress": "1.1.1.3"
24+
}
25+
]
26+
}
27+
}
28+
],
29+
"backendHttpSettingsCollection": [
30+
{
31+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-80-80---name--",
32+
"name": "bp---namespace---hello-world-80-80---name--",
33+
"properties": {
34+
"cookieBasedAffinity": "Disabled",
35+
"pickHostNameFromBackendAddress": false,
36+
"port": 80,
37+
"probe": {
38+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/pb---namespace---hello-world-80---name--"
39+
},
40+
"protocol": "Http",
41+
"requestTimeout": 30
42+
}
43+
},
44+
{
45+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/defaulthttpsetting",
46+
"name": "defaulthttpsetting",
47+
"properties": {
48+
"cookieBasedAffinity": "Disabled",
49+
"pickHostNameFromBackendAddress": false,
50+
"port": 80,
51+
"probe": {
52+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/defaultprobe-Http"
53+
},
54+
"protocol": "Http",
55+
"requestTimeout": 30
56+
}
57+
}
58+
],
59+
"frontendIPConfigurations": [
60+
{
61+
"id": "--front-end-ip-id-2--",
62+
"name": "yy3",
63+
"properties": {
64+
"privateIPAddress": "abc"
65+
}
66+
}
67+
],
68+
"frontendPorts": [
69+
{
70+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/frontendPorts/fp-443",
71+
"name": "fp-443",
72+
"properties": {
73+
"port": 443
74+
}
75+
},
76+
{
77+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/frontendPorts/fp-80",
78+
"name": "fp-80",
79+
"properties": {
80+
"port": 80
81+
}
82+
}
83+
],
84+
"httpListeners": [
85+
{
86+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-99e28aff3b2f87fe177626b33f1d8d7c",
87+
"name": "fl-99e28aff3b2f87fe177626b33f1d8d7c",
88+
"properties": {
89+
"frontendIPConfiguration": {
90+
"id": "--front-end-ip-id-2--"
91+
},
92+
"frontendPort": {
93+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/frontendPorts/fp-80"
94+
},
95+
"hostNames": [
96+
"foo.baz"
97+
],
98+
"protocol": "Http",
99+
"requireServerNameIndication": false
100+
}
101+
},
102+
{
103+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-fafc599c553da3501d29a7eb806da9c2",
104+
"name": "fl-fafc599c553da3501d29a7eb806da9c2",
105+
"properties": {
106+
"frontendIPConfiguration": {
107+
"id": "--front-end-ip-id-2--"
108+
},
109+
"frontendPort": {
110+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/frontendPorts/fp-443"
111+
},
112+
"hostNames": [
113+
"foo.baz"
114+
],
115+
"protocol": "Https",
116+
"requireServerNameIndication": false,
117+
"sslCertificate": {
118+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/sslCertificates/cert---namespace-----the-name-of-the-secret--"
119+
}
120+
}
121+
}
122+
],
123+
"probes": [
124+
{
125+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/defaultprobe-Http",
126+
"name": "defaultprobe-Http",
127+
"properties": {
128+
"host": "localhost",
129+
"interval": 30,
130+
"match": {},
131+
"minServers": 0,
132+
"path": "/",
133+
"pickHostNameFromBackendHttpSettings": false,
134+
"protocol": "Http",
135+
"timeout": 30,
136+
"unhealthyThreshold": 3
137+
}
138+
},
139+
{
140+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/defaultprobe-Https",
141+
"name": "defaultprobe-Https",
142+
"properties": {
143+
"host": "localhost",
144+
"interval": 30,
145+
"match": {},
146+
"minServers": 0,
147+
"path": "/",
148+
"pickHostNameFromBackendHttpSettings": false,
149+
"protocol": "Https",
150+
"timeout": 30,
151+
"unhealthyThreshold": 3
152+
}
153+
},
154+
{
155+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/probes/pb---namespace---hello-world-80---name--",
156+
"name": "pb---namespace---hello-world-80---name--",
157+
"properties": {
158+
"host": "foo.baz",
159+
"interval": 30,
160+
"match": {},
161+
"minServers": 0,
162+
"path": "/",
163+
"pickHostNameFromBackendHttpSettings": false,
164+
"protocol": "Http",
165+
"timeout": 30,
166+
"unhealthyThreshold": 3
167+
}
168+
}
169+
],
170+
"redirectConfigurations": [
171+
{
172+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/redirectConfigurations/sslr-fl-fafc599c553da3501d29a7eb806da9c2",
173+
"name": "sslr-fl-fafc599c553da3501d29a7eb806da9c2",
174+
"properties": {
175+
"includePath": true,
176+
"includeQueryString": true,
177+
"redirectType": "Permanent",
178+
"targetListener": {
179+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-fafc599c553da3501d29a7eb806da9c2"
180+
}
181+
}
182+
}
183+
],
184+
"requestRoutingRules": [
185+
{
186+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/requestRoutingRules/rr-99e28aff3b2f87fe177626b33f1d8d7c",
187+
"name": "rr-99e28aff3b2f87fe177626b33f1d8d7c",
188+
"properties": {
189+
"httpListener": {
190+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-99e28aff3b2f87fe177626b33f1d8d7c"
191+
},
192+
"priority": 19000,
193+
"redirectConfiguration": {
194+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/redirectConfigurations/sslr-fl-fafc599c553da3501d29a7eb806da9c2"
195+
},
196+
"ruleType": "Basic"
197+
}
198+
},
199+
{
200+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/requestRoutingRules/rr-fafc599c553da3501d29a7eb806da9c2",
201+
"name": "rr-fafc599c553da3501d29a7eb806da9c2",
202+
"properties": {
203+
"backendAddressPool": {
204+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendAddressPools/pool---namespace---hello-world-80-bp-80"
205+
},
206+
"backendHttpSettings": {
207+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/backendHttpSettingsCollection/bp---namespace---hello-world-80-80---name--"
208+
},
209+
"httpListener": {
210+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/httpListeners/fl-fafc599c553da3501d29a7eb806da9c2"
211+
},
212+
"priority": 19005,
213+
"ruleType": "Basic"
214+
}
215+
}
216+
],
217+
"rewriteRuleSets": [],
218+
"sku": {
219+
"capacity": 3,
220+
"name": "Standard_v2",
221+
"tier": "Standard_v2"
222+
},
223+
"sslCertificates": [
224+
{
225+
"id": "/subscriptions/--subscription--/resourceGroups/--resource-group--/providers/Microsoft.Network/applicationGateways/--app-gw-name--/sslCertificates/cert---namespace-----the-name-of-the-secret--",
226+
"name": "cert---namespace-----the-name-of-the-secret--",
227+
"properties": {
228+
"data": "xx",
229+
"password": "msazure"
230+
}
231+
}
232+
],
233+
"urlPathMaps": []
234+
},
235+
"tags": {
236+
"ingress-for-aks-cluster-id": "/subscriptions/subid/resourcegroups/aksresgp/providers/Microsoft.ContainerService/managedClusters/aksname",
237+
"managed-by-k8s-ingress": "a/b/c"
238+
}
239+
}

go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ require (
1414
github.com/knative/pkg v0.0.0-20190619032946-d90a9bc97dde
1515
github.com/kylelemons/godebug v1.1.0
1616
github.com/onsi/ginkgo v1.16.4
17-
github.com/onsi/ginkgo/v2 v2.1.6
18-
github.com/onsi/gomega v1.20.1
17+
github.com/onsi/ginkgo/v2 v2.7.0
18+
github.com/onsi/gomega v1.24.1
1919
github.com/prometheus/client_golang v1.7.1
2020
github.com/spf13/pflag v1.0.5
2121
gopkg.in/yaml.v2 v2.4.0
@@ -46,7 +46,7 @@ require (
4646
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
4747
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
4848
github.com/golang/protobuf v1.5.2 // indirect
49-
github.com/google/go-cmp v0.5.8 // indirect
49+
github.com/google/go-cmp v0.5.9 // indirect
5050
github.com/google/gofuzz v1.2.0 // indirect
5151
github.com/google/uuid v1.1.2 // indirect
5252
github.com/googleapis/gnostic v0.4.1 // indirect
@@ -67,11 +67,11 @@ require (
6767
github.com/prometheus/procfs v0.8.0 // indirect
6868
github.com/stretchr/testify v1.7.1 // indirect
6969
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
70-
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b // indirect
70+
golang.org/x/net v0.3.0 // indirect
7171
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
72-
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959 // indirect
73-
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
74-
golang.org/x/text v0.3.7 // indirect
72+
golang.org/x/sys v0.3.0 // indirect
73+
golang.org/x/term v0.3.0 // indirect
74+
golang.org/x/text v0.5.0 // indirect
7575
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
7676
google.golang.org/appengine v1.6.7 // indirect
7777
google.golang.org/protobuf v1.28.0 // indirect

0 commit comments

Comments
 (0)