Merge pull request #1495 from derekwaynecarr/introduce_context_obj

Add and validate namespace to pod, service, replication controller objects
This commit is contained in:
Tim Hockin 2014-10-01 12:40:37 -07:00
commit c391fe81a9
18 changed files with 219 additions and 43 deletions

View File

@ -12,6 +12,10 @@
"type": "string",
"required": false
},
"namespace": {
"type": "string",
"required": false
},
"creationTimestamp": {
"type": "string",
"required": false

View File

@ -12,6 +12,10 @@
"type": "string",
"required": false
},
"namespace": {
"type": "string",
"required": false
},
"creationTimestamp": {
"type": "string",
"required": false

View File

@ -12,6 +12,10 @@
"type": "string",
"required": false
},
"namespace": {
"type": "string",
"required": false
},
"creationTimestamp": {
"type": "string",
"required": false

View File

@ -32,6 +32,7 @@ import (
)
func validateObject(obj runtime.Object) (errors []error) {
ctx := api.NewDefaultContext()
switch t := obj.(type) {
case *api.ReplicationController:
errors = validation.ValidateManifest(&t.DesiredState.PodTemplate.DesiredState.Manifest)
@ -40,12 +41,14 @@ func validateObject(obj runtime.Object) (errors []error) {
errors = append(errors, validateObject(&t.Items[i])...)
}
case *api.Service:
api.ValidNamespace(ctx, &t.JSONBase)
errors = validation.ValidateService(t)
case *api.ServiceList:
for i := range t.Items {
errors = append(errors, validateObject(&t.Items[i])...)
}
case *api.Pod:
api.ValidNamespace(ctx, &t.JSONBase)
errors = validation.ValidateManifest(&t.DesiredState.Manifest)
case *api.PodList:
for i := range t.Items {

View File

@ -17,6 +17,8 @@ limitations under the License.
package api
import (
stderrs "errors"
"code.google.com/p/go.net/context"
)
@ -25,7 +27,47 @@ type Context interface {
Value(key interface{}) interface{}
}
// NewContext instantiates a base context object for request flows
// The key type is unexported to prevent collisions
type key int
// namespaceKey is the context key for the request namespace.
const namespaceKey key = 0
// NewContext instantiates a base context object for request flows.
func NewContext() Context {
return context.TODO()
}
// NewDefaultContext instantiates a base context object for request flows in the default namespace
func NewDefaultContext() Context {
return WithNamespace(NewContext(), NamespaceDefault)
}
// WithValue returns a copy of parent in which the value associated with key is val.
func WithValue(parent Context, key interface{}, val interface{}) Context {
internalCtx, ok := parent.(context.Context)
if !ok {
panic(stderrs.New("Invalid context type"))
}
return context.WithValue(internalCtx, key, val)
}
// WithNamespace returns a copy of parent in which the namespace value is set
func WithNamespace(parent Context, namespace string) Context {
return WithValue(parent, namespaceKey, namespace)
}
// NamespaceFrom returns the value of the namespace key on the ctx
func NamespaceFrom(ctx Context) (string, bool) {
namespace, ok := ctx.Value(namespaceKey).(string)
return namespace, ok
}
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context.
func ValidNamespace(ctx Context, resource *JSONBase) bool {
ns, ok := NamespaceFrom(ctx)
if len(resource.Namespace) == 0 {
resource.Namespace = ns
}
return ns == resource.Namespace && ok
}

62
pkg/api/context_test.go Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
// TestNamespaceContext validates that a namespace can be get/set on a context object
func TestNamespaceContext(t *testing.T) {
ctx := api.NewDefaultContext()
result, ok := api.NamespaceFrom(ctx)
if !ok {
t.Errorf("Error getting namespace")
}
if api.NamespaceDefault != result {
t.Errorf("Expected: %v, Actual: %v", api.NamespaceDefault, result)
}
ctx = api.NewContext()
result, ok = api.NamespaceFrom(ctx)
if ok {
t.Errorf("Should not be ok because there is no namespace on the context")
}
}
// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update
func TestValidNamespace(t *testing.T) {
ctx := api.NewDefaultContext()
namespace, _ := api.NamespaceFrom(ctx)
resource := api.ReplicationController{}
if !api.ValidNamespace(ctx, &resource.JSONBase) {
t.Errorf("expected success")
}
if namespace != resource.Namespace {
t.Errorf("expected resource to have the default namespace assigned during validation")
}
resource = api.ReplicationController{JSONBase: api.JSONBase{Namespace: "other"}}
if api.ValidNamespace(ctx, &resource.JSONBase) {
t.Errorf("Expected error that resource and context errors do not match because resource has different namespace")
}
ctx = api.NewContext()
if api.ValidNamespace(ctx, &resource.JSONBase) {
t.Errorf("Expected error that resource and context errors do not match since context has no namespace")
}
}

View File

@ -237,8 +237,16 @@ type JSONBase struct {
SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
ResourceVersion uint64 `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
Namespace string `json:"namespace",omitempty" yaml:"namespace,omitempty"`
}
const (
// NamespaceDefault means the object is in the default namespace which is applied when not specified by clients
NamespaceDefault string = "default"
// NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces
NamespaceAll string = ""
)
// PodStatus represents a status of a pod.
type PodStatus string

View File

@ -248,6 +248,7 @@ type JSONBase struct {
SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
ResourceVersion uint64 `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
Namespace string `json:"namespace",omitempty" yaml:"namespace,omitempty"`
}
func (*JSONBase) IsAnAPIObject() {}

View File

@ -246,6 +246,7 @@ type JSONBase struct {
SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
ResourceVersion uint64 `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
Namespace string `json:"namespace",omitempty" yaml:"namespace,omitempty"`
}
// PodStatus represents a status of a pod.

View File

@ -313,6 +313,9 @@ func ValidatePod(pod *api.Pod) errs.ErrorList {
if len(pod.ID) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("id", pod.ID))
}
if !util.IsDNSSubdomain(pod.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("pod.Namespace", pod.Namespace))
}
allErrs = append(allErrs, ValidatePodState(&pod.DesiredState).Prefix("desiredState")...)
return allErrs
}
@ -325,6 +328,9 @@ func ValidateService(service *api.Service) errs.ErrorList {
} else if !util.IsDNS952Label(service.ID) {
allErrs = append(allErrs, errs.NewFieldInvalid("id", service.ID))
}
if !util.IsDNSSubdomain(service.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("service.Namespace", service.Namespace))
}
if !util.IsValidPortNum(service.Port) {
allErrs = append(allErrs, errs.NewFieldInvalid("Service.Port", service.Port))
}
@ -345,6 +351,9 @@ func ValidateReplicationController(controller *api.ReplicationController) errs.E
if len(controller.ID) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("id", controller.ID))
}
if !util.IsDNSSubdomain(controller.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("controller.Namespace", controller.Namespace))
}
allErrs = append(allErrs, ValidateReplicationControllerState(&controller.DesiredState).Prefix("desiredState")...)
return allErrs
}

View File

@ -366,7 +366,7 @@ func TestValidateManifest(t *testing.T) {
func TestValidatePod(t *testing.T) {
errs := ValidatePod(&api.Pod{
JSONBase: api.JSONBase{ID: "foo"},
JSONBase: api.JSONBase{ID: "foo", Namespace: api.NamespaceDefault},
Labels: map[string]string{
"foo": "bar",
},
@ -384,7 +384,7 @@ func TestValidatePod(t *testing.T) {
t.Errorf("Unexpected non-zero error list: %#v", errs)
}
errs = ValidatePod(&api.Pod{
JSONBase: api.JSONBase{ID: "foo"},
JSONBase: api.JSONBase{ID: "foo", Namespace: api.NamespaceDefault},
Labels: map[string]string{
"foo": "bar",
},
@ -397,7 +397,7 @@ func TestValidatePod(t *testing.T) {
}
errs = ValidatePod(&api.Pod{
JSONBase: api.JSONBase{ID: "foo"},
JSONBase: api.JSONBase{ID: "foo", Namespace: api.NamespaceDefault},
Labels: map[string]string{
"foo": "bar",
},
@ -424,16 +424,27 @@ func TestValidateService(t *testing.T) {
{
name: "missing id",
svc: api.Service{
JSONBase: api.JSONBase{Namespace: api.NamespaceDefault},
Port: 8675,
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the ID is missing.
numErrs: 1,
},
{
name: "missing namespace",
svc: api.Service{
JSONBase: api.JSONBase{ID: "foo"},
Port: 8675,
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the Namespace is missing.
numErrs: 1,
},
{
name: "invalid id",
svc: api.Service{
JSONBase: api.JSONBase{ID: "123abc"},
JSONBase: api.JSONBase{ID: "123abc", Namespace: api.NamespaceDefault},
Port: 8675,
Selector: map[string]string{"foo": "bar"},
},
@ -443,7 +454,7 @@ func TestValidateService(t *testing.T) {
{
name: "missing port",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Selector: map[string]string{"foo": "bar"},
},
// Should fail because the port number is missing/invalid.
@ -452,7 +463,7 @@ func TestValidateService(t *testing.T) {
{
name: "invalid port",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Port: 65536,
Selector: map[string]string{"foo": "bar"},
},
@ -462,7 +473,7 @@ func TestValidateService(t *testing.T) {
{
name: "invalid protocol",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Port: 8675,
Protocol: "INVALID",
Selector: map[string]string{"foo": "bar"},
@ -473,7 +484,7 @@ func TestValidateService(t *testing.T) {
{
name: "missing selector",
svc: api.Service{
JSONBase: api.JSONBase{ID: "foo"},
JSONBase: api.JSONBase{ID: "foo", Namespace: api.NamespaceDefault},
Port: 8675,
},
// Should fail because the selector is missing.
@ -482,7 +493,7 @@ func TestValidateService(t *testing.T) {
{
name: "valid 1",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Port: 1,
Protocol: "TCP",
Selector: map[string]string{"foo": "bar"},
@ -492,7 +503,7 @@ func TestValidateService(t *testing.T) {
{
name: "valid 2",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Port: 65535,
Protocol: "UDP",
Selector: map[string]string{"foo": "bar"},
@ -502,7 +513,7 @@ func TestValidateService(t *testing.T) {
{
name: "valid 3",
svc: api.Service{
JSONBase: api.JSONBase{ID: "abc123"},
JSONBase: api.JSONBase{ID: "abc123", Namespace: api.NamespaceDefault},
Port: 80,
Selector: map[string]string{"foo": "bar"},
},
@ -519,7 +530,7 @@ func TestValidateService(t *testing.T) {
svc := api.Service{
Port: 6502,
JSONBase: api.JSONBase{ID: "foo"},
JSONBase: api.JSONBase{ID: "foo", Namespace: api.NamespaceDefault},
Selector: map[string]string{"foo": "bar"},
}
errs := ValidateService(&svc)
@ -544,14 +555,14 @@ func TestValidateReplicationController(t *testing.T) {
successCases := []api.ReplicationController{
{
JSONBase: api.JSONBase{ID: "abc"},
JSONBase: api.JSONBase{ID: "abc", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: validSelector,
PodTemplate: validPodTemplate,
},
},
{
JSONBase: api.JSONBase{ID: "abc-123"},
JSONBase: api.JSONBase{ID: "abc-123", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: validSelector,
PodTemplate: validPodTemplate,
@ -566,33 +577,40 @@ func TestValidateReplicationController(t *testing.T) {
errorCases := map[string]api.ReplicationController{
"zero-length ID": {
JSONBase: api.JSONBase{ID: ""},
JSONBase: api.JSONBase{ID: "", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: validSelector,
PodTemplate: validPodTemplate,
},
},
"missing-namespace": {
JSONBase: api.JSONBase{ID: "abc-123"},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: validSelector,
PodTemplate: validPodTemplate,
},
},
"empty selector": {
JSONBase: api.JSONBase{ID: "abc"},
JSONBase: api.JSONBase{ID: "abc", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
PodTemplate: validPodTemplate,
},
},
"selector_doesnt_match": {
JSONBase: api.JSONBase{ID: "abc"},
JSONBase: api.JSONBase{ID: "abc", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: map[string]string{"foo": "bar"},
PodTemplate: validPodTemplate,
},
},
"invalid manifest": {
JSONBase: api.JSONBase{ID: "abc"},
JSONBase: api.JSONBase{ID: "abc", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
ReplicaSelector: validSelector,
},
},
"negative_replicas": {
JSONBase: api.JSONBase{ID: "abc"},
JSONBase: api.JSONBase{ID: "abc", Namespace: api.NamespaceDefault},
DesiredState: api.ReplicationControllerState{
Replicas: -1,
ReplicaSelector: validSelector,
@ -608,6 +626,7 @@ func TestValidateReplicationController(t *testing.T) {
field := errs[i].(errors.ValidationError).Field
if !strings.HasPrefix(field, "desiredState.podTemplate.") &&
field != "id" &&
field != "controller.Namespace" &&
field != "desiredState.replicaSelector" &&
field != "desiredState.replicas" {
t.Errorf("%s: missing prefix for: %v", k, errs[i])

View File

@ -100,7 +100,8 @@ func curry(f func(runtime.Object, *http.Request) error, req *http.Request) func(
// timeout=<duration> Timeout for synchronous requests, only applies if sync=true
// labels=<label-selector> Used for filtering list operations
func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w http.ResponseWriter, storage RESTStorage) {
ctx := api.NewContext()
// TODO for now, we perform all operations in the default namespace
ctx := api.NewDefaultContext()
sync := req.URL.Query().Get("sync") == "true"
timeout := parseTimeout(req.URL.Query().Get("timeout"))
switch req.Method {

View File

@ -59,6 +59,10 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan runtime.Obje
if !ok {
return nil, fmt.Errorf("not a replication controller: %#v", obj)
}
if !api.ValidNamespace(ctx, &controller.JSONBase) {
return nil, errors.NewConflict("controller", controller.Namespace, fmt.Errorf("Controller.Namespace does not match the provided context"))
}
if len(controller.ID) == 0 {
controller.ID = uuid.NewUUID().String()
}
@ -128,6 +132,9 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan runtime.Obje
if !ok {
return nil, fmt.Errorf("not a replication controller: %#v", obj)
}
if !api.ValidNamespace(ctx, &controller.JSONBase) {
return nil, errors.NewConflict("controller", controller.Namespace, fmt.Errorf("Controller.Namespace does not match the provided context"))
}
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
return nil, errors.NewInvalid("replicationController", controller.ID, errs)
}

View File

@ -243,7 +243,7 @@ func TestCreateController(t *testing.T) {
PodTemplate: validPodTemplate,
},
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
channel, err := storage.Create(ctx, controller)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
@ -279,8 +279,8 @@ func TestControllerStorageValidatesCreate(t *testing.T) {
DesiredState: api.ReplicationControllerState{},
},
}
ctx := api.NewDefaultContext()
for _, failureCase := range failureCases {
ctx := api.NewContext()
c, err := storage.Create(ctx, &failureCase)
if c != nil {
t.Errorf("Expected nil channel")
@ -310,8 +310,8 @@ func TestControllerStorageValidatesUpdate(t *testing.T) {
DesiredState: api.ReplicationControllerState{},
},
}
ctx := api.NewDefaultContext()
for _, failureCase := range failureCases {
ctx := api.NewContext()
c, err := storage.Update(ctx, &failureCase)
if c != nil {
t.Errorf("Expected nil channel")

View File

@ -69,6 +69,9 @@ func NewREST(config *RESTConfig) *REST {
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan runtime.Object, error) {
pod := obj.(*api.Pod)
if !api.ValidNamespace(ctx, &pod.JSONBase) {
return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context"))
}
pod.DesiredState.Manifest.UUID = uuid.NewUUID().String()
if len(pod.ID) == 0 {
pod.ID = pod.DesiredState.Manifest.UUID
@ -77,7 +80,6 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan runtime.Obje
if errs := validation.ValidatePod(pod); len(errs) > 0 {
return nil, errors.NewInvalid("pod", pod.ID, errs)
}
pod.CreationTimestamp = util.Now()
return apiserver.MakeAsync(func() (runtime.Object, error) {
@ -159,6 +161,9 @@ func (*REST) New() runtime.Object {
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan runtime.Object, error) {
pod := obj.(*api.Pod)
if !api.ValidNamespace(ctx, &pod.JSONBase) {
return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context"))
}
if errs := validation.ValidatePod(pod); len(errs) > 0 {
return nil, errors.NewInvalid("pod", pod.ID, errs)
}

View File

@ -69,7 +69,7 @@ func TestCreatePodRegistryError(t *testing.T) {
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod)
if err != nil {
t.Errorf("Expected %#v, Got %#v", nil, err)
@ -89,7 +89,7 @@ func TestCreatePodSetsIds(t *testing.T) {
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod)
if err != nil {
t.Errorf("Expected %#v, Got %#v", nil, err)
@ -116,7 +116,7 @@ func TestCreatePodSetsUUIDs(t *testing.T) {
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod)
if err != nil {
t.Errorf("Expected %#v, Got %#v", nil, err)
@ -496,7 +496,7 @@ func TestPodStorageValidatesCreate(t *testing.T) {
storage := REST{
registry: podRegistry,
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
pod := &api.Pod{}
c, err := storage.Create(ctx, pod)
if c != nil {
@ -513,7 +513,7 @@ func TestPodStorageValidatesUpdate(t *testing.T) {
storage := REST{
registry: podRegistry,
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
pod := &api.Pod{}
c, err := storage.Update(ctx, pod)
if c != nil {
@ -545,7 +545,7 @@ func TestCreatePod(t *testing.T) {
JSONBase: api.JSONBase{ID: "foo"},
DesiredState: desiredState,
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
channel, err := storage.Create(ctx, pod)
if err != nil {
t.Errorf("unexpected error: %v", err)

View File

@ -52,6 +52,9 @@ func NewREST(registry Registry, cloud cloudprovider.Interface, machines minion.R
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan runtime.Object, error) {
srv := obj.(*api.Service)
if !api.ValidNamespace(ctx, &srv.JSONBase) {
return nil, errors.NewConflict("service", srv.Namespace, fmt.Errorf("Service.Namespace does not match the provided context"))
}
if errs := validation.ValidateService(srv); len(errs) > 0 {
return nil, errors.NewInvalid("service", srv.ID, errs)
}
@ -165,6 +168,9 @@ func GetServiceEnvironmentVariables(ctx api.Context, registry Registry, machine
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan runtime.Object, error) {
srv := obj.(*api.Service)
if !api.ValidNamespace(ctx, &srv.JSONBase) {
return nil, errors.NewConflict("service", srv.Namespace, fmt.Errorf("Service.Namespace does not match the provided context"))
}
if errs := validation.ValidateService(srv); len(errs) > 0 {
return nil, errors.NewInvalid("service", srv.ID, errs)
}

View File

@ -40,7 +40,7 @@ func TestServiceRegistryCreate(t *testing.T) {
JSONBase: api.JSONBase{ID: "foo"},
Selector: map[string]string{"bar": "baz"},
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
c, _ := storage.Create(ctx, svc)
created_svc := <-c
created_service := created_svc.(*api.Service)
@ -76,7 +76,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
Selector: map[string]string{},
},
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
for _, failureCase := range failureCases {
c, err := storage.Create(ctx, &failureCase)
if c != nil {
@ -90,7 +90,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
}
func TestServiceRegistryUpdate(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
registry.CreateService(ctx, &api.Service{
Port: 6502,
@ -120,7 +120,7 @@ func TestServiceRegistryUpdate(t *testing.T) {
}
func TestServiceStorageValidatesUpdate(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
registry.CreateService(ctx, &api.Service{
Port: 6502,
@ -152,7 +152,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) {
}
func TestServiceRegistryExternalService(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
fakeCloud := &cloud.FakeCloud{}
machines := []string{"foo", "bar", "baz"}
@ -190,7 +190,7 @@ func TestServiceRegistryExternalServiceError(t *testing.T) {
Selector: map[string]string{"bar": "baz"},
CreateExternalLoadBalancer: true,
}
ctx := api.NewContext()
ctx := api.NewDefaultContext()
c, _ := storage.Create(ctx, svc)
<-c
if len(fakeCloud.Calls) != 1 || fakeCloud.Calls[0] != "get-zone" {
@ -202,7 +202,7 @@ func TestServiceRegistryExternalServiceError(t *testing.T) {
}
func TestServiceRegistryDelete(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
fakeCloud := &cloud.FakeCloud{}
machines := []string{"foo", "bar", "baz"}
@ -223,7 +223,7 @@ func TestServiceRegistryDelete(t *testing.T) {
}
func TestServiceRegistryDeleteExternal(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
fakeCloud := &cloud.FakeCloud{}
machines := []string{"foo", "bar", "baz"}
@ -245,7 +245,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) {
}
func TestServiceRegistryMakeLinkVariables(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
registry.List = api.ServiceList{
Items: []api.Service{
@ -310,7 +310,7 @@ func TestServiceRegistryMakeLinkVariables(t *testing.T) {
}
func TestServiceRegistryGet(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
fakeCloud := &cloud.FakeCloud{}
machines := []string{"foo", "bar", "baz"}
@ -329,7 +329,7 @@ func TestServiceRegistryGet(t *testing.T) {
}
func TestServiceRegistryResourceLocation(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
registry.Endpoints = api.Endpoints{Endpoints: []string{"foo:80"}}
fakeCloud := &cloud.FakeCloud{}
@ -359,7 +359,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
}
func TestServiceRegistryList(t *testing.T) {
ctx := api.NewContext()
ctx := api.NewDefaultContext()
registry := registrytest.NewServiceRegistry()
fakeCloud := &cloud.FakeCloud{}
machines := []string{"foo", "bar", "baz"}