mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Merge pull request #5690 from satnam6502/failputnover
Give better error message for PUTs with no resource version
This commit is contained in:
commit
a4bf91c8c0
@ -33,6 +33,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
obj: &api.Service{
|
obj: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: "#$%%invalid",
|
Namespace: "#$%%invalid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -43,12 +44,14 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
obj: &api.Service{
|
obj: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: "valid",
|
Namespace: "valid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
old: &api.Service{
|
old: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: "valid",
|
Namespace: "valid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -58,6 +61,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
obj: &api.Service{
|
obj: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: "valid",
|
Namespace: "valid",
|
||||||
},
|
},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
@ -67,6 +71,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
old: &api.Service{
|
old: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: "valid",
|
Namespace: "valid",
|
||||||
},
|
},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
@ -79,6 +84,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
obj: &api.Service{
|
obj: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: api.NamespaceDefault,
|
Namespace: api.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
@ -89,6 +95,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
old: &api.Service{
|
old: &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
ResourceVersion: "1",
|
||||||
Namespace: api.NamespaceDefault,
|
Namespace: api.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
|
@ -232,6 +232,11 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis
|
|||||||
meta.CreationTimestamp = old.CreationTimestamp
|
meta.CreationTimestamp = old.CreationTimestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reject updates that don't specify a resource version
|
||||||
|
if meta.ResourceVersion == "" {
|
||||||
|
allErrs = append(allErrs, errs.NewFieldInvalid("resourceVersion", meta.ResourceVersion, "resourceVersion must be specified for an update"))
|
||||||
|
}
|
||||||
|
|
||||||
if old.Name != meta.Name {
|
if old.Name != meta.Name {
|
||||||
allErrs = append(allErrs, errs.NewFieldInvalid("name", meta.Name, "field is immutable"))
|
allErrs = append(allErrs, errs.NewFieldInvalid("name", meta.Name, "field is immutable"))
|
||||||
}
|
}
|
||||||
|
@ -56,20 +56,20 @@ func TestValidateObjectMetaCustomName(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) {
|
func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) {
|
||||||
if errs := ValidateObjectMetaUpdate(
|
if errs := ValidateObjectMetaUpdate(
|
||||||
&api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
||||||
&api.ObjectMeta{Name: "test"},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||||
); len(errs) != 0 {
|
); len(errs) != 0 {
|
||||||
t.Fatalf("unexpected errors: %v", errs)
|
t.Fatalf("unexpected errors: %v", errs)
|
||||||
}
|
}
|
||||||
if errs := ValidateObjectMetaUpdate(
|
if errs := ValidateObjectMetaUpdate(
|
||||||
&api.ObjectMeta{Name: "test"},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||||
&api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
||||||
); len(errs) != 0 {
|
); len(errs) != 0 {
|
||||||
t.Fatalf("unexpected errors: %v", errs)
|
t.Fatalf("unexpected errors: %v", errs)
|
||||||
}
|
}
|
||||||
if errs := ValidateObjectMetaUpdate(
|
if errs := ValidateObjectMetaUpdate(
|
||||||
&api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(11, 0))},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(11, 0))},
|
||||||
&api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
&api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
||||||
); len(errs) != 0 {
|
); len(errs) != 0 {
|
||||||
t.Fatalf("unexpected errors: %v", errs)
|
t.Fatalf("unexpected errors: %v", errs)
|
||||||
}
|
}
|
||||||
@ -1208,6 +1208,8 @@ func TestValidatePodUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test.a.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.b.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidatePodUpdate(&test.a, &test.b)
|
errs := ValidatePodUpdate(&test.a, &test.b)
|
||||||
if test.isValid {
|
if test.isValid {
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
@ -1522,6 +1524,8 @@ func TestValidateReplicationControllerUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, successCase := range successCases {
|
for _, successCase := range successCases {
|
||||||
|
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
|
successCase.update.ObjectMeta.ResourceVersion = "1"
|
||||||
if errs := ValidateReplicationControllerUpdate(&successCase.old, &successCase.update); len(errs) != 0 {
|
if errs := ValidateReplicationControllerUpdate(&successCase.old, &successCase.update); len(errs) != 0 {
|
||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
@ -2126,6 +2130,8 @@ func TestValidateMinionUpdate(t *testing.T) {
|
|||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
test.oldMinion.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.minion.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidateMinionUpdate(&test.oldMinion, &test.minion)
|
errs := ValidateMinionUpdate(&test.oldMinion, &test.minion)
|
||||||
if test.valid && len(errs) > 0 {
|
if test.valid && len(errs) > 0 {
|
||||||
t.Errorf("%d: Unexpected error: %v", i, errs)
|
t.Errorf("%d: Unexpected error: %v", i, errs)
|
||||||
@ -2295,6 +2301,8 @@ func TestValidateServiceUpdate(t *testing.T) {
|
|||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
test.oldService.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.service.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidateServiceUpdate(&test.oldService, &test.service)
|
errs := ValidateServiceUpdate(&test.oldService, &test.service)
|
||||||
if test.valid && len(errs) > 0 {
|
if test.valid && len(errs) > 0 {
|
||||||
t.Errorf("%d: Unexpected error: %v", i, errs)
|
t.Errorf("%d: Unexpected error: %v", i, errs)
|
||||||
@ -2560,6 +2568,8 @@ func TestValidateNamespaceFinalizeUpdate(t *testing.T) {
|
|||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
test.namespace.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.oldNamespace.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidateNamespaceFinalizeUpdate(&test.namespace, &test.oldNamespace)
|
errs := ValidateNamespaceFinalizeUpdate(&test.namespace, &test.oldNamespace)
|
||||||
if test.valid && len(errs) > 0 {
|
if test.valid && len(errs) > 0 {
|
||||||
t.Errorf("%d: Unexpected error: %v", i, errs)
|
t.Errorf("%d: Unexpected error: %v", i, errs)
|
||||||
@ -2600,6 +2610,8 @@ func TestValidateNamespaceStatusUpdate(t *testing.T) {
|
|||||||
}, false},
|
}, false},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
test.namespace.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.oldNamespace.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidateNamespaceStatusUpdate(&test.oldNamespace, &test.namespace)
|
errs := ValidateNamespaceStatusUpdate(&test.oldNamespace, &test.namespace)
|
||||||
if test.valid && len(errs) > 0 {
|
if test.valid && len(errs) > 0 {
|
||||||
t.Errorf("%d: Unexpected error: %v", i, errs)
|
t.Errorf("%d: Unexpected error: %v", i, errs)
|
||||||
@ -2670,6 +2682,8 @@ func TestValidateNamespaceUpdate(t *testing.T) {
|
|||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
test.namespace.ObjectMeta.ResourceVersion = "1"
|
||||||
|
test.oldNamespace.ObjectMeta.ResourceVersion = "1"
|
||||||
errs := ValidateNamespaceUpdate(&test.oldNamespace, &test.namespace)
|
errs := ValidateNamespaceUpdate(&test.oldNamespace, &test.namespace)
|
||||||
if test.valid && len(errs) > 0 {
|
if test.valid && len(errs) > 0 {
|
||||||
t.Errorf("%d: Unexpected error: %v", i, errs)
|
t.Errorf("%d: Unexpected error: %v", i, errs)
|
||||||
|
@ -129,15 +129,21 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
|
|||||||
func TestServiceRegistryUpdate(t *testing.T) {
|
func TestServiceRegistryUpdate(t *testing.T) {
|
||||||
ctx := api.NewDefaultContext()
|
ctx := api.NewDefaultContext()
|
||||||
storage, registry, _ := NewTestREST(t, nil)
|
storage, registry, _ := NewTestREST(t, nil)
|
||||||
registry.CreateService(ctx, &api.Service{
|
svc, err := registry.CreateService(ctx, &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
|
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: api.NamespaceDefault},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
Selector: map[string]string{"bar": "baz1"},
|
Selector: map[string]string{"bar": "baz1"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error: %v", err)
|
||||||
|
}
|
||||||
updated_svc, created, err := storage.Update(ctx, &api.Service{
|
updated_svc, created, err := storage.Update(ctx, &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
ResourceVersion: svc.ResourceVersion},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
Selector: map[string]string{"bar": "baz2"},
|
Selector: map[string]string{"bar": "baz2"},
|
||||||
@ -305,7 +311,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) {
|
|||||||
|
|
||||||
// Create non-external load balancer.
|
// Create non-external load balancer.
|
||||||
svc1 := &api.Service{
|
svc1 := &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
@ -546,7 +552,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
|
|||||||
rest.portalMgr.randomAttempts = 0
|
rest.portalMgr.randomAttempts = 0
|
||||||
|
|
||||||
svc := &api.Service{
|
svc := &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
@ -589,7 +595,7 @@ func TestServiceRegistryIPExternalLoadBalancer(t *testing.T) {
|
|||||||
rest.portalMgr.randomAttempts = 0
|
rest.portalMgr.randomAttempts = 0
|
||||||
|
|
||||||
svc := &api.Service{
|
svc := &api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
|
Loading…
Reference in New Issue
Block a user