mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #16152 from feihujiang/moveServiceStrategyToRegistryServicePackage
Auto commit by PR queue bot
This commit is contained in:
commit
fd03c2c1d7
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 The Kubernetes Authors 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 rest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCheckGeneratedNameError(t *testing.T) {
|
|
||||||
expect := errors.NewNotFound("foo", "bar")
|
|
||||||
if err := CheckGeneratedNameError(Services, expect, &api.Pod{}); err != expect {
|
|
||||||
t.Errorf("NotFoundError should be ignored: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expect = errors.NewAlreadyExists("foo", "bar")
|
|
||||||
if err := CheckGeneratedNameError(Services, expect, &api.Pod{}); err != expect {
|
|
||||||
t.Errorf("AlreadyExists should be returned when no GenerateName field: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expect = errors.NewAlreadyExists("foo", "bar")
|
|
||||||
if err := CheckGeneratedNameError(Services, expect, &api.Pod{ObjectMeta: api.ObjectMeta{GenerateName: "foo"}}); err == nil || !errors.IsServerTimeout(err) {
|
|
||||||
t.Errorf("expected try again later error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,10 +17,7 @@ limitations under the License.
|
|||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util/fielderrors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectFunc is a function to act on a given object. An error may be returned
|
// ObjectFunc is a function to act on a given object. An error may be returned
|
||||||
@ -43,51 +40,3 @@ func AllFuncs(fns ...ObjectFunc) ObjectFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// svcStrategy implements behavior for Services
|
|
||||||
// TODO: move to a service specific package.
|
|
||||||
type svcStrategy struct {
|
|
||||||
runtime.ObjectTyper
|
|
||||||
api.NameGenerator
|
|
||||||
}
|
|
||||||
|
|
||||||
// Services is the default logic that applies when creating and updating Service
|
|
||||||
// objects.
|
|
||||||
var Services = svcStrategy{api.Scheme, api.SimpleNameGenerator}
|
|
||||||
|
|
||||||
// NamespaceScoped is true for services.
|
|
||||||
func (svcStrategy) NamespaceScoped() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
|
||||||
func (svcStrategy) PrepareForCreate(obj runtime.Object) {
|
|
||||||
service := obj.(*api.Service)
|
|
||||||
service.Status = api.ServiceStatus{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
|
||||||
func (svcStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
|
||||||
// TODO: once service has a status sub-resource we can enable this.
|
|
||||||
//newService := obj.(*api.Service)
|
|
||||||
//oldService := old.(*api.Service)
|
|
||||||
//newService.Status = oldService.Status
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates a new service.
|
|
||||||
func (svcStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList {
|
|
||||||
service := obj.(*api.Service)
|
|
||||||
return validation.ValidateService(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svcStrategy) AllowCreateOnUpdate() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svcStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
|
|
||||||
return validation.ValidateServiceUpdate(old.(*api.Service), obj.(*api.Service))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svcStrategy) AllowUnconditionalUpdate() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
@ -211,7 +211,7 @@ func (c *Controller) CreateOrUpdateMasterServiceIfNeeded(serviceName string, ser
|
|||||||
Type: serviceType,
|
Type: serviceType,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := rest.BeforeCreate(rest.Services, ctx, svc); err != nil {
|
if err := rest.BeforeCreate(service.Strategy, ctx, svc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ type ResourceGetter interface {
|
|||||||
Get(api.Context, string) (runtime.Object, error)
|
Get(api.Context, string) (runtime.Object, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeToSelectableFields returns a label set that represents the object.
|
// NodeToSelectableFields returns a field set that represents the object.
|
||||||
func NodeToSelectableFields(node *api.Node) fields.Set {
|
func NodeToSelectableFields(node *api.Node) fields.Set {
|
||||||
objectMetaFieldsSet := generic.ObjectMetaFieldsSet(node.ObjectMeta, false)
|
objectMetaFieldsSet := generic.ObjectMetaFieldsSet(node.ObjectMeta, false)
|
||||||
specificFieldsSet := fields.Set{
|
specificFieldsSet := fields.Set{
|
||||||
|
@ -17,14 +17,12 @@ limitations under the License.
|
|||||||
package etcd
|
package etcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
|
||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
||||||
|
"k8s.io/kubernetes/pkg/registry/service"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
)
|
)
|
||||||
@ -49,29 +47,14 @@ func NewREST(s storage.Interface) *REST {
|
|||||||
return obj.(*api.Service).Name, nil
|
return obj.(*api.Service).Name, nil
|
||||||
},
|
},
|
||||||
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
|
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||||
return MatchServices(label, field)
|
return service.MatchServices(label, field)
|
||||||
},
|
},
|
||||||
EndpointName: "services",
|
EndpointName: "services",
|
||||||
|
|
||||||
CreateStrategy: rest.Services,
|
CreateStrategy: service.Strategy,
|
||||||
UpdateStrategy: rest.Services,
|
UpdateStrategy: service.Strategy,
|
||||||
|
|
||||||
Storage: s,
|
Storage: s,
|
||||||
}
|
}
|
||||||
return &REST{store}
|
return &REST{store}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Move it.
|
|
||||||
func MatchServices(label labels.Selector, field fields.Selector) generic.Matcher {
|
|
||||||
return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: ServiceAttributes}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ServiceAttributes(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
|
|
||||||
service, ok := obj.(*api.Service)
|
|
||||||
if !ok {
|
|
||||||
return nil, nil, fmt.Errorf("invalid object type %#v", obj)
|
|
||||||
}
|
|
||||||
return service.Labels, fields.Set{
|
|
||||||
"metadata.name": service.Name,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
@ -63,7 +63,7 @@ func NewStorage(registry Registry, endpoints endpoint.Registry, serviceIPs ipall
|
|||||||
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) {
|
||||||
service := obj.(*api.Service)
|
service := obj.(*api.Service)
|
||||||
|
|
||||||
if err := rest.BeforeCreate(rest.Services, ctx, obj); err != nil {
|
if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, err
|
|||||||
|
|
||||||
out, err := rs.registry.CreateService(ctx, service)
|
out, err := rs.registry.CreateService(ctx, service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = rest.CheckGeneratedNameError(rest.Services, err, service)
|
err = rest.CheckGeneratedNameError(Strategy, err, service)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
94
pkg/registry/service/strategy.go
Normal file
94
pkg/registry/service/strategy.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors 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 service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/util/fielderrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// svcStrategy implements behavior for Services
|
||||||
|
type svcStrategy struct {
|
||||||
|
runtime.ObjectTyper
|
||||||
|
api.NameGenerator
|
||||||
|
}
|
||||||
|
|
||||||
|
// Services is the default logic that applies when creating and updating Service
|
||||||
|
// objects.
|
||||||
|
var Strategy = svcStrategy{api.Scheme, api.SimpleNameGenerator}
|
||||||
|
|
||||||
|
// NamespaceScoped is true for services.
|
||||||
|
func (svcStrategy) NamespaceScoped() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||||
|
func (svcStrategy) PrepareForCreate(obj runtime.Object) {
|
||||||
|
service := obj.(*api.Service)
|
||||||
|
service.Status = api.ServiceStatus{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||||
|
func (svcStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||||
|
// TODO: once service has a status sub-resource we can enable this.
|
||||||
|
//newService := obj.(*api.Service)
|
||||||
|
//oldService := old.(*api.Service)
|
||||||
|
//newService.Status = oldService.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates a new service.
|
||||||
|
func (svcStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList {
|
||||||
|
service := obj.(*api.Service)
|
||||||
|
return validation.ValidateService(service)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svcStrategy) AllowCreateOnUpdate() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svcStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||||
|
return validation.ValidateServiceUpdate(old.(*api.Service), obj.(*api.Service))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svcStrategy) AllowUnconditionalUpdate() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func MatchServices(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||||
|
return &generic.SelectionPredicate{
|
||||||
|
Label: label,
|
||||||
|
Field: field,
|
||||||
|
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||||
|
service, ok := obj.(*api.Service)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, fmt.Errorf("Given object is not a service")
|
||||||
|
}
|
||||||
|
return labels.Set(service.ObjectMeta.Labels), ServiceToSelectableFields(service), nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServiceToSelectableFields(service *api.Service) fields.Set {
|
||||||
|
return generic.ObjectMetaFieldsSet(service.ObjectMeta, true)
|
||||||
|
}
|
@ -14,16 +14,35 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package rest
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestCheckGeneratedNameError(t *testing.T) {
|
||||||
|
expect := errors.NewNotFound("foo", "bar")
|
||||||
|
if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{}); err != expect {
|
||||||
|
t.Errorf("NotFoundError should be ignored: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expect = errors.NewAlreadyExists("foo", "bar")
|
||||||
|
if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{}); err != expect {
|
||||||
|
t.Errorf("AlreadyExists should be returned when no GenerateName field: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expect = errors.NewAlreadyExists("foo", "bar")
|
||||||
|
if err := rest.CheckGeneratedNameError(Strategy, expect, &api.Pod{ObjectMeta: api.ObjectMeta{GenerateName: "foo"}}); err == nil || !errors.IsServerTimeout(err) {
|
||||||
|
t.Errorf("expected try again later error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func makeValidService() api.Service {
|
func makeValidService() api.Service {
|
||||||
return api.Service{
|
return api.Service{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
@ -99,7 +118,7 @@ func TestBeforeUpdate(t *testing.T) {
|
|||||||
newSvc := makeValidService()
|
newSvc := makeValidService()
|
||||||
tc.tweakSvc(&oldSvc, &newSvc)
|
tc.tweakSvc(&oldSvc, &newSvc)
|
||||||
ctx := api.NewDefaultContext()
|
ctx := api.NewDefaultContext()
|
||||||
err := BeforeUpdate(Services, ctx, runtime.Object(&oldSvc), runtime.Object(&newSvc))
|
err := rest.BeforeUpdate(Strategy, ctx, runtime.Object(&oldSvc), runtime.Object(&newSvc))
|
||||||
if tc.expectErr && err == nil {
|
if tc.expectErr && err == nil {
|
||||||
t.Errorf("unexpected non-error for %q", tc.name)
|
t.Errorf("unexpected non-error for %q", tc.name)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user