From 3d1b5d0e9a7bd1ee5a35e3bd00d9211cbade27c5 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Mon, 4 Nov 2019 17:46:03 +0800 Subject: [PATCH] flowcontrol rest storage implementation --- hack/.golint_failures | 1 + pkg/apis/flowcontrol/validation/validation.go | 20 ++++ pkg/master/BUILD | 2 + pkg/master/master.go | 4 + pkg/registry/BUILD | 3 + pkg/registry/flowcontrol/flowschema/BUILD | 37 +++++++ pkg/registry/flowcontrol/flowschema/doc.go | 18 +++ .../flowcontrol/flowschema/storage/BUILD | 34 ++++++ .../flowcontrol/flowschema/storage/storage.go | 91 ++++++++++++++++ .../flowcontrol/flowschema/strategy.go | 103 ++++++++++++++++++ .../prioritylevelconfiguration/BUILD | 37 +++++++ .../prioritylevelconfiguration/doc.go | 18 +++ .../prioritylevelconfiguration/storage/BUILD | 34 ++++++ .../storage/storage.go | 91 ++++++++++++++++ .../prioritylevelconfiguration/strategy.go | 103 ++++++++++++++++++ pkg/registry/flowcontrol/rest/BUILD | 33 ++++++ .../flowcontrol/rest/storage_flowcontrol.go | 73 +++++++++++++ 17 files changed, 702 insertions(+) create mode 100644 pkg/registry/flowcontrol/flowschema/BUILD create mode 100644 pkg/registry/flowcontrol/flowschema/doc.go create mode 100644 pkg/registry/flowcontrol/flowschema/storage/BUILD create mode 100644 pkg/registry/flowcontrol/flowschema/storage/storage.go create mode 100644 pkg/registry/flowcontrol/flowschema/strategy.go create mode 100644 pkg/registry/flowcontrol/prioritylevelconfiguration/BUILD create mode 100644 pkg/registry/flowcontrol/prioritylevelconfiguration/doc.go create mode 100644 pkg/registry/flowcontrol/prioritylevelconfiguration/storage/BUILD create mode 100644 pkg/registry/flowcontrol/prioritylevelconfiguration/storage/storage.go create mode 100644 pkg/registry/flowcontrol/prioritylevelconfiguration/strategy.go create mode 100644 pkg/registry/flowcontrol/rest/BUILD create mode 100644 pkg/registry/flowcontrol/rest/storage_flowcontrol.go diff --git a/hack/.golint_failures b/hack/.golint_failures index 961ef017187..ebd0acbdea9 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -193,6 +193,7 @@ pkg/registry/core/serviceaccount/storage pkg/registry/events/rest pkg/registry/extensions/controller/storage pkg/registry/extensions/rest +pkg/registry/flowcontrol/rest pkg/registry/networking/networkpolicy/storage pkg/registry/networking/rest pkg/registry/node/rest diff --git a/pkg/apis/flowcontrol/validation/validation.go b/pkg/apis/flowcontrol/validation/validation.go index 74ef9bf6551..5fd3a93488c 100644 --- a/pkg/apis/flowcontrol/validation/validation.go +++ b/pkg/apis/flowcontrol/validation/validation.go @@ -73,6 +73,11 @@ func ValidateFlowSchema(fs *flowcontrol.FlowSchema) field.ErrorList { return allErrs } +// ValidateFlowSchemaUpdate validates the update of flow-schema +func ValidateFlowSchemaUpdate(old, fs *flowcontrol.FlowSchema) field.ErrorList { + return ValidateFlowSchema(fs) +} + // ValidateFlowSchemaSpec validates the content of flow-schema's spec func ValidateFlowSchemaSpec(spec *flowcontrol.FlowSchemaSpec, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList @@ -252,6 +257,11 @@ func ValidateFlowSchemaStatus(status *flowcontrol.FlowSchemaStatus, fldPath *fie return allErrs } +// ValidateFlowSchemaStatusUpdate validates the update of status for the flow-schema. +func ValidateFlowSchemaStatusUpdate(old, fs *flowcontrol.FlowSchema) field.ErrorList { + return ValidateFlowSchemaStatus(&fs.Status, field.NewPath("status")) +} + // ValidateFlowSchemaCondition validates condition in the flow-schema's status. func ValidateFlowSchemaCondition(condition *flowcontrol.FlowSchemaCondition, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList @@ -269,6 +279,11 @@ func ValidatePriorityLevelConfiguration(pl *flowcontrol.PriorityLevelConfigurati return allErrs } +// ValidatePriorityLevelConfigurationUpdate validates the update of priority-level-configuration. +func ValidatePriorityLevelConfigurationUpdate(old, pl *flowcontrol.PriorityLevelConfiguration) field.ErrorList { + return ValidatePriorityLevelConfiguration(pl) +} + // ValidatePriorityLevelConfigurationSpec validates priority-level-configuration's spec. func ValidatePriorityLevelConfigurationSpec(spec *flowcontrol.PriorityLevelConfigurationSpec, name string, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList @@ -333,6 +348,11 @@ func ValidatePriorityLevelConfigurationStatus(status *flowcontrol.PriorityLevelC return allErrs } +// ValidatePriorityLevelConfigurationStatusUpdate validates the update of priority-level-configuration's status. +func ValidatePriorityLevelConfigurationStatusUpdate(old, pl *flowcontrol.PriorityLevelConfiguration) field.ErrorList { + return ValidatePriorityLevelConfigurationStatus(&pl.Status, field.NewPath("status")) +} + // ValidatePriorityLevelConfigurationCondition validates condition in priority-level-configuration's status. func ValidatePriorityLevelConfigurationCondition(condition *flowcontrol.PriorityLevelConfigurationCondition, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList diff --git a/pkg/master/BUILD b/pkg/master/BUILD index cd46f4bf077..24fb140945d 100644 --- a/pkg/master/BUILD +++ b/pkg/master/BUILD @@ -59,6 +59,7 @@ go_library( "//pkg/registry/discovery/rest:go_default_library", "//pkg/registry/events/rest:go_default_library", "//pkg/registry/extensions/rest:go_default_library", + "//pkg/registry/flowcontrol/rest:go_default_library", "//pkg/registry/networking/rest:go_default_library", "//pkg/registry/node/rest:go_default_library", "//pkg/registry/policy/rest:go_default_library", @@ -93,6 +94,7 @@ go_library( "//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library", "//staging/src/k8s.io/api/events/v1beta1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", + "//staging/src/k8s.io/api/flowcontrol/v1alpha1:go_default_library", "//staging/src/k8s.io/api/networking/v1:go_default_library", "//staging/src/k8s.io/api/networking/v1beta1:go_default_library", "//staging/src/k8s.io/api/node/v1alpha1:go_default_library", diff --git a/pkg/master/master.go b/pkg/master/master.go index 5d22feb8df4..fe080c2103c 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -47,6 +47,7 @@ import ( discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1" eventsv1beta1 "k8s.io/api/events/v1beta1" extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1" + flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" networkingapiv1 "k8s.io/api/networking/v1" networkingapiv1beta1 "k8s.io/api/networking/v1beta1" nodev1alpha1 "k8s.io/api/node/v1alpha1" @@ -105,6 +106,7 @@ import ( discoveryrest "k8s.io/kubernetes/pkg/registry/discovery/rest" eventsrest "k8s.io/kubernetes/pkg/registry/events/rest" extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest" + flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest" networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest" noderest "k8s.io/kubernetes/pkg/registry/node/rest" policyrest "k8s.io/kubernetes/pkg/registry/policy/rest" @@ -391,6 +393,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) schedulingrest.RESTStorageProvider{}, settingsrest.RESTStorageProvider{}, storagerest.RESTStorageProvider{}, + flowcontrolrest.RESTStorageProvider{}, // keep apps after extensions so legacy clients resolve the extensions versions of shared resource names. // See https://github.com/kubernetes/kubernetes/issues/42392 appsrest.RESTStorageProvider{}, @@ -617,6 +620,7 @@ func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig { schedulingv1alpha1.SchemeGroupVersion, settingsv1alpha1.SchemeGroupVersion, storageapiv1alpha1.SchemeGroupVersion, + flowcontrolv1alpha1.SchemeGroupVersion, ) return ret diff --git a/pkg/registry/BUILD b/pkg/registry/BUILD index 0e8a91e5d2a..0f734e0db6b 100644 --- a/pkg/registry/BUILD +++ b/pkg/registry/BUILD @@ -75,6 +75,9 @@ filegroup( "//pkg/registry/events/rest:all-srcs", "//pkg/registry/extensions/controller/storage:all-srcs", "//pkg/registry/extensions/rest:all-srcs", + "//pkg/registry/flowcontrol/flowschema:all-srcs", + "//pkg/registry/flowcontrol/prioritylevelconfiguration:all-srcs", + "//pkg/registry/flowcontrol/rest:all-srcs", "//pkg/registry/networking/ingress:all-srcs", "//pkg/registry/networking/networkpolicy:all-srcs", "//pkg/registry/networking/rest:all-srcs", diff --git a/pkg/registry/flowcontrol/flowschema/BUILD b/pkg/registry/flowcontrol/flowschema/BUILD new file mode 100644 index 00000000000..6295fe2afeb --- /dev/null +++ b/pkg/registry/flowcontrol/flowschema/BUILD @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "strategy.go", + ], + importpath = "k8s.io/kubernetes/pkg/registry/flowcontrol/flowschema", + visibility = ["//visibility:public"], + deps = [ + "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/flowcontrol:go_default_library", + "//pkg/apis/flowcontrol/validation:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//pkg/registry/flowcontrol/flowschema/storage:all-srcs", + ], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/pkg/registry/flowcontrol/flowschema/doc.go b/pkg/registry/flowcontrol/flowschema/doc.go new file mode 100644 index 00000000000..074b2aecd94 --- /dev/null +++ b/pkg/registry/flowcontrol/flowschema/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2019 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 flowschema provides model implementation of flow-schema api +package flowschema // import "k8s.io/kubernetes/pkg/registry/flowcontrol/flowschema" diff --git a/pkg/registry/flowcontrol/flowschema/storage/BUILD b/pkg/registry/flowcontrol/flowschema/storage/BUILD new file mode 100644 index 00000000000..456278794ce --- /dev/null +++ b/pkg/registry/flowcontrol/flowschema/storage/BUILD @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["storage.go"], + importpath = "k8s.io/kubernetes/pkg/registry/flowcontrol/flowschema/storage", + visibility = ["//visibility:public"], + deps = [ + "//pkg/apis/flowcontrol:go_default_library", + "//pkg/printers:go_default_library", + "//pkg/printers/internalversion:go_default_library", + "//pkg/printers/storage:go_default_library", + "//pkg/registry/flowcontrol/flowschema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library", + "//staging/src/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"], + visibility = ["//visibility:public"], +) diff --git a/pkg/registry/flowcontrol/flowschema/storage/storage.go b/pkg/registry/flowcontrol/flowschema/storage/storage.go new file mode 100644 index 00000000000..e5b90b7fb7b --- /dev/null +++ b/pkg/registry/flowcontrol/flowschema/storage/storage.go @@ -0,0 +1,91 @@ +/* +Copyright 2019 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 ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "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/flowcontrol" + "k8s.io/kubernetes/pkg/printers" + printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" + printerstorage "k8s.io/kubernetes/pkg/printers/storage" + "k8s.io/kubernetes/pkg/registry/flowcontrol/flowschema" +) + +// FlowSchemaStorage implements storage for flow schema. +type FlowSchemaStorage struct { + FlowSchema *REST + Status *StatusREST +} + +// REST implements a RESTStorage for flow schema against etcd +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against flow schemas. +func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &flowcontrol.FlowSchema{} }, + NewListFunc: func() runtime.Object { return &flowcontrol.FlowSchemaList{} }, + DefaultQualifiedResource: flowcontrol.Resource("flowschemas"), + + CreateStrategy: flowschema.Strategy, + UpdateStrategy: flowschema.Strategy, + DeleteStrategy: flowschema.Strategy, + + TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, + } + options := &generic.StoreOptions{RESTOptions: optsGetter} + if err := store.CompleteWithOptions(options); err != nil { + return nil, nil, err + } + + statusStore := *store + statusStore.CreateStrategy = nil + statusStore.UpdateStrategy = flowschema.StatusStrategy + statusStore.DeleteStrategy = nil + + return &REST{store}, &StatusREST{store: &statusStore}, nil +} + +// StatusREST implements the REST endpoint for changing the status of a flow schema. +type StatusREST struct { + store *genericregistry.Store +} + +// New creates a new flow schema object. +func (r *StatusREST) New() runtime.Object { + return &flowcontrol.FlowSchema{} +} + +// Get retrieves the object from the storage. It is required to support Patch. +func (r *StatusREST) Get(ctx context.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 context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because + // subresources should never allow create on update. + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) +} diff --git a/pkg/registry/flowcontrol/flowschema/strategy.go b/pkg/registry/flowcontrol/flowschema/strategy.go new file mode 100644 index 00000000000..fee6b97a4d6 --- /dev/null +++ b/pkg/registry/flowcontrol/flowschema/strategy.go @@ -0,0 +1,103 @@ +/* +Copyright 2019 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 flowschema + +import ( + "context" + + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/storage/names" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/apis/flowcontrol" + "k8s.io/kubernetes/pkg/apis/flowcontrol/validation" +) + +// flowSchemaStrategy implements verification logic for FlowSchema. +type flowSchemaStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating flow schema objects. +var Strategy = flowSchemaStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} + +// NamespaceScoped returns false because all PriorityClasses are global. +func (flowSchemaStrategy) NamespaceScoped() bool { + return false +} + +// PrepareForCreate clears the status of a flow-schema before creation. +func (flowSchemaStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { + fl := obj.(*flowcontrol.FlowSchema) + fl.Status = flowcontrol.FlowSchemaStatus{} + fl.Generation = 1 +} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update. +func (flowSchemaStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + newFlowSchema := obj.(*flowcontrol.FlowSchema) + oldFlowSchema := old.(*flowcontrol.FlowSchema) + + // Spec updates bump the generation so that we can distinguish between status updates. + if !apiequality.Semantic.DeepEqual(newFlowSchema.Spec, oldFlowSchema.Spec) { + newFlowSchema.Generation = oldFlowSchema.Generation + 1 + } + newFlowSchema.Status = oldFlowSchema.Status +} + +// Validate validates a new flow-schema. +func (flowSchemaStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + return validation.ValidateFlowSchema(obj.(*flowcontrol.FlowSchema)) +} + +// Canonicalize normalizes the object after validation. +func (flowSchemaStrategy) Canonicalize(obj runtime.Object) { +} + +func (flowSchemaStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// AllowCreateOnUpdate is false for flow-schemas; this means a POST is needed to create one. +func (flowSchemaStrategy) AllowCreateOnUpdate() bool { + return false +} + +// ValidateUpdate is the default update validation for an end user. +func (flowSchemaStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateFlowSchemaUpdate(old.(*flowcontrol.FlowSchema), obj.(*flowcontrol.FlowSchema)) +} + +type flowSchemaStatusStrategy struct { + flowSchemaStrategy +} + +// StatusStrategy is the default logic that applies when updating flow-schema objects' status. +var StatusStrategy = flowSchemaStatusStrategy{Strategy} + +func (flowSchemaStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + newFlowSchema := obj.(*flowcontrol.FlowSchema) + oldFlowSchema := old.(*flowcontrol.FlowSchema) + newFlowSchema.ObjectMeta = oldFlowSchema.ObjectMeta + newFlowSchema.Spec = oldFlowSchema.Spec +} + +func (flowSchemaStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateFlowSchemaStatusUpdate(old.(*flowcontrol.FlowSchema), obj.(*flowcontrol.FlowSchema)) +} diff --git a/pkg/registry/flowcontrol/prioritylevelconfiguration/BUILD b/pkg/registry/flowcontrol/prioritylevelconfiguration/BUILD new file mode 100644 index 00000000000..8d72cd56a0a --- /dev/null +++ b/pkg/registry/flowcontrol/prioritylevelconfiguration/BUILD @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "strategy.go", + ], + importpath = "k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration", + visibility = ["//visibility:public"], + deps = [ + "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/flowcontrol:go_default_library", + "//pkg/apis/flowcontrol/validation:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//pkg/registry/flowcontrol/prioritylevelconfiguration/storage:all-srcs", + ], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/pkg/registry/flowcontrol/prioritylevelconfiguration/doc.go b/pkg/registry/flowcontrol/prioritylevelconfiguration/doc.go new file mode 100644 index 00000000000..57c8c47a9ea --- /dev/null +++ b/pkg/registry/flowcontrol/prioritylevelconfiguration/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2019 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 prioritylevelconfiguration provides model implementation of priority-level-configuration api +package prioritylevelconfiguration // import "k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration" diff --git a/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/BUILD b/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/BUILD new file mode 100644 index 00000000000..a9cdffe9b00 --- /dev/null +++ b/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/BUILD @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["storage.go"], + importpath = "k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration/storage", + visibility = ["//visibility:public"], + deps = [ + "//pkg/apis/flowcontrol:go_default_library", + "//pkg/printers:go_default_library", + "//pkg/printers/internalversion:go_default_library", + "//pkg/printers/storage:go_default_library", + "//pkg/registry/flowcontrol/prioritylevelconfiguration:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library", + "//staging/src/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"], + visibility = ["//visibility:public"], +) diff --git a/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/storage.go b/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/storage.go new file mode 100644 index 00000000000..4e5e5976354 --- /dev/null +++ b/pkg/registry/flowcontrol/prioritylevelconfiguration/storage/storage.go @@ -0,0 +1,91 @@ +/* +Copyright 2019 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 ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "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/flowcontrol" + "k8s.io/kubernetes/pkg/printers" + printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" + printerstorage "k8s.io/kubernetes/pkg/printers/storage" + "k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration" +) + +// PriorityLevelConfigurationStorage implements storage for priority level configuration. +type PriorityLevelConfigurationStorage struct { + PriorityLevelConfiguration *REST + Status *StatusREST +} + +// REST implements a RESTStorage for priority level configuration against etcd +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against priority level configuration. +func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, *StatusREST, error) { + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfiguration{} }, + NewListFunc: func() runtime.Object { return &flowcontrol.PriorityLevelConfigurationList{} }, + DefaultQualifiedResource: flowcontrol.Resource("prioritylevelconfigurations"), + + CreateStrategy: prioritylevelconfiguration.Strategy, + UpdateStrategy: prioritylevelconfiguration.Strategy, + DeleteStrategy: prioritylevelconfiguration.Strategy, + + TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, + } + options := &generic.StoreOptions{RESTOptions: optsGetter} + if err := store.CompleteWithOptions(options); err != nil { + return nil, nil, err + } + + statusStore := *store + statusStore.CreateStrategy = nil + statusStore.UpdateStrategy = prioritylevelconfiguration.StatusStrategy + statusStore.DeleteStrategy = nil + + return &REST{store}, &StatusREST{store: &statusStore}, nil +} + +// StatusREST implements the REST endpoint for changing the status of a priority level configuration. +type StatusREST struct { + store *genericregistry.Store +} + +// New creates a new priority level configuration object. +func (r *StatusREST) New() runtime.Object { + return &flowcontrol.PriorityLevelConfiguration{} +} + +// Get retrieves the object from the storage. It is required to support Patch. +func (r *StatusREST) Get(ctx context.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 context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because + // subresources should never allow create on update. + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) +} diff --git a/pkg/registry/flowcontrol/prioritylevelconfiguration/strategy.go b/pkg/registry/flowcontrol/prioritylevelconfiguration/strategy.go new file mode 100644 index 00000000000..9340407ed76 --- /dev/null +++ b/pkg/registry/flowcontrol/prioritylevelconfiguration/strategy.go @@ -0,0 +1,103 @@ +/* +Copyright 2019 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 prioritylevelconfiguration + +import ( + "context" + + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/storage/names" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/apis/flowcontrol" + "k8s.io/kubernetes/pkg/apis/flowcontrol/validation" +) + +// priorityLevelConfigurationStrategy implements verification logic for priority level configurations. +type priorityLevelConfigurationStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating priority level configuration objects. +var Strategy = priorityLevelConfigurationStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} + +// NamespaceScoped returns false because all PriorityClasses are global. +func (priorityLevelConfigurationStrategy) NamespaceScoped() bool { + return false +} + +// PrepareForCreate clears the status of a priority-level-configuration before creation. +func (priorityLevelConfigurationStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { + pl := obj.(*flowcontrol.PriorityLevelConfiguration) + pl.Status = flowcontrol.PriorityLevelConfigurationStatus{} + pl.Generation = 1 +} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update. +func (priorityLevelConfigurationStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + newPriorityLevelConfiguration := obj.(*flowcontrol.PriorityLevelConfiguration) + oldPriorityLevelConfiguration := old.(*flowcontrol.PriorityLevelConfiguration) + + // Spec updates bump the generation so that we can distinguish between status updates. + if !apiequality.Semantic.DeepEqual(newPriorityLevelConfiguration.Spec, oldPriorityLevelConfiguration.Spec) { + newPriorityLevelConfiguration.Generation = oldPriorityLevelConfiguration.Generation + 1 + } + newPriorityLevelConfiguration.Status = oldPriorityLevelConfiguration.Status +} + +// Validate validates a new priority-level. +func (priorityLevelConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + return validation.ValidatePriorityLevelConfiguration(obj.(*flowcontrol.PriorityLevelConfiguration)) +} + +// Canonicalize normalizes the object after validation. +func (priorityLevelConfigurationStrategy) Canonicalize(obj runtime.Object) { +} + +func (priorityLevelConfigurationStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// AllowCreateOnUpdate is false for priority-level-configurations; this means a POST is needed to create one. +func (priorityLevelConfigurationStrategy) AllowCreateOnUpdate() bool { + return false +} + +// ValidateUpdate is the default update validation for an end user. +func (priorityLevelConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidatePriorityLevelConfiguration(obj.(*flowcontrol.PriorityLevelConfiguration)) +} + +type priorityLevelConfigurationStatusStrategy struct { + priorityLevelConfigurationStrategy +} + +// StatusStrategy is the default logic that applies when updating priority level configuration objects' status. +var StatusStrategy = priorityLevelConfigurationStatusStrategy{Strategy} + +func (priorityLevelConfigurationStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + newPriorityLevelConfiguration := obj.(*flowcontrol.PriorityLevelConfiguration) + oldPriorityLevelConfiguration := old.(*flowcontrol.PriorityLevelConfiguration) + newPriorityLevelConfiguration.ObjectMeta = oldPriorityLevelConfiguration.ObjectMeta + newPriorityLevelConfiguration.Spec = oldPriorityLevelConfiguration.Spec +} + +func (priorityLevelConfigurationStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidatePriorityLevelConfigurationStatusUpdate(old.(*flowcontrol.PriorityLevelConfiguration), obj.(*flowcontrol.PriorityLevelConfiguration)) +} diff --git a/pkg/registry/flowcontrol/rest/BUILD b/pkg/registry/flowcontrol/rest/BUILD new file mode 100644 index 00000000000..ce2780d854a --- /dev/null +++ b/pkg/registry/flowcontrol/rest/BUILD @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["storage_flowcontrol.go"], + importpath = "k8s.io/kubernetes/pkg/registry/flowcontrol/rest", + visibility = ["//visibility:public"], + deps = [ + "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/flowcontrol:go_default_library", + "//pkg/registry/flowcontrol/flowschema/storage:go_default_library", + "//pkg/registry/flowcontrol/prioritylevelconfiguration/storage:go_default_library", + "//staging/src/k8s.io/api/flowcontrol/v1alpha1:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/server:go_default_library", + "//staging/src/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"], + visibility = ["//visibility:public"], +) diff --git a/pkg/registry/flowcontrol/rest/storage_flowcontrol.go b/pkg/registry/flowcontrol/rest/storage_flowcontrol.go new file mode 100644 index 00000000000..1565ef8b132 --- /dev/null +++ b/pkg/registry/flowcontrol/rest/storage_flowcontrol.go @@ -0,0 +1,73 @@ +/* +Copyright 2019 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 ( + flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + "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/flowcontrol" + flowschemastore "k8s.io/kubernetes/pkg/registry/flowcontrol/flowschema/storage" + prioritylevelconfigurationstore "k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration/storage" +) + +// RESTStorageProvider implements +type RESTStorageProvider struct{} + +// NewRESTStorage creates a new rest storage for flow-control api models. +func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { + apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(flowcontrol.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) + + if apiResourceConfigSource.VersionEnabled(flowcontrolv1alpha1.SchemeGroupVersion) { + flowControlStorage, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter) + if err != nil { + return genericapiserver.APIGroupInfo{}, false, err + } + apiGroupInfo.VersionedResourcesStorageMap[flowcontrolv1alpha1.SchemeGroupVersion.Version] = flowControlStorage + } + return apiGroupInfo, true, nil +} + +func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { + storage := map[string]rest.Storage{} + + // flow-schema + flowSchemaStorage, flowSchemaStatusStorage, err := flowschemastore.NewREST(restOptionsGetter) + if err != nil { + return nil, err + } + storage["flowschemas"] = flowSchemaStorage + storage["flowschemas/status"] = flowSchemaStatusStorage + + // priority-level-configuration + priorityLevelConfigurationStorage, priorityLevelConfigurationStatusStorage, err := prioritylevelconfigurationstore.NewREST(restOptionsGetter) + if err != nil { + return nil, err + } + storage["prioritylevelconfigurations"] = priorityLevelConfigurationStorage + storage["prioritylevelconfigurations/status"] = priorityLevelConfigurationStatusStorage + + return storage, nil +} + +// GroupName returns group name of the storage +func (p RESTStorageProvider) GroupName() string { + return flowcontrol.GroupName +}