-
Notifications
You must be signed in to change notification settings - Fork 39.3k
/
ingress.go
199 lines (165 loc) · 6.29 KB
/
ingress.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e
import (
"fmt"
"path/filepath"
"time"
"k8s.io/kubernetes/test/e2e/framework"
. "github.com/onsi/ginkgo"
)
const (
// parent path to yaml test manifests.
ingressManifestPath = "test/e2e/testing-manifests/ingress"
// timeout on a single http request.
reqTimeout = 10 * time.Second
// healthz port used to verify glbc restarted correctly on the master.
glbcHealthzPort = 8086
// On average it takes ~6 minutes for a single backend to come online in GCE.
lbPollTimeout = 15 * time.Minute
// General cloud resource poll timeout (eg: create static ip, firewall etc)
cloudResourcePollTimeout = 5 * time.Minute
// Time required by the loadbalancer to cleanup, proportional to numApps/Ing.
lbCleanupTimeout = 5 * time.Minute
lbPollInterval = 30 * time.Second
// Name of the config-map and key the ingress controller stores its uid in.
uidConfigMap = "ingress-uid"
uidKey = "uid"
// GCE only allows names < 64 characters, and the loadbalancer controller inserts
// a single character of padding.
nameLenLimit = 62
)
var _ = framework.KubeDescribe("Loadbalancing: L7 [Feature:Ingress]", func() {
defer GinkgoRecover()
var (
ns string
jig *testJig
conformanceTests []conformanceTests
)
f := framework.NewDefaultFramework("ingress")
BeforeEach(func() {
f.BeforeEach()
jig = newTestJig(f.Client)
ns = f.Namespace.Name
})
// Before enabling this loadbalancer test in any other test list you must
// make sure the associated project has enough quota. At the time of this
// writing a GCE project is allowed 3 backend services by default. This
// test requires at least 5.
//
// Slow by design ~10m for each "It" block dominated by loadbalancer setup time
// TODO: write similar tests for nginx, haproxy and AWS Ingress.
framework.KubeDescribe("GCE [Slow] [Feature: Ingress]", func() {
var gceController *GCEIngressController
// Platform specific setup
BeforeEach(func() {
framework.SkipUnlessProviderIs("gce", "gke")
By("Initializing gce controller")
gceController = &GCEIngressController{
ns: ns,
c: jig.client,
cloud: framework.TestContext.CloudConfig,
}
gceController.init()
})
// Platform specific cleanup
AfterEach(func() {
if CurrentGinkgoTestDescription().Failed {
describeIng(ns)
}
if jig.ing == nil {
By("No ingress created, no cleanup necessary")
return
}
By("Deleting ingress")
jig.deleteIngress()
By("Cleaning up cloud resources")
cleanupGCE(gceController)
})
It("should conform to Ingress spec", func() {
conformanceTests = createComformanceTests(jig, ns)
for _, t := range conformanceTests {
By(t.entryLog)
t.execute()
By(t.exitLog)
jig.waitForIngress()
}
})
It("shoud create ingress with given static-ip ", func() {
ip := gceController.staticIP(ns)
By(fmt.Sprintf("allocated static ip %v: %v through the GCE cloud provider", ns, ip))
jig.createIngress(filepath.Join(ingressManifestPath, "static-ip"), ns, map[string]string{
"kubernetes.io/ingress.global-static-ip-name": ns,
"kubernetes.io/ingress.allow-http": "false",
})
By("waiting for Ingress to come up with ip: " + ip)
httpClient := buildInsecureClient(reqTimeout)
ExpectNoError(pollURL(fmt.Sprintf("https://%v/", ip), "", lbPollTimeout, httpClient, false))
By("should reject HTTP traffic")
ExpectNoError(pollURL(fmt.Sprintf("http://%v/", ip), "", lbPollTimeout, httpClient, true))
// TODO: uncomment the restart test once we have a way to synchronize
// and know that the controller has resumed watching. If we delete
// the ingress before the controller is ready we will leak.
// By("restaring glbc")
// restarter := NewRestartConfig(
// framework.GetMasterHost(), "glbc", glbcHealthzPort, restartPollInterval, restartTimeout)
// restarter.restart()
// By("should continue serving on provided static-ip for 30 seconds")
// ExpectNoError(jig.verifyURL(fmt.Sprintf("https://%v/", ip), "", 30, 1*time.Second, httpClient))
})
// TODO: Implement a multizone e2e that verifies traffic reaches each
// zone based on pod labels.
})
// Time: borderline 5m, slow by design
framework.KubeDescribe("Nginx [Slow] [Feature: Ingress]", func() {
var nginxController *NginxIngressController
BeforeEach(func() {
framework.SkipUnlessProviderIs("gce", "gke")
By("Initializing nginx controller")
jig.class = "nginx"
nginxController = &NginxIngressController{ns: ns, c: jig.client}
// TODO: This test may fail on other platforms. We can simply skip it
// but we want to allow easy testing where a user might've hand
// configured firewalls.
if framework.ProviderIs("gce", "gke") {
ExpectNoError(gcloudCreate("firewall-rules", fmt.Sprintf("ingress-80-443-%v", ns), framework.TestContext.CloudConfig.ProjectID, "--allow", "tcp:80,tcp:443", "--network", framework.TestContext.CloudConfig.Network))
} else {
framework.Logf("WARNING: Not running on GCE/GKE, cannot create firewall rules for :80, :443. Assuming traffic can reach the external ips of all nodes in cluster on those ports.")
}
nginxController.init()
})
AfterEach(func() {
if framework.ProviderIs("gce", "gke") {
ExpectNoError(gcloudDelete("firewall-rules", fmt.Sprintf("ingress-80-443-%v", ns), framework.TestContext.CloudConfig.ProjectID))
}
if CurrentGinkgoTestDescription().Failed {
describeIng(ns)
}
if jig.ing == nil {
By("No ingress created, no cleanup necessary")
return
}
By("Deleting ingress")
jig.deleteIngress()
})
It("should conform to Ingress spec", func() {
conformanceTests = createComformanceTests(jig, ns)
for _, t := range conformanceTests {
By(t.entryLog)
t.execute()
By(t.exitLog)
jig.waitForIngress()
}
})
})
})