| 
						
					 | 
					 | 
					@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					limitations under the License.
 | 
					 | 
					 | 
					 | 
					limitations under the License.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					*/
 | 
					 | 
					 | 
					 | 
					*/
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					package e2e
 | 
					 | 
					 | 
					 | 
					package framework
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import (
 | 
					 | 
					 | 
					 | 
					import (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"bytes"
 | 
					 | 
					 | 
					 | 
						"bytes"
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -31,16 +31,12 @@ import (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"math/big"
 | 
					 | 
					 | 
					 | 
						"math/big"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"net"
 | 
					 | 
					 | 
					 | 
						"net"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"net/http"
 | 
					 | 
					 | 
					 | 
						"net/http"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"os"
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"os/exec"
 | 
					 | 
					 | 
					 | 
						"os/exec"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"path/filepath"
 | 
					 | 
					 | 
					 | 
						"path/filepath"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"strconv"
 | 
					 | 
					 | 
					 | 
						"strconv"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"strings"
 | 
					 | 
					 | 
					 | 
						"strings"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"time"
 | 
					 | 
					 | 
					 | 
						"time"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/api"
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/api/v1"
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						compute "google.golang.org/api/compute/v1"
 | 
					 | 
					 | 
					 | 
						compute "google.golang.org/api/compute/v1"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"google.golang.org/api/googleapi"
 | 
					 | 
					 | 
					 | 
						"google.golang.org/api/googleapi"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						apierrs "k8s.io/apimachinery/pkg/api/errors"
 | 
					 | 
					 | 
					 | 
						apierrs "k8s.io/apimachinery/pkg/api/errors"
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -51,11 +47,13 @@ import (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
					 | 
					 | 
					 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
					 | 
					 | 
					 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						utilyaml "k8s.io/apimachinery/pkg/util/yaml"
 | 
					 | 
					 | 
					 | 
						utilyaml "k8s.io/apimachinery/pkg/util/yaml"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/api/v1"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
 | 
					 | 
					 | 
					 | 
						extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
 | 
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
 | 
					 | 
					 | 
					 | 
						gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/pkg/util"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						utilexec "k8s.io/kubernetes/pkg/util/exec"
 | 
					 | 
					 | 
					 | 
						utilexec "k8s.io/kubernetes/pkg/util/exec"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"k8s.io/kubernetes/test/e2e/framework"
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						testutils "k8s.io/kubernetes/test/utils"
 | 
					 | 
					 | 
					 | 
						testutils "k8s.io/kubernetes/test/utils"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						. "github.com/onsi/ginkgo"
 | 
					 | 
					 | 
					 | 
						. "github.com/onsi/ginkgo"
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -80,59 +78,84 @@ const (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Name of the default http backend service
 | 
					 | 
					 | 
					 | 
						// Name of the default http backend service
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						defaultBackendName = "default-http-backend"
 | 
					 | 
					 | 
					 | 
						defaultBackendName = "default-http-backend"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// IP src range from which the GCE L7 performs health checks.
 | 
					 | 
					 | 
					 | 
						// GCEL7SrcRange is the IP src range from which the GCE L7 performs health checks.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						GCEL7SrcRange = "130.211.0.0/22"
 | 
					 | 
					 | 
					 | 
						GCEL7SrcRange = "130.211.0.0/22"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Cloud resources created by the ingress controller older than this
 | 
					 | 
					 | 
					 | 
						// Cloud resources created by the ingress controller older than this
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// are automatically purged to prevent running out of quota.
 | 
					 | 
					 | 
					 | 
						// are automatically purged to prevent running out of quota.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// TODO(37335): write soak tests and bump this up to a week.
 | 
					 | 
					 | 
					 | 
						// TODO(37335): write soak tests and bump this up to a week.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						maxAge = -48 * time.Hour
 | 
					 | 
					 | 
					 | 
						maxAge = -48 * time.Hour
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// IngressManifestPath is the parent path to yaml test manifests.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						IngressManifestPath = "test/e2e/testing-manifests/ingress"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// IngressReqTimeout is the timeout on a single http request.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						IngressReqTimeout = 10 * time.Second
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// healthz port used to verify glbc restarted correctly on the master.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						glbcHealthzPort = 8086
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// General cloud resource poll timeout (eg: create static ip, firewall etc)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						cloudResourcePollTimeout = 5 * time.Minute
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// 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
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					)
 | 
					 | 
					 | 
					 | 
					)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					type testJig struct {
 | 
					 | 
					 | 
					 | 
					// IngressTestJig holds the relevant state and parameters of the ingress test.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						client  clientset.Interface
 | 
					 | 
					 | 
					 | 
					type IngressTestJig struct {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rootCAs map[string][]byte
 | 
					 | 
					 | 
					 | 
						Client  clientset.Interface
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						address string
 | 
					 | 
					 | 
					 | 
						RootCAs map[string][]byte
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ing     *extensions.Ingress
 | 
					 | 
					 | 
					 | 
						Address string
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						Ingress *extensions.Ingress
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// class is the value of the annotation keyed under
 | 
					 | 
					 | 
					 | 
						// class is the value of the annotation keyed under
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// `kubernetes.io/ingress.class`. It's added to all ingresses created by
 | 
					 | 
					 | 
					 | 
						// `kubernetes.io/ingress.class`. It's added to all ingresses created by
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// this jig.
 | 
					 | 
					 | 
					 | 
						// this jig.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						class string
 | 
					 | 
					 | 
					 | 
						Class string
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// The interval used to poll urls
 | 
					 | 
					 | 
					 | 
						// The interval used to poll urls
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pollInterval time.Duration
 | 
					 | 
					 | 
					 | 
						PollInterval time.Duration
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					type conformanceTests struct {
 | 
					 | 
					 | 
					 | 
					// IngressConformanceTests contains a closure with an entry and exit log line.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						entryLog string
 | 
					 | 
					 | 
					 | 
					type IngressConformanceTests struct {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						execute  func()
 | 
					 | 
					 | 
					 | 
						EntryLog string
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						exitLog  string
 | 
					 | 
					 | 
					 | 
						Execute  func()
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						ExitLog  string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func createComformanceTests(jig *testJig, ns string) []conformanceTests {
 | 
					 | 
					 | 
					 | 
					// CreateIngressComformanceTests generates an slice of sequential test cases:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						manifestPath := filepath.Join(ingressManifestPath, "http")
 | 
					 | 
					 | 
					 | 
					// a simple http ingress, ingress with HTTPS, ingress HTTPS with a modified hostname,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// These constants match the manifests used in ingressManifestPath
 | 
					 | 
					 | 
					 | 
					// ingress https with a modified URLMap
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func CreateIngressComformanceTests(jig *IngressTestJig, ns string) []IngressConformanceTests {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						manifestPath := filepath.Join(IngressManifestPath, "http")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// These constants match the manifests used in IngressManifestPath
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tlsHost := "foo.bar.com"
 | 
					 | 
					 | 
					 | 
						tlsHost := "foo.bar.com"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tlsSecretName := "foo"
 | 
					 | 
					 | 
					 | 
						tlsSecretName := "foo"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						updatedTLSHost := "foobar.com"
 | 
					 | 
					 | 
					 | 
						updatedTLSHost := "foobar.com"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						updateURLMapHost := "bar.baz.com"
 | 
					 | 
					 | 
					 | 
						updateURLMapHost := "bar.baz.com"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						updateURLMapPath := "/testurl"
 | 
					 | 
					 | 
					 | 
						updateURLMapPath := "/testurl"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Platform agnostic list of tests that must be satisfied by all controllers
 | 
					 | 
					 | 
					 | 
						// Platform agnostic list of tests that must be satisfied by all controllers
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return []conformanceTests{
 | 
					 | 
					 | 
					 | 
						return []IngressConformanceTests{
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							{
 | 
					 | 
					 | 
					 | 
							{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("should create a basic HTTP ingress"),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("should create a basic HTTP ingress"),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								func() { jig.createIngress(manifestPath, ns, map[string]string{}) },
 | 
					 | 
					 | 
					 | 
								func() { jig.CreateIngress(manifestPath, ns, map[string]string{}) },
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("waiting for urls on basic HTTP ingress"),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("waiting for urls on basic HTTP ingress"),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							},
 | 
					 | 
					 | 
					 | 
							},
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							{
 | 
					 | 
					 | 
					 | 
							{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("should terminate TLS for host %v", tlsHost),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("should terminate TLS for host %v", tlsHost),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								func() { jig.addHTTPS(tlsSecretName, tlsHost) },
 | 
					 | 
					 | 
					 | 
								func() { jig.AddHTTPS(tlsSecretName, tlsHost) },
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("waiting for HTTPS updates to reflect in ingress"),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("waiting for HTTPS updates to reflect in ingress"),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							},
 | 
					 | 
					 | 
					 | 
							},
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							{
 | 
					 | 
					 | 
					 | 
							{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("should update SSL certificate with modified hostname %v", updatedTLSHost),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("should update SSL certificate with modified hostname %v", updatedTLSHost),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								func() {
 | 
					 | 
					 | 
					 | 
								func() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									jig.update(func(ing *extensions.Ingress) {
 | 
					 | 
					 | 
					 | 
									jig.Update(func(ing *extensions.Ingress) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										newRules := []extensions.IngressRule{}
 | 
					 | 
					 | 
					 | 
										newRules := []extensions.IngressRule{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										for _, rule := range ing.Spec.Rules {
 | 
					 | 
					 | 
					 | 
										for _, rule := range ing.Spec.Rules {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if rule.Host != tlsHost {
 | 
					 | 
					 | 
					 | 
											if rule.Host != tlsHost {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -146,7 +169,7 @@ func createComformanceTests(jig *testJig, ns string) []conformanceTests {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										}
 | 
					 | 
					 | 
					 | 
										}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										ing.Spec.Rules = newRules
 | 
					 | 
					 | 
					 | 
										ing.Spec.Rules = newRules
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									})
 | 
					 | 
					 | 
					 | 
									})
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									jig.addHTTPS(tlsSecretName, updatedTLSHost)
 | 
					 | 
					 | 
					 | 
									jig.AddHTTPS(tlsSecretName, updatedTLSHost)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								},
 | 
					 | 
					 | 
					 | 
								},
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("Waiting for updated certificates to accept requests for host %v", updatedTLSHost),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("Waiting for updated certificates to accept requests for host %v", updatedTLSHost),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							},
 | 
					 | 
					 | 
					 | 
							},
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -154,7 +177,7 @@ func createComformanceTests(jig *testJig, ns string) []conformanceTests {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("should update url map for host %v to expose a single url: %v", updateURLMapHost, updateURLMapPath),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("should update url map for host %v to expose a single url: %v", updateURLMapHost, updateURLMapPath),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								func() {
 | 
					 | 
					 | 
					 | 
								func() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									var pathToFail string
 | 
					 | 
					 | 
					 | 
									var pathToFail string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									jig.update(func(ing *extensions.Ingress) {
 | 
					 | 
					 | 
					 | 
									jig.Update(func(ing *extensions.Ingress) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										newRules := []extensions.IngressRule{}
 | 
					 | 
					 | 
					 | 
										newRules := []extensions.IngressRule{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										for _, rule := range ing.Spec.Rules {
 | 
					 | 
					 | 
					 | 
										for _, rule := range ing.Spec.Rules {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if rule.Host != updateURLMapHost {
 | 
					 | 
					 | 
					 | 
											if rule.Host != updateURLMapHost {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -180,8 +203,8 @@ func createComformanceTests(jig *testJig, ns string) []conformanceTests {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										ing.Spec.Rules = newRules
 | 
					 | 
					 | 
					 | 
										ing.Spec.Rules = newRules
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									})
 | 
					 | 
					 | 
					 | 
									})
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									By("Checking that " + pathToFail + " is not exposed by polling for failure")
 | 
					 | 
					 | 
					 | 
									By("Checking that " + pathToFail + " is not exposed by polling for failure")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									route := fmt.Sprintf("http://%v%v", jig.address, pathToFail)
 | 
					 | 
					 | 
					 | 
									route := fmt.Sprintf("http://%v%v", jig.Address, pathToFail)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									framework.ExpectNoError(framework.PollURL(route, updateURLMapHost, framework.LoadBalancerCleanupTimeout, jig.pollInterval, &http.Client{Timeout: reqTimeout}, true))
 | 
					 | 
					 | 
					 | 
									ExpectNoError(PollURL(route, updateURLMapHost, LoadBalancerCleanupTimeout, jig.PollInterval, &http.Client{Timeout: IngressReqTimeout}, true))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								},
 | 
					 | 
					 | 
					 | 
								},
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								fmt.Sprintf("Waiting for path updates to reflect in L7"),
 | 
					 | 
					 | 
					 | 
								fmt.Sprintf("Waiting for path updates to reflect in L7"),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							},
 | 
					 | 
					 | 
					 | 
							},
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -248,13 +271,13 @@ func generateRSACerts(host string, isCA bool, keyOut, certOut io.Writer) error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return nil
 | 
					 | 
					 | 
					 | 
						return nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// buildTransport creates a transport for use in executing HTTPS requests with
 | 
					 | 
					 | 
					 | 
					// buildTransportWithCA creates a transport for use in executing HTTPS requests with
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// the given certs. Note that the given rootCA must be configured with isCA=true.
 | 
					 | 
					 | 
					 | 
					// the given certs. Note that the given rootCA must be configured with isCA=true.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func buildTransport(serverName string, rootCA []byte) (*http.Transport, error) {
 | 
					 | 
					 | 
					 | 
					func buildTransportWithCA(serverName string, rootCA []byte) (*http.Transport, error) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pool := x509.NewCertPool()
 | 
					 | 
					 | 
					 | 
						pool := x509.NewCertPool()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ok := pool.AppendCertsFromPEM(rootCA)
 | 
					 | 
					 | 
					 | 
						ok := pool.AppendCertsFromPEM(rootCA)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if !ok {
 | 
					 | 
					 | 
					 | 
						if !ok {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return nil, fmt.Errorf("Unable to load serverCA.")
 | 
					 | 
					 | 
					 | 
							return nil, fmt.Errorf("Unable to load serverCA")
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return utilnet.SetTransportDefaults(&http.Transport{
 | 
					 | 
					 | 
					 | 
						return utilnet.SetTransportDefaults(&http.Transport{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							TLSClientConfig: &tls.Config{
 | 
					 | 
					 | 
					 | 
							TLSClientConfig: &tls.Config{
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -265,20 +288,20 @@ func buildTransport(serverName string, rootCA []byte) (*http.Transport, error) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}), nil
 | 
					 | 
					 | 
					 | 
						}), nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// buildInsecureClient returns an insecure http client. Can be used for "curl -k".
 | 
					 | 
					 | 
					 | 
					// BuildInsecureClient returns an insecure http client. Can be used for "curl -k".
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func buildInsecureClient(timeout time.Duration) *http.Client {
 | 
					 | 
					 | 
					 | 
					func BuildInsecureClient(timeout time.Duration) *http.Client {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						t := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
 | 
					 | 
					 | 
					 | 
						t := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return &http.Client{Timeout: timeout, Transport: utilnet.SetTransportDefaults(t)}
 | 
					 | 
					 | 
					 | 
						return &http.Client{Timeout: timeout, Transport: utilnet.SetTransportDefaults(t)}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// createSecret creates a secret containing TLS certificates for the given Ingress.
 | 
					 | 
					 | 
					 | 
					// createIngressTLSSecret creates a secret containing TLS certificates for the given Ingress.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// If a secret with the same name already exists in the namespace of the
 | 
					 | 
					 | 
					 | 
					// If a secret with the same name already pathExists in the namespace of the
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Ingress, it's updated.
 | 
					 | 
					 | 
					 | 
					// Ingress, it's updated.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func createSecret(kubeClient clientset.Interface, ing *extensions.Ingress) (host string, rootCA, privKey []byte, err error) {
 | 
					 | 
					 | 
					 | 
					func createIngressTLSSecret(kubeClient clientset.Interface, ing *extensions.Ingress) (host string, rootCA, privKey []byte, err error) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var k, c bytes.Buffer
 | 
					 | 
					 | 
					 | 
						var k, c bytes.Buffer
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tls := ing.Spec.TLS[0]
 | 
					 | 
					 | 
					 | 
						tls := ing.Spec.TLS[0]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						host = strings.Join(tls.Hosts, ",")
 | 
					 | 
					 | 
					 | 
						host = strings.Join(tls.Hosts, ",")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Generating RSA cert for host %v", host)
 | 
					 | 
					 | 
					 | 
						Logf("Generating RSA cert for host %v", host)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err = generateRSACerts(host, true, &k, &c); err != nil {
 | 
					 | 
					 | 
					 | 
						if err = generateRSACerts(host, true, &k, &c); err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return
 | 
					 | 
					 | 
					 | 
							return
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -297,20 +320,22 @@ func createSecret(kubeClient clientset.Interface, ing *extensions.Ingress) (host
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var s *v1.Secret
 | 
					 | 
					 | 
					 | 
						var s *v1.Secret
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if s, err = kubeClient.Core().Secrets(ing.Namespace).Get(tls.SecretName, metav1.GetOptions{}); err == nil {
 | 
					 | 
					 | 
					 | 
						if s, err = kubeClient.Core().Secrets(ing.Namespace).Get(tls.SecretName, metav1.GetOptions{}); err == nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// TODO: Retry the update. We don't really expect anything to conflict though.
 | 
					 | 
					 | 
					 | 
							// TODO: Retry the update. We don't really expect anything to conflict though.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Updating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name)
 | 
					 | 
					 | 
					 | 
							Logf("Updating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							s.Data = secret.Data
 | 
					 | 
					 | 
					 | 
							s.Data = secret.Data
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							_, err = kubeClient.Core().Secrets(ing.Namespace).Update(s)
 | 
					 | 
					 | 
					 | 
							_, err = kubeClient.Core().Secrets(ing.Namespace).Update(s)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else {
 | 
					 | 
					 | 
					 | 
						} else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Creating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name)
 | 
					 | 
					 | 
					 | 
							Logf("Creating secret %v in ns %v with hosts %v for ingress %v", secret.Name, secret.Namespace, host, ing.Name)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							_, err = kubeClient.Core().Secrets(ing.Namespace).Create(secret)
 | 
					 | 
					 | 
					 | 
							_, err = kubeClient.Core().Secrets(ing.Namespace).Create(secret)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return host, cert, key, err
 | 
					 | 
					 | 
					 | 
						return host, cert, key, err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func cleanupGCE(gceController *GCEIngressController) {
 | 
					 | 
					 | 
					 | 
					// CleanupGCEIngressController calls the GCEIngressController.Cleanup(false)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pollErr := wait.Poll(5*time.Second, framework.LoadBalancerCleanupTimeout, func() (bool, error) {
 | 
					 | 
					 | 
					 | 
					// followed with deleting the static ip, and then a final GCEIngressController.Cleanup(true)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func CleanupGCEIngressController(gceController *GCEIngressController) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						pollErr := wait.Poll(5*time.Second, LoadBalancerCleanupTimeout, func() (bool, error) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err := gceController.Cleanup(false); err != nil {
 | 
					 | 
					 | 
					 | 
							if err := gceController.Cleanup(false); err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Logf("Still waiting for glbc to cleanup:\n%v", err)
 | 
					 | 
					 | 
					 | 
								Logf("Still waiting for glbc to cleanup:\n%v", err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return false, nil
 | 
					 | 
					 | 
					 | 
								return false, nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return true, nil
 | 
					 | 
					 | 
					 | 
							return true, nil
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -320,9 +345,9 @@ func cleanupGCE(gceController *GCEIngressController) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// controller. Delete this IP only after the controller has had a chance
 | 
					 | 
					 | 
					 | 
						// controller. Delete this IP only after the controller has had a chance
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// to cleanup or it might interfere with the controller, causing it to
 | 
					 | 
					 | 
					 | 
						// to cleanup or it might interfere with the controller, causing it to
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// throw out confusing events.
 | 
					 | 
					 | 
					 | 
						// throw out confusing events.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if ipErr := wait.Poll(5*time.Second, framework.LoadBalancerCleanupTimeout, func() (bool, error) {
 | 
					 | 
					 | 
					 | 
						if ipErr := wait.Poll(5*time.Second, LoadBalancerCleanupTimeout, func() (bool, error) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err := gceController.deleteStaticIPs(); err != nil {
 | 
					 | 
					 | 
					 | 
							if err := gceController.deleteStaticIPs(); err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Logf("Failed to delete static-ip: %v\n", err)
 | 
					 | 
					 | 
					 | 
								Logf("Failed to delete static-ip: %v\n", err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return false, nil
 | 
					 | 
					 | 
					 | 
								return false, nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return true, nil
 | 
					 | 
					 | 
					 | 
							return true, nil
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -342,7 +367,7 @@ func cleanupGCE(gceController *GCEIngressController) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Fail if the controller didn't cleanup
 | 
					 | 
					 | 
					 | 
						// Fail if the controller didn't cleanup
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if pollErr != nil {
 | 
					 | 
					 | 
					 | 
						if pollErr != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Failf("L7 controller failed to delete all cloud resources on time. %v", pollErr)
 | 
					 | 
					 | 
					 | 
							Failf("L7 controller failed to delete all cloud resources on time. %v", pollErr)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -350,7 +375,7 @@ func (cont *GCEIngressController) deleteForwardingRule(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						msg := ""
 | 
					 | 
					 | 
					 | 
						msg := ""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fwList := []compute.ForwardingRule{}
 | 
					 | 
					 | 
					 | 
						fwList := []compute.ForwardingRule{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for _, regex := range []string{fmt.Sprintf("%vfw-.*%v.*", k8sPrefix, clusterDelimiter), fmt.Sprintf("%vfws-.*%v.*", k8sPrefix, clusterDelimiter)} {
 | 
					 | 
					 | 
					 | 
						for _, regex := range []string{fmt.Sprintf("%vfw-.*%v.*", k8sPrefix, clusterDelimiter), fmt.Sprintf("%vfws-.*%v.*", k8sPrefix, clusterDelimiter)} {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							gcloudList("forwarding-rules", regex, cont.cloud.ProjectID, &fwList)
 | 
					 | 
					 | 
					 | 
							gcloudComputeResourceList("forwarding-rules", regex, cont.Cloud.ProjectID, &fwList)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if len(fwList) == 0 {
 | 
					 | 
					 | 
					 | 
							if len(fwList) == 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue
 | 
					 | 
					 | 
					 | 
								continue
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -360,7 +385,7 @@ func (cont *GCEIngressController) deleteForwardingRule(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (forwarding rule)\n", f.Name)
 | 
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (forwarding rule)\n", f.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if del {
 | 
					 | 
					 | 
					 | 
								if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									gcloudDelete("forwarding-rules", f.Name, cont.cloud.ProjectID, "--global")
 | 
					 | 
					 | 
					 | 
									GcloudComputeResourceDelete("forwarding-rules", f.Name, cont.Cloud.ProjectID, "--global")
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -371,7 +396,7 @@ func (cont *GCEIngressController) deleteAddresses(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						msg := ""
 | 
					 | 
					 | 
					 | 
						msg := ""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ipList := []compute.Address{}
 | 
					 | 
					 | 
					 | 
						ipList := []compute.Address{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vfw-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vfw-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gcloudList("addresses", regex, cont.cloud.ProjectID, &ipList)
 | 
					 | 
					 | 
					 | 
						gcloudComputeResourceList("addresses", regex, cont.Cloud.ProjectID, &ipList)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(ipList) != 0 {
 | 
					 | 
					 | 
					 | 
						if len(ipList) != 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, ip := range ipList {
 | 
					 | 
					 | 
					 | 
							for _, ip := range ipList {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if !cont.canDelete(ip.Name, ip.CreationTimestamp, del) {
 | 
					 | 
					 | 
					 | 
								if !cont.canDelete(ip.Name, ip.CreationTimestamp, del) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -379,7 +404,7 @@ func (cont *GCEIngressController) deleteAddresses(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (static-ip)\n", ip.Name)
 | 
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (static-ip)\n", ip.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if del {
 | 
					 | 
					 | 
					 | 
								if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									gcloudDelete("addresses", ip.Name, cont.cloud.ProjectID, "--global")
 | 
					 | 
					 | 
					 | 
									GcloudComputeResourceDelete("addresses", ip.Name, cont.Cloud.ProjectID, "--global")
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -390,7 +415,7 @@ func (cont *GCEIngressController) deleteTargetProxy(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						msg := ""
 | 
					 | 
					 | 
					 | 
						msg := ""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tpList := []compute.TargetHttpProxy{}
 | 
					 | 
					 | 
					 | 
						tpList := []compute.TargetHttpProxy{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vtp-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vtp-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gcloudList("target-http-proxies", regex, cont.cloud.ProjectID, &tpList)
 | 
					 | 
					 | 
					 | 
						gcloudComputeResourceList("target-http-proxies", regex, cont.Cloud.ProjectID, &tpList)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(tpList) != 0 {
 | 
					 | 
					 | 
					 | 
						if len(tpList) != 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, t := range tpList {
 | 
					 | 
					 | 
					 | 
							for _, t := range tpList {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if !cont.canDelete(t.Name, t.CreationTimestamp, del) {
 | 
					 | 
					 | 
					 | 
								if !cont.canDelete(t.Name, t.CreationTimestamp, del) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -398,13 +423,13 @@ func (cont *GCEIngressController) deleteTargetProxy(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (target-http-proxy)\n", t.Name)
 | 
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (target-http-proxy)\n", t.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if del {
 | 
					 | 
					 | 
					 | 
								if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									gcloudDelete("target-http-proxies", t.Name, cont.cloud.ProjectID)
 | 
					 | 
					 | 
					 | 
									GcloudComputeResourceDelete("target-http-proxies", t.Name, cont.Cloud.ProjectID)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tpsList := []compute.TargetHttpsProxy{}
 | 
					 | 
					 | 
					 | 
						tpsList := []compute.TargetHttpsProxy{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						regex = fmt.Sprintf("%vtps-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
					 | 
					 | 
					 | 
						regex = fmt.Sprintf("%vtps-.*%v.*", k8sPrefix, clusterDelimiter)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gcloudList("target-https-proxies", regex, cont.cloud.ProjectID, &tpsList)
 | 
					 | 
					 | 
					 | 
						gcloudComputeResourceList("target-https-proxies", regex, cont.Cloud.ProjectID, &tpsList)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(tpsList) != 0 {
 | 
					 | 
					 | 
					 | 
						if len(tpsList) != 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, t := range tpsList {
 | 
					 | 
					 | 
					 | 
							for _, t := range tpsList {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if !cont.canDelete(t.Name, t.CreationTimestamp, del) {
 | 
					 | 
					 | 
					 | 
								if !cont.canDelete(t.Name, t.CreationTimestamp, del) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -412,15 +437,15 @@ func (cont *GCEIngressController) deleteTargetProxy(del bool) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (target-https-proxy)\n", t.Name)
 | 
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (target-https-proxy)\n", t.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if del {
 | 
					 | 
					 | 
					 | 
								if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									gcloudDelete("target-https-proxies", t.Name, cont.cloud.ProjectID)
 | 
					 | 
					 | 
					 | 
									GcloudComputeResourceDelete("target-https-proxies", t.Name, cont.Cloud.ProjectID)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return msg
 | 
					 | 
					 | 
					 | 
						return msg
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteUrlMap(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteURLMap(del bool) (msg string) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						umList, err := gceCloud.ListUrlMaps()
 | 
					 | 
					 | 
					 | 
						umList, err := gceCloud.ListUrlMaps()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -447,7 +472,7 @@ func (cont *GCEIngressController) deleteUrlMap(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteBackendService(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteBackendService(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						beList, err := gceCloud.ListBackendServices()
 | 
					 | 
					 | 
					 | 
						beList, err := gceCloud.ListBackendServices()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -456,7 +481,7 @@ func (cont *GCEIngressController) deleteBackendService(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return fmt.Sprintf("Failed to list backend services: %v", err)
 | 
					 | 
					 | 
					 | 
							return fmt.Sprintf("Failed to list backend services: %v", err)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(beList.Items) == 0 {
 | 
					 | 
					 | 
					 | 
						if len(beList.Items) == 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("No backend services found")
 | 
					 | 
					 | 
					 | 
							Logf("No backend services found")
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return msg
 | 
					 | 
					 | 
					 | 
							return msg
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for _, be := range beList.Items {
 | 
					 | 
					 | 
					 | 
						for _, be := range beList.Items {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -474,8 +499,8 @@ func (cont *GCEIngressController) deleteBackendService(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return msg
 | 
					 | 
					 | 
					 | 
						return msg
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteHttpHealthCheck(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteHTTPHealthCheck(del bool) (msg string) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						hcList, err := gceCloud.ListHttpHealthChecks()
 | 
					 | 
					 | 
					 | 
						hcList, err := gceCloud.ListHttpHealthChecks()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -502,7 +527,7 @@ func (cont *GCEIngressController) deleteHttpHealthCheck(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteSSLCertificate(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteSSLCertificate(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sslList, err := gceCloud.ListSslCertificates()
 | 
					 | 
					 | 
					 | 
						sslList, err := gceCloud.ListSslCertificates()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -528,10 +553,10 @@ func (cont *GCEIngressController) deleteSSLCertificate(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteInstanceGroup(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteInstanceGroup(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// TODO: E2E cloudprovider has only 1 zone, but the cluster can have many.
 | 
					 | 
					 | 
					 | 
						// TODO: E2E cloudprovider has only 1 zone, but the cluster can have many.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// We need to poll on all IGs across all zones.
 | 
					 | 
					 | 
					 | 
						// We need to poll on all IGs across all zones.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						igList, err := gceCloud.ListInstanceGroups(cont.cloud.Zone)
 | 
					 | 
					 | 
					 | 
						igList, err := gceCloud.ListInstanceGroups(cont.Cloud.Zone)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
							if cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return msg
 | 
					 | 
					 | 
					 | 
								return msg
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -547,7 +572,7 @@ func (cont *GCEIngressController) deleteInstanceGroup(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							msg += fmt.Sprintf("%v (instance-group)\n", ig.Name)
 | 
					 | 
					 | 
					 | 
							msg += fmt.Sprintf("%v (instance-group)\n", ig.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if del {
 | 
					 | 
					 | 
					 | 
							if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if err := gceCloud.DeleteInstanceGroup(ig.Name, cont.cloud.Zone); err != nil &&
 | 
					 | 
					 | 
					 | 
								if err := gceCloud.DeleteInstanceGroup(ig.Name, cont.Cloud.Zone); err != nil &&
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									!cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
									!cont.isHTTPErrorCode(err, http.StatusNotFound) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									msg += fmt.Sprintf("Failed to delete instance group %v\n", ig.Name)
 | 
					 | 
					 | 
					 | 
									msg += fmt.Sprintf("Failed to delete instance group %v\n", ig.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -574,23 +599,25 @@ func (cont *GCEIngressController) canDelete(resourceName, creationTimestamp stri
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						createdTime, err := time.Parse(time.RFC3339, creationTimestamp)
 | 
					 | 
					 | 
					 | 
						createdTime, err := time.Parse(time.RFC3339, creationTimestamp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("WARNING: Failed to parse creation timestamp %v for %v: %v", creationTimestamp, resourceName, err)
 | 
					 | 
					 | 
					 | 
							Logf("WARNING: Failed to parse creation timestamp %v for %v: %v", creationTimestamp, resourceName, err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return false
 | 
					 | 
					 | 
					 | 
							return false
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if createdTime.Before(time.Now().Add(maxAge)) {
 | 
					 | 
					 | 
					 | 
						if createdTime.Before(time.Now().Add(maxAge)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("%v created on %v IS too old", resourceName, creationTimestamp)
 | 
					 | 
					 | 
					 | 
							Logf("%v created on %v IS too old", resourceName, creationTimestamp)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return true
 | 
					 | 
					 | 
					 | 
							return true
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return false
 | 
					 | 
					 | 
					 | 
						return false
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) getFirewallRuleName() string {
 | 
					 | 
					 | 
					 | 
					// GetFirewallRuleName returns the name of the firewall used for the GCEIngressController.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) GetFirewallRuleName() string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return fmt.Sprintf("%vfw-l7%v%v", k8sPrefix, clusterDelimiter, cont.UID)
 | 
					 | 
					 | 
					 | 
						return fmt.Sprintf("%vfw-l7%v%v", k8sPrefix, clusterDelimiter, cont.UID)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) getFirewallRule() *compute.Firewall {
 | 
					 | 
					 | 
					 | 
					// GetFirewallRule returns the firewall used by the GCEIngressController.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) GetFirewallRule() *compute.Firewall {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fwName := cont.getFirewallRuleName()
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						fwName := cont.GetFirewallRuleName()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw, err := gceCloud.GetFirewall(fwName)
 | 
					 | 
					 | 
					 | 
						fw, err := gceCloud.GetFirewall(fwName)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return fw
 | 
					 | 
					 | 
					 | 
						return fw
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -599,7 +626,7 @@ func (cont *GCEIngressController) getFirewallRule() *compute.Firewall {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteFirewallRule(del bool) (msg string) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteFirewallRule(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fwList := []compute.Firewall{}
 | 
					 | 
					 | 
					 | 
						fwList := []compute.Firewall{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vfw-l7%v.*", k8sPrefix, clusterDelimiter)
 | 
					 | 
					 | 
					 | 
						regex := fmt.Sprintf("%vfw-l7%v.*", k8sPrefix, clusterDelimiter)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gcloudList("firewall-rules", regex, cont.cloud.ProjectID, &fwList)
 | 
					 | 
					 | 
					 | 
						gcloudComputeResourceList("firewall-rules", regex, cont.Cloud.ProjectID, &fwList)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(fwList) != 0 {
 | 
					 | 
					 | 
					 | 
						if len(fwList) != 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, f := range fwList {
 | 
					 | 
					 | 
					 | 
							for _, f := range fwList {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if !cont.canDelete(f.Name, f.CreationTimestamp, del) {
 | 
					 | 
					 | 
					 | 
								if !cont.canDelete(f.Name, f.CreationTimestamp, del) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -607,7 +634,7 @@ func (cont *GCEIngressController) deleteFirewallRule(del bool) (msg string) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (firewall rule)\n", f.Name)
 | 
					 | 
					 | 
					 | 
								msg += fmt.Sprintf("%v (firewall rule)\n", f.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if del {
 | 
					 | 
					 | 
					 | 
								if del {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									gcloudDelete("firewall-rules", f.Name, cont.cloud.ProjectID)
 | 
					 | 
					 | 
					 | 
									GcloudComputeResourceDelete("firewall-rules", f.Name, cont.Cloud.ProjectID)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -631,9 +658,9 @@ func (cont *GCEIngressController) Cleanup(del bool) error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteAddresses(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteAddresses(del)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteTargetProxy(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteTargetProxy(del)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteUrlMap(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteURLMap(del)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteBackendService(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteBackendService(del)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteHttpHealthCheck(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteHTTPHealthCheck(del)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteInstanceGroup(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteInstanceGroup(del)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						errMsg += cont.deleteFirewallRule(del)
 | 
					 | 
					 | 
					 | 
						errMsg += cont.deleteFirewallRule(del)
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -648,63 +675,64 @@ func (cont *GCEIngressController) Cleanup(del bool) error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return fmt.Errorf(errMsg)
 | 
					 | 
					 | 
					 | 
						return fmt.Errorf(errMsg)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) init() {
 | 
					 | 
					 | 
					 | 
					// Init initializes the GCEIngressController with an UID
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) Init() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uid, err := cont.getL7AddonUID()
 | 
					 | 
					 | 
					 | 
						uid, err := cont.getL7AddonUID()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cont.UID = uid
 | 
					 | 
					 | 
					 | 
						cont.UID = uid
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// There's a name limit imposed by GCE. The controller will truncate.
 | 
					 | 
					 | 
					 | 
						// There's a name limit imposed by GCE. The controller will truncate.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						testName := fmt.Sprintf("k8s-fw-foo-app-X-%v--%v", cont.ns, cont.UID)
 | 
					 | 
					 | 
					 | 
						testName := fmt.Sprintf("k8s-fw-foo-app-X-%v--%v", cont.Ns, cont.UID)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(testName) > nameLenLimit {
 | 
					 | 
					 | 
					 | 
						if len(testName) > nameLenLimit {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("WARNING: test name including cluster UID: %v is over the GCE limit of %v", testName, nameLenLimit)
 | 
					 | 
					 | 
					 | 
							Logf("WARNING: test name including cluster UID: %v is over the GCE limit of %v", testName, nameLenLimit)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else {
 | 
					 | 
					 | 
					 | 
						} else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Detected cluster UID %v", cont.UID)
 | 
					 | 
					 | 
					 | 
							Logf("Detected cluster UID %v", cont.UID)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// createStaticIP allocates a random static ip with the given name. Returns a string
 | 
					 | 
					 | 
					 | 
					// CreateStaticIP allocates a random static ip with the given name. Returns a string
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// representation of the ip. Caller is expected to manage cleanup of the ip by
 | 
					 | 
					 | 
					 | 
					// representation of the ip. Caller is expected to manage cleanup of the ip by
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// invoking deleteStaticIPs.
 | 
					 | 
					 | 
					 | 
					// invoking deleteStaticIPs.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) createStaticIP(name string) string {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) CreateStaticIP(name string) string {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						gceCloud := cont.cloud.Provider.(*gcecloud.GCECloud)
 | 
					 | 
					 | 
					 | 
						gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ip, err := gceCloud.ReserveGlobalStaticIP(name, "")
 | 
					 | 
					 | 
					 | 
						ip, err := gceCloud.ReserveGlobalStaticIP(name, "")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if delErr := gceCloud.DeleteGlobalStaticIP(name); delErr != nil {
 | 
					 | 
					 | 
					 | 
							if delErr := gceCloud.DeleteGlobalStaticIP(name); delErr != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if cont.isHTTPErrorCode(delErr, http.StatusNotFound) {
 | 
					 | 
					 | 
					 | 
								if cont.isHTTPErrorCode(delErr, http.StatusNotFound) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									framework.Logf("Static ip with name %v was not allocated, nothing to delete", name)
 | 
					 | 
					 | 
					 | 
									Logf("Static ip with name %v was not allocated, nothing to delete", name)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else {
 | 
					 | 
					 | 
					 | 
								} else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									framework.Logf("Failed to delete static ip %v: %v", name, delErr)
 | 
					 | 
					 | 
					 | 
									Logf("Failed to delete static ip %v: %v", name, delErr)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Failf("Failed to allocated static ip %v: %v", name, err)
 | 
					 | 
					 | 
					 | 
							Failf("Failed to allocated static ip %v: %v", name, err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cont.staticIPName = ip.Name
 | 
					 | 
					 | 
					 | 
						cont.staticIPName = ip.Name
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Reserved static ip %v: %v", cont.staticIPName, ip.Address)
 | 
					 | 
					 | 
					 | 
						Logf("Reserved static ip %v: %v", cont.staticIPName, ip.Address)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return ip.Address
 | 
					 | 
					 | 
					 | 
						return ip.Address
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// deleteStaticIPs deletes all static-ips allocated through calls to
 | 
					 | 
					 | 
					 | 
					// deleteStaticIPs delets all static-ips allocated through calls to
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// createStaticIP.
 | 
					 | 
					 | 
					 | 
					// CreateStaticIP.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteStaticIPs() error {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) deleteStaticIPs() error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if cont.staticIPName != "" {
 | 
					 | 
					 | 
					 | 
						if cont.staticIPName != "" {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err := gcloudDelete("addresses", cont.staticIPName, cont.cloud.ProjectID, "--global"); err == nil {
 | 
					 | 
					 | 
					 | 
							if err := GcloudComputeResourceDelete("addresses", cont.staticIPName, cont.Cloud.ProjectID, "--global"); err == nil {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								cont.staticIPName = ""
 | 
					 | 
					 | 
					 | 
								cont.staticIPName = ""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} else {
 | 
					 | 
					 | 
					 | 
							} else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return err
 | 
					 | 
					 | 
					 | 
								return err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else {
 | 
					 | 
					 | 
					 | 
						} else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							e2eIPs := []compute.Address{}
 | 
					 | 
					 | 
					 | 
							e2eIPs := []compute.Address{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							gcloudList("addresses", "e2e-.*", cont.cloud.ProjectID, &e2eIPs)
 | 
					 | 
					 | 
					 | 
							gcloudComputeResourceList("addresses", "e2e-.*", cont.Cloud.ProjectID, &e2eIPs)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ips := []string{}
 | 
					 | 
					 | 
					 | 
							ips := []string{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, ip := range e2eIPs {
 | 
					 | 
					 | 
					 | 
							for _, ip := range e2eIPs {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								ips = append(ips, ip.Name)
 | 
					 | 
					 | 
					 | 
								ips = append(ips, ip.Name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("None of the remaining %d static-ips were created by this e2e: %v", len(ips), strings.Join(ips, ", "))
 | 
					 | 
					 | 
					 | 
							Logf("None of the remaining %d static-ips were created by this e2e: %v", len(ips), strings.Join(ips, ", "))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return nil
 | 
					 | 
					 | 
					 | 
						return nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// gcloudList unmarshals json output of gcloud into given out interface.
 | 
					 | 
					 | 
					 | 
					// gcloudComputeResourceList unmarshals json output of gcloud into given out interface.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func gcloudList(resource, regex, project string, out interface{}) {
 | 
					 | 
					 | 
					 | 
					func gcloudComputeResourceList(resource, regex, project string, out interface{}) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// gcloud prints a message to stderr if it has an available update
 | 
					 | 
					 | 
					 | 
						// gcloud prints a message to stderr if it has an available update
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// so we only look at stdout.
 | 
					 | 
					 | 
					 | 
						// so we only look at stdout.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						command := []string{
 | 
					 | 
					 | 
					 | 
						command := []string{
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -724,204 +752,210 @@ func gcloudList(resource, regex, project string, out interface{}) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									errMsg = fmt.Sprintf("%v, stderr %v", errMsg, string(osExitErr.Stderr))
 | 
					 | 
					 | 
					 | 
									errMsg = fmt.Sprintf("%v, stderr %v", errMsg, string(osExitErr.Stderr))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Error running gcloud command 'gcloud %s': err: %v, output: %v, status: %d, msg: %v", strings.Join(command, " "), err, string(output), errCode, errMsg)
 | 
					 | 
					 | 
					 | 
							Logf("Error running gcloud command 'gcloud %s': err: %v, output: %v, status: %d, msg: %v", strings.Join(command, " "), err, string(output), errCode, errMsg)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err := json.Unmarshal([]byte(output), out); err != nil {
 | 
					 | 
					 | 
					 | 
						if err := json.Unmarshal([]byte(output), out); err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Error unmarshalling gcloud output for %v: %v, output: %v", resource, err, string(output))
 | 
					 | 
					 | 
					 | 
							Logf("Error unmarshalling gcloud output for %v: %v, output: %v", resource, err, string(output))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func gcloudDelete(resource, name, project string, args ...string) error {
 | 
					 | 
					 | 
					 | 
					// GcloudComputeResourceDelete deletes the specified compute resource by name and project.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Deleting %v: %v", resource, name)
 | 
					 | 
					 | 
					 | 
					func GcloudComputeResourceDelete(resource, name, project string, args ...string) error {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						Logf("Deleting %v: %v", resource, name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						argList := append([]string{"compute", resource, "delete", name, fmt.Sprintf("--project=%v", project), "-q"}, args...)
 | 
					 | 
					 | 
					 | 
						argList := append([]string{"compute", resource, "delete", name, fmt.Sprintf("--project=%v", project), "-q"}, args...)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						output, err := exec.Command("gcloud", argList...).CombinedOutput()
 | 
					 | 
					 | 
					 | 
						output, err := exec.Command("gcloud", argList...).CombinedOutput()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Error deleting %v, output: %v\nerror: %+v", resource, string(output), err)
 | 
					 | 
					 | 
					 | 
							Logf("Error deleting %v, output: %v\nerror: %+v", resource, string(output), err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return err
 | 
					 | 
					 | 
					 | 
						return err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func gcloudCreate(resource, name, project string, args ...string) error {
 | 
					 | 
					 | 
					 | 
					// GcloudComputeResourceCreate creates a compute resource with a name and arguments.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Creating %v in project %v: %v", resource, project, name)
 | 
					 | 
					 | 
					 | 
					func GcloudComputeResourceCreate(resource, name, project string, args ...string) error {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						Logf("Creating %v in project %v: %v", resource, project, name)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						argsList := append([]string{"compute", resource, "create", name, fmt.Sprintf("--project=%v", project)}, args...)
 | 
					 | 
					 | 
					 | 
						argsList := append([]string{"compute", resource, "create", name, fmt.Sprintf("--project=%v", project)}, args...)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Running command: gcloud %+v", strings.Join(argsList, " "))
 | 
					 | 
					 | 
					 | 
						Logf("Running command: gcloud %+v", strings.Join(argsList, " "))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						output, err := exec.Command("gcloud", argsList...).CombinedOutput()
 | 
					 | 
					 | 
					 | 
						output, err := exec.Command("gcloud", argsList...).CombinedOutput()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Error creating %v, output: %v\nerror: %+v", resource, string(output), err)
 | 
					 | 
					 | 
					 | 
							Logf("Error creating %v, output: %v\nerror: %+v", resource, string(output), err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return err
 | 
					 | 
					 | 
					 | 
						return err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// createIngress creates the Ingress and associated service/rc.
 | 
					 | 
					 | 
					 | 
					// CreateIngress creates the Ingress and associated service/rc.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Required: ing.yaml, rc.yaml, svc.yaml must exist in manifestPath
 | 
					 | 
					 | 
					 | 
					// Required: ing.yaml, rc.yaml, svc.yaml must exist in manifestPath
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Optional: secret.yaml, ingAnnotations
 | 
					 | 
					 | 
					 | 
					// Optional: secret.yaml, ingAnnotations
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// If ingAnnotations is specified it will overwrite any annotations in ing.yaml
 | 
					 | 
					 | 
					 | 
					// If ingAnnotations is specified it will overwrite any annotations in ing.yaml
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) createIngress(manifestPath, ns string, ingAnnotations map[string]string) {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) CreateIngress(manifestPath, ns string, ingAnnotations map[string]string) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mkpath := func(file string) string {
 | 
					 | 
					 | 
					 | 
						mkpath := func(file string) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return filepath.Join(framework.TestContext.RepoRoot, manifestPath, file)
 | 
					 | 
					 | 
					 | 
							return filepath.Join(TestContext.RepoRoot, manifestPath, file)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("creating replication controller")
 | 
					 | 
					 | 
					 | 
						Logf("creating replication controller")
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.RunKubectlOrDie("create", "-f", mkpath("rc.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
					 | 
					 | 
					 | 
						RunKubectlOrDie("create", "-f", mkpath("rc.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("creating service")
 | 
					 | 
					 | 
					 | 
						Logf("creating service")
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.RunKubectlOrDie("create", "-f", mkpath("svc.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
					 | 
					 | 
					 | 
						RunKubectlOrDie("create", "-f", mkpath("svc.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if exists(mkpath("secret.yaml")) {
 | 
					 | 
					 | 
					 | 
						if exists, _ := util.FileExists(mkpath("secret.yaml")); exists {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("creating secret")
 | 
					 | 
					 | 
					 | 
							Logf("creating secret")
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.RunKubectlOrDie("create", "-f", mkpath("secret.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
					 | 
					 | 
					 | 
							RunKubectlOrDie("create", "-f", mkpath("secret.yaml"), fmt.Sprintf("--namespace=%v", ns))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.ing = ingFromManifest(mkpath("ing.yaml"))
 | 
					 | 
					 | 
					 | 
						j.Ingress = createIngressFromManifest(mkpath("ing.yaml"))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.ing.Namespace = ns
 | 
					 | 
					 | 
					 | 
						j.Ingress.Namespace = ns
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.ing.Annotations = map[string]string{ingressClass: j.class}
 | 
					 | 
					 | 
					 | 
						j.Ingress.Annotations = map[string]string{ingressClass: j.Class}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for k, v := range ingAnnotations {
 | 
					 | 
					 | 
					 | 
						for k, v := range ingAnnotations {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							j.ing.Annotations[k] = v
 | 
					 | 
					 | 
					 | 
							j.Ingress.Annotations[k] = v
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf(fmt.Sprintf("creating" + j.ing.Name + " ingress"))
 | 
					 | 
					 | 
					 | 
						Logf(fmt.Sprintf("creating" + j.Ingress.Name + " ingress"))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var err error
 | 
					 | 
					 | 
					 | 
						var err error
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.ing, err = j.client.Extensions().Ingresses(ns).Create(j.ing)
 | 
					 | 
					 | 
					 | 
						j.Ingress, err = j.Client.Extensions().Ingresses(ns).Create(j.Ingress)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) update(update func(ing *extensions.Ingress)) {
 | 
					 | 
					 | 
					 | 
					// Update retrieves the ingress, performs the passed function, and then updates it.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) Update(update func(ing *extensions.Ingress)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var err error
 | 
					 | 
					 | 
					 | 
						var err error
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ns, name := j.ing.Namespace, j.ing.Name
 | 
					 | 
					 | 
					 | 
						ns, name := j.Ingress.Namespace, j.Ingress.Name
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for i := 0; i < 3; i++ {
 | 
					 | 
					 | 
					 | 
						for i := 0; i < 3; i++ {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							j.ing, err = j.client.Extensions().Ingresses(ns).Get(name, metav1.GetOptions{})
 | 
					 | 
					 | 
					 | 
							j.Ingress, err = j.Client.Extensions().Ingresses(ns).Get(name, metav1.GetOptions{})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err != nil {
 | 
					 | 
					 | 
					 | 
							if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Failf("failed to get ingress %q: %v", name, err)
 | 
					 | 
					 | 
					 | 
								Failf("failed to get ingress %q: %v", name, err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							update(j.ing)
 | 
					 | 
					 | 
					 | 
							update(j.Ingress)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							j.ing, err = j.client.Extensions().Ingresses(ns).Update(j.ing)
 | 
					 | 
					 | 
					 | 
							j.Ingress, err = j.Client.Extensions().Ingresses(ns).Update(j.Ingress)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err == nil {
 | 
					 | 
					 | 
					 | 
							if err == nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.DescribeIng(j.ing.Namespace)
 | 
					 | 
					 | 
					 | 
								DescribeIng(j.Ingress.Namespace)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return
 | 
					 | 
					 | 
					 | 
								return
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if !apierrs.IsConflict(err) && !apierrs.IsServerTimeout(err) {
 | 
					 | 
					 | 
					 | 
							if !apierrs.IsConflict(err) && !apierrs.IsServerTimeout(err) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Failf("failed to update ingress %q: %v", name, err)
 | 
					 | 
					 | 
					 | 
								Failf("failed to update ingress %q: %v", name, err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Failf("too many retries updating ingress %q", name)
 | 
					 | 
					 | 
					 | 
						Failf("too many retries updating ingress %q", name)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) addHTTPS(secretName string, hosts ...string) {
 | 
					 | 
					 | 
					 | 
					// AddHTTPS updates the ingress to use this secret for these hosts.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.ing.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}}
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) AddHTTPS(secretName string, hosts ...string) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// TODO: Just create the secret in getRootCAs once we're watching secrets in
 | 
					 | 
					 | 
					 | 
						j.Ingress.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						// TODO: Just create the secret in GetRootCAs once we're watching secrets in
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// the ingress controller.
 | 
					 | 
					 | 
					 | 
						// the ingress controller.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						_, cert, _, err := createSecret(j.client, j.ing)
 | 
					 | 
					 | 
					 | 
						_, cert, _, err := createIngressTLSSecret(j.Client, j.Ingress)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Updating ingress %v to use secret %v for TLS termination", j.ing.Name, secretName)
 | 
					 | 
					 | 
					 | 
						Logf("Updating ingress %v to use secret %v for TLS termination", j.Ingress.Name, secretName)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.update(func(ing *extensions.Ingress) {
 | 
					 | 
					 | 
					 | 
						j.Update(func(ing *extensions.Ingress) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							ing.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}}
 | 
					 | 
					 | 
					 | 
							ing.Spec.TLS = []extensions.IngressTLS{{Hosts: hosts, SecretName: secretName}}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						})
 | 
					 | 
					 | 
					 | 
						})
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.rootCAs[secretName] = cert
 | 
					 | 
					 | 
					 | 
						j.RootCAs[secretName] = cert
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) getRootCA(secretName string) (rootCA []byte) {
 | 
					 | 
					 | 
					 | 
					// GetRootCA returns a rootCA from the ingress test jig.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) GetRootCA(secretName string) (rootCA []byte) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var ok bool
 | 
					 | 
					 | 
					 | 
						var ok bool
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rootCA, ok = j.rootCAs[secretName]
 | 
					 | 
					 | 
					 | 
						rootCA, ok = j.RootCAs[secretName]
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if !ok {
 | 
					 | 
					 | 
					 | 
						if !ok {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Failf("Failed to retrieve rootCAs, no recorded secret by name %v", secretName)
 | 
					 | 
					 | 
					 | 
							Failf("Failed to retrieve rootCAs, no recorded secret by name %v", secretName)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return
 | 
					 | 
					 | 
					 | 
						return
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) deleteIngress() {
 | 
					 | 
					 | 
					 | 
					// DeleteIngress deletes the ingress resource
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(j.client.Extensions().Ingresses(j.ing.Namespace).Delete(j.ing.Name, nil))
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) DeleteIngress() {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						ExpectNoError(j.Client.Extensions().Ingresses(j.Ingress.Namespace).Delete(j.Ingress.Name, nil))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// waitForIngress waits till the ingress acquires an IP, then waits for its
 | 
					 | 
					 | 
					 | 
					// WaitForIngress waits till the ingress acquires an IP, then waits for its
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// hosts/urls to respond to a protocol check (either http or https). If
 | 
					 | 
					 | 
					 | 
					// hosts/urls to respond to a protocol check (either http or https). If
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// waitForNodePort is true, the NodePort of the Service is verified before
 | 
					 | 
					 | 
					 | 
					// waitForNodePort is true, the NodePort of the Service is verified before
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// verifying the Ingress. NodePort is currently a requirement for cloudprovider
 | 
					 | 
					 | 
					 | 
					// verifying the Ingress. NodePort is currently a requirement for cloudprovider
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Ingress.
 | 
					 | 
					 | 
					 | 
					// Ingress.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) waitForIngress(waitForNodePort bool) {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) WaitForIngress(waitForNodePort bool) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Wait for the loadbalancer IP.
 | 
					 | 
					 | 
					 | 
						// Wait for the loadbalancer IP.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						address, err := framework.WaitForIngressAddress(j.client, j.ing.Namespace, j.ing.Name, framework.LoadBalancerPollTimeout)
 | 
					 | 
					 | 
					 | 
						address, err := WaitForIngressAddress(j.Client, j.Ingress.Namespace, j.Ingress.Name, LoadBalancerPollTimeout)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Failf("Ingress failed to acquire an IP address within %v", framework.LoadBalancerPollTimeout)
 | 
					 | 
					 | 
					 | 
							Failf("Ingress failed to acquire an IP address within %v", LoadBalancerPollTimeout)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						j.address = address
 | 
					 | 
					 | 
					 | 
						j.Address = address
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Found address %v for ingress %v", j.address, j.ing.Name)
 | 
					 | 
					 | 
					 | 
						Logf("Found address %v for ingress %v", j.Address, j.Ingress.Name)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						timeoutClient := &http.Client{Timeout: reqTimeout}
 | 
					 | 
					 | 
					 | 
						timeoutClient := &http.Client{Timeout: IngressReqTimeout}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Check that all rules respond to a simple GET.
 | 
					 | 
					 | 
					 | 
						// Check that all rules respond to a simple GET.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for _, rules := range j.ing.Spec.Rules {
 | 
					 | 
					 | 
					 | 
						for _, rules := range j.Ingress.Spec.Rules {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							proto := "http"
 | 
					 | 
					 | 
					 | 
							proto := "http"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if len(j.ing.Spec.TLS) > 0 {
 | 
					 | 
					 | 
					 | 
							if len(j.Ingress.Spec.TLS) > 0 {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								knownHosts := sets.NewString(j.ing.Spec.TLS[0].Hosts...)
 | 
					 | 
					 | 
					 | 
								knownHosts := sets.NewString(j.Ingress.Spec.TLS[0].Hosts...)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if knownHosts.Has(rules.Host) {
 | 
					 | 
					 | 
					 | 
								if knownHosts.Has(rules.Host) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									timeoutClient.Transport, err = buildTransport(rules.Host, j.getRootCA(j.ing.Spec.TLS[0].SecretName))
 | 
					 | 
					 | 
					 | 
									timeoutClient.Transport, err = buildTransportWithCA(rules.Host, j.GetRootCA(j.Ingress.Spec.TLS[0].SecretName))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
									ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									proto = "https"
 | 
					 | 
					 | 
					 | 
									proto = "https"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, p := range rules.IngressRuleValue.HTTP.Paths {
 | 
					 | 
					 | 
					 | 
							for _, p := range rules.IngressRuleValue.HTTP.Paths {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if waitForNodePort {
 | 
					 | 
					 | 
					 | 
								if waitForNodePort {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									j.curlServiceNodePort(j.ing.Namespace, p.Backend.ServiceName, int(p.Backend.ServicePort.IntVal))
 | 
					 | 
					 | 
					 | 
									j.pollServiceNodePort(j.Ingress.Namespace, p.Backend.ServiceName, int(p.Backend.ServicePort.IntVal))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
 | 
					 | 
					 | 
					 | 
								route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Logf("Testing route %v host %v with simple GET", route, rules.Host)
 | 
					 | 
					 | 
					 | 
								Logf("Testing route %v host %v with simple GET", route, rules.Host)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.ExpectNoError(framework.PollURL(route, rules.Host, framework.LoadBalancerPollTimeout, j.pollInterval, timeoutClient, false))
 | 
					 | 
					 | 
					 | 
								ExpectNoError(PollURL(route, rules.Host, LoadBalancerPollTimeout, j.PollInterval, timeoutClient, false))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// verifyURL polls for the given iterations, in intervals, and fails if the
 | 
					 | 
					 | 
					 | 
					// VerifyURL polls for the given iterations, in intervals, and fails if the
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// given url returns a non-healthy http code even once.
 | 
					 | 
					 | 
					 | 
					// given url returns a non-healthy http code even once.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) verifyURL(route, host string, iterations int, interval time.Duration, httpClient *http.Client) error {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) VerifyURL(route, host string, iterations int, interval time.Duration, httpClient *http.Client) error {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for i := 0; i < iterations; i++ {
 | 
					 | 
					 | 
					 | 
						for i := 0; i < iterations; i++ {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							b, err := framework.SimpleGET(httpClient, route, host)
 | 
					 | 
					 | 
					 | 
							b, err := SimpleGET(httpClient, route, host)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if err != nil {
 | 
					 | 
					 | 
					 | 
							if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								framework.Logf(b)
 | 
					 | 
					 | 
					 | 
								Logf(b)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return err
 | 
					 | 
					 | 
					 | 
								return err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Logf("Verfied %v with host %v %d times, sleeping for %v", route, host, i, interval)
 | 
					 | 
					 | 
					 | 
							Logf("Verfied %v with host %v %d times, sleeping for %v", route, host, i, interval)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							time.Sleep(interval)
 | 
					 | 
					 | 
					 | 
							time.Sleep(interval)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return nil
 | 
					 | 
					 | 
					 | 
						return nil
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) curlServiceNodePort(ns, name string, port int) {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) pollServiceNodePort(ns, name string, port int) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// TODO: Curl all nodes?
 | 
					 | 
					 | 
					 | 
						// TODO: Curl all nodes?
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						u, err := framework.GetNodePortURL(j.client, ns, name, port)
 | 
					 | 
					 | 
					 | 
						u, err := GetNodePortURL(j.Client, ns, name, port)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(framework.PollURL(u, "", 30*time.Second, j.pollInterval, &http.Client{Timeout: reqTimeout}, false))
 | 
					 | 
					 | 
					 | 
						ExpectNoError(PollURL(u, "", 30*time.Second, j.PollInterval, &http.Client{Timeout: IngressReqTimeout}, false))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// getIngressNodePorts returns all related backend services' nodePorts.
 | 
					 | 
					 | 
					 | 
					// GetIngressNodePorts returns all related backend services' nodePorts.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Current GCE ingress controller allows traffic to the default HTTP backend
 | 
					 | 
					 | 
					 | 
					// Current GCE ingress controller allows traffic to the default HTTP backend
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// by default, so retrieve its nodePort as well.
 | 
					 | 
					 | 
					 | 
					// by default, so retrieve its nodePort as well.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) getIngressNodePorts() []string {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) GetIngressNodePorts() []string {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						nodePorts := []string{}
 | 
					 | 
					 | 
					 | 
						nodePorts := []string{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						defaultSvc, err := j.client.Core().Services(metav1.NamespaceSystem).Get(defaultBackendName, metav1.GetOptions{})
 | 
					 | 
					 | 
					 | 
						defaultSvc, err := j.Client.Core().Services(metav1.NamespaceSystem).Get(defaultBackendName, metav1.GetOptions{})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
					 | 
					 | 
					 | 
						Expect(err).NotTo(HaveOccurred())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						nodePorts = append(nodePorts, strconv.Itoa(int(defaultSvc.Spec.Ports[0].NodePort)))
 | 
					 | 
					 | 
					 | 
						nodePorts = append(nodePorts, strconv.Itoa(int(defaultSvc.Spec.Ports[0].NodePort)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						backendSvcs := []string{}
 | 
					 | 
					 | 
					 | 
						backendSvcs := []string{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if j.ing.Spec.Backend != nil {
 | 
					 | 
					 | 
					 | 
						if j.Ingress.Spec.Backend != nil {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							backendSvcs = append(backendSvcs, j.ing.Spec.Backend.ServiceName)
 | 
					 | 
					 | 
					 | 
							backendSvcs = append(backendSvcs, j.Ingress.Spec.Backend.ServiceName)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for _, rule := range j.ing.Spec.Rules {
 | 
					 | 
					 | 
					 | 
						for _, rule := range j.Ingress.Spec.Rules {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							for _, ingPath := range rule.HTTP.Paths {
 | 
					 | 
					 | 
					 | 
							for _, ingPath := range rule.HTTP.Paths {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								backendSvcs = append(backendSvcs, ingPath.Backend.ServiceName)
 | 
					 | 
					 | 
					 | 
								backendSvcs = append(backendSvcs, ingPath.Backend.ServiceName)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for _, svcName := range backendSvcs {
 | 
					 | 
					 | 
					 | 
						for _, svcName := range backendSvcs {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							svc, err := j.client.Core().Services(j.ing.Namespace).Get(svcName, metav1.GetOptions{})
 | 
					 | 
					 | 
					 | 
							svc, err := j.Client.Core().Services(j.Ingress.Namespace).Get(svcName, metav1.GetOptions{})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							Expect(err).NotTo(HaveOccurred())
 | 
					 | 
					 | 
					 | 
							Expect(err).NotTo(HaveOccurred())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							nodePorts = append(nodePorts, strconv.Itoa(int(svc.Spec.Ports[0].NodePort)))
 | 
					 | 
					 | 
					 | 
							nodePorts = append(nodePorts, strconv.Itoa(int(svc.Spec.Ports[0].NodePort)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return nodePorts
 | 
					 | 
					 | 
					 | 
						return nodePorts
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// constructFirewallForIngress returns the expected GCE firewall rule for the ingress resource
 | 
					 | 
					 | 
					 | 
					// ConstructFirewallForIngress returns the expected GCE firewall rule for the ingress resource
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (j *testJig) constructFirewallForIngress(gceController *GCEIngressController) *compute.Firewall {
 | 
					 | 
					 | 
					 | 
					func (j *IngressTestJig) ConstructFirewallForIngress(gceController *GCEIngressController) *compute.Firewall {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						nodeTags := framework.GetNodeTags(j.client, gceController.cloud)
 | 
					 | 
					 | 
					 | 
						nodeTags := GetNodeTags(j.Client, gceController.Cloud)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						nodePorts := j.getIngressNodePorts()
 | 
					 | 
					 | 
					 | 
						nodePorts := j.GetIngressNodePorts()
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw := compute.Firewall{}
 | 
					 | 
					 | 
					 | 
						fw := compute.Firewall{}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw.Name = gceController.getFirewallRuleName()
 | 
					 | 
					 | 
					 | 
						fw.Name = gceController.GetFirewallRuleName()
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw.SourceRanges = []string{GCEL7SrcRange}
 | 
					 | 
					 | 
					 | 
						fw.SourceRanges = []string{GCEL7SrcRange}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw.TargetTags = nodeTags.Items
 | 
					 | 
					 | 
					 | 
						fw.TargetTags = nodeTags.Items
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						fw.Allowed = []*compute.FirewallAllowed{
 | 
					 | 
					 | 
					 | 
						fw.Allowed = []*compute.FirewallAllowed{
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -933,23 +967,23 @@ func (j *testJig) constructFirewallForIngress(gceController *GCEIngressControlle
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return &fw
 | 
					 | 
					 | 
					 | 
						return &fw
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// ingFromManifest reads a .json/yaml file and returns the rc in it.
 | 
					 | 
					 | 
					 | 
					// createIngressFromManifest reads a .json/yaml file and returns the rc in it.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func ingFromManifest(fileName string) *extensions.Ingress {
 | 
					 | 
					 | 
					 | 
					func createIngressFromManifest(fileName string) *extensions.Ingress {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						var ing extensions.Ingress
 | 
					 | 
					 | 
					 | 
						var ing extensions.Ingress
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Parsing ingress from %v", fileName)
 | 
					 | 
					 | 
					 | 
						Logf("Parsing ingress from %v", fileName)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data, err := ioutil.ReadFile(fileName)
 | 
					 | 
					 | 
					 | 
						data, err := ioutil.ReadFile(fileName)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json, err := utilyaml.ToJSON(data)
 | 
					 | 
					 | 
					 | 
						json, err := utilyaml.ToJSON(data)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &ing))
 | 
					 | 
					 | 
					 | 
						ExpectNoError(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &ing))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return &ing
 | 
					 | 
					 | 
					 | 
						return &ing
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) getL7AddonUID() (string, error) {
 | 
					 | 
					 | 
					 | 
					func (cont *GCEIngressController) getL7AddonUID() (string, error) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("Retrieving UID from config map: %v/%v", metav1.NamespaceSystem, uidConfigMap)
 | 
					 | 
					 | 
					 | 
						Logf("Retrieving UID from config map: %v/%v", metav1.NamespaceSystem, uidConfigMap)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cm, err := cont.c.Core().ConfigMaps(metav1.NamespaceSystem).Get(uidConfigMap, metav1.GetOptions{})
 | 
					 | 
					 | 
					 | 
						cm, err := cont.Client.Core().ConfigMaps(metav1.NamespaceSystem).Get(uidConfigMap, metav1.GetOptions{})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return "", err
 | 
					 | 
					 | 
					 | 
							return "", err
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -959,64 +993,54 @@ func (cont *GCEIngressController) getL7AddonUID() (string, error) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return "", fmt.Errorf("Could not find cluster UID for L7 addon pod")
 | 
					 | 
					 | 
					 | 
						return "", fmt.Errorf("Could not find cluster UID for L7 addon pod")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func exists(path string) bool {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						_, err := os.Stat(path)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err == nil {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return true
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if os.IsNotExist(err) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return false
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Failf("Failed to os.Stat path %v", path)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return false
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// GCEIngressController manages implementation details of Ingress on GCE/GKE.
 | 
					 | 
					 | 
					 | 
					// GCEIngressController manages implementation details of Ingress on GCE/GKE.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					type GCEIngressController struct {
 | 
					 | 
					 | 
					 | 
					type GCEIngressController struct {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ns           string
 | 
					 | 
					 | 
					 | 
						Ns           string
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rcPath       string
 | 
					 | 
					 | 
					 | 
						rcPath       string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						UID          string
 | 
					 | 
					 | 
					 | 
						UID          string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						staticIPName string
 | 
					 | 
					 | 
					 | 
						staticIPName string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rc           *v1.ReplicationController
 | 
					 | 
					 | 
					 | 
						rc           *v1.ReplicationController
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						svc          *v1.Service
 | 
					 | 
					 | 
					 | 
						svc          *v1.Service
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						c            clientset.Interface
 | 
					 | 
					 | 
					 | 
						Client       clientset.Interface
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cloud        framework.CloudConfig
 | 
					 | 
					 | 
					 | 
						Cloud        CloudConfig
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func newTestJig(c clientset.Interface) *testJig {
 | 
					 | 
					 | 
					 | 
					// NewIngressTestJig instantiates struct with client
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return &testJig{client: c, rootCAs: map[string][]byte{}, pollInterval: framework.LoadBalancerPollInterval}
 | 
					 | 
					 | 
					 | 
					func NewIngressTestJig(c clientset.Interface) *IngressTestJig {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return &IngressTestJig{Client: c, RootCAs: map[string][]byte{}, PollInterval: LoadBalancerPollInterval}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// NginxIngressController manages implementation details of Ingress on Nginx.
 | 
					 | 
					 | 
					 | 
					// NginxIngressController manages implementation details of Ingress on Nginx.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					type NginxIngressController struct {
 | 
					 | 
					 | 
					 | 
					type NginxIngressController struct {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ns         string
 | 
					 | 
					 | 
					 | 
						Ns         string
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rc         *v1.ReplicationController
 | 
					 | 
					 | 
					 | 
						rc         *v1.ReplicationController
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pod        *v1.Pod
 | 
					 | 
					 | 
					 | 
						pod        *v1.Pod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						c          clientset.Interface
 | 
					 | 
					 | 
					 | 
						Client     clientset.Interface
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						externalIP string
 | 
					 | 
					 | 
					 | 
						externalIP string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (cont *NginxIngressController) init() {
 | 
					 | 
					 | 
					 | 
					// Init initializes the NginxIngressController
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					func (cont *NginxIngressController) Init() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mkpath := func(file string) string {
 | 
					 | 
					 | 
					 | 
						mkpath := func(file string) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return filepath.Join(framework.TestContext.RepoRoot, ingressManifestPath, "nginx", file)
 | 
					 | 
					 | 
					 | 
							return filepath.Join(TestContext.RepoRoot, IngressManifestPath, "nginx", file)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("initializing nginx ingress controller")
 | 
					 | 
					 | 
					 | 
						Logf("initializing nginx ingress controller")
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.RunKubectlOrDie("create", "-f", mkpath("rc.yaml"), fmt.Sprintf("--namespace=%v", cont.ns))
 | 
					 | 
					 | 
					 | 
						RunKubectlOrDie("create", "-f", mkpath("rc.yaml"), fmt.Sprintf("--namespace=%v", cont.Ns))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						rc, err := cont.c.Core().ReplicationControllers(cont.ns).Get("nginx-ingress-controller", metav1.GetOptions{})
 | 
					 | 
					 | 
					 | 
						rc, err := cont.Client.Core().ReplicationControllers(cont.Ns).Get("nginx-ingress-controller", metav1.GetOptions{})
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cont.rc = rc
 | 
					 | 
					 | 
					 | 
						cont.rc = rc
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("waiting for pods with label %v", rc.Spec.Selector)
 | 
					 | 
					 | 
					 | 
						Logf("waiting for pods with label %v", rc.Spec.Selector)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sel := labels.SelectorFromSet(labels.Set(rc.Spec.Selector))
 | 
					 | 
					 | 
					 | 
						sel := labels.SelectorFromSet(labels.Set(rc.Spec.Selector))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(testutils.WaitForPodsWithLabelRunning(cont.c, cont.ns, sel))
 | 
					 | 
					 | 
					 | 
						ExpectNoError(testutils.WaitForPodsWithLabelRunning(cont.Client, cont.Ns, sel))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pods, err := cont.c.Core().Pods(cont.ns).List(metav1.ListOptions{LabelSelector: sel.String()})
 | 
					 | 
					 | 
					 | 
						pods, err := cont.Client.Core().Pods(cont.Ns).List(metav1.ListOptions{LabelSelector: sel.String()})
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if len(pods.Items) == 0 {
 | 
					 | 
					 | 
					 | 
						if len(pods.Items) == 0 {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							framework.Failf("Failed to find nginx ingress controller pods with selector %v", sel)
 | 
					 | 
					 | 
					 | 
							Failf("Failed to find nginx ingress controller pods with selector %v", sel)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cont.pod = &pods.Items[0]
 | 
					 | 
					 | 
					 | 
						cont.pod = &pods.Items[0]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cont.externalIP, err = framework.GetHostExternalAddress(cont.c, cont.pod)
 | 
					 | 
					 | 
					 | 
						cont.externalIP, err = GetHostExternalAddress(cont.Client, cont.pod)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.ExpectNoError(err)
 | 
					 | 
					 | 
					 | 
						ExpectNoError(err)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						framework.Logf("ingress controller running in pod %v on ip %v", cont.pod.Name, cont.externalIP)
 | 
					 | 
					 | 
					 | 
						Logf("ingress controller running in pod %v on ip %v", cont.pod.Name, cont.externalIP)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 |