ingress.go 6.3 KB

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