vendor files

This commit is contained in:
Serguei Bezverkhi
2018-01-09 13:57:14 -05:00
parent 558bc6c02a
commit 7b24313bd6
16547 changed files with 4527373 additions and 0 deletions

3
vendor/k8s.io/kubernetes/pkg/registry/policy/OWNERS generated vendored Executable file
View File

@ -0,0 +1,3 @@
reviewers:
- deads2k
- hongchaodeng

View File

@ -0,0 +1,55 @@
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/policy/poddisruptionbudget",
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/apis/policy/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime: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/storage/names:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["strategy_test.go"],
importpath = "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget",
library = ":go_default_library",
deps = [
"//pkg/apis/policy:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/registry/policy/poddisruptionbudget/storage:all-srcs",
],
tags = ["automanaged"],
)

View File

@ -0,0 +1,17 @@
/*
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 poddisruptionbudget // import "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget"

View File

@ -0,0 +1,59 @@
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"],
importpath = "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget/storage",
library = ":go_default_library",
deps = [
"//pkg/apis/policy: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/util/intstr: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/testing:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/rest: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/policy/poddisruptionbudget/storage",
deps = [
"//pkg/apis/policy:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/printers/storage:go_default_library",
"//pkg/registry/policy/poddisruptionbudget: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"],
)

View File

@ -0,0 +1,83 @@
/*
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"
policyapi "k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
printerstorage "k8s.io/kubernetes/pkg/printers/storage"
"k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget"
)
// rest implements a RESTStorage for pod disruption budgets against etcd
type REST struct {
*genericregistry.Store
}
// NewREST returns a RESTStorage object that will work against pod disruption budgets.
func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST) {
store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &policyapi.PodDisruptionBudget{} },
NewListFunc: func() runtime.Object { return &policyapi.PodDisruptionBudgetList{} },
DefaultQualifiedResource: policyapi.Resource("poddisruptionbudgets"),
CreateStrategy: poddisruptionbudget.Strategy,
UpdateStrategy: poddisruptionbudget.Strategy,
DeleteStrategy: poddisruptionbudget.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 = poddisruptionbudget.StatusStrategy
return &REST{store}, &StatusREST{store: &statusStore}
}
// ShortNames implements the ShortNamesProvider interface. Returns a list of short names for a resource.
func (r *REST) ShortNames() []string {
return []string{"pdb"}
}
// StatusREST implements the REST endpoint for changing the status of an podDisruptionBudget
type StatusREST struct {
store *genericregistry.Store
}
func (r *StatusREST) New() runtime.Object {
return &policyapi.PodDisruptionBudget{}
}
// 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)
}

View File

@ -0,0 +1,182 @@
/*
Copyright 2016 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/util/intstr"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/generic"
genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
"k8s.io/apiserver/pkg/registry/rest"
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/registry/registrytest"
)
func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, policy.GroupName)
restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "poddisruptionbudgets"}
podDisruptionBudgetStorage, statusStorage := NewREST(restOptions)
return podDisruptionBudgetStorage, statusStorage, server
}
// createPodDisruptionBudget is a helper function that returns a PodDisruptionBudget with the updated resource version.
func createPodDisruptionBudget(storage *REST, pdb policy.PodDisruptionBudget, t *testing.T) (policy.PodDisruptionBudget, error) {
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), pdb.Namespace)
obj, err := storage.Create(ctx, &pdb, rest.ValidateAllObjectFunc, false)
if err != nil {
t.Errorf("Failed to create PodDisruptionBudget, %v", err)
}
newPS := obj.(*policy.PodDisruptionBudget)
return *newPS, nil
}
func validNewPodDisruptionBudget() *policy.PodDisruptionBudget {
minAvailable := intstr.FromInt(7)
return &policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: metav1.NamespaceDefault,
Labels: map[string]string{"a": "b"},
},
Spec: policy.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
MinAvailable: &minAvailable,
},
Status: policy.PodDisruptionBudgetStatus{},
}
}
func TestCreate(t *testing.T) {
storage, _, server := newStorage(t)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
test := genericregistrytest.New(t, storage.Store)
pdb := validNewPodDisruptionBudget()
pdb.ObjectMeta = metav1.ObjectMeta{}
test.TestCreate(
// valid
pdb,
// TODO: Add an invalid case when we have validation.
)
}
// TODO: Test updates to spec when we allow them.
func TestStatusUpdate(t *testing.T) {
storage, statusStorage, server := newStorage(t)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault)
key := "/poddisruptionbudgets/" + metav1.NamespaceDefault + "/foo"
validPodDisruptionBudget := validNewPodDisruptionBudget()
if err := storage.Storage.Create(ctx, key, validPodDisruptionBudget, nil, 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{})
if err != nil {
t.Fatalf("failed to get pdb: %v", err)
}
obtainedPdb := obj.(*policy.PodDisruptionBudget)
minAvailable := intstr.FromInt(8)
update := policy.PodDisruptionBudget{
ObjectMeta: obtainedPdb.ObjectMeta,
Spec: policy.PodDisruptionBudgetSpec{
MinAvailable: &minAvailable,
},
Status: policy.PodDisruptionBudgetStatus{
ExpectedPods: 8,
},
}
if _, _, err := statusStorage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc); err != nil {
t.Fatalf("unexpected error: %v", err)
}
obj, err = storage.Get(ctx, "foo", &metav1.GetOptions{})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
pdb := obj.(*policy.PodDisruptionBudget)
if pdb.Spec.MinAvailable.IntValue() != 7 {
t.Errorf("we expected .spec.replicas to not be updated but it was updated to %v", pdb.Spec.MinAvailable)
}
if pdb.Status.ExpectedPods != 8 {
t.Errorf("we expected .status.replicas to be updated to %d but it was %v", 7, pdb.Status.ExpectedPods)
}
}
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(validNewPodDisruptionBudget())
}
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(validNewPodDisruptionBudget())
}
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(validNewPodDisruptionBudget())
}
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(
validNewPodDisruptionBudget(),
// matching labels
[]labels.Set{
{"a": "b"},
},
// not matching labels
[]labels.Set{
{"a": "c"},
{"foo": "bar"},
},
// matching fields
[]fields.Set{
{"metadata.name": "foo"},
},
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
},
)
}
// TODO: Test generation number.

View File

@ -0,0 +1,115 @@
/*
Copyright 2014 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 poddisruptionbudget
import (
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/storage/names"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/apis/policy/validation"
)
// podDisruptionBudgetStrategy implements verification logic for PodDisruptionBudgets.
type podDisruptionBudgetStrategy struct {
runtime.ObjectTyper
names.NameGenerator
}
// Strategy is the default logic that applies when creating and updating PodDisruptionBudget objects.
var Strategy = podDisruptionBudgetStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
// NamespaceScoped returns true because all PodDisruptionBudget' need to be within a namespace.
func (podDisruptionBudgetStrategy) NamespaceScoped() bool {
return true
}
// PrepareForCreate clears the status of an PodDisruptionBudget before creation.
func (podDisruptionBudgetStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
podDisruptionBudget := obj.(*policy.PodDisruptionBudget)
// create cannot set status
podDisruptionBudget.Status = policy.PodDisruptionBudgetStatus{}
podDisruptionBudget.Generation = 1
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (podDisruptionBudgetStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget)
oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget)
// Update is not allowed to set status
newPodDisruptionBudget.Status = oldPodDisruptionBudget.Status
// Any changes to the spec increment the generation number, any changes to the
// status should reflect the generation number of the corresponding object.
// See metav1.ObjectMeta description for more information on Generation.
if !apiequality.Semantic.DeepEqual(oldPodDisruptionBudget.Spec, newPodDisruptionBudget.Spec) {
newPodDisruptionBudget.Generation = oldPodDisruptionBudget.Generation + 1
}
}
// Validate validates a new PodDisruptionBudget.
func (podDisruptionBudgetStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
podDisruptionBudget := obj.(*policy.PodDisruptionBudget)
return validation.ValidatePodDisruptionBudget(podDisruptionBudget)
}
// Canonicalize normalizes the object after validation.
func (podDisruptionBudgetStrategy) Canonicalize(obj runtime.Object) {
}
// AllowCreateOnUpdate is true for PodDisruptionBudget; this means you may create one with a PUT request.
func (podDisruptionBudgetStrategy) AllowCreateOnUpdate() bool {
return false
}
// ValidateUpdate is the default update validation for an end user.
func (podDisruptionBudgetStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
validationErrorList := validation.ValidatePodDisruptionBudget(obj.(*policy.PodDisruptionBudget))
updateErrorList := validation.ValidatePodDisruptionBudgetUpdate(obj.(*policy.PodDisruptionBudget), old.(*policy.PodDisruptionBudget))
return append(validationErrorList, updateErrorList...)
}
// AllowUnconditionalUpdate is the default update policy for PodDisruptionBudget objects. Status update should
// only be allowed if version match.
func (podDisruptionBudgetStrategy) AllowUnconditionalUpdate() bool {
return false
}
type podDisruptionBudgetStatusStrategy struct {
podDisruptionBudgetStrategy
}
var StatusStrategy = podDisruptionBudgetStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (podDisruptionBudgetStatusStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget)
oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget)
// status changes are not allowed to update spec
newPodDisruptionBudget.Spec = oldPodDisruptionBudget.Spec
}
// ValidateUpdate is the default update validation for an end user updating status
func (podDisruptionBudgetStatusStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
// TODO: Validate status updates.
return field.ErrorList{}
// return validation.ValidatePodDisruptionBudgetStatusUpdate(obj.(*policy.PodDisruptionBudget), old.(*policy.PodDisruptionBudget))
}

View File

@ -0,0 +1,148 @@
/*
Copyright 2016 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 poddisruptionbudget
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/kubernetes/pkg/apis/policy"
)
func TestPodDisruptionBudgetStrategy(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
if !Strategy.NamespaceScoped() {
t.Errorf("PodDisruptionBudget must be namespace scoped")
}
if Strategy.AllowCreateOnUpdate() {
t.Errorf("PodDisruptionBudget should not allow create on update")
}
validSelector := map[string]string{"a": "b"}
minAvailable := intstr.FromInt(3)
pdb := &policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: policy.PodDisruptionBudgetSpec{
MinAvailable: &minAvailable,
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
},
}
Strategy.PrepareForCreate(ctx, pdb)
errs := Strategy.Validate(ctx, pdb)
if len(errs) != 0 {
t.Errorf("Unexpected error validating %v", errs)
}
newPdb := &policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{Name: pdb.Name, Namespace: pdb.Namespace},
Spec: pdb.Spec,
Status: policy.PodDisruptionBudgetStatus{
PodDisruptionsAllowed: 1,
CurrentHealthy: 3,
DesiredHealthy: 3,
ExpectedPods: 3,
},
}
// Nothing in Spec changes: OK
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) != 0 {
t.Errorf("Unexpected error updating PodDisruptionBudget.")
}
// Changing the selector? No.
newPdb.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{"a": "bar"}}
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on poddisruptionbudgets.")
}
newPdb.Spec.Selector = pdb.Spec.Selector
// Changing MinAvailable? Also no.
newMinAvailable := intstr.FromString("28%")
newPdb.Spec.MinAvailable = &newMinAvailable
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on poddisruptionbudgets.")
}
maxUnavailable := intstr.FromString("28%")
newPdb.Spec.MaxUnavailable = &maxUnavailable
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on poddisruptionbudgets.")
}
}
func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
if !StatusStrategy.NamespaceScoped() {
t.Errorf("PodDisruptionBudgetStatus must be namespace scoped")
}
if StatusStrategy.AllowCreateOnUpdate() {
t.Errorf("PodDisruptionBudgetStatus should not allow create on update")
}
oldMinAvailable := intstr.FromInt(3)
newMinAvailable := intstr.FromInt(2)
validSelector := map[string]string{"a": "b"}
oldPdb := &policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "10"},
Spec: policy.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
MinAvailable: &oldMinAvailable,
},
Status: policy.PodDisruptionBudgetStatus{
PodDisruptionsAllowed: 1,
CurrentHealthy: 3,
DesiredHealthy: 3,
ExpectedPods: 3,
},
}
newPdb := &policy.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "9"},
Spec: policy.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
MinAvailable: &newMinAvailable,
},
Status: policy.PodDisruptionBudgetStatus{
PodDisruptionsAllowed: 0,
CurrentHealthy: 2,
DesiredHealthy: 3,
ExpectedPods: 3,
},
}
StatusStrategy.PrepareForUpdate(ctx, newPdb, oldPdb)
if newPdb.Status.CurrentHealthy != 2 {
t.Errorf("PodDisruptionBudget status updates should allow change of CurrentHealthy: %v", newPdb.Status.CurrentHealthy)
}
if newPdb.Spec.MinAvailable.IntValue() != 3 {
t.Errorf("PodDisruptionBudget status updates should not clobber spec: %v", newPdb.Spec)
}
errs := StatusStrategy.ValidateUpdate(ctx, newPdb, oldPdb)
if len(errs) != 0 {
t.Errorf("Unexpected error %v", errs)
}
}

View File

@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["storage_policy.go"],
importpath = "k8s.io/kubernetes/pkg/registry/policy/rest",
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/registry/policy/poddisruptionbudget/storage:go_default_library",
"//vendor/k8s.io/api/policy/v1beta1:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,57 @@
/*
Copyright 2016 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 rest
import (
policyapiv1beta1 "k8s.io/api/policy/v1beta1"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
serverstorage "k8s.io/apiserver/pkg/server/storage"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/policy"
poddisruptionbudgetstore "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget/storage"
)
type RESTStorageProvider struct{}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(policy.GroupName, legacyscheme.Registry, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
// TODO refactor the plumbing to provide the information in the APIGroupInfo
if apiResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1beta1.SchemeGroupVersion) {
apiGroupInfo.VersionedResourcesStorageMap[policyapiv1beta1.SchemeGroupVersion.Version] = p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter)
apiGroupInfo.GroupMeta.GroupVersion = policyapiv1beta1.SchemeGroupVersion
}
return apiGroupInfo, true
}
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
version := policyapiv1beta1.SchemeGroupVersion
storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("poddisruptionbudgets")) {
poddisruptionbudgetStorage, poddisruptionbudgetStatusStorage := poddisruptionbudgetstore.NewREST(restOptionsGetter)
storage["poddisruptionbudgets"] = poddisruptionbudgetStorage
storage["poddisruptionbudgets/status"] = poddisruptionbudgetStatusStorage
}
return storage
}
func (p RESTStorageProvider) GroupName() string {
return policy.GroupName
}