By default block service proxy to external IP addresses.
Service proxy uses redirects to Pods instead of direct access.
This commit is contained in:
		@@ -168,6 +168,13 @@ const (
 | 
				
			|||||||
	// Enable nodes to exclude themselves from service load balancers
 | 
						// Enable nodes to exclude themselves from service load balancers
 | 
				
			||||||
	ServiceNodeExclusion utilfeature.Feature = "ServiceNodeExclusion"
 | 
						ServiceNodeExclusion utilfeature.Feature = "ServiceNodeExclusion"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// owner @brendandburns
 | 
				
			||||||
 | 
						// stable: v1.10
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Enable the service proxy to contact external IP addresses. Note this feature is present
 | 
				
			||||||
 | 
						// only for backward compatability, it will be removed in the 1.11 release.
 | 
				
			||||||
 | 
						ServiceProxyAllowExternalIPs utilfeature.Feature = "ServiceProxyAllowExternalIPs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// owner: @jsafrane
 | 
						// owner: @jsafrane
 | 
				
			||||||
	// alpha: v1.9
 | 
						// alpha: v1.9
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
@@ -268,4 +275,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
 | 
				
			|||||||
	// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
 | 
						// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
 | 
				
			||||||
	// unintentionally on either side:
 | 
						// unintentionally on either side:
 | 
				
			||||||
	apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
 | 
						apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// backward compatability features that enable backwards compatability but should be removed soon.
 | 
				
			||||||
 | 
						ServiceProxyAllowExternalIPs: {Default: false, PreRelease: utilfeature.Beta},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -172,7 +172,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	controllerStorage := controllerstore.NewStorage(restOptionsGetter)
 | 
						controllerStorage := controllerstore.NewStorage(restOptionsGetter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serviceRest := service.NewStorage(serviceRegistry, endpointRegistry, ServiceClusterIPAllocator, ServiceNodePortAllocator, c.ProxyTransport)
 | 
						serviceRest := service.NewStorage(serviceRegistry, endpointRegistry, podStorage.Pod, ServiceClusterIPAllocator, ServiceNodePortAllocator, c.ProxyTransport)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	restStorageMap := map[string]rest.Storage{
 | 
						restStorageMap := map[string]rest.Storage{
 | 
				
			||||||
		"pods":             podStorage.Pod,
 | 
							"pods":             podStorage.Pod,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,9 @@ go_library(
 | 
				
			|||||||
        "//pkg/apis/core/helper:go_default_library",
 | 
					        "//pkg/apis/core/helper:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core/validation:go_default_library",
 | 
					        "//pkg/apis/core/validation:go_default_library",
 | 
				
			||||||
        "//pkg/capabilities:go_default_library",
 | 
					        "//pkg/capabilities:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/features:go_default_library",
 | 
				
			||||||
        "//pkg/registry/core/endpoint:go_default_library",
 | 
					        "//pkg/registry/core/endpoint:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/registry/core/pod/storage:go_default_library",
 | 
				
			||||||
        "//pkg/registry/core/service/ipallocator:go_default_library",
 | 
					        "//pkg/registry/core/service/ipallocator:go_default_library",
 | 
				
			||||||
        "//pkg/registry/core/service/portallocator:go_default_library",
 | 
					        "//pkg/registry/core/service/portallocator:go_default_library",
 | 
				
			||||||
        "//vendor/github.com/golang/glog:go_default_library",
 | 
					        "//vendor/github.com/golang/glog:go_default_library",
 | 
				
			||||||
@@ -39,6 +41,7 @@ go_library(
 | 
				
			|||||||
        "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
 | 
					        "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
 | 
					        "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
 | 
					        "//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,6 +57,7 @@ go_test(
 | 
				
			|||||||
        "//pkg/api/service:go_default_library",
 | 
					        "//pkg/api/service:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core:go_default_library",
 | 
					        "//pkg/apis/core:go_default_library",
 | 
				
			||||||
        "//pkg/apis/core/helper:go_default_library",
 | 
					        "//pkg/apis/core/helper:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/registry/core/pod/storage:go_default_library",
 | 
				
			||||||
        "//pkg/registry/core/service/ipallocator:go_default_library",
 | 
					        "//pkg/registry/core/service/ipallocator:go_default_library",
 | 
				
			||||||
        "//pkg/registry/core/service/portallocator:go_default_library",
 | 
					        "//pkg/registry/core/service/portallocator:go_default_library",
 | 
				
			||||||
        "//pkg/registry/registrytest:go_default_library",
 | 
					        "//pkg/registry/registrytest:go_default_library",
 | 
				
			||||||
@@ -65,7 +69,9 @@ go_test(
 | 
				
			|||||||
        "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
 | 
					        "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
 | 
					        "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,11 +35,14 @@ import (
 | 
				
			|||||||
	"k8s.io/apimachinery/pkg/watch"
 | 
						"k8s.io/apimachinery/pkg/watch"
 | 
				
			||||||
	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
						genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/registry/rest"
 | 
						"k8s.io/apiserver/pkg/registry/rest"
 | 
				
			||||||
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	apiservice "k8s.io/kubernetes/pkg/api/service"
 | 
						apiservice "k8s.io/kubernetes/pkg/api/service"
 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/validation"
 | 
						"k8s.io/kubernetes/pkg/apis/core/validation"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/core/endpoint"
 | 
						"k8s.io/kubernetes/pkg/registry/core/endpoint"
 | 
				
			||||||
 | 
						podstore "k8s.io/kubernetes/pkg/registry/core/pod/storage"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
 | 
						"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/core/service/portallocator"
 | 
						"k8s.io/kubernetes/pkg/registry/core/service/portallocator"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -57,6 +60,7 @@ type REST struct {
 | 
				
			|||||||
	serviceIPs       ipallocator.Interface
 | 
						serviceIPs       ipallocator.Interface
 | 
				
			||||||
	serviceNodePorts portallocator.Interface
 | 
						serviceNodePorts portallocator.Interface
 | 
				
			||||||
	proxyTransport   http.RoundTripper
 | 
						proxyTransport   http.RoundTripper
 | 
				
			||||||
 | 
						pods             *podstore.REST
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ServiceNodePort includes protocol and port number of a service NodePort.
 | 
					// ServiceNodePort includes protocol and port number of a service NodePort.
 | 
				
			||||||
@@ -70,7 +74,7 @@ type ServiceNodePort struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewStorage returns a new REST.
 | 
					// NewStorage returns a new REST.
 | 
				
			||||||
func NewStorage(registry Registry, endpoints endpoint.Registry, serviceIPs ipallocator.Interface,
 | 
					func NewStorage(registry Registry, endpoints endpoint.Registry, pods *podstore.REST, serviceIPs ipallocator.Interface,
 | 
				
			||||||
	serviceNodePorts portallocator.Interface, proxyTransport http.RoundTripper) *ServiceRest {
 | 
						serviceNodePorts portallocator.Interface, proxyTransport http.RoundTripper) *ServiceRest {
 | 
				
			||||||
	rest := &REST{
 | 
						rest := &REST{
 | 
				
			||||||
		registry:         registry,
 | 
							registry:         registry,
 | 
				
			||||||
@@ -78,6 +82,7 @@ func NewStorage(registry Registry, endpoints endpoint.Registry, serviceIPs ipall
 | 
				
			|||||||
		serviceIPs:       serviceIPs,
 | 
							serviceIPs:       serviceIPs,
 | 
				
			||||||
		serviceNodePorts: serviceNodePorts,
 | 
							serviceNodePorts: serviceNodePorts,
 | 
				
			||||||
		proxyTransport:   proxyTransport,
 | 
							proxyTransport:   proxyTransport,
 | 
				
			||||||
 | 
							pods:             pods,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &ServiceRest{
 | 
						return &ServiceRest{
 | 
				
			||||||
		Service: rest,
 | 
							Service: rest,
 | 
				
			||||||
@@ -425,19 +430,57 @@ func (rs *REST) ResourceLocation(ctx genericapirequest.Context, id string) (*url
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		for i := range ss.Ports {
 | 
							for i := range ss.Ports {
 | 
				
			||||||
			if ss.Ports[i].Name == portStr {
 | 
								if ss.Ports[i].Name == portStr {
 | 
				
			||||||
				// Pick a random address.
 | 
									addrSeed := rand.Intn(len(ss.Addresses))
 | 
				
			||||||
				ip := ss.Addresses[rand.Intn(len(ss.Addresses))].IP
 | 
									// This is a little wonky, but it's expensive to test for the presence of a Pod
 | 
				
			||||||
 | 
									// So we repeatedly try at random and validate it, this means that for an invalid
 | 
				
			||||||
 | 
									// service with a lot of endpoints we're going to potentially make a lot of calls,
 | 
				
			||||||
 | 
									// but in the expected case we'll only make one.
 | 
				
			||||||
 | 
									for try := 0; try < len(ss.Addresses); try++ {
 | 
				
			||||||
 | 
										addr := ss.Addresses[(addrSeed+try)%len(ss.Addresses)]
 | 
				
			||||||
 | 
										if !utilfeature.DefaultFeatureGate.Enabled(features.ServiceProxyAllowExternalIPs) {
 | 
				
			||||||
 | 
											if err := isValidAddress(ctx, &addr, rs.pods); err != nil {
 | 
				
			||||||
 | 
												glog.Errorf("Address %v isn't valid (%v)", addr, err)
 | 
				
			||||||
 | 
												continue
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										ip := addr.IP
 | 
				
			||||||
					port := int(ss.Ports[i].Port)
 | 
										port := int(ss.Ports[i].Port)
 | 
				
			||||||
					return &url.URL{
 | 
										return &url.URL{
 | 
				
			||||||
						Scheme: svcScheme,
 | 
											Scheme: svcScheme,
 | 
				
			||||||
						Host:   net.JoinHostPort(ip, strconv.Itoa(port)),
 | 
											Host:   net.JoinHostPort(ip, strconv.Itoa(port)),
 | 
				
			||||||
					}, rs.proxyTransport, nil
 | 
										}, rs.proxyTransport, nil
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									glog.Errorf("Failed to find a valid address, skipping subset: %v", ss)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", id))
 | 
						return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", id))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isValidAddress(ctx genericapirequest.Context, addr *api.EndpointAddress, pods *podstore.REST) error {
 | 
				
			||||||
 | 
						if addr.TargetRef == nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Address has no target ref, skipping: %v", addr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if genericapirequest.NamespaceValue(ctx) != addr.TargetRef.Namespace {
 | 
				
			||||||
 | 
							return fmt.Errorf("Address namespace doesn't match context namespace")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						obj, err := pods.Get(ctx, addr.TargetRef.Name, &metav1.GetOptions{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pod, ok := obj.(*api.Pod)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to cast to pod: %v", obj)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if pod == nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("pod is missing, skipping (%s/%s)", addr.TargetRef.Namespace, addr.TargetRef.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if pod.Status.PodIP != addr.IP {
 | 
				
			||||||
 | 
							return fmt.Errorf("pod ip doesn't match endpoint ip, skipping: %s vs %s (%s/%s)", pod.Status.PodIP, addr.IP, addr.TargetRef.Namespace, addr.TargetRef.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This is O(N), but we expect haystack to be small;
 | 
					// This is O(N), but we expect haystack to be small;
 | 
				
			||||||
// so small that we expect a linear search to be faster
 | 
					// so small that we expect a linear search to be faster
 | 
				
			||||||
func containsNumber(haystack []int, needle int) bool {
 | 
					func containsNumber(haystack []int, needle int) bool {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,10 +30,13 @@ import (
 | 
				
			|||||||
	utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
						utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/rand"
 | 
						"k8s.io/apimachinery/pkg/util/rand"
 | 
				
			||||||
	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
						genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
				
			||||||
 | 
						"k8s.io/apiserver/pkg/registry/generic"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/registry/rest"
 | 
						"k8s.io/apiserver/pkg/registry/rest"
 | 
				
			||||||
 | 
						etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/service"
 | 
						"k8s.io/kubernetes/pkg/api/service"
 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
 | 
						podstore "k8s.io/kubernetes/pkg/registry/core/pod/storage"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
 | 
						"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/core/service/portallocator"
 | 
						"k8s.io/kubernetes/pkg/registry/core/service/portallocator"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/registry/registrytest"
 | 
						"k8s.io/kubernetes/pkg/registry/registrytest"
 | 
				
			||||||
@@ -47,19 +50,40 @@ func generateRandomNodePort() int32 {
 | 
				
			|||||||
	return int32(rand.IntnRange(30001, 30999))
 | 
						return int32(rand.IntnRange(30001, 30999))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTestREST(t *testing.T, endpoints *api.EndpointsList) (*REST, *registrytest.ServiceRegistry) {
 | 
					func NewTestREST(t *testing.T, endpoints *api.EndpointsList) (*REST, *registrytest.ServiceRegistry, *etcdtesting.EtcdTestServer) {
 | 
				
			||||||
 | 
						return NewTestRESTWithPods(t, endpoints, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.PodList) (*REST, *registrytest.ServiceRegistry, *etcdtesting.EtcdTestServer) {
 | 
				
			||||||
	registry := registrytest.NewServiceRegistry()
 | 
						registry := registrytest.NewServiceRegistry()
 | 
				
			||||||
	endpointRegistry := ®istrytest.EndpointRegistry{
 | 
						endpointRegistry := ®istrytest.EndpointRegistry{
 | 
				
			||||||
		Endpoints: endpoints,
 | 
							Endpoints: endpoints,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						etcdStorage, server := registrytest.NewEtcdStorage(t, "")
 | 
				
			||||||
 | 
						restOptions := generic.RESTOptions{
 | 
				
			||||||
 | 
							StorageConfig:           etcdStorage,
 | 
				
			||||||
 | 
							Decorator:               generic.UndecoratedStorage,
 | 
				
			||||||
 | 
							DeleteCollectionWorkers: 3,
 | 
				
			||||||
 | 
							ResourcePrefix:          "pods",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						podStorage := podstore.NewStorage(restOptions, nil, nil, nil)
 | 
				
			||||||
 | 
						if pods != nil && pods.Items != nil {
 | 
				
			||||||
 | 
							ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
 | 
							for ix := range pods.Items {
 | 
				
			||||||
 | 
								key, _ := podStorage.Pod.KeyFunc(ctx, pods.Items[ix].Name)
 | 
				
			||||||
 | 
								if err := podStorage.Pod.Storage.Create(ctx, key, &pods.Items[ix], nil, 0); err != nil {
 | 
				
			||||||
 | 
									t.Fatalf("Couldn't create pod: %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	r := ipallocator.NewCIDRRange(makeIPNet(t))
 | 
						r := ipallocator.NewCIDRRange(makeIPNet(t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	portRange := utilnet.PortRange{Base: 30000, Size: 1000}
 | 
						portRange := utilnet.PortRange{Base: 30000, Size: 1000}
 | 
				
			||||||
	portAllocator := portallocator.NewPortAllocator(portRange)
 | 
						portAllocator := portallocator.NewPortAllocator(portRange)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	storage := NewStorage(registry, endpointRegistry, r, portAllocator, nil)
 | 
						storage := NewStorage(registry, endpointRegistry, podStorage.Pod, r, portAllocator, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return storage.Service, registry
 | 
						return storage.Service, registry, server
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeIPNet(t *testing.T) *net.IPNet {
 | 
					func makeIPNet(t *testing.T) *net.IPNet {
 | 
				
			||||||
@@ -89,7 +113,8 @@ func releaseServiceNodePorts(t *testing.T, ctx genericapirequest.Context, svcNam
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryCreate(t *testing.T) {
 | 
					func TestServiceRegistryCreate(t *testing.T) {
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
@@ -136,7 +161,9 @@ func TestServiceRegistryCreate(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) {
 | 
					func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) {
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testCases := []struct {
 | 
						testCases := []struct {
 | 
				
			||||||
		svc             *api.Service
 | 
							svc             *api.Service
 | 
				
			||||||
		name            string
 | 
							name            string
 | 
				
			||||||
@@ -264,7 +291,8 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceStorageValidatesCreate(t *testing.T) {
 | 
					func TestServiceStorageValidatesCreate(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	failureCases := map[string]api.Service{
 | 
						failureCases := map[string]api.Service{
 | 
				
			||||||
		"empty ID": {
 | 
							"empty ID": {
 | 
				
			||||||
			ObjectMeta: metav1.ObjectMeta{Name: ""},
 | 
								ObjectMeta: metav1.ObjectMeta{Name: ""},
 | 
				
			||||||
@@ -317,7 +345,9 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryUpdate(t *testing.T) {
 | 
					func TestServiceRegistryUpdate(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc, err := registry.CreateService(ctx, &api.Service{
 | 
						svc, err := registry.CreateService(ctx, &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -368,7 +398,8 @@ func TestServiceRegistryUpdate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceStorageValidatesUpdate(t *testing.T) {
 | 
					func TestServiceStorageValidatesUpdate(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	registry.CreateService(ctx, &api.Service{
 | 
						registry.CreateService(ctx, &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -420,7 +451,8 @@ func TestServiceStorageValidatesUpdate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryExternalService(t *testing.T) {
 | 
					func TestServiceRegistryExternalService(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -458,7 +490,8 @@ func TestServiceRegistryExternalService(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryDelete(t *testing.T) {
 | 
					func TestServiceRegistryDelete(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -480,7 +513,8 @@ func TestServiceRegistryDelete(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryDeleteExternal(t *testing.T) {
 | 
					func TestServiceRegistryDeleteExternal(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -502,7 +536,8 @@ func TestServiceRegistryDeleteExternal(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryUpdateExternalService(t *testing.T) {
 | 
					func TestServiceRegistryUpdateExternalService(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create non-external load balancer.
 | 
						// Create non-external load balancer.
 | 
				
			||||||
	svc1 := &api.Service{
 | 
						svc1 := &api.Service{
 | 
				
			||||||
@@ -540,7 +575,8 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) {
 | 
					func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create external load balancer.
 | 
						// Create external load balancer.
 | 
				
			||||||
	svc1 := &api.Service{
 | 
						svc1 := &api.Service{
 | 
				
			||||||
@@ -577,7 +613,8 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryGet(t *testing.T) {
 | 
					func TestServiceRegistryGet(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	registry.CreateService(ctx, &api.Service{
 | 
						registry.CreateService(ctx, &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -594,13 +631,27 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
 | 
				
			|||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	endpoints := &api.EndpointsList{
 | 
						endpoints := &api.EndpointsList{
 | 
				
			||||||
		Items: []api.Endpoints{
 | 
							Items: []api.Endpoints{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
										Name:      "bad",
 | 
				
			||||||
 | 
										Namespace: metav1.NamespaceDefault,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Subsets: []api.EndpointSubset{{
 | 
				
			||||||
 | 
										Addresses: []api.EndpointAddress{
 | 
				
			||||||
 | 
											{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: "doesn't exist"}},
 | 
				
			||||||
 | 
											{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "doesn't exist", Namespace: metav1.NamespaceDefault}},
 | 
				
			||||||
 | 
											{IP: "23.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
				
			||||||
 | 
									}},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				ObjectMeta: metav1.ObjectMeta{
 | 
									ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
					Name:      "foo",
 | 
										Name:      "foo",
 | 
				
			||||||
					Namespace: metav1.NamespaceDefault,
 | 
										Namespace: metav1.NamespaceDefault,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Subsets: []api.EndpointSubset{{
 | 
									Subsets: []api.EndpointSubset{{
 | 
				
			||||||
					Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
 | 
										Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}},
 | 
				
			||||||
					Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
										Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
				
			||||||
				}},
 | 
									}},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@@ -613,18 +664,52 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
 | 
				
			|||||||
					Addresses: []api.EndpointAddress{},
 | 
										Addresses: []api.EndpointAddress{},
 | 
				
			||||||
					Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
										Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
				
			||||||
				}, {
 | 
									}, {
 | 
				
			||||||
					Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
 | 
										Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}},
 | 
				
			||||||
					Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
										Ports:     []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}},
 | 
				
			||||||
				}, {
 | 
									}, {
 | 
				
			||||||
					Addresses: []api.EndpointAddress{{IP: "1.2.3.5"}},
 | 
										Addresses: []api.EndpointAddress{{IP: "1.2.3.5", TargetRef: &api.ObjectReference{Name: "bar", Namespace: metav1.NamespaceDefault}}},
 | 
				
			||||||
					Ports:     []api.EndpointPort{},
 | 
										Ports:     []api.EndpointPort{},
 | 
				
			||||||
				}},
 | 
									}},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	storage, registry := NewTestREST(t, endpoints)
 | 
						pods := &api.PodList{
 | 
				
			||||||
 | 
							Items: []api.Pod{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
										Name:      "foo",
 | 
				
			||||||
 | 
										Namespace: metav1.NamespaceDefault,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
 | 
										RestartPolicy: "Always",
 | 
				
			||||||
 | 
										DNSPolicy:     "Default",
 | 
				
			||||||
 | 
										Containers:    []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePolicy: api.TerminationMessageReadFile}},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Status: api.PodStatus{
 | 
				
			||||||
 | 
										PodIP: "1.2.3.4",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
										Name:      "bar",
 | 
				
			||||||
 | 
										Namespace: metav1.NamespaceDefault,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
 | 
										RestartPolicy: "Always",
 | 
				
			||||||
 | 
										DNSPolicy:     "Default",
 | 
				
			||||||
 | 
										Containers:    []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePolicy: api.TerminationMessageReadFile}},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Status: api.PodStatus{
 | 
				
			||||||
 | 
										PodIP: "1.2.3.5",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						storage, registry, server := NewTestRESTWithPods(t, endpoints, pods)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
						for _, name := range []string{"foo", "bad"} {
 | 
				
			||||||
		registry.CreateService(ctx, &api.Service{
 | 
							registry.CreateService(ctx, &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
								ObjectMeta: metav1.ObjectMeta{Name: name},
 | 
				
			||||||
			Spec: api.ServiceSpec{
 | 
								Spec: api.ServiceSpec{
 | 
				
			||||||
				Selector: map[string]string{"bar": "baz"},
 | 
									Selector: map[string]string{"bar": "baz"},
 | 
				
			||||||
				Ports: []api.ServicePort{
 | 
									Ports: []api.ServicePort{
 | 
				
			||||||
@@ -637,6 +722,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}, rest.ValidateAllObjectFunc)
 | 
							}, rest.ValidateAllObjectFunc)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	redirector := rest.Redirector(storage)
 | 
						redirector := rest.Redirector(storage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Test a simple id.
 | 
						// Test a simple id.
 | 
				
			||||||
@@ -709,11 +795,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
 | 
				
			|||||||
	if _, _, err = redirector.ResourceLocation(ctx, "bar"); err == nil {
 | 
						if _, _, err = redirector.ResourceLocation(ctx, "bar"); err == nil {
 | 
				
			||||||
		t.Errorf("unexpected nil error")
 | 
							t.Errorf("unexpected nil error")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test a simple id.
 | 
				
			||||||
 | 
						_, _, err = redirector.ResourceLocation(ctx, "bad")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected nil error")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryList(t *testing.T) {
 | 
					func TestServiceRegistryList(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	registry.CreateService(ctx, &api.Service{
 | 
						registry.CreateService(ctx, &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -744,7 +837,8 @@ func TestServiceRegistryList(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryIPAllocation(t *testing.T) {
 | 
					func TestServiceRegistryIPAllocation(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc1 := &api.Service{
 | 
						svc1 := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
@@ -826,7 +920,8 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryIPReallocation(t *testing.T) {
 | 
					func TestServiceRegistryIPReallocation(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc1 := &api.Service{
 | 
						svc1 := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo"},
 | 
				
			||||||
@@ -881,7 +976,8 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryIPUpdate(t *testing.T) {
 | 
					func TestServiceRegistryIPUpdate(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"},
 | 
				
			||||||
@@ -935,7 +1031,8 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestServiceRegistryIPLoadBalancer(t *testing.T) {
 | 
					func TestServiceRegistryIPLoadBalancer(t *testing.T) {
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"},
 | 
				
			||||||
@@ -974,7 +1071,8 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
 | 
					func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	service := &api.Service{
 | 
						service := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "not-default"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "not-default"},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -995,7 +1093,8 @@ func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
 | 
				
			|||||||
// and type is LoadBalancer.
 | 
					// and type is LoadBalancer.
 | 
				
			||||||
func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) {
 | 
					func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -1034,7 +1133,8 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.
 | 
				
			|||||||
func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) {
 | 
					func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) {
 | 
				
			||||||
	randomNodePort := generateRandomNodePort()
 | 
						randomNodePort := generateRandomNodePort()
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -1076,7 +1176,8 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test
 | 
				
			|||||||
// Validate that the service creation fails when the requested port number is -1.
 | 
					// Validate that the service creation fails when the requested port number is -1.
 | 
				
			||||||
func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) {
 | 
					func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -1102,7 +1203,8 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T)
 | 
				
			|||||||
// Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global.
 | 
					// Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global.
 | 
				
			||||||
func TestServiceRegistryExternalTrafficGlobal(t *testing.T) {
 | 
					func TestServiceRegistryExternalTrafficGlobal(t *testing.T) {
 | 
				
			||||||
	ctx := genericapirequest.NewDefaultContext()
 | 
						ctx := genericapirequest.NewDefaultContext()
 | 
				
			||||||
	storage, registry := NewTestREST(t, nil)
 | 
						storage, registry, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	svc := &api.Service{
 | 
						svc := &api.Service{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
 | 
				
			||||||
		Spec: api.ServiceSpec{
 | 
							Spec: api.ServiceSpec{
 | 
				
			||||||
@@ -1137,7 +1239,8 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestInitClusterIP(t *testing.T) {
 | 
					func TestInitClusterIP(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testCases := []struct {
 | 
						testCases := []struct {
 | 
				
			||||||
		name            string
 | 
							name            string
 | 
				
			||||||
@@ -1228,7 +1331,8 @@ func TestInitClusterIP(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestInitNodePorts(t *testing.T) {
 | 
					func TestInitNodePorts(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	nodePortOp := portallocator.StartOperation(storage.serviceNodePorts)
 | 
						nodePortOp := portallocator.StartOperation(storage.serviceNodePorts)
 | 
				
			||||||
	defer nodePortOp.Finish()
 | 
						defer nodePortOp.Finish()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1409,7 +1513,8 @@ func TestInitNodePorts(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestUpdateNodePorts(t *testing.T) {
 | 
					func TestUpdateNodePorts(t *testing.T) {
 | 
				
			||||||
	storage, _ := NewTestREST(t, nil)
 | 
						storage, _, server := NewTestREST(t, nil)
 | 
				
			||||||
 | 
						defer server.Terminate(t)
 | 
				
			||||||
	nodePortOp := portallocator.StartOperation(storage.serviceNodePorts)
 | 
						nodePortOp := portallocator.StartOperation(storage.serviceNodePorts)
 | 
				
			||||||
	defer nodePortOp.Finish()
 | 
						defer nodePortOp.Finish()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user