mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
Add an rc strategy, start delta validating updates
This commit is contained in:
parent
df0838ed31
commit
6193608e9b
@ -17,12 +17,10 @@ limitations under the License.
|
|||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckGeneratedNameError(t *testing.T) {
|
func TestCheckGeneratedNameError(t *testing.T) {
|
||||||
@ -41,75 +39,3 @@ func TestCheckGeneratedNameError(t *testing.T) {
|
|||||||
t.Errorf("expected try again later error: %v", err)
|
t.Errorf("expected try again later error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeforeCreate(t *testing.T) {
|
|
||||||
failures := []runtime.Object{
|
|
||||||
&api.Service{},
|
|
||||||
&api.Service{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
Namespace: "#$%%invalid",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&api.Service{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "##&*(&invalid",
|
|
||||||
Namespace: api.NamespaceDefault,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range failures {
|
|
||||||
ctx := api.NewDefaultContext()
|
|
||||||
err := BeforeCreate(Services, ctx, test)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("unexpected non-error for %v", test)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obj := &api.ReplicationController{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
Namespace: api.NamespaceDefault,
|
|
||||||
},
|
|
||||||
Spec: api.ReplicationControllerSpec{
|
|
||||||
Selector: map[string]string{"name": "foo"},
|
|
||||||
Template: &api.PodTemplateSpec{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"name": "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Spec: api.PodSpec{
|
|
||||||
Containers: []api.Container{
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Image: "foo",
|
|
||||||
ImagePullPolicy: api.PullAlways,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
|
|
||||||
DNSPolicy: api.DNSDefault,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Status: api.ReplicationControllerStatus{
|
|
||||||
Replicas: 3,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ctx := api.NewDefaultContext()
|
|
||||||
err := BeforeCreate(ReplicationControllers, ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(obj.Status, api.ReplicationControllerStatus{}) {
|
|
||||||
t.Errorf("status was not cleared as expected.")
|
|
||||||
}
|
|
||||||
if obj.Name != "foo" || obj.Namespace != api.NamespaceDefault {
|
|
||||||
t.Errorf("unexpected object metadata: %v", obj.ObjectMeta)
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.Spec.Replicas = -1
|
|
||||||
if err := BeforeCreate(ReplicationControllers, ctx, obj); err == nil {
|
|
||||||
t.Errorf("unexpected non-error for invalid replication controller.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -44,34 +44,6 @@ func AllFuncs(fns ...ObjectFunc) ObjectFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rcStrategy implements behavior for Replication Controllers.
|
|
||||||
// TODO: move to a replicationcontroller specific package.
|
|
||||||
type rcStrategy struct {
|
|
||||||
runtime.ObjectTyper
|
|
||||||
api.NameGenerator
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReplicationControllers is the default logic that applies when creating and updating Replication Controller
|
|
||||||
// objects.
|
|
||||||
var ReplicationControllers RESTCreateStrategy = rcStrategy{api.Scheme, api.SimpleNameGenerator}
|
|
||||||
|
|
||||||
// NamespaceScoped is true for replication controllers.
|
|
||||||
func (rcStrategy) NamespaceScoped() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
|
||||||
func (rcStrategy) ResetBeforeCreate(obj runtime.Object) {
|
|
||||||
controller := obj.(*api.ReplicationController)
|
|
||||||
controller.Status = api.ReplicationControllerStatus{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates a new replication controller.
|
|
||||||
func (rcStrategy) Validate(obj runtime.Object) errors.ValidationErrorList {
|
|
||||||
controller := obj.(*api.ReplicationController)
|
|
||||||
return validation.ValidateReplicationController(controller)
|
|
||||||
}
|
|
||||||
|
|
||||||
// svcStrategy implements behavior for Services
|
// svcStrategy implements behavior for Services
|
||||||
// TODO: move to a service specific package.
|
// TODO: move to a service specific package.
|
||||||
type svcStrategy struct {
|
type svcStrategy struct {
|
||||||
|
@ -29,6 +29,43 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// rcStrategy implements verification logic for Replication Controllers.
|
||||||
|
type rcStrategy struct {
|
||||||
|
runtime.ObjectTyper
|
||||||
|
api.NameGenerator
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy is the default logic that applies when creating and updating Replication Controller objects.
|
||||||
|
var Strategy = rcStrategy{api.Scheme, api.SimpleNameGenerator}
|
||||||
|
|
||||||
|
// NamespaceScoped returns true because all Replication Controllers need to be within a namespace.
|
||||||
|
func (rcStrategy) NamespaceScoped() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetBeforeCreate clears the status of a replication controller before creation.
|
||||||
|
func (rcStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||||
|
controller := obj.(*api.ReplicationController)
|
||||||
|
controller.Status = api.ReplicationControllerStatus{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates a new replication controller.
|
||||||
|
func (rcStrategy) Validate(obj runtime.Object) errors.ValidationErrorList {
|
||||||
|
controller := obj.(*api.ReplicationController)
|
||||||
|
return validation.ValidateReplicationController(controller)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowCreateOnUpdate is false for replication controllers; this means a POST is
|
||||||
|
// needed to create one.
|
||||||
|
func (rcStrategy) AllowCreateOnUpdate() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateUpdate is the default update validation for an end user.
|
||||||
|
func (rcStrategy) ValidateUpdate(obj, old runtime.Object) errors.ValidationErrorList {
|
||||||
|
return validation.ValidateReplicationControllerUpdate(old.(*api.ReplicationController), obj.(*api.ReplicationController))
|
||||||
|
}
|
||||||
|
|
||||||
// PodLister is anything that knows how to list pods.
|
// PodLister is anything that knows how to list pods.
|
||||||
type PodLister interface {
|
type PodLister interface {
|
||||||
ListPods(ctx api.Context, labels labels.Selector) (*api.PodList, error)
|
ListPods(ctx api.Context, labels labels.Selector) (*api.PodList, error)
|
||||||
@ -38,6 +75,7 @@ type PodLister interface {
|
|||||||
type REST struct {
|
type REST struct {
|
||||||
registry Registry
|
registry Registry
|
||||||
podLister PodLister
|
podLister PodLister
|
||||||
|
strategy rcStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewREST returns a new apiserver.RESTStorage for the given registry and PodLister.
|
// NewREST returns a new apiserver.RESTStorage for the given registry and PodLister.
|
||||||
@ -45,23 +83,25 @@ func NewREST(registry Registry, podLister PodLister) *REST {
|
|||||||
return &REST{
|
return &REST{
|
||||||
registry: registry,
|
registry: registry,
|
||||||
podLister: podLister,
|
podLister: podLister,
|
||||||
|
strategy: Strategy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create registers the given ReplicationController.
|
// Create registers the given ReplicationController with the system,
|
||||||
|
// which eventually leads to the controller manager acting on its behalf.
|
||||||
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||||
controller, ok := obj.(*api.ReplicationController)
|
controller, ok := obj.(*api.ReplicationController)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
return nil, fmt.Errorf("not a replication controller: %#v", obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := rest.BeforeCreate(rest.ReplicationControllers, ctx, obj); err != nil {
|
if err := rest.BeforeCreate(rs.strategy, ctx, obj); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := rs.registry.CreateController(ctx, controller)
|
out, err := rs.registry.CreateController(ctx, controller)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = rest.CheckGeneratedNameError(rest.ReplicationControllers, err, controller)
|
err = rest.CheckGeneratedNameError(rs.strategy, err, controller)
|
||||||
}
|
}
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
@ -115,11 +155,12 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, fmt.Errorf("not a replication controller: %#v", obj)
|
return nil, false, fmt.Errorf("not a replication controller: %#v", obj)
|
||||||
}
|
}
|
||||||
if !api.ValidNamespace(ctx, &controller.ObjectMeta) {
|
existingController, err := rs.registry.GetController(ctx, controller.Name)
|
||||||
return nil, false, errors.NewConflict("controller", controller.Namespace, fmt.Errorf("Controller.Namespace does not match the provided context"))
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
}
|
}
|
||||||
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
|
if err := rest.BeforeUpdate(rs.strategy, ctx, controller, existingController); err != nil {
|
||||||
return nil, false, errors.NewInvalid("replicationController", controller.Name, errs)
|
return nil, false, err
|
||||||
}
|
}
|
||||||
out, err := rs.registry.UpdateController(ctx, controller)
|
out, err := rs.registry.UpdateController(ctx, controller)
|
||||||
return out, false, err
|
return out, false, err
|
||||||
|
@ -20,17 +20,20 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
|
||||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestListControllersError(t *testing.T) {
|
func TestListControllersError(t *testing.T) {
|
||||||
@ -258,6 +261,7 @@ func TestCreateController(t *testing.T) {
|
|||||||
storage := REST{
|
storage := REST{
|
||||||
registry: &mockRegistry,
|
registry: &mockRegistry,
|
||||||
podLister: &mockPodRegistry,
|
podLister: &mockPodRegistry,
|
||||||
|
strategy: Strategy,
|
||||||
}
|
}
|
||||||
controller := &api.ReplicationController{
|
controller := &api.ReplicationController{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "test"},
|
ObjectMeta: api.ObjectMeta{Name: "test"},
|
||||||
@ -287,6 +291,7 @@ func TestControllerStorageValidatesCreate(t *testing.T) {
|
|||||||
storage := REST{
|
storage := REST{
|
||||||
registry: &mockRegistry,
|
registry: &mockRegistry,
|
||||||
podLister: nil,
|
podLister: nil,
|
||||||
|
strategy: Strategy,
|
||||||
}
|
}
|
||||||
failureCases := map[string]api.ReplicationController{
|
failureCases := map[string]api.ReplicationController{
|
||||||
"empty ID": {
|
"empty ID": {
|
||||||
@ -312,34 +317,71 @@ func TestControllerStorageValidatesCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestControllerStorageValidatesUpdate(t *testing.T) {
|
func TestControllerValidatesUpdate(t *testing.T) {
|
||||||
mockRegistry := registrytest.ControllerRegistry{}
|
mockRegistry := registrytest.ControllerRegistry{
|
||||||
|
Controllers: &api.ReplicationControllerList{},
|
||||||
|
}
|
||||||
storage := REST{
|
storage := REST{
|
||||||
registry: &mockRegistry,
|
registry: &mockRegistry,
|
||||||
podLister: nil,
|
podLister: nil,
|
||||||
|
strategy: Strategy,
|
||||||
}
|
}
|
||||||
failureCases := map[string]api.ReplicationController{
|
|
||||||
"empty ID": {
|
var validControllerSpec = api.ReplicationControllerSpec{
|
||||||
ObjectMeta: api.ObjectMeta{Name: ""},
|
Selector: validPodTemplate.Spec.Labels,
|
||||||
Spec: api.ReplicationControllerSpec{
|
Template: &validPodTemplate.Spec,
|
||||||
Selector: map[string]string{"bar": "baz"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"empty selector": {
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: "abc"},
|
|
||||||
Spec: api.ReplicationControllerSpec{},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var validController = api.ReplicationController{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
|
||||||
|
Spec: validControllerSpec,
|
||||||
|
}
|
||||||
|
|
||||||
ctx := api.NewDefaultContext()
|
ctx := api.NewDefaultContext()
|
||||||
for _, failureCase := range failureCases {
|
storage.Create(ctx, &validController)
|
||||||
c, created, err := storage.Update(ctx, &failureCase)
|
ns := "newNamespace"
|
||||||
if c != nil || created {
|
|
||||||
|
updaters := []func(rc api.ReplicationController) (runtime.Object, bool, error){
|
||||||
|
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||||
|
rc.UID = "newUID"
|
||||||
|
return storage.Update(ctx, &rc)
|
||||||
|
},
|
||||||
|
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||||
|
rc.Name = ""
|
||||||
|
return storage.Update(ctx, &rc)
|
||||||
|
},
|
||||||
|
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||||
|
rc.Namespace = ns
|
||||||
|
return storage.Update(api.WithNamespace(ctx, ns), &rc)
|
||||||
|
},
|
||||||
|
func(rc api.ReplicationController) (runtime.Object, bool, error) {
|
||||||
|
rc.Spec.Selector = map[string]string{}
|
||||||
|
return storage.Update(ctx, &rc)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, u := range updaters {
|
||||||
|
c, updated, err := u(validController)
|
||||||
|
if c != nil || updated {
|
||||||
t.Errorf("Expected nil object and not created")
|
t.Errorf("Expected nil object and not created")
|
||||||
}
|
}
|
||||||
if !errors.IsInvalid(err) {
|
if !errors.IsInvalid(err) {
|
||||||
t.Errorf("Expected to get an invalid resource error, got %v", err)
|
t.Errorf("Expected to get an invalid resource error, got %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// The update should fail if the namespace on the controller is set to something
|
||||||
|
// other than the namespace on the given context, even if the namespace on the
|
||||||
|
// controller is valid.
|
||||||
|
c, updated, err := storage.Update(api.WithNamespace(ctx, ns), &validController)
|
||||||
|
if c != nil || updated {
|
||||||
|
t.Errorf("Expected nil object and not created")
|
||||||
|
}
|
||||||
|
errSubString := "namespace"
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected an error, but we didn't get one")
|
||||||
|
} else if !errors.IsBadRequest(err) ||
|
||||||
|
strings.Index(err.Error(), errSubString) == -1 {
|
||||||
|
t.Errorf("Expected a Bad Request error with the sub string '%s', got %v", errSubString, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakePodLister struct {
|
type fakePodLister struct {
|
||||||
@ -380,7 +422,7 @@ func TestCreateControllerWithGeneratedName(t *testing.T) {
|
|||||||
|
|
||||||
// TODO: remove, covered by TestCreate
|
// TODO: remove, covered by TestCreate
|
||||||
func TestCreateControllerWithConflictingNamespace(t *testing.T) {
|
func TestCreateControllerWithConflictingNamespace(t *testing.T) {
|
||||||
storage := REST{}
|
storage := REST{strategy: Strategy}
|
||||||
controller := &api.ReplicationController{
|
controller := &api.ReplicationController{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
||||||
}
|
}
|
||||||
@ -390,28 +432,12 @@ func TestCreateControllerWithConflictingNamespace(t *testing.T) {
|
|||||||
if channel != nil {
|
if channel != nil {
|
||||||
t.Error("Expected a nil channel, but we got a value")
|
t.Error("Expected a nil channel, but we got a value")
|
||||||
}
|
}
|
||||||
|
errSubString := "namespace"
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected an error, but we didn't get one")
|
t.Errorf("Expected an error, but we didn't get one")
|
||||||
} else if strings.Contains(err.Error(), "Controller.Namespace does not match the provided context") {
|
} else if !errors.IsBadRequest(err) ||
|
||||||
t.Errorf("Expected 'Controller.Namespace does not match the provided context' error, got '%v'", err.Error())
|
strings.Index(err.Error(), errSubString) == -1 {
|
||||||
}
|
t.Errorf("Expected a Bad Request error with the sub string '%s', got %v", errSubString, err)
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdateControllerWithConflictingNamespace(t *testing.T) {
|
|
||||||
storage := REST{}
|
|
||||||
controller := &api.ReplicationController{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := api.NewDefaultContext()
|
|
||||||
obj, created, err := storage.Update(ctx, controller)
|
|
||||||
if obj != nil || created {
|
|
||||||
t.Error("Expected a nil object, but we got a value or created was true")
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("Expected an error, but we didn't get one")
|
|
||||||
} else if strings.Index(err.Error(), "Controller.Namespace does not match the provided context") == -1 {
|
|
||||||
t.Errorf("Expected 'Controller.Namespace does not match the provided context' error, got '%v'", err.Error())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,3 +463,75 @@ func TestCreate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBeforeCreate(t *testing.T) {
|
||||||
|
failures := []runtime.Object{
|
||||||
|
&api.Service{},
|
||||||
|
&api.Service{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
Namespace: "#$%%invalid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&api.Service{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "##&*(&invalid",
|
||||||
|
Namespace: api.NamespaceDefault,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range failures {
|
||||||
|
ctx := api.NewDefaultContext()
|
||||||
|
err := rest.BeforeCreate(rest.Services, ctx, test)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("unexpected non-error for %v", test)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := &api.ReplicationController{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
Namespace: api.NamespaceDefault,
|
||||||
|
},
|
||||||
|
Spec: api.ReplicationControllerSpec{
|
||||||
|
Selector: map[string]string{"name": "foo"},
|
||||||
|
Template: &api.PodTemplateSpec{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"name": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Image: "foo",
|
||||||
|
ImagePullPolicy: api.PullAlways,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
|
||||||
|
DNSPolicy: api.DNSDefault,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: api.ReplicationControllerStatus{
|
||||||
|
Replicas: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx := api.NewDefaultContext()
|
||||||
|
err := rest.BeforeCreate(Strategy, ctx, obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(obj.Status, api.ReplicationControllerStatus{}) {
|
||||||
|
t.Errorf("status was not cleared as expected.")
|
||||||
|
}
|
||||||
|
if obj.Name != "foo" || obj.Namespace != api.NamespaceDefault {
|
||||||
|
t.Errorf("unexpected object metadata: %v", obj.ObjectMeta)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.Spec.Replicas = -1
|
||||||
|
if err := rest.BeforeCreate(Strategy, ctx, obj); err == nil {
|
||||||
|
t.Errorf("unexpected non-error for invalid replication controller.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -47,12 +47,22 @@ func (r *ControllerRegistry) ListControllers(ctx api.Context) (*api.ReplicationC
|
|||||||
func (r *ControllerRegistry) GetController(ctx api.Context, ID string) (*api.ReplicationController, error) {
|
func (r *ControllerRegistry) GetController(ctx api.Context, ID string) (*api.ReplicationController, error) {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
|
if r.Controllers != nil {
|
||||||
|
for _, rc := range r.Controllers.Items {
|
||||||
|
if ID == rc.Name {
|
||||||
|
return &r.Controllers.Items[0], r.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return &api.ReplicationController{}, r.Err
|
return &api.ReplicationController{}, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ControllerRegistry) CreateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) {
|
func (r *ControllerRegistry) CreateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
|
if r.Controllers != nil {
|
||||||
|
r.Controllers.Items = append(r.Controllers.Items, *controller)
|
||||||
|
}
|
||||||
return controller, r.Err
|
return controller, r.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user