mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
vendor updates
This commit is contained in:
62
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/BUILD
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/BUILD
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"strategy.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/registry/apps/daemonset",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/pod:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/extensions/validation:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta2:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field: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/storage/names:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["strategy_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/registry/apps/daemonset/storage:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
19
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/doc.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 daemonset provides Registry interface and its RESTStorage
|
||||
// implementation for storing DaemonSet api objects.
|
||||
package daemonset // import "k8s.io/kubernetes/pkg/registry/apps/daemonset"
|
57
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/BUILD
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/BUILD
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["storage_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/registry/registrytest:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/generic/testing:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["storage.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/registry/apps/daemonset/storage",
|
||||
deps = [
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/printers/internalversion:go_default_library",
|
||||
"//pkg/printers/storage:go_default_library",
|
||||
"//pkg/registry/apps/daemonset:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime: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/generic/registry:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
100
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/storage.go
generated
vendored
Normal file
100
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/storage.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 storage
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
printerstorage "k8s.io/kubernetes/pkg/printers/storage"
|
||||
"k8s.io/kubernetes/pkg/registry/apps/daemonset"
|
||||
)
|
||||
|
||||
// rest implements a RESTStorage for DaemonSets
|
||||
type REST struct {
|
||||
*genericregistry.Store
|
||||
categories []string
|
||||
}
|
||||
|
||||
// NewREST returns a RESTStorage object that will work against DaemonSets.
|
||||
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: func() runtime.Object { return &extensions.DaemonSet{} },
|
||||
NewListFunc: func() runtime.Object { return &extensions.DaemonSetList{} },
|
||||
DefaultQualifiedResource: extensions.Resource("daemonsets"),
|
||||
|
||||
CreateStrategy: daemonset.Strategy,
|
||||
UpdateStrategy: daemonset.Strategy,
|
||||
DeleteStrategy: daemonset.Strategy,
|
||||
|
||||
TableConvertor: printerstorage.TableConvertor{TablePrinter: printers.NewTablePrinter().With(printersinternal.AddHandlers)},
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
||||
panic(err) // TODO: Propagate error up
|
||||
}
|
||||
|
||||
statusStore := *store
|
||||
statusStore.UpdateStrategy = daemonset.StatusStrategy
|
||||
|
||||
return &REST{store, []string{"all"}}, &StatusREST{store: &statusStore}
|
||||
}
|
||||
|
||||
// Implement ShortNamesProvider
|
||||
var _ rest.ShortNamesProvider = &REST{}
|
||||
|
||||
// ShortNames implements the ShortNamesProvider interface. Returns a list of short names for a resource.
|
||||
func (r *REST) ShortNames() []string {
|
||||
return []string{"ds"}
|
||||
}
|
||||
|
||||
var _ rest.CategoriesProvider = &REST{}
|
||||
|
||||
// Categories implements the CategoriesProvider interface. Returns a list of categories a resource is part of.
|
||||
func (r *REST) Categories() []string {
|
||||
return r.categories
|
||||
}
|
||||
|
||||
func (r *REST) WithCategories(categories []string) *REST {
|
||||
r.categories = categories
|
||||
return r
|
||||
}
|
||||
|
||||
// StatusREST implements the REST endpoint for changing the status of a daemonset
|
||||
type StatusREST struct {
|
||||
store *genericregistry.Store
|
||||
}
|
||||
|
||||
func (r *StatusREST) New() runtime.Object {
|
||||
return &extensions.DaemonSet{}
|
||||
}
|
||||
|
||||
// Get retrieves the object from the storage. It is required to support Patch.
|
||||
func (r *StatusREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
return r.store.Get(ctx, name, options)
|
||||
}
|
||||
|
||||
// Update alters the status subset of an object.
|
||||
func (r *StatusREST) Update(ctx genericapirequest.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (runtime.Object, bool, error) {
|
||||
return r.store.Update(ctx, name, objInfo, createValidation, updateValidation)
|
||||
}
|
196
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/storage_test.go
generated
vendored
Normal file
196
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/storage/storage_test.go
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 storage
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
|
||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, extensions.GroupName)
|
||||
restOptions := generic.RESTOptions{
|
||||
StorageConfig: etcdStorage,
|
||||
Decorator: generic.UndecoratedStorage,
|
||||
DeleteCollectionWorkers: 1,
|
||||
ResourcePrefix: "daemonsets",
|
||||
}
|
||||
daemonSetStorage, statusStorage := NewREST(restOptions)
|
||||
return daemonSetStorage, statusStorage, server
|
||||
}
|
||||
|
||||
func newValidDaemonSet() *extensions.DaemonSet {
|
||||
return &extensions.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
UpdateStrategy: extensions.DaemonSetUpdateStrategy{
|
||||
Type: extensions.OnDeleteDaemonSetStrategyType,
|
||||
},
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: "test",
|
||||
Image: "test_image",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
TerminationMessagePolicy: api.TerminationMessageReadFile,
|
||||
},
|
||||
},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var validDaemonSet = newValidDaemonSet()
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
ds := newValidDaemonSet()
|
||||
ds.ObjectMeta = metav1.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
ds,
|
||||
// invalid (invalid selector)
|
||||
&extensions.DaemonSet{
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{}},
|
||||
Template: validDaemonSet.Spec.Template,
|
||||
},
|
||||
},
|
||||
// invalid update strategy
|
||||
&extensions.DaemonSet{
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: validDaemonSet.Spec.Selector,
|
||||
Template: validDaemonSet.Spec.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
test.TestUpdate(
|
||||
// valid
|
||||
newValidDaemonSet(),
|
||||
// updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.DaemonSet)
|
||||
object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"}
|
||||
object.Spec.Template.Spec.DNSPolicy = api.DNSDefault
|
||||
return object
|
||||
},
|
||||
// invalid updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.DaemonSet)
|
||||
object.Name = ""
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.DaemonSet)
|
||||
object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
test.TestDelete(newValidDaemonSet())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
test.TestGet(newValidDaemonSet())
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
test.TestList(newValidDaemonSet())
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
test := genericregistrytest.New(t, storage.Store)
|
||||
test.TestWatch(
|
||||
validDaemonSet,
|
||||
// matching labels
|
||||
[]labels.Set{
|
||||
{"a": "b"},
|
||||
},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"a": "c"},
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
},
|
||||
// notmatching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestShortNames(t *testing.T) {
|
||||
storage, _, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
expected := []string{"ds"}
|
||||
registrytest.AssertShortNames(t, storage, expected)
|
||||
}
|
||||
|
||||
// TODO TestUpdateStatus
|
173
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/strategy.go
generated
vendored
Normal file
173
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/strategy.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 daemonset
|
||||
|
||||
import (
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/api/pod"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions/validation"
|
||||
)
|
||||
|
||||
// daemonSetStrategy implements verification logic for daemon sets.
|
||||
type daemonSetStrategy struct {
|
||||
runtime.ObjectTyper
|
||||
names.NameGenerator
|
||||
}
|
||||
|
||||
// Strategy is the default logic that applies when creating and updating DaemonSet objects.
|
||||
var Strategy = daemonSetStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
|
||||
|
||||
// DefaultGarbageCollectionPolicy returns OrphanDependents by default. For apps/v1, returns DeleteDependents.
|
||||
func (daemonSetStrategy) DefaultGarbageCollectionPolicy(ctx genericapirequest.Context) rest.GarbageCollectionPolicy {
|
||||
if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
|
||||
groupVersion := schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
|
||||
switch groupVersion {
|
||||
case extensionsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion:
|
||||
// for back compatibility
|
||||
return rest.OrphanDependents
|
||||
default:
|
||||
return rest.DeleteDependents
|
||||
}
|
||||
}
|
||||
return rest.OrphanDependents
|
||||
}
|
||||
|
||||
// NamespaceScoped returns true because all DaemonSets need to be within a namespace.
|
||||
func (daemonSetStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PrepareForCreate clears the status of a daemon set before creation.
|
||||
func (daemonSetStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
daemonSet := obj.(*extensions.DaemonSet)
|
||||
daemonSet.Status = extensions.DaemonSetStatus{}
|
||||
|
||||
daemonSet.Generation = 1
|
||||
if daemonSet.Spec.TemplateGeneration < 1 {
|
||||
daemonSet.Spec.TemplateGeneration = 1
|
||||
}
|
||||
|
||||
pod.DropDisabledAlphaFields(&daemonSet.Spec.Template.Spec)
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (daemonSetStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
newDaemonSet := obj.(*extensions.DaemonSet)
|
||||
oldDaemonSet := old.(*extensions.DaemonSet)
|
||||
|
||||
pod.DropDisabledAlphaFields(&newDaemonSet.Spec.Template.Spec)
|
||||
pod.DropDisabledAlphaFields(&oldDaemonSet.Spec.Template.Spec)
|
||||
|
||||
// update is not allowed to set status
|
||||
newDaemonSet.Status = oldDaemonSet.Status
|
||||
|
||||
// update is not allowed to set TemplateGeneration
|
||||
newDaemonSet.Spec.TemplateGeneration = oldDaemonSet.Spec.TemplateGeneration
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object. We push
|
||||
// the burden of managing the status onto the clients because we can't (in general)
|
||||
// know here what version of spec the writer of the status has seen. It may seem like
|
||||
// we can at first -- since obj contains spec -- but in the future we will probably make
|
||||
// status its own object, and even if we don't, writes may be the result of a
|
||||
// read-update-write loop, so the contents of spec may not actually be the spec that
|
||||
// the manager has *seen*.
|
||||
//
|
||||
// TODO: Any changes to a part of the object that represents desired state (labels,
|
||||
// annotations etc) should also increment the generation.
|
||||
if !apiequality.Semantic.DeepEqual(oldDaemonSet.Spec.Template, newDaemonSet.Spec.Template) {
|
||||
newDaemonSet.Spec.TemplateGeneration = oldDaemonSet.Spec.TemplateGeneration + 1
|
||||
newDaemonSet.Generation = oldDaemonSet.Generation + 1
|
||||
return
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(oldDaemonSet.Spec, newDaemonSet.Spec) {
|
||||
newDaemonSet.Generation = oldDaemonSet.Generation + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Validate validates a new daemon set.
|
||||
func (daemonSetStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
daemonSet := obj.(*extensions.DaemonSet)
|
||||
return validation.ValidateDaemonSet(daemonSet)
|
||||
}
|
||||
|
||||
// Canonicalize normalizes the object after validation.
|
||||
func (daemonSetStrategy) Canonicalize(obj runtime.Object) {
|
||||
}
|
||||
|
||||
// AllowCreateOnUpdate is false for daemon set; this means a POST is
|
||||
// needed to create one
|
||||
func (daemonSetStrategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (daemonSetStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
newDaemonSet := obj.(*extensions.DaemonSet)
|
||||
oldDaemonSet := old.(*extensions.DaemonSet)
|
||||
allErrs := validation.ValidateDaemonSet(obj.(*extensions.DaemonSet))
|
||||
allErrs = append(allErrs, validation.ValidateDaemonSetUpdate(newDaemonSet, oldDaemonSet)...)
|
||||
|
||||
// Update is not allowed to set Spec.Selector for apps/v1 and apps/v1beta2 (allowed for extensions/v1beta1).
|
||||
// If RequestInfo is nil, it is better to revert to old behavior (i.e. allow update to set Spec.Selector)
|
||||
// to prevent unintentionally breaking users who may rely on the old behavior.
|
||||
// TODO(#50791): after extensions/v1beta1 is removed, move selector immutability check inside ValidateDaemonSetUpdate().
|
||||
if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
|
||||
groupVersion := schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
|
||||
switch groupVersion {
|
||||
case extensionsv1beta1.SchemeGroupVersion:
|
||||
// no-op for compatibility
|
||||
default:
|
||||
// disallow mutation of selector
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newDaemonSet.Spec.Selector, oldDaemonSet.Spec.Selector, field.NewPath("spec").Child("selector"))...)
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// AllowUnconditionalUpdate is the default update policy for daemon set objects.
|
||||
func (daemonSetStrategy) AllowUnconditionalUpdate() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type daemonSetStatusStrategy struct {
|
||||
daemonSetStrategy
|
||||
}
|
||||
|
||||
var StatusStrategy = daemonSetStatusStrategy{Strategy}
|
||||
|
||||
func (daemonSetStatusStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
newDaemonSet := obj.(*extensions.DaemonSet)
|
||||
oldDaemonSet := old.(*extensions.DaemonSet)
|
||||
newDaemonSet.Spec = oldDaemonSet.Spec
|
||||
}
|
||||
|
||||
func (daemonSetStatusStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
return validation.ValidateDaemonSetStatusUpdate(obj.(*extensions.DaemonSet), old.(*extensions.DaemonSet))
|
||||
}
|
191
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/strategy_test.go
generated
vendored
Normal file
191
vendor/k8s.io/kubernetes/pkg/registry/apps/daemonset/strategy_test.go
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
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 daemonset
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
const (
|
||||
fakeImageName = "fake-name"
|
||||
fakeImage = "fakeimage"
|
||||
daemonsetName = "test-daemonset"
|
||||
namespace = "test-namespace"
|
||||
)
|
||||
|
||||
func TestDaemonsetDefaultGarbageCollectionPolicy(t *testing.T) {
|
||||
// Make sure we correctly implement the interface.
|
||||
// Otherwise a typo could silently change the default.
|
||||
var gcds rest.GarbageCollectionDeleteStrategy = Strategy
|
||||
tests := []struct {
|
||||
requestInfo genericapirequest.RequestInfo
|
||||
expectedGCPolicy rest.GarbageCollectionPolicy
|
||||
isNilRequestInfo bool
|
||||
}{
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "extensions",
|
||||
APIVersion: "v1beta1",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
rest.OrphanDependents,
|
||||
false,
|
||||
},
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: "v1beta2",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
rest.OrphanDependents,
|
||||
false,
|
||||
},
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: "v1",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
rest.DeleteDependents,
|
||||
false,
|
||||
},
|
||||
{
|
||||
expectedGCPolicy: rest.OrphanDependents,
|
||||
isNilRequestInfo: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
context := genericapirequest.NewContext()
|
||||
if !test.isNilRequestInfo {
|
||||
context = genericapirequest.WithRequestInfo(context, &test.requestInfo)
|
||||
}
|
||||
if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want {
|
||||
t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup,
|
||||
test.requestInfo.APIVersion, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectorImmutability(t *testing.T) {
|
||||
tests := []struct {
|
||||
requestInfo genericapirequest.RequestInfo
|
||||
oldSelectorLabels map[string]string
|
||||
newSelectorLabels map[string]string
|
||||
expectedErrorList field.ErrorList
|
||||
}{
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: "v1",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
map[string]string{"a": "b"},
|
||||
map[string]string{"c": "d"},
|
||||
field.ErrorList{
|
||||
&field.Error{
|
||||
Type: field.ErrorTypeInvalid,
|
||||
Field: field.NewPath("spec").Child("selector").String(),
|
||||
BadValue: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"c": "d"},
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{},
|
||||
},
|
||||
Detail: "field is immutable",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: "v1beta2",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
map[string]string{"a": "b"},
|
||||
map[string]string{"c": "d"},
|
||||
field.ErrorList{
|
||||
&field.Error{
|
||||
Type: field.ErrorTypeInvalid,
|
||||
Field: field.NewPath("spec").Child("selector").String(),
|
||||
BadValue: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"c": "d"},
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{},
|
||||
},
|
||||
Detail: "field is immutable",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
genericapirequest.RequestInfo{
|
||||
APIGroup: "extensions",
|
||||
APIVersion: "v1beta1",
|
||||
Resource: "daemonsets",
|
||||
},
|
||||
map[string]string{"a": "b"},
|
||||
map[string]string{"c": "d"},
|
||||
field.ErrorList{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
oldDaemonSet := newDaemonSetWithSelectorLabels(test.oldSelectorLabels, 1)
|
||||
newDaemonSet := newDaemonSetWithSelectorLabels(test.newSelectorLabels, 2)
|
||||
context := genericapirequest.NewContext()
|
||||
context = genericapirequest.WithRequestInfo(context, &test.requestInfo)
|
||||
errorList := daemonSetStrategy{}.ValidateUpdate(context, newDaemonSet, oldDaemonSet)
|
||||
if !reflect.DeepEqual(test.expectedErrorList, errorList) {
|
||||
t.Errorf("Unexpected error list, expected: %v, actual: %v", test.expectedErrorList, errorList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newDaemonSetWithSelectorLabels(selectorLabels map[string]string, templateGeneration int64) *extensions.DaemonSet {
|
||||
return &extensions.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: daemonsetName,
|
||||
Namespace: namespace,
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: selectorLabels,
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{},
|
||||
},
|
||||
UpdateStrategy: extensions.DaemonSetUpdateStrategy{
|
||||
Type: extensions.OnDeleteDaemonSetStrategyType,
|
||||
},
|
||||
TemplateGeneration: templateGeneration,
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: selectorLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: fakeImageName, Image: fakeImage, ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user