Merge pull request #84005 from yue9944882/chore/crd-internal-client-prune
Prune internal clients from CRD apiserver
This commit is contained in:
commit
eff703de21
@ -34,7 +34,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion"
|
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -140,7 +140,7 @@ func createAggregatorServer(aggregatorConfig *aggregatorapiserver.Config, delega
|
|||||||
autoRegistrationController := autoregister.NewAutoRegisterController(aggregatorServer.APIRegistrationInformers.Apiregistration().V1().APIServices(), apiRegistrationClient)
|
autoRegistrationController := autoregister.NewAutoRegisterController(aggregatorServer.APIRegistrationInformers.Apiregistration().V1().APIServices(), apiRegistrationClient)
|
||||||
apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
|
apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
|
||||||
crdRegistrationController := crdregistration.NewCRDRegistrationController(
|
crdRegistrationController := crdregistration.NewCRDRegistrationController(
|
||||||
apiExtensionInformers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
apiExtensionInformers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||||
autoRegistrationController)
|
autoRegistrationController)
|
||||||
|
|
||||||
err = aggregatorServer.GenericAPIServer.AddPostStartHook("kube-apiserver-autoregistration", func(context genericapiserver.PostStartHookContext) error {
|
err = aggregatorServer.GenericAPIServer.AddPostStartHook("kube-apiserver-autoregistration", func(context genericapiserver.PostStartHookContext) error {
|
||||||
|
@ -11,9 +11,9 @@ go_library(
|
|||||||
srcs = ["crdregistration_controller.go"],
|
srcs = ["crdregistration_controller.go"],
|
||||||
importpath = "k8s.io/kubernetes/pkg/master/controller/crdregistration",
|
importpath = "k8s.io/kubernetes/pkg/master/controller/crdregistration",
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
@ -44,8 +44,8 @@ go_test(
|
|||||||
srcs = ["crdregistration_controller_test.go"],
|
srcs = ["crdregistration_controller_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||||
|
@ -22,9 +22,9 @@ import (
|
|||||||
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
crdinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
crdinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -73,24 +73,24 @@ func NewCRDRegistrationController(crdinformer crdinformers.CustomResourceDefinit
|
|||||||
|
|
||||||
crdinformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
crdinformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
AddFunc: func(obj interface{}) {
|
AddFunc: func(obj interface{}) {
|
||||||
cast := obj.(*apiextensions.CustomResourceDefinition)
|
cast := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
c.enqueueCRD(cast)
|
c.enqueueCRD(cast)
|
||||||
},
|
},
|
||||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
UpdateFunc: func(oldObj, newObj interface{}) {
|
||||||
// Enqueue both old and new object to make sure we remove and add appropriate API services.
|
// Enqueue both old and new object to make sure we remove and add appropriate API services.
|
||||||
// The working queue will resolve any duplicates and only changes will stay in the queue.
|
// The working queue will resolve any duplicates and only changes will stay in the queue.
|
||||||
c.enqueueCRD(oldObj.(*apiextensions.CustomResourceDefinition))
|
c.enqueueCRD(oldObj.(*apiextensionsv1.CustomResourceDefinition))
|
||||||
c.enqueueCRD(newObj.(*apiextensions.CustomResourceDefinition))
|
c.enqueueCRD(newObj.(*apiextensionsv1.CustomResourceDefinition))
|
||||||
},
|
},
|
||||||
DeleteFunc: func(obj interface{}) {
|
DeleteFunc: func(obj interface{}) {
|
||||||
cast, ok := obj.(*apiextensions.CustomResourceDefinition)
|
cast, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.V(2).Infof("Couldn't get object from tombstone %#v", obj)
|
klog.V(2).Infof("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cast, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
cast, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.V(2).Infof("Tombstone contained unexpected object: %#v", obj)
|
klog.V(2).Infof("Tombstone contained unexpected object: %#v", obj)
|
||||||
return
|
return
|
||||||
@ -184,7 +184,7 @@ func (c *crdRegistrationController) processNextWorkItem() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *crdRegistrationController) enqueueCRD(crd *apiextensions.CustomResourceDefinition) {
|
func (c *crdRegistrationController) enqueueCRD(crd *apiextensionsv1.CustomResourceDefinition) {
|
||||||
for _, version := range crd.Spec.Versions {
|
for _, version := range crd.Spec.Versions {
|
||||||
c.queue.Add(schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name})
|
c.queue.Add(schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name})
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
@ -31,7 +31,7 @@ import (
|
|||||||
func TestHandleVersionUpdate(t *testing.T) {
|
func TestHandleVersionUpdate(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
startingCRDs []*apiextensions.CustomResourceDefinition
|
startingCRDs []*apiextensionsv1.CustomResourceDefinition
|
||||||
version schema.GroupVersion
|
version schema.GroupVersion
|
||||||
|
|
||||||
expectedAdded []*apiregistration.APIService
|
expectedAdded []*apiregistration.APIService
|
||||||
@ -39,13 +39,13 @@ func TestHandleVersionUpdate(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple add crd",
|
name: "simple add crd",
|
||||||
startingCRDs: []*apiextensions.CustomResourceDefinition{
|
startingCRDs: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
{
|
{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "group.com",
|
Group: "group.com",
|
||||||
// Version field is deprecated and crd registration won't rely on it at all.
|
// Version field is deprecated and crd registration won't rely on it at all.
|
||||||
// defaulting route will fill up Versions field if user only provided version field.
|
// defaulting route will fill up Versions field if user only provided version field.
|
||||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
{
|
{
|
||||||
Name: "v1",
|
Name: "v1",
|
||||||
Served: true,
|
Served: true,
|
||||||
@ -71,11 +71,11 @@ func TestHandleVersionUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "simple remove crd",
|
name: "simple remove crd",
|
||||||
startingCRDs: []*apiextensions.CustomResourceDefinition{
|
startingCRDs: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
{
|
{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "group.com",
|
Group: "group.com",
|
||||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
{
|
{
|
||||||
Name: "v1",
|
Name: "v1",
|
||||||
Served: true,
|
Served: true,
|
||||||
|
@ -40,10 +40,7 @@ filegroup(
|
|||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1:all-srcs",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server:all-srcs",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server:all-srcs",
|
||||||
|
@ -21,13 +21,18 @@ set -o pipefail
|
|||||||
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
|
CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
|
||||||
|
|
||||||
# generate the code with:
|
|
||||||
# --output-base because this script should also be able to run inside the vendor dir of
|
|
||||||
# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
|
|
||||||
# instead of the $GOPATH directly. For normal projects this can be dropped.
|
|
||||||
CLIENTSET_NAME_VERSIONED=clientset \
|
CLIENTSET_NAME_VERSIONED=clientset \
|
||||||
|
CLIENTSET_PKG_NAME=clientset \
|
||||||
|
bash "${CODEGEN_PKG}/generate-groups.sh" deepcopy,client,lister,informer \
|
||||||
|
k8s.io/apiextensions-apiserver/pkg/client k8s.io/apiextensions-apiserver/pkg/apis \
|
||||||
|
"apiextensions:v1beta1,v1" \
|
||||||
|
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
||||||
|
--go-header-file "${SCRIPT_ROOT}/hack/boilerplate.go.txt"
|
||||||
|
|
||||||
|
CLIENTSET_NAME_VERSIONED=clientset \
|
||||||
|
CLIENTSET_PKG_NAME=clientset \
|
||||||
CLIENTSET_NAME_INTERNAL=internalclientset \
|
CLIENTSET_NAME_INTERNAL=internalclientset \
|
||||||
bash "${CODEGEN_PKG}/generate-internal-groups.sh" deepcopy,client,lister,informer,conversion \
|
bash "${CODEGEN_PKG}/generate-internal-groups.sh" deepcopy,conversion \
|
||||||
k8s.io/apiextensions-apiserver/pkg/client k8s.io/apiextensions-apiserver/pkg/apis k8s.io/apiextensions-apiserver/pkg/apis \
|
k8s.io/apiextensions-apiserver/pkg/client k8s.io/apiextensions-apiserver/pkg/apis k8s.io/apiextensions-apiserver/pkg/apis \
|
||||||
"apiextensions:v1beta1,v1" \
|
"apiextensions:v1beta1,v1" \
|
||||||
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
||||||
|
@ -6,14 +6,20 @@ go_library(
|
|||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = ["//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library"],
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["helpers_test.go"],
|
srcs = ["helpers_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = ["//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library"],
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -20,8 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsProtectedCommunityGroup returns whether or not a group specified for a CRD is protected for the community and needs
|
// IsProtectedCommunityGroup returns whether or not a group specified for a CRD is protected for the community and needs
|
||||||
@ -54,18 +56,205 @@ const (
|
|||||||
|
|
||||||
// GetAPIApprovalState returns the state of the API approval and reason for that state
|
// GetAPIApprovalState returns the state of the API approval and reason for that state
|
||||||
func GetAPIApprovalState(annotations map[string]string) (state APIApprovalState, reason string) {
|
func GetAPIApprovalState(annotations map[string]string) (state APIApprovalState, reason string) {
|
||||||
annotation := annotations[v1beta1.KubeAPIApprovedAnnotation]
|
annotation := annotations[apiextensionsv1.KubeAPIApprovedAnnotation]
|
||||||
|
|
||||||
// we use the result of this parsing in the switch/case below
|
// we use the result of this parsing in the switch/case below
|
||||||
url, annotationURLParseErr := url.ParseRequestURI(annotation)
|
url, annotationURLParseErr := url.ParseRequestURI(annotation)
|
||||||
switch {
|
switch {
|
||||||
case len(annotation) == 0:
|
case len(annotation) == 0:
|
||||||
return APIApprovalMissing, fmt.Sprintf("protected groups must have approval annotation %q, see https://github.com/kubernetes/enhancements/pull/1111", v1beta1.KubeAPIApprovedAnnotation)
|
return APIApprovalMissing, fmt.Sprintf("protected groups must have approval annotation %q, see https://github.com/kubernetes/enhancements/pull/1111", apiextensionsv1.KubeAPIApprovedAnnotation)
|
||||||
case strings.HasPrefix(annotation, "unapproved"):
|
case strings.HasPrefix(annotation, "unapproved"):
|
||||||
return APIApprovalBypassed, fmt.Sprintf("not approved: %q", annotation)
|
return APIApprovalBypassed, fmt.Sprintf("not approved: %q", annotation)
|
||||||
case annotationURLParseErr == nil && url != nil && len(url.Host) > 0 && len(url.Scheme) > 0:
|
case annotationURLParseErr == nil && url != nil && len(url.Host) > 0 && len(url.Scheme) > 0:
|
||||||
return APIApproved, fmt.Sprintf("approved in %v", annotation)
|
return APIApproved, fmt.Sprintf("approved in %v", annotation)
|
||||||
default:
|
default:
|
||||||
return APIApprovalInvalid, fmt.Sprintf("protected groups must have approval annotation %q with either a URL or a reason starting with \"unapproved\", see https://github.com/kubernetes/enhancements/pull/1111", v1beta1.KubeAPIApprovedAnnotation)
|
return APIApprovalInvalid, fmt.Sprintf("protected groups must have approval annotation %q with either a URL or a reason starting with \"unapproved\", see https://github.com/kubernetes/enhancements/pull/1111", apiextensionsv1.KubeAPIApprovedAnnotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCRDCondition sets the status condition. It either overwrites the existing one or creates a new one.
|
||||||
|
func SetCRDCondition(crd *apiextensionsv1.CustomResourceDefinition, newCondition apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||||
|
newCondition.LastTransitionTime = metav1.NewTime(time.Now())
|
||||||
|
|
||||||
|
existingCondition := FindCRDCondition(crd, newCondition.Type)
|
||||||
|
if existingCondition == nil {
|
||||||
|
crd.Status.Conditions = append(crd.Status.Conditions, newCondition)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if existingCondition.Status != newCondition.Status || existingCondition.LastTransitionTime.IsZero() {
|
||||||
|
existingCondition.LastTransitionTime = newCondition.LastTransitionTime
|
||||||
|
}
|
||||||
|
|
||||||
|
existingCondition.Status = newCondition.Status
|
||||||
|
existingCondition.Reason = newCondition.Reason
|
||||||
|
existingCondition.Message = newCondition.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveCRDCondition removes the status condition.
|
||||||
|
func RemoveCRDCondition(crd *apiextensionsv1.CustomResourceDefinition, conditionType apiextensionsv1.CustomResourceDefinitionConditionType) {
|
||||||
|
newConditions := []apiextensionsv1.CustomResourceDefinitionCondition{}
|
||||||
|
for _, condition := range crd.Status.Conditions {
|
||||||
|
if condition.Type != conditionType {
|
||||||
|
newConditions = append(newConditions, condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crd.Status.Conditions = newConditions
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindCRDCondition returns the condition you're looking for or nil.
|
||||||
|
func FindCRDCondition(crd *apiextensionsv1.CustomResourceDefinition, conditionType apiextensionsv1.CustomResourceDefinitionConditionType) *apiextensionsv1.CustomResourceDefinitionCondition {
|
||||||
|
for i := range crd.Status.Conditions {
|
||||||
|
if crd.Status.Conditions[i].Type == conditionType {
|
||||||
|
return &crd.Status.Conditions[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCRDConditionTrue indicates if the condition is present and strictly true.
|
||||||
|
func IsCRDConditionTrue(crd *apiextensionsv1.CustomResourceDefinition, conditionType apiextensionsv1.CustomResourceDefinitionConditionType) bool {
|
||||||
|
return IsCRDConditionPresentAndEqual(crd, conditionType, apiextensionsv1.ConditionTrue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCRDConditionFalse indicates if the condition is present and false.
|
||||||
|
func IsCRDConditionFalse(crd *apiextensionsv1.CustomResourceDefinition, conditionType apiextensionsv1.CustomResourceDefinitionConditionType) bool {
|
||||||
|
return IsCRDConditionPresentAndEqual(crd, conditionType, apiextensionsv1.ConditionFalse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCRDConditionPresentAndEqual indicates if the condition is present and equal to the given status.
|
||||||
|
func IsCRDConditionPresentAndEqual(crd *apiextensionsv1.CustomResourceDefinition, conditionType apiextensionsv1.CustomResourceDefinitionConditionType, status apiextensionsv1.ConditionStatus) bool {
|
||||||
|
for _, condition := range crd.Status.Conditions {
|
||||||
|
if condition.Type == conditionType {
|
||||||
|
return condition.Status == status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCRDConditionEquivalent returns true if the lhs and rhs are equivalent except for times.
|
||||||
|
func IsCRDConditionEquivalent(lhs, rhs *apiextensionsv1.CustomResourceDefinitionCondition) bool {
|
||||||
|
if lhs == nil && rhs == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if lhs == nil || rhs == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return lhs.Message == rhs.Message && lhs.Reason == rhs.Reason && lhs.Status == rhs.Status && lhs.Type == rhs.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRDHasFinalizer returns true if the finalizer is in the list.
|
||||||
|
func CRDHasFinalizer(crd *apiextensionsv1.CustomResourceDefinition, needle string) bool {
|
||||||
|
for _, finalizer := range crd.Finalizers {
|
||||||
|
if finalizer == needle {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRDRemoveFinalizer removes the finalizer if present.
|
||||||
|
func CRDRemoveFinalizer(crd *apiextensionsv1.CustomResourceDefinition, needle string) {
|
||||||
|
newFinalizers := []string{}
|
||||||
|
for _, finalizer := range crd.Finalizers {
|
||||||
|
if finalizer != needle {
|
||||||
|
newFinalizers = append(newFinalizers, finalizer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crd.Finalizers = newFinalizers
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasServedCRDVersion returns true if the given version is in the list of CRD's versions and the Served flag is set.
|
||||||
|
func HasServedCRDVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) bool {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if v.Name == version {
|
||||||
|
return v.Served
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCRDStorageVersion returns the storage version for given CRD.
|
||||||
|
func GetCRDStorageVersion(crd *apiextensionsv1.CustomResourceDefinition) (string, error) {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if v.Storage {
|
||||||
|
return v.Name, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This should not happened if crd is valid
|
||||||
|
return "", fmt.Errorf("invalid apiextensionsv1.CustomResourceDefinition, no storage version")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStoredVersion returns whether the given version is the storage version of the CRD.
|
||||||
|
func IsStoredVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) bool {
|
||||||
|
for _, v := range crd.Status.StoredVersions {
|
||||||
|
if version == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSchemaForVersion returns the validation schema for the given version or nil.
|
||||||
|
func GetSchemaForVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) (*apiextensionsv1.CustomResourceValidation, error) {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if version == v.Name {
|
||||||
|
return v.Schema, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("version %s not found in apiextensionsv1.CustomResourceDefinition: %v", version, crd.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSubresourcesForVersion returns the subresources for given version or nil.
|
||||||
|
func GetSubresourcesForVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) (*apiextensionsv1.CustomResourceSubresources, error) {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if version == v.Name {
|
||||||
|
return v.Subresources, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("version %s not found in apiextensionsv1.CustomResourceDefinition: %v", version, crd.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPerVersionSchema returns true if a CRD uses per-version schema.
|
||||||
|
func HasPerVersionSchema(versions []apiextensionsv1.CustomResourceDefinitionVersion) bool {
|
||||||
|
for _, v := range versions {
|
||||||
|
if v.Schema != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPerVersionSubresources returns true if a CRD uses per-version subresources.
|
||||||
|
func HasPerVersionSubresources(versions []apiextensionsv1.CustomResourceDefinitionVersion) bool {
|
||||||
|
for _, v := range versions {
|
||||||
|
if v.Subresources != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPerVersionColumns returns true if a CRD uses per-version columns.
|
||||||
|
func HasPerVersionColumns(versions []apiextensionsv1.CustomResourceDefinitionVersion) bool {
|
||||||
|
for _, v := range versions {
|
||||||
|
if len(v.AdditionalPrinterColumns) > 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasVersionServed returns true if given CRD has given version served.
|
||||||
|
func HasVersionServed(crd *apiextensionsv1.CustomResourceDefinition, version string) bool {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if !v.Served || v.Name != version {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -17,9 +17,12 @@ limitations under the License.
|
|||||||
package apihelpers
|
package apihelpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIsProtectedCommunityGroup(t *testing.T) {
|
func TestIsProtectedCommunityGroup(t *testing.T) {
|
||||||
@ -76,22 +79,22 @@ func TestGetAPIApprovalState(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "bare unapproved",
|
name: "bare unapproved",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "unapproved"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "unapproved"},
|
||||||
expected: APIApprovalBypassed,
|
expected: APIApprovalBypassed,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unapproved with message",
|
name: "unapproved with message",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "unapproved, experimental-only"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "unapproved, experimental-only"},
|
||||||
expected: APIApprovalBypassed,
|
expected: APIApprovalBypassed,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mismatched case",
|
name: "mismatched case",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "Unapproved"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "Unapproved"},
|
||||||
expected: APIApprovalInvalid,
|
expected: APIApprovalInvalid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: ""},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: ""},
|
||||||
expected: APIApprovalMissing,
|
expected: APIApprovalMissing,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -101,27 +104,27 @@ func TestGetAPIApprovalState(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "url",
|
name: "url",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "https://github.com/kubernetes/kubernetes/pull/78458"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "https://github.com/kubernetes/kubernetes/pull/78458"},
|
||||||
expected: APIApproved,
|
expected: APIApproved,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "url - no scheme",
|
name: "url - no scheme",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "github.com/kubernetes/kubernetes/pull/78458"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "github.com/kubernetes/kubernetes/pull/78458"},
|
||||||
expected: APIApprovalInvalid,
|
expected: APIApprovalInvalid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "url - no host",
|
name: "url - no host",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "http:///kubernetes/kubernetes/pull/78458"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "http:///kubernetes/kubernetes/pull/78458"},
|
||||||
expected: APIApprovalInvalid,
|
expected: APIApprovalInvalid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "url - just path",
|
name: "url - just path",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "/"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "/"},
|
||||||
expected: APIApprovalInvalid,
|
expected: APIApprovalInvalid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing scheme",
|
name: "missing scheme",
|
||||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "github.com/kubernetes/kubernetes/pull/78458"},
|
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "github.com/kubernetes/kubernetes/pull/78458"},
|
||||||
expected: APIApprovalInvalid,
|
expected: APIApprovalInvalid,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -136,3 +139,461 @@ func TestGetAPIApprovalState(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCRDHasFinalizer(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
crd *apiextensionsv1.CustomResourceDefinition
|
||||||
|
finalizerToCheck string
|
||||||
|
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "missing",
|
||||||
|
crd: &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"not-it"}},
|
||||||
|
},
|
||||||
|
finalizerToCheck: "it",
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "present",
|
||||||
|
crd: &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"not-it", "it"}},
|
||||||
|
},
|
||||||
|
finalizerToCheck: "it",
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
actual := CRDHasFinalizer(tc.crd, tc.finalizerToCheck)
|
||||||
|
if tc.expected != actual {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCRDRemoveFinalizer(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
crd *apiextensionsv1.CustomResourceDefinition
|
||||||
|
finalizerToCheck string
|
||||||
|
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "missing",
|
||||||
|
crd: &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"not-it"}},
|
||||||
|
},
|
||||||
|
finalizerToCheck: "it",
|
||||||
|
expected: []string{"not-it"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "present",
|
||||||
|
crd: &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"not-it", "it"}},
|
||||||
|
},
|
||||||
|
finalizerToCheck: "it",
|
||||||
|
expected: []string{"not-it"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
CRDRemoveFinalizer(tc.crd, tc.finalizerToCheck)
|
||||||
|
if !reflect.DeepEqual(tc.expected, tc.crd.Finalizers) {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expected, tc.crd.Finalizers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetCRDCondition(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
crdCondition []apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
newCondition apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
expectedcrdCondition []apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test setCRDcondition when one condition",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newCondition: apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "NotAccepted",
|
||||||
|
Message: "Not accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "NotAccepted",
|
||||||
|
Message: "Not accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test setCRDcondition when two condition",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newCondition: apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Conflicts",
|
||||||
|
Message: "conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Conflicts",
|
||||||
|
Message: "conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test setCRDcondition when condition needs to be appended",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newCondition: apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
Type: apiextensionsv1.Terminating,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Neverapiextensionsv1.Established",
|
||||||
|
Message: "resource was never apiextensionsv1.Established",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Terminating,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Neverapiextensionsv1.Established",
|
||||||
|
Message: "resource was never apiextensionsv1.Established",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "set new condition which doesn't have lastTransitionTime set",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newCondition: apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "NotAccepted",
|
||||||
|
Message: "Not accepted",
|
||||||
|
},
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "NotAccepted",
|
||||||
|
Message: "Not accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "append new condition which doesn't have lastTransitionTime set",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newCondition: apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
Type: apiextensionsv1.Terminating,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Neverapiextensionsv1.Established",
|
||||||
|
Message: "resource was never apiextensionsv1.Established",
|
||||||
|
},
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Terminating,
|
||||||
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
|
Reason: "Neverapiextensionsv1.Established",
|
||||||
|
Message: "resource was never apiextensionsv1.Established",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
crd := generateCRDwithCondition(tc.crdCondition)
|
||||||
|
SetCRDCondition(crd, tc.newCondition)
|
||||||
|
if len(tc.expectedcrdCondition) != len(crd.Status.Conditions) {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expectedcrdCondition, crd.Status.Conditions)
|
||||||
|
}
|
||||||
|
for i := range tc.expectedcrdCondition {
|
||||||
|
if !IsCRDConditionEquivalent(&tc.expectedcrdCondition[i], &crd.Status.Conditions[i]) {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expectedcrdCondition[i], crd.Status.Conditions[i])
|
||||||
|
}
|
||||||
|
if crd.Status.Conditions[i].LastTransitionTime.IsZero() {
|
||||||
|
t.Errorf("%q/%d lastTransitionTime should not be null: %v", tc.name, i, crd.Status.Conditions[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveCRDCondition(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
crdCondition []apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
conditionType apiextensionsv1.CustomResourceDefinitionConditionType
|
||||||
|
expectedcrdCondition []apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test remove CRDCondition when the conditionType meets",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
conditionType: apiextensionsv1.NamesAccepted,
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2011, 1, 2, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test remove CRDCondition when the conditionType not meets",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
conditionType: apiextensionsv1.Terminating,
|
||||||
|
expectedcrdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
crd := generateCRDwithCondition(tc.crdCondition)
|
||||||
|
RemoveCRDCondition(crd, tc.conditionType)
|
||||||
|
if len(tc.expectedcrdCondition) != len(crd.Status.Conditions) {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expectedcrdCondition, crd.Status.Conditions)
|
||||||
|
}
|
||||||
|
for i := range tc.expectedcrdCondition {
|
||||||
|
if !IsCRDConditionEquivalent(&tc.expectedcrdCondition[i], &crd.Status.Conditions[i]) {
|
||||||
|
t.Errorf("%v expected %v, got %v", tc.name, tc.expectedcrdCondition, crd.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsCRDConditionPresentAndEqual(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
crdCondition []apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
|
conditionType apiextensionsv1.CustomResourceDefinitionConditionType
|
||||||
|
status apiextensionsv1.ConditionStatus
|
||||||
|
expectresult bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test CRDCondition is not Present",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
conditionType: apiextensionsv1.Terminating,
|
||||||
|
status: apiextensionsv1.ConditionTrue,
|
||||||
|
expectresult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test CRDCondition is Present but not Equal",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
conditionType: apiextensionsv1.Established,
|
||||||
|
status: apiextensionsv1.ConditionFalse,
|
||||||
|
expectresult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test CRDCondition is Present and Equal",
|
||||||
|
crdCondition: []apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.Established,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "Accepted",
|
||||||
|
Message: "the initial names have been accepted",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
|
Reason: "NoConflicts",
|
||||||
|
Message: "no conflicts found",
|
||||||
|
LastTransitionTime: metav1.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
conditionType: apiextensionsv1.NamesAccepted,
|
||||||
|
status: apiextensionsv1.ConditionTrue,
|
||||||
|
expectresult: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
crd := generateCRDwithCondition(tc.crdCondition)
|
||||||
|
res := IsCRDConditionPresentAndEqual(crd, tc.conditionType, tc.status)
|
||||||
|
if res != tc.expectresult {
|
||||||
|
t.Errorf("%v expected %t, got %t", tc.name, tc.expectresult, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateCRDwithCondition(conditions []apiextensionsv1.CustomResourceDefinitionCondition) *apiextensionsv1.CustomResourceDefinition {
|
||||||
|
testCRDObjectMeta := metav1.ObjectMeta{
|
||||||
|
Name: "plural.group.com",
|
||||||
|
ResourceVersion: "12",
|
||||||
|
}
|
||||||
|
testCRDSpec := apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
|
Group: "group.com",
|
||||||
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
|
Plural: "plural",
|
||||||
|
Singular: "singular",
|
||||||
|
Kind: "kind",
|
||||||
|
ListKind: "listkind",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testCRDAcceptedNames := apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
|
Plural: "plural",
|
||||||
|
Singular: "singular",
|
||||||
|
Kind: "kind",
|
||||||
|
ListKind: "listkind",
|
||||||
|
}
|
||||||
|
return &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: testCRDObjectMeta,
|
||||||
|
Spec: testCRDSpec,
|
||||||
|
Status: apiextensionsv1.CustomResourceDefinitionStatus{
|
||||||
|
AcceptedNames: testCRDAcceptedNames,
|
||||||
|
Conditions: conditions,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,12 +13,14 @@ go_library(
|
|||||||
"customresource_discovery.go",
|
"customresource_discovery.go",
|
||||||
"customresource_discovery_controller.go",
|
"customresource_discovery_controller.go",
|
||||||
"customresource_handler.go",
|
"customresource_handler.go",
|
||||||
|
"helpers.go",
|
||||||
],
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver",
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
@ -30,11 +32,9 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/apiapproval:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/apiapproval:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/establish:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/establish:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/finalizer:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/finalizer:go_default_library",
|
||||||
@ -101,9 +101,9 @@ go_test(
|
|||||||
srcs = ["customresource_handler_test.go"],
|
srcs = ["customresource_handler_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/conversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/conversion:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library",
|
||||||
|
@ -25,10 +25,10 @@ import (
|
|||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
|
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
_ "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
_ "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset"
|
|
||||||
_ "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
_ "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||||
internalinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion"
|
externalinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/apiapproval"
|
"k8s.io/apiextensions-apiserver/pkg/controller/apiapproval"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/establish"
|
"k8s.io/apiextensions-apiserver/pkg/controller/establish"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
||||||
@ -109,7 +109,7 @@ type CustomResourceDefinitions struct {
|
|||||||
GenericAPIServer *genericapiserver.GenericAPIServer
|
GenericAPIServer *genericapiserver.GenericAPIServer
|
||||||
|
|
||||||
// provided for easier embedding
|
// provided for easier embedding
|
||||||
Informers internalinformers.SharedInformerFactory
|
Informers externalinformers.SharedInformerFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
|
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
|
||||||
@ -164,13 +164,13 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
crdClient, err := internalclientset.NewForConfig(s.GenericAPIServer.LoopbackClientConfig)
|
crdClient, err := clientset.NewForConfig(s.GenericAPIServer.LoopbackClientConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// it's really bad that this is leaking here, but until we can fix the test (which I'm pretty sure isn't even testing what it wants to test),
|
// it's really bad that this is leaking here, but until we can fix the test (which I'm pretty sure isn't even testing what it wants to test),
|
||||||
// we need to be able to move forward
|
// we need to be able to move forward
|
||||||
return nil, fmt.Errorf("failed to create clientset: %v", err)
|
return nil, fmt.Errorf("failed to create clientset: %v", err)
|
||||||
}
|
}
|
||||||
s.Informers = internalinformers.NewSharedInformerFactory(crdClient, 5*time.Minute)
|
s.Informers = externalinformers.NewSharedInformerFactory(crdClient, 5*time.Minute)
|
||||||
|
|
||||||
delegateHandler := delegationTarget.UnprotectedHandler()
|
delegateHandler := delegationTarget.UnprotectedHandler()
|
||||||
if delegateHandler == nil {
|
if delegateHandler == nil {
|
||||||
@ -185,11 +185,11 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||||||
discovery: map[string]*discovery.APIGroupHandler{},
|
discovery: map[string]*discovery.APIGroupHandler{},
|
||||||
delegate: delegateHandler,
|
delegate: delegateHandler,
|
||||||
}
|
}
|
||||||
establishingController := establish.NewEstablishingController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
establishingController := establish.NewEstablishingController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||||
crdHandler, err := NewCustomResourceDefinitionHandler(
|
crdHandler, err := NewCustomResourceDefinitionHandler(
|
||||||
versionDiscoveryHandler,
|
versionDiscoveryHandler,
|
||||||
groupDiscoveryHandler,
|
groupDiscoveryHandler,
|
||||||
s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
s.Informers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||||
delegateHandler,
|
delegateHandler,
|
||||||
c.ExtraConfig.CRDRESTOptionsGetter,
|
c.ExtraConfig.CRDRESTOptionsGetter,
|
||||||
c.GenericConfig.AdmissionControl,
|
c.GenericConfig.AdmissionControl,
|
||||||
@ -209,18 +209,18 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||||||
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", crdHandler)
|
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", crdHandler)
|
||||||
s.GenericAPIServer.Handler.NonGoRestfulMux.HandlePrefix("/apis/", crdHandler)
|
s.GenericAPIServer.Handler.NonGoRestfulMux.HandlePrefix("/apis/", crdHandler)
|
||||||
|
|
||||||
crdController := NewDiscoveryController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler)
|
crdController := NewDiscoveryController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler)
|
||||||
namingController := status.NewNamingConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
namingController := status.NewNamingConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||||
nonStructuralSchemaController := nonstructuralschema.NewConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
nonStructuralSchemaController := nonstructuralschema.NewConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||||
apiApprovalController := apiapproval.NewKubernetesAPIApprovalPolicyConformantConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
apiApprovalController := apiapproval.NewKubernetesAPIApprovalPolicyConformantConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||||
finalizingController := finalizer.NewCRDFinalizer(
|
finalizingController := finalizer.NewCRDFinalizer(
|
||||||
s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
s.Informers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||||
crdClient.Apiextensions(),
|
crdClient.ApiextensionsV1(),
|
||||||
crdHandler,
|
crdHandler,
|
||||||
)
|
)
|
||||||
var openapiController *openapicontroller.Controller
|
var openapiController *openapicontroller.Controller
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourcePublishOpenAPI) {
|
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourcePublishOpenAPI) {
|
||||||
openapiController = openapicontroller.NewController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions())
|
openapiController = openapicontroller.NewController(s.Informers.Apiextensions().V1().CustomResourceDefinitions())
|
||||||
}
|
}
|
||||||
|
|
||||||
s.GenericAPIServer.AddPostStartHookOrDie("start-apiextensions-informers", func(context genericapiserver.PostStartHookContext) error {
|
s.GenericAPIServer.AddPostStartHookOrDie("start-apiextensions-informers", func(context genericapiserver.PostStartHookContext) error {
|
||||||
@ -249,7 +249,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||||||
// but we won't go healthy until we can handle the ones already present.
|
// but we won't go healthy until we can handle the ones already present.
|
||||||
s.GenericAPIServer.AddPostStartHookOrDie("crd-informer-synced", func(context genericapiserver.PostStartHookContext) error {
|
s.GenericAPIServer.AddPostStartHookOrDie("crd-informer-synced", func(context genericapiserver.PostStartHookContext) error {
|
||||||
return wait.PollImmediateUntil(100*time.Millisecond, func() (bool, error) {
|
return wait.PollImmediateUntil(100*time.Millisecond, func() (bool, error) {
|
||||||
return s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions().Informer().HasSynced(), nil
|
return s.Informers.Apiextensions().V1().CustomResourceDefinitions().Informer().HasSynced(), nil
|
||||||
}, context.StopCh)
|
}, context.StopCh)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
|
||||||
@ -58,7 +57,6 @@ go_test(
|
|||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -55,7 +55,7 @@ func NewCRConverterFactory(serviceResolver webhook.ServiceResolver, authResolver
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewConverter returns a new CR converter based on the conversion settings in crd object.
|
// NewConverter returns a new CR converter based on the conversion settings in crd object.
|
||||||
func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefinition) (safe, unsafe runtime.ObjectConvertor, err error) {
|
func (m *CRConverterFactory) NewConverter(crd *apiextensionsv1.CustomResourceDefinition) (safe, unsafe runtime.ObjectConvertor, err error) {
|
||||||
validVersions := map[schema.GroupVersion]bool{}
|
validVersions := map[schema.GroupVersion]bool{}
|
||||||
for _, version := range crd.Spec.Versions {
|
for _, version := range crd.Spec.Versions {
|
||||||
validVersions[schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name}] = true
|
validVersions[schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name}] = true
|
||||||
@ -63,9 +63,9 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin
|
|||||||
|
|
||||||
var converter crConverterInterface
|
var converter crConverterInterface
|
||||||
switch crd.Spec.Conversion.Strategy {
|
switch crd.Spec.Conversion.Strategy {
|
||||||
case apiextensions.NoneConverter:
|
case apiextensionsv1.NoneConverter:
|
||||||
converter = &nopConverter{}
|
converter = &nopConverter{}
|
||||||
case apiextensions.WebhookConverter:
|
case apiextensionsv1.WebhookConverter:
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
|
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
|
||||||
return nil, nil, fmt.Errorf("webhook conversion is disabled on this cluster")
|
return nil, nil, fmt.Errorf("webhook conversion is disabled on this cluster")
|
||||||
}
|
}
|
||||||
@ -84,7 +84,6 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin
|
|||||||
// Determine whether we should expect to be asked to "convert" autoscaling/v1 Scale types
|
// Determine whether we should expect to be asked to "convert" autoscaling/v1 Scale types
|
||||||
convertScale := false
|
convertScale := false
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
|
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
|
||||||
convertScale = crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil
|
|
||||||
for _, version := range crd.Spec.Versions {
|
for _, version := range crd.Spec.Versions {
|
||||||
if version.Subresources != nil && version.Subresources.Scale != nil {
|
if version.Subresources != nil && version.Subresources.Scale != nil {
|
||||||
convertScale = true
|
convertScale = true
|
||||||
@ -95,7 +94,7 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin
|
|||||||
unsafe = &crConverter{
|
unsafe = &crConverter{
|
||||||
convertScale: convertScale,
|
convertScale: convertScale,
|
||||||
validVersions: validVersions,
|
validVersions: validVersions,
|
||||||
clusterScoped: crd.Spec.Scope == apiextensions.ClusterScoped,
|
clusterScoped: crd.Spec.Scope == apiextensionsv1.ClusterScoped,
|
||||||
converter: converter,
|
converter: converter,
|
||||||
}
|
}
|
||||||
return &safeConverterWrapper{unsafe}, unsafe, nil
|
return &safeConverterWrapper{unsafe}, unsafe, nil
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -159,16 +159,16 @@ func TestConversion(t *testing.T) {
|
|||||||
t.Fatalf("Cannot create conversion factory: %v", err)
|
t.Fatalf("Cannot create conversion factory: %v", err)
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
testCRD := apiextensions.CustomResourceDefinition{
|
testCRD := apiextensionsv1.CustomResourceDefinition{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Conversion: &apiextensions.CustomResourceConversion{
|
Conversion: &apiextensionsv1.CustomResourceConversion{
|
||||||
Strategy: apiextensions.NoneConverter,
|
Strategy: apiextensionsv1.NoneConverter,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, v := range test.ValidVersions {
|
for _, v := range test.ValidVersions {
|
||||||
gv, _ := schema.ParseGroupVersion(v)
|
gv, _ := schema.ParseGroupVersion(v)
|
||||||
testCRD.Spec.Versions = append(testCRD.Spec.Versions, apiextensions.CustomResourceDefinitionVersion{Name: gv.Version, Served: true})
|
testCRD.Spec.Versions = append(testCRD.Spec.Versions, apiextensionsv1.CustomResourceDefinitionVersion{Name: gv.Version, Served: true})
|
||||||
testCRD.Spec.Group = gv.Group
|
testCRD.Spec.Group = gv.Group
|
||||||
}
|
}
|
||||||
safeConverter, _, err := CRConverterFactory.NewConverter(&testCRD)
|
safeConverter, _, err := CRConverterFactory.NewConverter(&testCRD)
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||||
@ -73,8 +73,8 @@ type webhookConverter struct {
|
|||||||
conversionReviewVersions []string
|
conversionReviewVersions []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.ClientConfig {
|
func webhookClientConfigForCRD(crd *apiextensionsv1.CustomResourceDefinition) *webhook.ClientConfig {
|
||||||
apiConfig := crd.Spec.Conversion.WebhookClientConfig
|
apiConfig := crd.Spec.Conversion.Webhook.ClientConfig
|
||||||
ret := webhook.ClientConfig{
|
ret := webhook.ClientConfig{
|
||||||
Name: fmt.Sprintf("conversion_webhook_for_%s", crd.Name),
|
Name: fmt.Sprintf("conversion_webhook_for_%s", crd.Name),
|
||||||
CABundle: apiConfig.CABundle,
|
CABundle: apiConfig.CABundle,
|
||||||
@ -86,7 +86,7 @@ func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.
|
|||||||
ret.Service = &webhook.ClientConfigService{
|
ret.Service = &webhook.ClientConfigService{
|
||||||
Name: apiConfig.Service.Name,
|
Name: apiConfig.Service.Name,
|
||||||
Namespace: apiConfig.Service.Namespace,
|
Namespace: apiConfig.Service.Namespace,
|
||||||
Port: apiConfig.Service.Port,
|
Port: *apiConfig.Service.Port,
|
||||||
}
|
}
|
||||||
if apiConfig.Service.Path != nil {
|
if apiConfig.Service.Path != nil {
|
||||||
ret.Service.Path = *apiConfig.Service.Path
|
ret.Service.Path = *apiConfig.Service.Path
|
||||||
@ -97,7 +97,7 @@ func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.
|
|||||||
|
|
||||||
var _ crConverterInterface = &webhookConverter{}
|
var _ crConverterInterface = &webhookConverter{}
|
||||||
|
|
||||||
func (f *webhookConverterFactory) NewWebhookConverter(crd *internal.CustomResourceDefinition) (*webhookConverter, error) {
|
func (f *webhookConverterFactory) NewWebhookConverter(crd *apiextensionsv1.CustomResourceDefinition) (*webhookConverter, error) {
|
||||||
restClient, err := f.clientManager.HookClient(*webhookClientConfigForCRD(crd))
|
restClient, err := f.clientManager.HookClient(*webhookClientConfigForCRD(crd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -108,7 +108,7 @@ func (f *webhookConverterFactory) NewWebhookConverter(crd *internal.CustomResour
|
|||||||
name: crd.Name,
|
name: crd.Name,
|
||||||
nopConverter: nopConverter{},
|
nopConverter: nopConverter{},
|
||||||
|
|
||||||
conversionReviewVersions: crd.Spec.Conversion.ConversionReviewVersions,
|
conversionReviewVersions: crd.Spec.Conversion.Webhook.ConversionReviewVersions,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,10 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiscoveryController struct {
|
type DiscoveryController struct {
|
||||||
@ -86,7 +87,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
|||||||
foundVersion := false
|
foundVersion := false
|
||||||
foundGroup := false
|
foundGroup := false
|
||||||
for _, crd := range crds {
|
for _, crd := range crds {
|
||||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,14 +127,14 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
|||||||
|
|
||||||
verbs := metav1.Verbs([]string{"delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"})
|
verbs := metav1.Verbs([]string{"delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"})
|
||||||
// if we're terminating we don't allow some verbs
|
// if we're terminating we don't allow some verbs
|
||||||
if apiextensions.IsCRDConditionTrue(crd, apiextensions.Terminating) {
|
if apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Terminating) {
|
||||||
verbs = metav1.Verbs([]string{"delete", "deletecollection", "get", "list", "watch"})
|
verbs = metav1.Verbs([]string{"delete", "deletecollection", "get", "list", "watch"})
|
||||||
}
|
}
|
||||||
|
|
||||||
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
||||||
Name: crd.Status.AcceptedNames.Plural,
|
Name: crd.Status.AcceptedNames.Plural,
|
||||||
SingularName: crd.Status.AcceptedNames.Singular,
|
SingularName: crd.Status.AcceptedNames.Singular,
|
||||||
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
|
Namespaced: crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||||
Kind: crd.Status.AcceptedNames.Kind,
|
Kind: crd.Status.AcceptedNames.Kind,
|
||||||
Verbs: verbs,
|
Verbs: verbs,
|
||||||
ShortNames: crd.Status.AcceptedNames.ShortNames,
|
ShortNames: crd.Status.AcceptedNames.ShortNames,
|
||||||
@ -141,14 +142,14 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
|||||||
StorageVersionHash: storageVersionHash,
|
StorageVersionHash: storageVersionHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, version.Version)
|
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, version.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if subresources != nil && subresources.Status != nil {
|
if subresources != nil && subresources.Status != nil {
|
||||||
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
||||||
Name: crd.Status.AcceptedNames.Plural + "/status",
|
Name: crd.Status.AcceptedNames.Plural + "/status",
|
||||||
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
|
Namespaced: crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||||
Kind: crd.Status.AcceptedNames.Kind,
|
Kind: crd.Status.AcceptedNames.Kind,
|
||||||
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
|
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
|
||||||
})
|
})
|
||||||
@ -160,7 +161,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
|||||||
Version: "v1",
|
Version: "v1",
|
||||||
Kind: "Scale",
|
Kind: "Scale",
|
||||||
Name: crd.Status.AcceptedNames.Plural + "/scale",
|
Name: crd.Status.AcceptedNames.Plural + "/scale",
|
||||||
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
|
Namespaced: crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||||
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
|
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -243,21 +244,21 @@ func (c *DiscoveryController) processNextWorkItem() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DiscoveryController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *DiscoveryController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
for _, v := range obj.Spec.Versions {
|
for _, v := range obj.Spec.Versions {
|
||||||
c.queue.Add(schema.GroupVersion{Group: obj.Spec.Group, Version: v.Name})
|
c.queue.Add(schema.GroupVersion{Group: obj.Spec.Group, Version: v.Name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DiscoveryController) addCustomResourceDefinition(obj interface{}) {
|
func (c *DiscoveryController) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DiscoveryController) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
func (c *DiscoveryController) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||||
castNewObj := newObj.(*apiextensions.CustomResourceDefinition)
|
castNewObj := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
castOldObj := oldObj.(*apiextensions.CustomResourceDefinition)
|
castOldObj := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Updating customresourcedefinition %s", castOldObj.Name)
|
klog.V(4).Infof("Updating customresourcedefinition %s", castOldObj.Name)
|
||||||
// Enqueue both old and new object to make sure we remove and add appropriate Versions.
|
// Enqueue both old and new object to make sure we remove and add appropriate Versions.
|
||||||
// The working queue will resolve any duplicates and only changes will stay in the queue.
|
// The working queue will resolve any duplicates and only changes will stay in the queue.
|
||||||
@ -266,14 +267,14 @@ func (c *DiscoveryController) updateCustomResourceDefinition(oldObj, newObj inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *DiscoveryController) deleteCustomResourceDefinition(obj interface{}) {
|
func (c *DiscoveryController) deleteCustomResourceDefinition(obj interface{}) {
|
||||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||||
return
|
return
|
||||||
|
@ -29,15 +29,17 @@ import (
|
|||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/validate"
|
"github.com/go-openapi/validate"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
|
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apiserver/conversion"
|
"k8s.io/apiextensions-apiserver/pkg/apiserver/conversion"
|
||||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||||
structuraldefaulting "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting"
|
structuraldefaulting "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting"
|
||||||
schemaobjectmeta "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta"
|
schemaobjectmeta "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta"
|
||||||
structuralpruning "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning"
|
structuralpruning "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning"
|
||||||
apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
|
apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/establish"
|
"k8s.io/apiextensions-apiserver/pkg/controller/establish"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
||||||
@ -135,8 +137,8 @@ type crdHandler struct {
|
|||||||
type crdInfo struct {
|
type crdInfo struct {
|
||||||
// spec and acceptedNames are used to compare against if a change is made on a CRD. We only update
|
// spec and acceptedNames are used to compare against if a change is made on a CRD. We only update
|
||||||
// the storage if one of these changes.
|
// the storage if one of these changes.
|
||||||
spec *apiextensions.CustomResourceDefinitionSpec
|
spec *apiextensionsv1.CustomResourceDefinitionSpec
|
||||||
acceptedNames *apiextensions.CustomResourceDefinitionNames
|
acceptedNames *apiextensionsv1.CustomResourceDefinitionNames
|
||||||
|
|
||||||
// Storage per version
|
// Storage per version
|
||||||
storages map[string]customresource.CustomResourceStorage
|
storages map[string]customresource.CustomResourceStorage
|
||||||
@ -277,7 +279,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
// if the scope in the CRD and the scope in request differ (with exception of the verbs in possiblyAcrossAllNamespacesVerbs
|
// if the scope in the CRD and the scope in request differ (with exception of the verbs in possiblyAcrossAllNamespacesVerbs
|
||||||
// for namespaced resources), pass request to the delegate, which is supposed to lead to a 404.
|
// for namespaced resources), pass request to the delegate, which is supposed to lead to a 404.
|
||||||
namespacedCRD, namespacedReq := crd.Spec.Scope == apiextensions.NamespaceScoped, len(requestInfo.Namespace) > 0
|
namespacedCRD, namespacedReq := crd.Spec.Scope == apiextensionsv1.NamespaceScoped, len(requestInfo.Namespace) > 0
|
||||||
if !namespacedCRD && namespacedReq {
|
if !namespacedCRD && namespacedReq {
|
||||||
r.delegate.ServeHTTP(w, req)
|
r.delegate.ServeHTTP(w, req)
|
||||||
return
|
return
|
||||||
@ -287,7 +289,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apiextensions.HasServedCRDVersion(crd, requestInfo.APIVersion) {
|
if !apiextensionshelpers.HasServedCRDVersion(crd, requestInfo.APIVersion) {
|
||||||
r.delegate.ServeHTTP(w, req)
|
r.delegate.ServeHTTP(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -296,13 +298,13 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
// but it becomes "unserved" because another names update leads to a conflict
|
// but it becomes "unserved" because another names update leads to a conflict
|
||||||
// and EstablishingController wasn't fast enough to put the CRD into the Established condition.
|
// and EstablishingController wasn't fast enough to put the CRD into the Established condition.
|
||||||
// We accept this as the problem is small and self-healing.
|
// We accept this as the problem is small and self-healing.
|
||||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.NamesAccepted) &&
|
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.NamesAccepted) &&
|
||||||
!apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
!apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||||
r.delegate.ServeHTTP(w, req)
|
r.delegate.ServeHTTP(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
terminating := apiextensions.IsCRDConditionTrue(crd, apiextensions.Terminating)
|
terminating := apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Terminating)
|
||||||
|
|
||||||
crdInfo, err := r.getOrCreateServingInfoFor(crd.UID, crd.Name)
|
crdInfo, err := r.getOrCreateServingInfoFor(crd.UID, crd.Name)
|
||||||
if apierrors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
@ -335,7 +337,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var handlerFunc http.HandlerFunc
|
var handlerFunc http.HandlerFunc
|
||||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, requestInfo.APIVersion)
|
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, requestInfo.APIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
responsewriters.ErrorNegotiated(
|
responsewriters.ErrorNegotiated(
|
||||||
@ -448,7 +450,7 @@ func (r *crdHandler) serveScale(w http.ResponseWriter, req *http.Request, reques
|
|||||||
|
|
||||||
// createCustomResourceDefinition removes potentially stale storage so it gets re-created
|
// createCustomResourceDefinition removes potentially stale storage so it gets re-created
|
||||||
func (r *crdHandler) createCustomResourceDefinition(obj interface{}) {
|
func (r *crdHandler) createCustomResourceDefinition(obj interface{}) {
|
||||||
crd := obj.(*apiextensions.CustomResourceDefinition)
|
crd := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
r.customStorageLock.Lock()
|
r.customStorageLock.Lock()
|
||||||
defer r.customStorageLock.Unlock()
|
defer r.customStorageLock.Unlock()
|
||||||
// this could happen if the create event is merged from create-update events
|
// this could happen if the create event is merged from create-update events
|
||||||
@ -457,8 +459,8 @@ func (r *crdHandler) createCustomResourceDefinition(obj interface{}) {
|
|||||||
|
|
||||||
// updateCustomResourceDefinition removes potentially stale storage so it gets re-created
|
// updateCustomResourceDefinition removes potentially stale storage so it gets re-created
|
||||||
func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||||
oldCRD := oldObj.(*apiextensions.CustomResourceDefinition)
|
oldCRD := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
newCRD := newObj.(*apiextensions.CustomResourceDefinition)
|
newCRD := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
|
|
||||||
r.customStorageLock.Lock()
|
r.customStorageLock.Lock()
|
||||||
defer r.customStorageLock.Unlock()
|
defer r.customStorageLock.Unlock()
|
||||||
@ -467,8 +469,8 @@ func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{})
|
|||||||
// For HA clusters, we want to prevent race conditions when changing status to Established,
|
// For HA clusters, we want to prevent race conditions when changing status to Established,
|
||||||
// so we want to be sure that CRD is Installing at least for 5 seconds before Establishing it.
|
// so we want to be sure that CRD is Installing at least for 5 seconds before Establishing it.
|
||||||
// TODO: find a real HA safe checkpointing mechanism instead of an arbitrary wait.
|
// TODO: find a real HA safe checkpointing mechanism instead of an arbitrary wait.
|
||||||
if !apiextensions.IsCRDConditionTrue(newCRD, apiextensions.Established) &&
|
if !apiextensionshelpers.IsCRDConditionTrue(newCRD, apiextensionsv1.Established) &&
|
||||||
apiextensions.IsCRDConditionTrue(newCRD, apiextensions.NamesAccepted) {
|
apiextensionshelpers.IsCRDConditionTrue(newCRD, apiextensionsv1.NamesAccepted) {
|
||||||
if r.masterCount > 1 {
|
if r.masterCount > 1 {
|
||||||
r.establishingController.QueueCRD(newCRD.Name, 5*time.Second)
|
r.establishingController.QueueCRD(newCRD.Name, 5*time.Second)
|
||||||
} else {
|
} else {
|
||||||
@ -575,7 +577,7 @@ func (r *crdHandler) tearDown(oldInfo *crdInfo) {
|
|||||||
|
|
||||||
// GetCustomResourceListerCollectionDeleter returns the ListerCollectionDeleter of
|
// GetCustomResourceListerCollectionDeleter returns the ListerCollectionDeleter of
|
||||||
// the given crd.
|
// the given crd.
|
||||||
func (r *crdHandler) GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) (finalizer.ListerCollectionDeleter, error) {
|
func (r *crdHandler) GetCustomResourceListerCollectionDeleter(crd *apiextensionsv1.CustomResourceDefinition) (finalizer.ListerCollectionDeleter, error) {
|
||||||
info, err := r.getOrCreateServingInfoFor(crd.UID, crd.Name)
|
info, err := r.getOrCreateServingInfoFor(crd.UID, crd.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -607,7 +609,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
storageVersion, err := apiextensions.GetCRDStorageVersion(crd)
|
storageVersion, err := apiextensionshelpers.GetCRDStorageVersion(crd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -622,7 +624,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
|
|
||||||
structuralSchemas := map[string]*structuralschema.Structural{}
|
structuralSchemas := map[string]*structuralschema.Structural{}
|
||||||
for _, v := range crd.Spec.Versions {
|
for _, v := range crd.Spec.Versions {
|
||||||
val, err := apiextensions.GetSchemaForVersion(crd, v.Name)
|
val, err := apiextensionshelpers.GetSchemaForVersion(crd, v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
return nil, fmt.Errorf("the server could not properly serve the CR schema")
|
return nil, fmt.Errorf("the server could not properly serve the CR schema")
|
||||||
@ -630,14 +632,18 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
if val == nil {
|
if val == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s, err := structuralschema.NewStructural(val.OpenAPIV3Schema)
|
internalValidation := &apiextensionsinternal.CustomResourceValidation{}
|
||||||
if *crd.Spec.PreserveUnknownFields == false && err != nil {
|
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(val, internalValidation, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed converting CRD validation to internal version: %v", err)
|
||||||
|
}
|
||||||
|
s, err := structuralschema.NewStructural(internalValidation.OpenAPIV3Schema)
|
||||||
|
if crd.Spec.PreserveUnknownFields == false && err != nil {
|
||||||
// This should never happen. If it does, it is a programming error.
|
// This should never happen. If it does, it is a programming error.
|
||||||
utilruntime.HandleError(fmt.Errorf("failed to convert schema to structural: %v", err))
|
utilruntime.HandleError(fmt.Errorf("failed to convert schema to structural: %v", err))
|
||||||
return nil, fmt.Errorf("the server could not properly serve the CR schema") // validation should avoid this
|
return nil, fmt.Errorf("the server could not properly serve the CR schema") // validation should avoid this
|
||||||
}
|
}
|
||||||
|
|
||||||
if *crd.Spec.PreserveUnknownFields == false {
|
if crd.Spec.PreserveUnknownFields == false {
|
||||||
// we don't own s completely, e.g. defaults are not deep-copied. So better make a copy here.
|
// we don't own s completely, e.g. defaults are not deep-copied. So better make a copy here.
|
||||||
s = s.DeepCopy()
|
s = s.DeepCopy()
|
||||||
|
|
||||||
@ -679,36 +685,39 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
typer := newUnstructuredObjectTyper(parameterScheme)
|
typer := newUnstructuredObjectTyper(parameterScheme)
|
||||||
creator := unstructuredCreator{}
|
creator := unstructuredCreator{}
|
||||||
|
|
||||||
validationSchema, err := apiextensions.GetSchemaForVersion(crd, v.Name)
|
validationSchema, err := apiextensionshelpers.GetSchemaForVersion(crd, v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
return nil, fmt.Errorf("the server could not properly serve the CR schema")
|
return nil, fmt.Errorf("the server could not properly serve the CR schema")
|
||||||
}
|
}
|
||||||
validator, _, err := apiservervalidation.NewSchemaValidator(validationSchema)
|
var internalValidationSchema *apiextensionsinternal.CustomResourceValidation
|
||||||
|
if validationSchema != nil {
|
||||||
|
internalValidationSchema = &apiextensionsinternal.CustomResourceValidation{}
|
||||||
|
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(validationSchema, internalValidationSchema, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert CRD validation to internal version: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validator, _, err := apiservervalidation.NewSchemaValidator(internalValidationSchema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for nil because we dereference this throughout the handler code.
|
var statusSpec *apiextensionsinternal.CustomResourceSubresourceStatus
|
||||||
// Note: we always default this to non-nil. But we should guard these dereferences any way.
|
|
||||||
if crd.Spec.PreserveUnknownFields == nil {
|
|
||||||
return nil, fmt.Errorf("unexpected nil spec.preserveUnknownFields in the CustomResourceDefinition")
|
|
||||||
}
|
|
||||||
|
|
||||||
var statusSpec *apiextensions.CustomResourceSubresourceStatus
|
|
||||||
var statusValidator *validate.SchemaValidator
|
var statusValidator *validate.SchemaValidator
|
||||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, v.Name)
|
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
return nil, fmt.Errorf("the server could not properly serve the CR subresources")
|
return nil, fmt.Errorf("the server could not properly serve the CR subresources")
|
||||||
}
|
}
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Status != nil {
|
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Status != nil {
|
||||||
equivalentResourceRegistry.RegisterKindFor(resource, "status", kind)
|
equivalentResourceRegistry.RegisterKindFor(resource, "status", kind)
|
||||||
|
statusSpec = &apiextensionsinternal.CustomResourceSubresourceStatus{}
|
||||||
statusSpec = subresources.Status
|
if err := apiextensionsv1.Convert_v1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus(subresources.Status, statusSpec, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed converting CRD status subresource to internal version: %v", err)
|
||||||
|
}
|
||||||
// for the status subresource, validate only against the status schema
|
// for the status subresource, validate only against the status schema
|
||||||
if validationSchema != nil && validationSchema.OpenAPIV3Schema != nil && validationSchema.OpenAPIV3Schema.Properties != nil {
|
if internalValidationSchema != nil && internalValidationSchema.OpenAPIV3Schema != nil && internalValidationSchema.OpenAPIV3Schema.Properties != nil {
|
||||||
if statusSchema, ok := validationSchema.OpenAPIV3Schema.Properties["status"]; ok {
|
if statusSchema, ok := internalValidationSchema.OpenAPIV3Schema.Properties["status"]; ok {
|
||||||
openapiSchema := &spec.Schema{}
|
openapiSchema := &spec.Schema{}
|
||||||
if err := apiservervalidation.ConvertJSONSchemaPropsWithPostProcess(&statusSchema, openapiSchema, apiservervalidation.StripUnsupportedFormatsPostProcess); err != nil {
|
if err := apiservervalidation.ConvertJSONSchemaPropsWithPostProcess(&statusSchema, openapiSchema, apiservervalidation.StripUnsupportedFormatsPostProcess); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -718,14 +727,16 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var scaleSpec *apiextensions.CustomResourceSubresourceScale
|
var scaleSpec *apiextensionsinternal.CustomResourceSubresourceScale
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Scale != nil {
|
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Scale != nil {
|
||||||
equivalentResourceRegistry.RegisterKindFor(resource, "scale", autoscalingv1.SchemeGroupVersion.WithKind("Scale"))
|
equivalentResourceRegistry.RegisterKindFor(resource, "scale", autoscalingv1.SchemeGroupVersion.WithKind("Scale"))
|
||||||
|
scaleSpec = &apiextensionsinternal.CustomResourceSubresourceScale{}
|
||||||
scaleSpec = subresources.Scale
|
if err := apiextensionsv1.Convert_v1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale(subresources.Scale, scaleSpec, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed converting CRD status subresource to internal version: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
columns, err := apiextensions.GetColumnsForVersion(crd, v.Name)
|
columns, err := getColumnsForVersion(crd, v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
return nil, fmt.Errorf("the server could not properly serve the CR columns")
|
return nil, fmt.Errorf("the server could not properly serve the CR columns")
|
||||||
@ -741,7 +752,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind},
|
schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind},
|
||||||
customresource.NewStrategy(
|
customresource.NewStrategy(
|
||||||
typer,
|
typer,
|
||||||
crd.Spec.Scope == apiextensions.NamespaceScoped,
|
crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||||
kind,
|
kind,
|
||||||
validator,
|
validator,
|
||||||
statusValidator,
|
statusValidator,
|
||||||
@ -756,7 +767,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
encoderVersion: schema.GroupVersion{Group: crd.Spec.Group, Version: storageVersion},
|
encoderVersion: schema.GroupVersion{Group: crd.Spec.Group, Version: storageVersion},
|
||||||
structuralSchemas: structuralSchemas,
|
structuralSchemas: structuralSchemas,
|
||||||
structuralSchemaGK: kind.GroupKind(),
|
structuralSchemaGK: kind.GroupKind(),
|
||||||
preserveUnknownFields: *crd.Spec.PreserveUnknownFields,
|
preserveUnknownFields: crd.Spec.PreserveUnknownFields,
|
||||||
},
|
},
|
||||||
crd.Status.AcceptedNames.Categories,
|
crd.Status.AcceptedNames.Categories,
|
||||||
table,
|
table,
|
||||||
@ -764,13 +775,13 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
|
|
||||||
selfLinkPrefix := ""
|
selfLinkPrefix := ""
|
||||||
switch crd.Spec.Scope {
|
switch crd.Spec.Scope {
|
||||||
case apiextensions.ClusterScoped:
|
case apiextensionsv1.ClusterScoped:
|
||||||
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name) + "/" + crd.Status.AcceptedNames.Plural + "/"
|
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name) + "/" + crd.Status.AcceptedNames.Plural + "/"
|
||||||
case apiextensions.NamespaceScoped:
|
case apiextensionsv1.NamespaceScoped:
|
||||||
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name, "namespaces") + "/"
|
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name, "namespaces") + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
clusterScoped := crd.Spec.Scope == apiextensions.ClusterScoped
|
clusterScoped := crd.Spec.Scope == apiextensionsv1.ClusterScoped
|
||||||
|
|
||||||
// CRDs explicitly do not support protobuf, but some objects returned by the API server do
|
// CRDs explicitly do not support protobuf, but some objects returned by the API server do
|
||||||
negotiatedSerializer := unstructuredNegotiatedSerializer{
|
negotiatedSerializer := unstructuredNegotiatedSerializer{
|
||||||
@ -779,7 +790,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
converter: safeConverter,
|
converter: safeConverter,
|
||||||
structuralSchemas: structuralSchemas,
|
structuralSchemas: structuralSchemas,
|
||||||
structuralSchemaGK: kind.GroupKind(),
|
structuralSchemaGK: kind.GroupKind(),
|
||||||
preserveUnknownFields: *crd.Spec.PreserveUnknownFields,
|
preserveUnknownFields: crd.Spec.PreserveUnknownFields,
|
||||||
}
|
}
|
||||||
var standardSerializers []runtime.SerializerInfo
|
var standardSerializers []runtime.SerializerInfo
|
||||||
for _, s := range negotiatedSerializer.SupportedMediaTypes() {
|
for _, s := range negotiatedSerializer.SupportedMediaTypes() {
|
||||||
@ -830,7 +841,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
|||||||
reqScope.Creater,
|
reqScope.Creater,
|
||||||
reqScope.Kind,
|
reqScope.Kind,
|
||||||
reqScope.HubGroupVersion,
|
reqScope.HubGroupVersion,
|
||||||
*crd.Spec.PreserveUnknownFields,
|
crd.Spec.PreserveUnknownFields,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1211,7 +1222,7 @@ func (v *unstructuredSchemaCoercer) apply(u *unstructured.Unstructured) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hasServedCRDVersion returns true if the given version is in the list of CRD's versions and the Served flag is set.
|
// hasServedCRDVersion returns true if the given version is in the list of CRD's versions and the Served flag is set.
|
||||||
func hasServedCRDVersion(spec *apiextensions.CustomResourceDefinitionSpec, version string) bool {
|
func hasServedCRDVersion(spec *apiextensionsv1.CustomResourceDefinitionSpec, version string) bool {
|
||||||
for _, v := range spec.Versions {
|
for _, v := range spec.Versions {
|
||||||
if v.Name == version {
|
if v.Name == version {
|
||||||
return v.Served
|
return v.Served
|
||||||
@ -1235,7 +1246,7 @@ func serverStartingError() error {
|
|||||||
// buildOpenAPIModelsForApply constructs openapi models from any validation schemas specified in the custom resource,
|
// buildOpenAPIModelsForApply constructs openapi models from any validation schemas specified in the custom resource,
|
||||||
// and merges it with the models defined in the static OpenAPI spec.
|
// and merges it with the models defined in the static OpenAPI spec.
|
||||||
// Returns nil models if the ServerSideApply feature is disabled, or the static spec is nil, or an error is encountered.
|
// Returns nil models if the ServerSideApply feature is disabled, or the static spec is nil, or an error is encountered.
|
||||||
func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensions.CustomResourceDefinition) (proto.Models, error) {
|
func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensionsv1.CustomResourceDefinition) (proto.Models, error) {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ import (
|
|||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apiserver/conversion"
|
"k8s.io/apiextensions-apiserver/pkg/apiserver/conversion"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
|
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
|
||||||
@ -78,18 +78,18 @@ func TestConvertFieldLabel(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
|
||||||
crd := apiextensions.CustomResourceDefinition{
|
crd := apiextensionsv1.CustomResourceDefinition{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Conversion: &apiextensions.CustomResourceConversion{
|
Conversion: &apiextensionsv1.CustomResourceConversion{
|
||||||
Strategy: "None",
|
Strategy: "None",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.clusterScoped {
|
if test.clusterScoped {
|
||||||
crd.Spec.Scope = apiextensions.ClusterScoped
|
crd.Spec.Scope = apiextensionsv1.ClusterScoped
|
||||||
} else {
|
} else {
|
||||||
crd.Spec.Scope = apiextensions.NamespaceScoped
|
crd.Spec.Scope = apiextensionsv1.NamespaceScoped
|
||||||
}
|
}
|
||||||
f, err := conversion.NewCRConverterFactory(nil, nil)
|
f, err := conversion.NewCRConverterFactory(nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
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 apiserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
|
||||||
|
|
||||||
|
// getColumnsForVersion returns the columns for given version or nil.
|
||||||
|
// NOTE: the newly logically-defaulted columns is not pointing to the original CRD object.
|
||||||
|
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
|
||||||
|
// the original CRD object instead.
|
||||||
|
func getColumnsForVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) ([]apiextensionsv1.CustomResourceColumnDefinition, error) {
|
||||||
|
for _, v := range crd.Spec.Versions {
|
||||||
|
if version == v.Name {
|
||||||
|
return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("version %s not found in apiextensionsv1.CustomResourceDefinition: %v", version, crd.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty.
|
||||||
|
// NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object.
|
||||||
|
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
|
||||||
|
// the original CRD object instead.
|
||||||
|
func serveDefaultColumnsIfEmpty(columns []apiextensionsv1.CustomResourceColumnDefinition) []apiextensionsv1.CustomResourceColumnDefinition {
|
||||||
|
if len(columns) > 0 {
|
||||||
|
return columns
|
||||||
|
}
|
||||||
|
return []apiextensionsv1.CustomResourceColumnDefinition{
|
||||||
|
{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality: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/runtime:go_default_library",
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer"
|
apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer"
|
||||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
|
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -43,7 +43,7 @@ func TestRoundTrip(t *testing.T) {
|
|||||||
if err := apiextensions.AddToScheme(scheme); err != nil {
|
if err := apiextensions.AddToScheme(scheme); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := apiextensionsv1beta1.AddToScheme(scheme); err != nil {
|
if err := apiextensionsv1.AddToScheme(scheme); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ func TestRoundTrip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JSON -> external
|
// JSON -> external
|
||||||
external := &apiextensionsv1beta1.JSONSchemaProps{}
|
external := &apiextensionsv1.JSONSchemaProps{}
|
||||||
if err := json.Unmarshal(openAPIJSON, external); err != nil {
|
if err := json.Unmarshal(openAPIJSON, external); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"clientset.go",
|
|
||||||
"doc.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [
|
|
||||||
":package-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:all-srcs",
|
|
||||||
],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalclientset
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
apiextensionsinternalversion "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
|
||||||
discovery "k8s.io/client-go/discovery"
|
|
||||||
rest "k8s.io/client-go/rest"
|
|
||||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Interface interface {
|
|
||||||
Discovery() discovery.DiscoveryInterface
|
|
||||||
Apiextensions() apiextensionsinternalversion.ApiextensionsInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clientset contains the clients for groups. Each group has exactly one
|
|
||||||
// version included in a Clientset.
|
|
||||||
type Clientset struct {
|
|
||||||
*discovery.DiscoveryClient
|
|
||||||
apiextensions *apiextensionsinternalversion.ApiextensionsClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apiextensions retrieves the ApiextensionsClient
|
|
||||||
func (c *Clientset) Apiextensions() apiextensionsinternalversion.ApiextensionsInterface {
|
|
||||||
return c.apiextensions
|
|
||||||
}
|
|
||||||
|
|
||||||
// Discovery retrieves the DiscoveryClient
|
|
||||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
|
||||||
if c == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c.DiscoveryClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewForConfig creates a new Clientset for the given config.
|
|
||||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
|
||||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
|
||||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|
||||||
configShallowCopy := *c
|
|
||||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
|
||||||
if configShallowCopy.Burst <= 0 {
|
|
||||||
return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
|
||||||
}
|
|
||||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
|
||||||
}
|
|
||||||
var cs Clientset
|
|
||||||
var err error
|
|
||||||
cs.apiextensions, err = apiextensionsinternalversion.NewForConfig(&configShallowCopy)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &cs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
|
||||||
// panics if there is an error in the config.
|
|
||||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
|
||||||
var cs Clientset
|
|
||||||
cs.apiextensions = apiextensionsinternalversion.NewForConfigOrDie(c)
|
|
||||||
|
|
||||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
|
||||||
return &cs
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Clientset for the given RESTClient.
|
|
||||||
func New(c rest.Interface) *Clientset {
|
|
||||||
var cs Clientset
|
|
||||||
cs.apiextensions = apiextensionsinternalversion.New(c)
|
|
||||||
|
|
||||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
|
||||||
return &cs
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// This package has the automatically generated clientset.
|
|
||||||
package internalclientset
|
|
@ -1,45 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"clientset_generated.go",
|
|
||||||
"doc.go",
|
|
||||||
"register.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake: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/apimachinery/pkg/runtime/schema:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/discovery/fake:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package fake
|
|
||||||
|
|
||||||
import (
|
|
||||||
clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset"
|
|
||||||
apiextensionsinternalversion "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
|
||||||
fakeapiextensionsinternalversion "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
|
||||||
"k8s.io/client-go/discovery"
|
|
||||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
|
||||||
"k8s.io/client-go/testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
|
||||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
|
||||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
|
||||||
// for a real clientset and is mostly useful in simple unit tests.
|
|
||||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
|
||||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
|
||||||
for _, obj := range objects {
|
|
||||||
if err := o.Add(obj); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cs := &Clientset{tracker: o}
|
|
||||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
|
||||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
|
||||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
|
||||||
gvr := action.GetResource()
|
|
||||||
ns := action.GetNamespace()
|
|
||||||
watch, err := o.Watch(gvr, ns)
|
|
||||||
if err != nil {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
return true, watch, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return cs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
|
||||||
// struct to get a default implementation. This makes faking out just the method
|
|
||||||
// you want to test easier.
|
|
||||||
type Clientset struct {
|
|
||||||
testing.Fake
|
|
||||||
discovery *fakediscovery.FakeDiscovery
|
|
||||||
tracker testing.ObjectTracker
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
|
||||||
return c.discovery
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Clientset) Tracker() testing.ObjectTracker {
|
|
||||||
return c.tracker
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ clientset.Interface = &Clientset{}
|
|
||||||
|
|
||||||
// Apiextensions retrieves the ApiextensionsClient
|
|
||||||
func (c *Clientset) Apiextensions() apiextensionsinternalversion.ApiextensionsInterface {
|
|
||||||
return &fakeapiextensionsinternalversion.FakeApiextensions{Fake: &c.Fake}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// This package has the automatically generated fake clientset.
|
|
||||||
package fake
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package fake
|
|
||||||
|
|
||||||
import (
|
|
||||||
apiextensionsinternalversion "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var scheme = runtime.NewScheme()
|
|
||||||
var codecs = serializer.NewCodecFactory(scheme)
|
|
||||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
|
||||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
|
||||||
apiextensionsinternalversion.AddToScheme,
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
|
||||||
// of clientsets, like in:
|
|
||||||
//
|
|
||||||
// import (
|
|
||||||
// "k8s.io/client-go/kubernetes"
|
|
||||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
|
||||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
|
||||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
|
||||||
//
|
|
||||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
|
||||||
// correctly.
|
|
||||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
|
|
||||||
utilruntime.Must(AddToScheme(scheme))
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"doc.go",
|
|
||||||
"register.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install: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/apimachinery/pkg/runtime/schema:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// This package contains the scheme of the automatically generated clientset.
|
|
||||||
package scheme
|
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package scheme
|
|
||||||
|
|
||||||
import (
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Scheme = runtime.NewScheme()
|
|
||||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
|
||||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
|
||||||
Install(Scheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install registers the API group and adds types to a scheme
|
|
||||||
func Install(scheme *runtime.Scheme) {
|
|
||||||
apiextensions.Install(scheme)
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"apiextensions_client.go",
|
|
||||||
"customresourcedefinition.go",
|
|
||||||
"doc.go",
|
|
||||||
"generated_expansion.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [
|
|
||||||
":package-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake:all-srcs",
|
|
||||||
],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme"
|
|
||||||
rest "k8s.io/client-go/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ApiextensionsInterface interface {
|
|
||||||
RESTClient() rest.Interface
|
|
||||||
CustomResourceDefinitionsGetter
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiextensionsClient is used to interact with features provided by the apiextensions.k8s.io group.
|
|
||||||
type ApiextensionsClient struct {
|
|
||||||
restClient rest.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ApiextensionsClient) CustomResourceDefinitions() CustomResourceDefinitionInterface {
|
|
||||||
return newCustomResourceDefinitions(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewForConfig creates a new ApiextensionsClient for the given config.
|
|
||||||
func NewForConfig(c *rest.Config) (*ApiextensionsClient, error) {
|
|
||||||
config := *c
|
|
||||||
if err := setConfigDefaults(&config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
client, err := rest.RESTClientFor(&config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ApiextensionsClient{client}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewForConfigOrDie creates a new ApiextensionsClient for the given config and
|
|
||||||
// panics if there is an error in the config.
|
|
||||||
func NewForConfigOrDie(c *rest.Config) *ApiextensionsClient {
|
|
||||||
client, err := NewForConfig(c)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return client
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new ApiextensionsClient for the given RESTClient.
|
|
||||||
func New(c rest.Interface) *ApiextensionsClient {
|
|
||||||
return &ApiextensionsClient{c}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setConfigDefaults(config *rest.Config) error {
|
|
||||||
config.APIPath = "/apis"
|
|
||||||
if config.UserAgent == "" {
|
|
||||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
|
||||||
}
|
|
||||||
if config.GroupVersion == nil || config.GroupVersion.Group != scheme.Scheme.PrioritizedVersionsForGroup("apiextensions.k8s.io")[0].Group {
|
|
||||||
gv := scheme.Scheme.PrioritizedVersionsForGroup("apiextensions.k8s.io")[0]
|
|
||||||
config.GroupVersion = &gv
|
|
||||||
}
|
|
||||||
config.NegotiatedSerializer = scheme.Codecs
|
|
||||||
|
|
||||||
if config.QPS == 0 {
|
|
||||||
config.QPS = 5
|
|
||||||
}
|
|
||||||
if config.Burst == 0 {
|
|
||||||
config.Burst = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RESTClient returns a RESTClient that is used to communicate
|
|
||||||
// with API server by this client implementation.
|
|
||||||
func (c *ApiextensionsClient) RESTClient() rest.Interface {
|
|
||||||
if c == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c.restClient
|
|
||||||
}
|
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
scheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
|
||||||
rest "k8s.io/client-go/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CustomResourceDefinitionsGetter has a method to return a CustomResourceDefinitionInterface.
|
|
||||||
// A group's client should implement this interface.
|
|
||||||
type CustomResourceDefinitionsGetter interface {
|
|
||||||
CustomResourceDefinitions() CustomResourceDefinitionInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// CustomResourceDefinitionInterface has methods to work with CustomResourceDefinition resources.
|
|
||||||
type CustomResourceDefinitionInterface interface {
|
|
||||||
Create(*apiextensions.CustomResourceDefinition) (*apiextensions.CustomResourceDefinition, error)
|
|
||||||
Update(*apiextensions.CustomResourceDefinition) (*apiextensions.CustomResourceDefinition, error)
|
|
||||||
UpdateStatus(*apiextensions.CustomResourceDefinition) (*apiextensions.CustomResourceDefinition, error)
|
|
||||||
Delete(name string, options *v1.DeleteOptions) error
|
|
||||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
|
||||||
Get(name string, options v1.GetOptions) (*apiextensions.CustomResourceDefinition, error)
|
|
||||||
List(opts v1.ListOptions) (*apiextensions.CustomResourceDefinitionList, error)
|
|
||||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
|
||||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apiextensions.CustomResourceDefinition, err error)
|
|
||||||
CustomResourceDefinitionExpansion
|
|
||||||
}
|
|
||||||
|
|
||||||
// customResourceDefinitions implements CustomResourceDefinitionInterface
|
|
||||||
type customResourceDefinitions struct {
|
|
||||||
client rest.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCustomResourceDefinitions returns a CustomResourceDefinitions
|
|
||||||
func newCustomResourceDefinitions(c *ApiextensionsClient) *customResourceDefinitions {
|
|
||||||
return &customResourceDefinitions{
|
|
||||||
client: c.RESTClient(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get takes name of the customResourceDefinition, and returns the corresponding customResourceDefinition object, and an error if there is any.
|
|
||||||
func (c *customResourceDefinitions) Get(name string, options v1.GetOptions) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
result = &apiextensions.CustomResourceDefinition{}
|
|
||||||
err = c.client.Get().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
Name(name).
|
|
||||||
VersionedParams(&options, scheme.ParameterCodec).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// List takes label and field selectors, and returns the list of CustomResourceDefinitions that match those selectors.
|
|
||||||
func (c *customResourceDefinitions) List(opts v1.ListOptions) (result *apiextensions.CustomResourceDefinitionList, err error) {
|
|
||||||
var timeout time.Duration
|
|
||||||
if opts.TimeoutSeconds != nil {
|
|
||||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
|
||||||
}
|
|
||||||
result = &apiextensions.CustomResourceDefinitionList{}
|
|
||||||
err = c.client.Get().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
VersionedParams(&opts, scheme.ParameterCodec).
|
|
||||||
Timeout(timeout).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch returns a watch.Interface that watches the requested customResourceDefinitions.
|
|
||||||
func (c *customResourceDefinitions) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
|
||||||
var timeout time.Duration
|
|
||||||
if opts.TimeoutSeconds != nil {
|
|
||||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
|
||||||
}
|
|
||||||
opts.Watch = true
|
|
||||||
return c.client.Get().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
VersionedParams(&opts, scheme.ParameterCodec).
|
|
||||||
Timeout(timeout).
|
|
||||||
Watch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create takes the representation of a customResourceDefinition and creates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
|
|
||||||
func (c *customResourceDefinitions) Create(customResourceDefinition *apiextensions.CustomResourceDefinition) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
result = &apiextensions.CustomResourceDefinition{}
|
|
||||||
err = c.client.Post().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
Body(customResourceDefinition).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update takes the representation of a customResourceDefinition and updates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
|
|
||||||
func (c *customResourceDefinitions) Update(customResourceDefinition *apiextensions.CustomResourceDefinition) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
result = &apiextensions.CustomResourceDefinition{}
|
|
||||||
err = c.client.Put().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
Name(customResourceDefinition.Name).
|
|
||||||
Body(customResourceDefinition).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateStatus was generated because the type contains a Status member.
|
|
||||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
|
||||||
|
|
||||||
func (c *customResourceDefinitions) UpdateStatus(customResourceDefinition *apiextensions.CustomResourceDefinition) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
result = &apiextensions.CustomResourceDefinition{}
|
|
||||||
err = c.client.Put().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
Name(customResourceDefinition.Name).
|
|
||||||
SubResource("status").
|
|
||||||
Body(customResourceDefinition).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete takes name of the customResourceDefinition and deletes it. Returns an error if one occurs.
|
|
||||||
func (c *customResourceDefinitions) Delete(name string, options *v1.DeleteOptions) error {
|
|
||||||
return c.client.Delete().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
Name(name).
|
|
||||||
Body(options).
|
|
||||||
Do().
|
|
||||||
Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteCollection deletes a collection of objects.
|
|
||||||
func (c *customResourceDefinitions) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
|
||||||
var timeout time.Duration
|
|
||||||
if listOptions.TimeoutSeconds != nil {
|
|
||||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
|
||||||
}
|
|
||||||
return c.client.Delete().
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
|
||||||
Timeout(timeout).
|
|
||||||
Body(options).
|
|
||||||
Do().
|
|
||||||
Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Patch applies the patch and returns the patched customResourceDefinition.
|
|
||||||
func (c *customResourceDefinitions) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
result = &apiextensions.CustomResourceDefinition{}
|
|
||||||
err = c.client.Patch(pt).
|
|
||||||
Resource("customresourcedefinitions").
|
|
||||||
SubResource(subresources...).
|
|
||||||
Name(name).
|
|
||||||
Body(data).
|
|
||||||
Do().
|
|
||||||
Into(result)
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// This package has the automatically generated typed clients.
|
|
||||||
package internalversion
|
|
@ -1,41 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"doc.go",
|
|
||||||
"fake_apiextensions_client.go",
|
|
||||||
"fake_customresourcedefinition.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// Package fake has the automatically generated clients.
|
|
||||||
package fake
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package fake
|
|
||||||
|
|
||||||
import (
|
|
||||||
internalversion "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
|
||||||
rest "k8s.io/client-go/rest"
|
|
||||||
testing "k8s.io/client-go/testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FakeApiextensions struct {
|
|
||||||
*testing.Fake
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeApiextensions) CustomResourceDefinitions() internalversion.CustomResourceDefinitionInterface {
|
|
||||||
return &FakeCustomResourceDefinitions{c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RESTClient returns a RESTClient that is used to communicate
|
|
||||||
// with API server by this client implementation.
|
|
||||||
func (c *FakeApiextensions) RESTClient() rest.Interface {
|
|
||||||
var ret *rest.RESTClient
|
|
||||||
return ret
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package fake
|
|
||||||
|
|
||||||
import (
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
|
||||||
testing "k8s.io/client-go/testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FakeCustomResourceDefinitions implements CustomResourceDefinitionInterface
|
|
||||||
type FakeCustomResourceDefinitions struct {
|
|
||||||
Fake *FakeApiextensions
|
|
||||||
}
|
|
||||||
|
|
||||||
var customresourcedefinitionsResource = schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "", Resource: "customresourcedefinitions"}
|
|
||||||
|
|
||||||
var customresourcedefinitionsKind = schema.GroupVersionKind{Group: "apiextensions.k8s.io", Version: "", Kind: "CustomResourceDefinition"}
|
|
||||||
|
|
||||||
// Get takes name of the customResourceDefinition, and returns the corresponding customResourceDefinition object, and an error if there is any.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Get(name string, options v1.GetOptions) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootGetAction(customresourcedefinitionsResource, name), &apiextensions.CustomResourceDefinition{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// List takes label and field selectors, and returns the list of CustomResourceDefinitions that match those selectors.
|
|
||||||
func (c *FakeCustomResourceDefinitions) List(opts v1.ListOptions) (result *apiextensions.CustomResourceDefinitionList, err error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootListAction(customresourcedefinitionsResource, customresourcedefinitionsKind, opts), &apiextensions.CustomResourceDefinitionList{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
|
||||||
if label == nil {
|
|
||||||
label = labels.Everything()
|
|
||||||
}
|
|
||||||
list := &apiextensions.CustomResourceDefinitionList{ListMeta: obj.(*apiextensions.CustomResourceDefinitionList).ListMeta}
|
|
||||||
for _, item := range obj.(*apiextensions.CustomResourceDefinitionList).Items {
|
|
||||||
if label.Matches(labels.Set(item.Labels)) {
|
|
||||||
list.Items = append(list.Items, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch returns a watch.Interface that watches the requested customResourceDefinitions.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
|
||||||
return c.Fake.
|
|
||||||
InvokesWatch(testing.NewRootWatchAction(customresourcedefinitionsResource, opts))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create takes the representation of a customResourceDefinition and creates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Create(customResourceDefinition *apiextensions.CustomResourceDefinition) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootCreateAction(customresourcedefinitionsResource, customResourceDefinition), &apiextensions.CustomResourceDefinition{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update takes the representation of a customResourceDefinition and updates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Update(customResourceDefinition *apiextensions.CustomResourceDefinition) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootUpdateAction(customresourcedefinitionsResource, customResourceDefinition), &apiextensions.CustomResourceDefinition{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateStatus was generated because the type contains a Status member.
|
|
||||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
|
||||||
func (c *FakeCustomResourceDefinitions) UpdateStatus(customResourceDefinition *apiextensions.CustomResourceDefinition) (*apiextensions.CustomResourceDefinition, error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootUpdateSubresourceAction(customresourcedefinitionsResource, "status", customResourceDefinition), &apiextensions.CustomResourceDefinition{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete takes name of the customResourceDefinition and deletes it. Returns an error if one occurs.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Delete(name string, options *v1.DeleteOptions) error {
|
|
||||||
_, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootDeleteAction(customresourcedefinitionsResource, name), &apiextensions.CustomResourceDefinition{})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteCollection deletes a collection of objects.
|
|
||||||
func (c *FakeCustomResourceDefinitions) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
|
||||||
action := testing.NewRootDeleteCollectionAction(customresourcedefinitionsResource, listOptions)
|
|
||||||
|
|
||||||
_, err := c.Fake.Invokes(action, &apiextensions.CustomResourceDefinitionList{})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Patch applies the patch and returns the patched customResourceDefinition.
|
|
||||||
func (c *FakeCustomResourceDefinitions) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
obj, err := c.Fake.
|
|
||||||
Invokes(testing.NewRootPatchSubresourceAction(customresourcedefinitionsResource, name, pt, data, subresources...), &apiextensions.CustomResourceDefinition{})
|
|
||||||
if obj == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), err
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
type CustomResourceDefinitionExpansion interface{}
|
|
@ -1,43 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"factory.go",
|
|
||||||
"generic.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces: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/apimachinery/pkg/runtime/schema:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [
|
|
||||||
":package-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces:all-srcs",
|
|
||||||
],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,33 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["interface.go"],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [
|
|
||||||
":package-srcs",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:all-srcs",
|
|
||||||
],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package apiextensions
|
|
||||||
|
|
||||||
import (
|
|
||||||
internalversion "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
|
||||||
internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Interface provides access to each of this group's versions.
|
|
||||||
type Interface interface {
|
|
||||||
// InternalVersion provides access to shared informers for resources in InternalVersion.
|
|
||||||
InternalVersion() internalversion.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
type group struct {
|
|
||||||
factory internalinterfaces.SharedInformerFactory
|
|
||||||
namespace string
|
|
||||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new Interface.
|
|
||||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
|
||||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalVersion returns a new internalversion.Interface.
|
|
||||||
func (g *group) InternalVersion() internalversion.Interface {
|
|
||||||
return internalversion.New(g.factory, g.namespace, g.tweakListOptions)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"customresourcedefinition.go",
|
|
||||||
"interface.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion: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/apimachinery/pkg/watch:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
time "time"
|
|
||||||
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset"
|
|
||||||
internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces"
|
|
||||||
internalversion "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
|
||||||
cache "k8s.io/client-go/tools/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CustomResourceDefinitionInformer provides access to a shared informer and lister for
|
|
||||||
// CustomResourceDefinitions.
|
|
||||||
type CustomResourceDefinitionInformer interface {
|
|
||||||
Informer() cache.SharedIndexInformer
|
|
||||||
Lister() internalversion.CustomResourceDefinitionLister
|
|
||||||
}
|
|
||||||
|
|
||||||
type customResourceDefinitionInformer struct {
|
|
||||||
factory internalinterfaces.SharedInformerFactory
|
|
||||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCustomResourceDefinitionInformer constructs a new informer for CustomResourceDefinition type.
|
|
||||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
|
||||||
// one. This reduces memory footprint and number of connections to the server.
|
|
||||||
func NewCustomResourceDefinitionInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
|
||||||
return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, indexers, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFilteredCustomResourceDefinitionInformer constructs a new informer for CustomResourceDefinition type.
|
|
||||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
|
||||||
// one. This reduces memory footprint and number of connections to the server.
|
|
||||||
func NewFilteredCustomResourceDefinitionInformer(client internalclientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
|
||||||
return cache.NewSharedIndexInformer(
|
|
||||||
&cache.ListWatch{
|
|
||||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
|
||||||
if tweakListOptions != nil {
|
|
||||||
tweakListOptions(&options)
|
|
||||||
}
|
|
||||||
return client.Apiextensions().CustomResourceDefinitions().List(options)
|
|
||||||
},
|
|
||||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
|
||||||
if tweakListOptions != nil {
|
|
||||||
tweakListOptions(&options)
|
|
||||||
}
|
|
||||||
return client.Apiextensions().CustomResourceDefinitions().Watch(options)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&apiextensions.CustomResourceDefinition{},
|
|
||||||
resyncPeriod,
|
|
||||||
indexers,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *customResourceDefinitionInformer) defaultInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
|
||||||
return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *customResourceDefinitionInformer) Informer() cache.SharedIndexInformer {
|
|
||||||
return f.factory.InformerFor(&apiextensions.CustomResourceDefinition{}, f.defaultInformer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *customResourceDefinitionInformer) Lister() internalversion.CustomResourceDefinitionLister {
|
|
||||||
return internalversion.NewCustomResourceDefinitionLister(f.Informer().GetIndexer())
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Interface provides access to all the informers in this group version.
|
|
||||||
type Interface interface {
|
|
||||||
// CustomResourceDefinitions returns a CustomResourceDefinitionInformer.
|
|
||||||
CustomResourceDefinitions() CustomResourceDefinitionInformer
|
|
||||||
}
|
|
||||||
|
|
||||||
type version struct {
|
|
||||||
factory internalinterfaces.SharedInformerFactory
|
|
||||||
namespace string
|
|
||||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new Interface.
|
|
||||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
|
||||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CustomResourceDefinitions returns a CustomResourceDefinitionInformer.
|
|
||||||
func (v *version) CustomResourceDefinitions() CustomResourceDefinitionInformer {
|
|
||||||
return &customResourceDefinitionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
|
||||||
}
|
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
time "time"
|
|
||||||
|
|
||||||
internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset"
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions"
|
|
||||||
internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
cache "k8s.io/client-go/tools/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedInformerOption defines the functional option type for SharedInformerFactory.
|
|
||||||
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
|
|
||||||
|
|
||||||
type sharedInformerFactory struct {
|
|
||||||
client internalclientset.Interface
|
|
||||||
namespace string
|
|
||||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
|
||||||
lock sync.Mutex
|
|
||||||
defaultResync time.Duration
|
|
||||||
customResync map[reflect.Type]time.Duration
|
|
||||||
|
|
||||||
informers map[reflect.Type]cache.SharedIndexInformer
|
|
||||||
// startedInformers is used for tracking which informers have been started.
|
|
||||||
// This allows Start() to be called multiple times safely.
|
|
||||||
startedInformers map[reflect.Type]bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
|
||||||
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
|
|
||||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
|
||||||
for k, v := range resyncConfig {
|
|
||||||
factory.customResync[reflect.TypeOf(k)] = v
|
|
||||||
}
|
|
||||||
return factory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
|
|
||||||
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
|
|
||||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
|
||||||
factory.tweakListOptions = tweakListOptions
|
|
||||||
return factory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithNamespace limits the SharedInformerFactory to the specified namespace.
|
|
||||||
func WithNamespace(namespace string) SharedInformerOption {
|
|
||||||
return func(factory *sharedInformerFactory) *sharedInformerFactory {
|
|
||||||
factory.namespace = namespace
|
|
||||||
return factory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
|
|
||||||
func NewSharedInformerFactory(client internalclientset.Interface, defaultResync time.Duration) SharedInformerFactory {
|
|
||||||
return NewSharedInformerFactoryWithOptions(client, defaultResync)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
|
|
||||||
// Listers obtained via this SharedInformerFactory will be subject to the same filters
|
|
||||||
// as specified here.
|
|
||||||
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
|
|
||||||
func NewFilteredSharedInformerFactory(client internalclientset.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
|
|
||||||
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
|
|
||||||
func NewSharedInformerFactoryWithOptions(client internalclientset.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
|
|
||||||
factory := &sharedInformerFactory{
|
|
||||||
client: client,
|
|
||||||
namespace: v1.NamespaceAll,
|
|
||||||
defaultResync: defaultResync,
|
|
||||||
informers: make(map[reflect.Type]cache.SharedIndexInformer),
|
|
||||||
startedInformers: make(map[reflect.Type]bool),
|
|
||||||
customResync: make(map[reflect.Type]time.Duration),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply all options
|
|
||||||
for _, opt := range options {
|
|
||||||
factory = opt(factory)
|
|
||||||
}
|
|
||||||
|
|
||||||
return factory
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start initializes all requested informers.
|
|
||||||
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
|
||||||
f.lock.Lock()
|
|
||||||
defer f.lock.Unlock()
|
|
||||||
|
|
||||||
for informerType, informer := range f.informers {
|
|
||||||
if !f.startedInformers[informerType] {
|
|
||||||
go informer.Run(stopCh)
|
|
||||||
f.startedInformers[informerType] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForCacheSync waits for all started informers' cache were synced.
|
|
||||||
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
|
||||||
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
|
||||||
f.lock.Lock()
|
|
||||||
defer f.lock.Unlock()
|
|
||||||
|
|
||||||
informers := map[reflect.Type]cache.SharedIndexInformer{}
|
|
||||||
for informerType, informer := range f.informers {
|
|
||||||
if f.startedInformers[informerType] {
|
|
||||||
informers[informerType] = informer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return informers
|
|
||||||
}()
|
|
||||||
|
|
||||||
res := map[reflect.Type]bool{}
|
|
||||||
for informType, informer := range informers {
|
|
||||||
res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
|
|
||||||
// client.
|
|
||||||
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
|
|
||||||
f.lock.Lock()
|
|
||||||
defer f.lock.Unlock()
|
|
||||||
|
|
||||||
informerType := reflect.TypeOf(obj)
|
|
||||||
informer, exists := f.informers[informerType]
|
|
||||||
if exists {
|
|
||||||
return informer
|
|
||||||
}
|
|
||||||
|
|
||||||
resyncPeriod, exists := f.customResync[informerType]
|
|
||||||
if !exists {
|
|
||||||
resyncPeriod = f.defaultResync
|
|
||||||
}
|
|
||||||
|
|
||||||
informer = newFunc(f.client, resyncPeriod)
|
|
||||||
f.informers[informerType] = informer
|
|
||||||
|
|
||||||
return informer
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedInformerFactory provides shared informers for resources in all known
|
|
||||||
// API group versions.
|
|
||||||
type SharedInformerFactory interface {
|
|
||||||
internalinterfaces.SharedInformerFactory
|
|
||||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
|
||||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
|
||||||
|
|
||||||
Apiextensions() apiextensions.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sharedInformerFactory) Apiextensions() apiextensions.Interface {
|
|
||||||
return apiextensions.New(f, f.namespace, f.tweakListOptions)
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
cache "k8s.io/client-go/tools/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
|
|
||||||
// sharedInformers based on type
|
|
||||||
type GenericInformer interface {
|
|
||||||
Informer() cache.SharedIndexInformer
|
|
||||||
Lister() cache.GenericLister
|
|
||||||
}
|
|
||||||
|
|
||||||
type genericInformer struct {
|
|
||||||
informer cache.SharedIndexInformer
|
|
||||||
resource schema.GroupResource
|
|
||||||
}
|
|
||||||
|
|
||||||
// Informer returns the SharedIndexInformer.
|
|
||||||
func (f *genericInformer) Informer() cache.SharedIndexInformer {
|
|
||||||
return f.informer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lister returns the GenericLister.
|
|
||||||
func (f *genericInformer) Lister() cache.GenericLister {
|
|
||||||
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForResource gives generic access to a shared informer of the matching type
|
|
||||||
// TODO extend this to unknown resources with a client pool
|
|
||||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
|
||||||
switch resource {
|
|
||||||
// Group=apiextensions.k8s.io, Version=internalVersion
|
|
||||||
case apiextensions.SchemeGroupVersion.WithResource("customresourcedefinitions"):
|
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Apiextensions().InternalVersion().CustomResourceDefinitions().Informer()}, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["factory_interfaces.go"],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset: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/client-go/tools/cache:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalinterfaces
|
|
||||||
|
|
||||||
import (
|
|
||||||
time "time"
|
|
||||||
|
|
||||||
internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset"
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
cache "k8s.io/client-go/tools/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewInformerFunc takes internalclientset.Interface and time.Duration to return a SharedIndexInformer.
|
|
||||||
type NewInformerFunc func(internalclientset.Interface, time.Duration) cache.SharedIndexInformer
|
|
||||||
|
|
||||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
|
||||||
type SharedInformerFactory interface {
|
|
||||||
Start(stopCh <-chan struct{})
|
|
||||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
|
||||||
}
|
|
||||||
|
|
||||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
|
||||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
|
@ -1,35 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"customresourcedefinition.go",
|
|
||||||
"expansion_generated.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion",
|
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by lister-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
import (
|
|
||||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
"k8s.io/client-go/tools/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CustomResourceDefinitionLister helps list CustomResourceDefinitions.
|
|
||||||
type CustomResourceDefinitionLister interface {
|
|
||||||
// List lists all CustomResourceDefinitions in the indexer.
|
|
||||||
List(selector labels.Selector) (ret []*apiextensions.CustomResourceDefinition, err error)
|
|
||||||
// Get retrieves the CustomResourceDefinition from the index for a given name.
|
|
||||||
Get(name string) (*apiextensions.CustomResourceDefinition, error)
|
|
||||||
CustomResourceDefinitionListerExpansion
|
|
||||||
}
|
|
||||||
|
|
||||||
// customResourceDefinitionLister implements the CustomResourceDefinitionLister interface.
|
|
||||||
type customResourceDefinitionLister struct {
|
|
||||||
indexer cache.Indexer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCustomResourceDefinitionLister returns a new CustomResourceDefinitionLister.
|
|
||||||
func NewCustomResourceDefinitionLister(indexer cache.Indexer) CustomResourceDefinitionLister {
|
|
||||||
return &customResourceDefinitionLister{indexer: indexer}
|
|
||||||
}
|
|
||||||
|
|
||||||
// List lists all CustomResourceDefinitions in the indexer.
|
|
||||||
func (s *customResourceDefinitionLister) List(selector labels.Selector) (ret []*apiextensions.CustomResourceDefinition, err error) {
|
|
||||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
|
||||||
ret = append(ret, m.(*apiextensions.CustomResourceDefinition))
|
|
||||||
})
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get retrieves the CustomResourceDefinition from the index for a given name.
|
|
||||||
func (s *customResourceDefinitionLister) Get(name string) (*apiextensions.CustomResourceDefinition, error) {
|
|
||||||
obj, exists, err := s.indexer.GetByKey(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
return nil, errors.NewNotFound(apiextensions.Resource("customresourcedefinition"), name)
|
|
||||||
}
|
|
||||||
return obj.(*apiextensions.CustomResourceDefinition), nil
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by lister-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package internalversion
|
|
||||||
|
|
||||||
// CustomResourceDefinitionListerExpansion allows custom methods to be added to
|
|
||||||
// CustomResourceDefinitionLister.
|
|
||||||
type CustomResourceDefinitionListerExpansion interface{}
|
|
@ -8,11 +8,10 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
@ -27,8 +26,7 @@ go_test(
|
|||||||
srcs = ["apiapproval_controller_test.go"],
|
srcs = ["apiapproval_controller_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -22,11 +22,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
"k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -78,7 +77,7 @@ func NewKubernetesAPIApprovalPolicyConformantConditionController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculateCondition determines the new KubernetesAPIApprovalPolicyConformant condition
|
// calculateCondition determines the new KubernetesAPIApprovalPolicyConformant condition
|
||||||
func calculateCondition(crd *apiextensions.CustomResourceDefinition) *apiextensions.CustomResourceDefinitionCondition {
|
func calculateCondition(crd *apiextensionsv1.CustomResourceDefinition) *apiextensionsv1.CustomResourceDefinitionCondition {
|
||||||
if !apihelpers.IsProtectedCommunityGroup(crd.Spec.Group) {
|
if !apihelpers.IsProtectedCommunityGroup(crd.Spec.Group) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -86,37 +85,37 @@ func calculateCondition(crd *apiextensions.CustomResourceDefinition) *apiextensi
|
|||||||
approvalState, reason := apihelpers.GetAPIApprovalState(crd.Annotations)
|
approvalState, reason := apihelpers.GetAPIApprovalState(crd.Annotations)
|
||||||
switch approvalState {
|
switch approvalState {
|
||||||
case apihelpers.APIApprovalInvalid:
|
case apihelpers.APIApprovalInvalid:
|
||||||
return &apiextensions.CustomResourceDefinitionCondition{
|
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "InvalidAnnotation",
|
Reason: "InvalidAnnotation",
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}
|
}
|
||||||
case apihelpers.APIApprovalMissing:
|
case apihelpers.APIApprovalMissing:
|
||||||
return &apiextensions.CustomResourceDefinitionCondition{
|
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "MissingAnnotation",
|
Reason: "MissingAnnotation",
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}
|
}
|
||||||
case apihelpers.APIApproved:
|
case apihelpers.APIApproved:
|
||||||
return &apiextensions.CustomResourceDefinitionCondition{
|
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "ApprovedAnnotation",
|
Reason: "ApprovedAnnotation",
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}
|
}
|
||||||
case apihelpers.APIApprovalBypassed:
|
case apihelpers.APIApprovalBypassed:
|
||||||
return &apiextensions.CustomResourceDefinitionCondition{
|
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "UnapprovedAnnotation",
|
Reason: "UnapprovedAnnotation",
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return &apiextensions.CustomResourceDefinitionCondition{
|
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||||
Status: apiextensions.ConditionUnknown,
|
Status: apiextensionsv1.ConditionUnknown,
|
||||||
Reason: "UnknownAnnotation",
|
Reason: "UnknownAnnotation",
|
||||||
Message: reason,
|
Message: reason,
|
||||||
}
|
}
|
||||||
@ -133,7 +132,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) sync(key stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// avoid repeated calculation for the same annotation
|
// avoid repeated calculation for the same annotation
|
||||||
protectionAnnotationValue := inCustomResourceDefinition.Annotations[v1beta1.KubeAPIApprovedAnnotation]
|
protectionAnnotationValue := inCustomResourceDefinition.Annotations[apiextensionsv1.KubeAPIApprovedAnnotation]
|
||||||
c.lastSeenProtectedAnnotationLock.Lock()
|
c.lastSeenProtectedAnnotationLock.Lock()
|
||||||
lastSeen, seenBefore := c.lastSeenProtectedAnnotation[inCustomResourceDefinition.Name]
|
lastSeen, seenBefore := c.lastSeenProtectedAnnotation[inCustomResourceDefinition.Name]
|
||||||
c.lastSeenProtectedAnnotationLock.Unlock()
|
c.lastSeenProtectedAnnotationLock.Unlock()
|
||||||
@ -147,7 +146,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) sync(key stri
|
|||||||
// because group is immutable, if we have no condition now, we have no need to remove a condition.
|
// because group is immutable, if we have no condition now, we have no need to remove a condition.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
old := apiextensions.FindCRDCondition(inCustomResourceDefinition, apiextensions.KubernetesAPIApprovalPolicyConformant)
|
old := apihelpers.FindCRDCondition(inCustomResourceDefinition, apiextensionsv1.KubernetesAPIApprovalPolicyConformant)
|
||||||
|
|
||||||
// don't attempt a write if all the condition details are the same
|
// don't attempt a write if all the condition details are the same
|
||||||
if old != nil && old.Status == cond.Status && old.Reason == cond.Reason && old.Message == cond.Message {
|
if old != nil && old.Status == cond.Status && old.Reason == cond.Reason && old.Message == cond.Message {
|
||||||
@ -157,7 +156,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) sync(key stri
|
|||||||
|
|
||||||
// update condition
|
// update condition
|
||||||
crd := inCustomResourceDefinition.DeepCopy()
|
crd := inCustomResourceDefinition.DeepCopy()
|
||||||
apiextensions.SetCRDCondition(crd, *cond)
|
apihelpers.SetCRDCondition(crd, *cond)
|
||||||
|
|
||||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||||
@ -221,7 +220,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) processNextWo
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *KubernetesAPIApprovalPolicyConformantConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", obj, err))
|
utilruntime.HandleError(fmt.Errorf("Couldn't get key for object %#v: %v", obj, err))
|
||||||
@ -232,26 +231,26 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) enqueue(obj *
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) addCustomResourceDefinition(obj interface{}) {
|
func (c *KubernetesAPIApprovalPolicyConformantConditionController) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
func (c *KubernetesAPIApprovalPolicyConformantConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
func (c *KubernetesAPIApprovalPolicyConformantConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||||
return
|
return
|
||||||
|
@ -19,21 +19,20 @@ package apiapproval
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCalculateCondition(t *testing.T) {
|
func TestCalculateCondition(t *testing.T) {
|
||||||
noConditionFn := func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition) {
|
noConditionFn := func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if condition != nil {
|
if condition != nil {
|
||||||
t.Fatal(condition)
|
t.Fatal(condition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyCondition := func(status apiextensions.ConditionStatus, message string) func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition) {
|
verifyCondition := func(status apiextensionsv1.ConditionStatus, message string) func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||||
return func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition) {
|
return func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if condition == nil {
|
if condition == nil {
|
||||||
t.Fatal("missing condition")
|
t.Fatal("missing condition")
|
||||||
@ -52,7 +51,7 @@ func TestCalculateCondition(t *testing.T) {
|
|||||||
|
|
||||||
group string
|
group string
|
||||||
annotationValue string
|
annotationValue string
|
||||||
validateCondition func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition)
|
validateCondition func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "for other group",
|
name: "for other group",
|
||||||
@ -64,33 +63,33 @@ func TestCalculateCondition(t *testing.T) {
|
|||||||
name: "missing annotation",
|
name: "missing annotation",
|
||||||
group: "sigs.k8s.io",
|
group: "sigs.k8s.io",
|
||||||
annotationValue: "",
|
annotationValue: "",
|
||||||
validateCondition: verifyCondition(apiextensions.ConditionFalse, `protected groups must have approval annotation "api-approved.kubernetes.io", see https://github.com/kubernetes/enhancements/pull/1111`),
|
validateCondition: verifyCondition(apiextensionsv1.ConditionFalse, `protected groups must have approval annotation "api-approved.kubernetes.io", see https://github.com/kubernetes/enhancements/pull/1111`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid annotation",
|
name: "invalid annotation",
|
||||||
group: "sigs.k8s.io",
|
group: "sigs.k8s.io",
|
||||||
annotationValue: "bad value",
|
annotationValue: "bad value",
|
||||||
validateCondition: verifyCondition(apiextensions.ConditionFalse, `protected groups must have approval annotation "api-approved.kubernetes.io" with either a URL or a reason starting with "unapproved", see https://github.com/kubernetes/enhancements/pull/1111`),
|
validateCondition: verifyCondition(apiextensionsv1.ConditionFalse, `protected groups must have approval annotation "api-approved.kubernetes.io" with either a URL or a reason starting with "unapproved", see https://github.com/kubernetes/enhancements/pull/1111`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "approved",
|
name: "approved",
|
||||||
group: "sigs.k8s.io",
|
group: "sigs.k8s.io",
|
||||||
annotationValue: "https://github.com/kubernetes/kubernetes/pull/79724",
|
annotationValue: "https://github.com/kubernetes/kubernetes/pull/79724",
|
||||||
validateCondition: verifyCondition(apiextensions.ConditionTrue, `approved in https://github.com/kubernetes/kubernetes/pull/79724`),
|
validateCondition: verifyCondition(apiextensionsv1.ConditionTrue, `approved in https://github.com/kubernetes/kubernetes/pull/79724`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unapproved",
|
name: "unapproved",
|
||||||
group: "sigs.k8s.io",
|
group: "sigs.k8s.io",
|
||||||
annotationValue: "unapproved for reasons",
|
annotationValue: "unapproved for reasons",
|
||||||
validateCondition: verifyCondition(apiextensions.ConditionFalse, `not approved: "unapproved for reasons"`),
|
validateCondition: verifyCondition(apiextensionsv1.ConditionFalse, `not approved: "unapproved for reasons"`),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
crd := &apiextensions.CustomResourceDefinition{
|
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: test.annotationValue}},
|
ObjectMeta: metav1.ObjectMeta{Name: "foo", Annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: test.annotationValue}},
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: test.group,
|
Group: test.group,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,11 @@ go_library(
|
|||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/establish",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/establish",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
|
@ -27,10 +27,11 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EstablishingController controls how and when CRD is established.
|
// EstablishingController controls how and when CRD is established.
|
||||||
@ -119,19 +120,19 @@ func (ec *EstablishingController) sync(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apiextensions.IsCRDConditionTrue(cachedCRD, apiextensions.NamesAccepted) ||
|
if !apiextensionshelpers.IsCRDConditionTrue(cachedCRD, apiextensionsv1.NamesAccepted) ||
|
||||||
apiextensions.IsCRDConditionTrue(cachedCRD, apiextensions.Established) {
|
apiextensionshelpers.IsCRDConditionTrue(cachedCRD, apiextensionsv1.Established) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
crd := cachedCRD.DeepCopy()
|
crd := cachedCRD.DeepCopy()
|
||||||
establishedCondition := apiextensions.CustomResourceDefinitionCondition{
|
establishedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Established,
|
Type: apiextensionsv1.Established,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InitialNamesAccepted",
|
Reason: "InitialNamesAccepted",
|
||||||
Message: "the initial names have been accepted",
|
Message: "the initial names have been accepted",
|
||||||
}
|
}
|
||||||
apiextensions.SetCRDCondition(crd, establishedCondition)
|
apiextensionshelpers.SetCRDCondition(crd, establishedCondition)
|
||||||
|
|
||||||
// Update server with new CRD condition.
|
// Update server with new CRD condition.
|
||||||
_, err = ec.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
_, err = ec.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||||
|
@ -11,10 +11,11 @@ go_library(
|
|||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
|
@ -36,10 +36,11 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OverlappingBuiltInResources returns the set of built-in group/resources that are persisted
|
// OverlappingBuiltInResources returns the set of built-in group/resources that are persisted
|
||||||
@ -76,7 +77,7 @@ type ListerCollectionDeleter interface {
|
|||||||
type CRClientGetter interface {
|
type CRClientGetter interface {
|
||||||
// GetCustomResourceListerCollectionDeleter gets the ListerCollectionDeleter for the given CRD
|
// GetCustomResourceListerCollectionDeleter gets the ListerCollectionDeleter for the given CRD
|
||||||
// UID.
|
// UID.
|
||||||
GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) (ListerCollectionDeleter, error)
|
GetCustomResourceListerCollectionDeleter(crd *apiextensionsv1.CustomResourceDefinition) (ListerCollectionDeleter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCRDFinalizer creates a new CRDFinalizer.
|
// NewCRDFinalizer creates a new CRDFinalizer.
|
||||||
@ -113,16 +114,16 @@ func (c *CRDFinalizer) sync(key string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no work to do
|
// no work to do
|
||||||
if cachedCRD.DeletionTimestamp.IsZero() || !apiextensions.CRDHasFinalizer(cachedCRD, apiextensions.CustomResourceCleanupFinalizer) {
|
if cachedCRD.DeletionTimestamp.IsZero() || !apiextensionshelpers.CRDHasFinalizer(cachedCRD, apiextensionsv1.CustomResourceCleanupFinalizer) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
crd := cachedCRD.DeepCopy()
|
crd := cachedCRD.DeepCopy()
|
||||||
|
|
||||||
// update the status condition. This cleanup could take a while.
|
// update the status condition. This cleanup could take a while.
|
||||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InstanceDeletionInProgress",
|
Reason: "InstanceDeletionInProgress",
|
||||||
Message: "CustomResource deletion is in progress",
|
Message: "CustomResource deletion is in progress",
|
||||||
})
|
})
|
||||||
@ -139,15 +140,15 @@ func (c *CRDFinalizer) sync(key string) error {
|
|||||||
// Since we control the endpoints, we know that delete collection works. No need to delete if not established.
|
// Since we control the endpoints, we know that delete collection works. No need to delete if not established.
|
||||||
if OverlappingBuiltInResources()[schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Spec.Names.Plural}] {
|
if OverlappingBuiltInResources()[schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Spec.Names.Plural}] {
|
||||||
// Skip deletion, explain why, and proceed to remove the finalizer and delete the CRD
|
// Skip deletion, explain why, and proceed to remove the finalizer and delete the CRD
|
||||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "OverlappingBuiltInResource",
|
Reason: "OverlappingBuiltInResource",
|
||||||
Message: "instances overlap with built-in resources in storage",
|
Message: "instances overlap with built-in resources in storage",
|
||||||
})
|
})
|
||||||
} else if apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
} else if apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||||
cond, deleteErr := c.deleteInstances(crd)
|
cond, deleteErr := c.deleteInstances(crd)
|
||||||
apiextensions.SetCRDCondition(crd, cond)
|
apiextensionshelpers.SetCRDCondition(crd, cond)
|
||||||
if deleteErr != nil {
|
if deleteErr != nil {
|
||||||
if _, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd); err != nil {
|
if _, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd); err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
@ -155,15 +156,15 @@ func (c *CRDFinalizer) sync(key string) error {
|
|||||||
return deleteErr
|
return deleteErr
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "NeverEstablished",
|
Reason: "NeverEstablished",
|
||||||
Message: "resource was never established",
|
Message: "resource was never established",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
apiextensions.CRDRemoveFinalizer(crd, apiextensions.CustomResourceCleanupFinalizer)
|
apiextensionshelpers.CRDRemoveFinalizer(crd, apiextensionsv1.CustomResourceCleanupFinalizer)
|
||||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||||
// deleted or changed in the meantime, we'll get called again
|
// deleted or changed in the meantime, we'll get called again
|
||||||
@ -172,16 +173,16 @@ func (c *CRDFinalizer) sync(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefinition) (apiextensions.CustomResourceDefinitionCondition, error) {
|
func (c *CRDFinalizer) deleteInstances(crd *apiextensionsv1.CustomResourceDefinition) (apiextensionsv1.CustomResourceDefinitionCondition, error) {
|
||||||
// Now we can start deleting items. While it would be ideal to use a REST API client, doing so
|
// Now we can start deleting items. While it would be ideal to use a REST API client, doing so
|
||||||
// could incorrectly delete a ThirdPartyResource with the same URL as the CustomResource, so we go
|
// could incorrectly delete a ThirdPartyResource with the same URL as the CustomResource, so we go
|
||||||
// directly to the storage instead. Since we control the storage, we know that delete collection works.
|
// directly to the storage instead. Since we control the storage, we know that delete collection works.
|
||||||
crClient, err := c.crClientGetter.GetCustomResourceListerCollectionDeleter(crd)
|
crClient, err := c.crClientGetter.GetCustomResourceListerCollectionDeleter(crd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("unable to find a custom resource client for %s.%s: %v", crd.Status.AcceptedNames.Plural, crd.Spec.Group, err)
|
err = fmt.Errorf("unable to find a custom resource client for %s.%s: %v", crd.Status.AcceptedNames.Plural, crd.Spec.Group, err)
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InstanceDeletionFailed",
|
Reason: "InstanceDeletionFailed",
|
||||||
Message: fmt.Sprintf("could not list instances: %v", err),
|
Message: fmt.Sprintf("could not list instances: %v", err),
|
||||||
}, err
|
}, err
|
||||||
@ -190,9 +191,9 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
|||||||
ctx := genericapirequest.NewContext()
|
ctx := genericapirequest.NewContext()
|
||||||
allResources, err := crClient.List(ctx, nil)
|
allResources, err := crClient.List(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InstanceDeletionFailed",
|
Reason: "InstanceDeletionFailed",
|
||||||
Message: fmt.Sprintf("could not list instances: %v", err),
|
Message: fmt.Sprintf("could not list instances: %v", err),
|
||||||
}, err
|
}, err
|
||||||
@ -218,9 +219,9 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if deleteError := utilerrors.NewAggregate(deleteErrors); deleteError != nil {
|
if deleteError := utilerrors.NewAggregate(deleteErrors); deleteError != nil {
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InstanceDeletionFailed",
|
Reason: "InstanceDeletionFailed",
|
||||||
Message: fmt.Sprintf("could not issue all deletes: %v", deleteError),
|
Message: fmt.Sprintf("could not issue all deletes: %v", deleteError),
|
||||||
}, deleteError
|
}, deleteError
|
||||||
@ -241,16 +242,16 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
|||||||
return false, nil
|
return false, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "InstanceDeletionCheck",
|
Reason: "InstanceDeletionCheck",
|
||||||
Message: fmt.Sprintf("could not confirm zero CustomResources remaining: %v", err),
|
Message: fmt.Sprintf("could not confirm zero CustomResources remaining: %v", err),
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Terminating,
|
Type: apiextensionsv1.Terminating,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "InstanceDeletionCompleted",
|
Reason: "InstanceDeletionCompleted",
|
||||||
Message: "removed all instances",
|
Message: "removed all instances",
|
||||||
}, nil
|
}, nil
|
||||||
@ -299,7 +300,7 @@ func (c *CRDFinalizer) processNextWorkItem() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CRDFinalizer) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *CRDFinalizer) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
||||||
@ -310,18 +311,18 @@ func (c *CRDFinalizer) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CRDFinalizer) addCustomResourceDefinition(obj interface{}) {
|
func (c *CRDFinalizer) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
// only queue deleted things
|
// only queue deleted things
|
||||||
if !castObj.DeletionTimestamp.IsZero() && apiextensions.CRDHasFinalizer(castObj, apiextensions.CustomResourceCleanupFinalizer) {
|
if !castObj.DeletionTimestamp.IsZero() && apiextensionshelpers.CRDHasFinalizer(castObj, apiextensionsv1.CustomResourceCleanupFinalizer) {
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CRDFinalizer) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
func (c *CRDFinalizer) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||||
oldCRD := oldObj.(*apiextensions.CustomResourceDefinition)
|
oldCRD := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
newCRD := newObj.(*apiextensions.CustomResourceDefinition)
|
newCRD := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
// only queue deleted things that haven't been finalized by us
|
// only queue deleted things that haven't been finalized by us
|
||||||
if newCRD.DeletionTimestamp.IsZero() || !apiextensions.CRDHasFinalizer(newCRD, apiextensions.CustomResourceCleanupFinalizer) {
|
if newCRD.DeletionTimestamp.IsZero() || !apiextensionshelpers.CRDHasFinalizer(newCRD, apiextensionsv1.CustomResourceCleanupFinalizer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,8 +340,8 @@ func (c *CRDFinalizer) updateCustomResourceDefinition(oldObj, newObj interface{}
|
|||||||
newCopy := newCRD.DeepCopy()
|
newCopy := newCRD.DeepCopy()
|
||||||
oldCopy.ResourceVersion = ""
|
oldCopy.ResourceVersion = ""
|
||||||
newCopy.ResourceVersion = ""
|
newCopy.ResourceVersion = ""
|
||||||
apiextensions.RemoveCRDCondition(oldCopy, apiextensions.Terminating)
|
apiextensionshelpers.RemoveCRDCondition(oldCopy, apiextensionsv1.Terminating)
|
||||||
apiextensions.RemoveCRDCondition(newCopy, apiextensions.Terminating)
|
apiextensionshelpers.RemoveCRDCondition(newCopy, apiextensionsv1.Terminating)
|
||||||
|
|
||||||
if !reflect.DeepEqual(oldCopy, newCopy) {
|
if !reflect.DeepEqual(oldCopy, newCopy) {
|
||||||
c.enqueue(newCRD)
|
c.enqueue(newCRD)
|
||||||
|
@ -7,11 +7,13 @@ go_library(
|
|||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/nonstructuralschema",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/nonstructuralschema",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
|
@ -30,11 +30,13 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
|
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConditionController is maintaining the NonStructuralSchema condition.
|
// ConditionController is maintaining the NonStructuralSchema condition.
|
||||||
@ -79,33 +81,25 @@ func NewConditionController(
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateCondition(in *apiextensions.CustomResourceDefinition) *apiextensions.CustomResourceDefinitionCondition {
|
func calculateCondition(in *apiextensionsv1.CustomResourceDefinition) *apiextensionsv1.CustomResourceDefinitionCondition {
|
||||||
cond := &apiextensions.CustomResourceDefinitionCondition{
|
cond := &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.NonStructuralSchema,
|
Type: apiextensionsv1.NonStructuralSchema,
|
||||||
Status: apiextensions.ConditionUnknown,
|
Status: apiextensionsv1.ConditionUnknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
if in.Spec.Validation != nil && in.Spec.Validation.OpenAPIV3Schema != nil {
|
|
||||||
s, err := schema.NewStructural(in.Spec.Validation.OpenAPIV3Schema)
|
|
||||||
if err != nil {
|
|
||||||
cond.Reason = "StructuralError"
|
|
||||||
cond.Message = fmt.Sprintf("failed to check global validation schema: %v", err)
|
|
||||||
return cond
|
|
||||||
}
|
|
||||||
|
|
||||||
pth := field.NewPath("spec", "validation", "openAPIV3Schema")
|
|
||||||
|
|
||||||
allErrs = append(allErrs, schema.ValidateStructural(pth, s)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range in.Spec.Versions {
|
for i, v := range in.Spec.Versions {
|
||||||
if v.Schema == nil || v.Schema.OpenAPIV3Schema == nil {
|
if v.Schema == nil || v.Schema.OpenAPIV3Schema == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := schema.NewStructural(v.Schema.OpenAPIV3Schema)
|
internalSchema := &apiextensionsinternal.CustomResourceValidation{}
|
||||||
|
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(v.Schema, internalSchema, nil); err != nil {
|
||||||
|
klog.Errorf("failed to convert CRD validation to internal version: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s, err := schema.NewStructural(internalSchema.OpenAPIV3Schema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cond.Reason = "StructuralError"
|
cond.Reason = "StructuralError"
|
||||||
cond.Message = fmt.Sprintf("failed to check validation schema for version %s: %v", v.Name, err)
|
cond.Message = fmt.Sprintf("failed to check validation schema for version %s: %v", v.Name, err)
|
||||||
@ -121,7 +115,7 @@ func calculateCondition(in *apiextensions.CustomResourceDefinition) *apiextensio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cond.Status = apiextensions.ConditionTrue
|
cond.Status = apiextensionsv1.ConditionTrue
|
||||||
cond.Reason = "Violations"
|
cond.Reason = "Violations"
|
||||||
cond.Message = allErrs.ToAggregate().Error()
|
cond.Message = allErrs.ToAggregate().Error()
|
||||||
|
|
||||||
@ -147,7 +141,7 @@ func (c *ConditionController) sync(key string) error {
|
|||||||
|
|
||||||
// check old condition
|
// check old condition
|
||||||
cond := calculateCondition(inCustomResourceDefinition)
|
cond := calculateCondition(inCustomResourceDefinition)
|
||||||
old := apiextensions.FindCRDCondition(inCustomResourceDefinition, apiextensions.NonStructuralSchema)
|
old := apiextensionshelpers.FindCRDCondition(inCustomResourceDefinition, apiextensionsv1.NonStructuralSchema)
|
||||||
|
|
||||||
if cond == nil && old == nil {
|
if cond == nil && old == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -159,10 +153,10 @@ func (c *ConditionController) sync(key string) error {
|
|||||||
// update condition
|
// update condition
|
||||||
crd := inCustomResourceDefinition.DeepCopy()
|
crd := inCustomResourceDefinition.DeepCopy()
|
||||||
if cond == nil {
|
if cond == nil {
|
||||||
apiextensions.RemoveCRDCondition(crd, apiextensions.NonStructuralSchema)
|
apiextensionshelpers.RemoveCRDCondition(crd, apiextensionsv1.NonStructuralSchema)
|
||||||
} else {
|
} else {
|
||||||
cond.LastTransitionTime = metav1.NewTime(time.Now())
|
cond.LastTransitionTime = metav1.NewTime(time.Now())
|
||||||
apiextensions.SetCRDCondition(crd, *cond)
|
apiextensionshelpers.SetCRDCondition(crd, *cond)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||||
@ -227,7 +221,7 @@ func (c *ConditionController) processNextWorkItem() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *ConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
||||||
@ -238,26 +232,26 @@ func (c *ConditionController) enqueue(obj *apiextensions.CustomResourceDefinitio
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConditionController) addCustomResourceDefinition(obj interface{}) {
|
func (c *ConditionController) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
func (c *ConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
func (c *ConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||||
return
|
return
|
||||||
|
@ -10,9 +10,10 @@ go_library(
|
|||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/openapi",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/openapi",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
|
@ -11,7 +11,9 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2:go_default_library",
|
||||||
@ -40,7 +42,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||||
|
@ -26,7 +26,9 @@ import (
|
|||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
|
|
||||||
v1 "k8s.io/api/autoscaling/v1"
|
v1 "k8s.io/api/autoscaling/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
|
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
|
||||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||||
openapiv2 "k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2"
|
openapiv2 "k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2"
|
||||||
@ -84,16 +86,20 @@ type Options struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildSwagger builds swagger for the given crd in the given version
|
// BuildSwagger builds swagger for the given crd in the given version
|
||||||
func BuildSwagger(crd *apiextensions.CustomResourceDefinition, version string, opts Options) (*spec.Swagger, error) {
|
func BuildSwagger(crd *apiextensionsv1.CustomResourceDefinition, version string, opts Options) (*spec.Swagger, error) {
|
||||||
var schema *structuralschema.Structural
|
var schema *structuralschema.Structural
|
||||||
s, err := apiextensions.GetSchemaForVersion(crd, version)
|
s, err := apiextensionshelpers.GetSchemaForVersion(crd, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s != nil && s.OpenAPIV3Schema != nil {
|
if s != nil && s.OpenAPIV3Schema != nil {
|
||||||
if !validation.SchemaHasInvalidTypes(s.OpenAPIV3Schema) {
|
internalCRDSchema := &apiextensionsinternal.CustomResourceValidation{}
|
||||||
if ss, err := structuralschema.NewStructural(s.OpenAPIV3Schema); err == nil {
|
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(s, internalCRDSchema, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed converting CRD validation to internal version: %v", err)
|
||||||
|
}
|
||||||
|
if !validation.SchemaHasInvalidTypes(internalCRDSchema.OpenAPIV3Schema) {
|
||||||
|
if ss, err := structuralschema.NewStructural(internalCRDSchema.OpenAPIV3Schema); err == nil {
|
||||||
// skip non-structural schemas unless explicitly asked to produce swagger from them
|
// skip non-structural schemas unless explicitly asked to produce swagger from them
|
||||||
if opts.AllowNonStructural || len(structuralschema.ValidateStructural(nil, ss)) == 0 {
|
if opts.AllowNonStructural || len(structuralschema.ValidateStructural(nil, ss)) == 0 {
|
||||||
schema = ss
|
schema = ss
|
||||||
@ -151,7 +157,7 @@ func BuildSwagger(crd *apiextensions.CustomResourceDefinition, version string, o
|
|||||||
routes = append(routes, b.buildRoute(root, "/{name}", "DELETE", "delete", "delete", status))
|
routes = append(routes, b.buildRoute(root, "/{name}", "DELETE", "delete", "delete", status))
|
||||||
routes = append(routes, b.buildRoute(root, "/{name}", "PATCH", "patch", "patch", sample).Reads(patch))
|
routes = append(routes, b.buildRoute(root, "/{name}", "PATCH", "patch", "patch", sample).Reads(patch))
|
||||||
|
|
||||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, version)
|
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -498,7 +504,7 @@ func (b *builder) getOpenAPIConfig() *common.Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBuilder(crd *apiextensions.CustomResourceDefinition, version string, schema *structuralschema.Structural, v2 bool) *builder {
|
func newBuilder(crd *apiextensionsv1.CustomResourceDefinition, version string, schema *structuralschema.Structural, v2 bool) *builder {
|
||||||
b := &builder{
|
b := &builder{
|
||||||
schema: &spec.Schema{
|
schema: &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||||
@ -512,13 +518,12 @@ func newBuilder(crd *apiextensions.CustomResourceDefinition, version string, sch
|
|||||||
listKind: crd.Spec.Names.ListKind,
|
listKind: crd.Spec.Names.ListKind,
|
||||||
plural: crd.Spec.Names.Plural,
|
plural: crd.Spec.Names.Plural,
|
||||||
}
|
}
|
||||||
if crd.Spec.Scope == apiextensions.NamespaceScoped {
|
if crd.Spec.Scope == apiextensionsv1.NamespaceScoped {
|
||||||
b.namespaced = true
|
b.namespaced = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-build schema with Kubernetes native properties
|
// Pre-build schema with Kubernetes native properties
|
||||||
preserveUnknownFields := crd.Spec.PreserveUnknownFields != nil && *crd.Spec.PreserveUnknownFields
|
b.schema = b.buildKubeNative(schema, v2, crd.Spec.PreserveUnknownFields)
|
||||||
b.schema = b.buildKubeNative(schema, v2, preserveUnknownFields)
|
|
||||||
b.listSchema = b.buildListSchema()
|
b.listSchema = b.buildListSchema()
|
||||||
|
|
||||||
return b
|
return b
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
"k8s.io/apimachinery/pkg/util/json"
|
||||||
@ -352,12 +352,12 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var schema *structuralschema.Structural
|
var schema *structuralschema.Structural
|
||||||
if len(tt.schema) > 0 {
|
if len(tt.schema) > 0 {
|
||||||
v1beta1Schema := &v1beta1.JSONSchemaProps{}
|
v1beta1Schema := &apiextensionsv1.JSONSchemaProps{}
|
||||||
if err := json.Unmarshal([]byte(tt.schema), &v1beta1Schema); err != nil {
|
if err := json.Unmarshal([]byte(tt.schema), &v1beta1Schema); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
internalSchema := &apiextensions.JSONSchemaProps{}
|
internalSchema := &apiextensionsinternal.JSONSchemaProps{}
|
||||||
v1beta1.Convert_v1beta1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
apiextensionsv1.Convert_v1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
||||||
var err error
|
var err error
|
||||||
schema, err = structuralschema.NewStructural(internalSchema)
|
schema, err = structuralschema.NewStructural(internalSchema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -369,17 +369,21 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
schema = schema.Unfold()
|
schema = schema.Unfold()
|
||||||
}
|
}
|
||||||
|
|
||||||
got := newBuilder(&apiextensions.CustomResourceDefinition{
|
got := newBuilder(&apiextensionsv1.CustomResourceDefinition{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "bar.k8s.io",
|
Group: "bar.k8s.io",
|
||||||
Version: "v1",
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
Names: apiextensions.CustomResourceDefinitionNames{
|
{
|
||||||
|
Name: "v1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Singular: "foo",
|
Singular: "foo",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
ListKind: "FooList",
|
ListKind: "FooList",
|
||||||
},
|
},
|
||||||
Scope: apiextensions.NamespaceScoped,
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
},
|
},
|
||||||
}, "v1", schema, tt.v2)
|
}, "v1", schema, tt.v2)
|
||||||
|
|
||||||
@ -430,7 +434,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
|||||||
testCRDResourceName := "foos"
|
testCRDResourceName := "foos"
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
scope apiextensions.ResourceScope
|
scope apiextensionsv1.ResourceScope
|
||||||
paths map[string]struct {
|
paths map[string]struct {
|
||||||
expectNamespaceParam bool
|
expectNamespaceParam bool
|
||||||
expectNameParam bool
|
expectNameParam bool
|
||||||
@ -438,7 +442,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
scope: apiextensions.NamespaceScoped,
|
scope: apiextensionsv1.NamespaceScoped,
|
||||||
paths: map[string]struct {
|
paths: map[string]struct {
|
||||||
expectNamespaceParam bool
|
expectNamespaceParam bool
|
||||||
expectNameParam bool
|
expectNameParam bool
|
||||||
@ -452,7 +456,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scope: apiextensions.ClusterScoped,
|
scope: apiextensionsv1.ClusterScoped,
|
||||||
paths: map[string]struct {
|
paths: map[string]struct {
|
||||||
expectNamespaceParam bool
|
expectNamespaceParam bool
|
||||||
expectNameParam bool
|
expectNameParam bool
|
||||||
@ -467,23 +471,23 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
testNamespacedCRD := &apiextensions.CustomResourceDefinition{
|
testNamespacedCRD := &apiextensionsv1.CustomResourceDefinition{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Scope: testCase.scope,
|
Scope: testCase.scope,
|
||||||
Group: testCRDGroup,
|
Group: testCRDGroup,
|
||||||
Names: apiextensions.CustomResourceDefinitionNames{
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Kind: testCRDKind,
|
Kind: testCRDKind,
|
||||||
Plural: testCRDResourceName,
|
Plural: testCRDResourceName,
|
||||||
},
|
},
|
||||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
{
|
{
|
||||||
Name: testCRDVersion,
|
Name: testCRDVersion,
|
||||||
|
Subresources: &apiextensionsv1.CustomResourceSubresources{
|
||||||
|
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
|
||||||
|
Scale: &apiextensionsv1.CustomResourceSubresourceScale{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subresources: &apiextensions.CustomResourceSubresources{
|
|
||||||
Status: &apiextensions.CustomResourceSubresourceStatus{},
|
|
||||||
Scale: &apiextensions.CustomResourceSubresourceScale{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
swagger, err := BuildSwagger(testNamespacedCRD, testCRDVersion, Options{V2: true, StripDefaults: true})
|
swagger, err := BuildSwagger(testNamespacedCRD, testCRDVersion, Options{V2: true, StripDefaults: true})
|
||||||
@ -627,33 +631,37 @@ func TestBuildSwagger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var validation *apiextensions.CustomResourceValidation
|
var validation *apiextensionsv1.CustomResourceValidation
|
||||||
if len(tt.schema) > 0 {
|
if len(tt.schema) > 0 {
|
||||||
v1beta1Schema := &v1beta1.JSONSchemaProps{}
|
v1Schema := &apiextensionsv1.JSONSchemaProps{}
|
||||||
if err := json.Unmarshal([]byte(tt.schema), &v1beta1Schema); err != nil {
|
if err := json.Unmarshal([]byte(tt.schema), &v1Schema); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
internalSchema := &apiextensions.JSONSchemaProps{}
|
validation = &apiextensionsv1.CustomResourceValidation{
|
||||||
v1beta1.Convert_v1beta1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
OpenAPIV3Schema: v1Schema,
|
||||||
validation = &apiextensions.CustomResourceValidation{
|
|
||||||
OpenAPIV3Schema: internalSchema,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if tt.preserveUnknownFields != nil && *tt.preserveUnknownFields {
|
||||||
|
validation.OpenAPIV3Schema.XPreserveUnknownFields = utilpointer.BoolPtr(true)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: mostly copied from the test above. reuse code to cleanup
|
// TODO: mostly copied from the test above. reuse code to cleanup
|
||||||
got, err := BuildSwagger(&apiextensions.CustomResourceDefinition{
|
got, err := BuildSwagger(&apiextensionsv1.CustomResourceDefinition{
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "bar.k8s.io",
|
Group: "bar.k8s.io",
|
||||||
Version: "v1",
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
Names: apiextensions.CustomResourceDefinitionNames{
|
{
|
||||||
|
Name: "v1",
|
||||||
|
Schema: validation,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Singular: "foo",
|
Singular: "foo",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
ListKind: "FooList",
|
ListKind: "FooList",
|
||||||
},
|
},
|
||||||
Scope: apiextensions.NamespaceScoped,
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
Validation: validation,
|
|
||||||
PreserveUnknownFields: tt.preserveUnknownFields,
|
|
||||||
},
|
},
|
||||||
}, "v1", tt.opts)
|
}, "v1", tt.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,9 +33,10 @@ import (
|
|||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
"k8s.io/kube-openapi/pkg/handler"
|
"k8s.io/kube-openapi/pkg/handler"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ func (c *Controller) Run(staticSpec *spec.Swagger, openAPIService *handler.OpenA
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, crd := range crds {
|
for _, crd := range crds {
|
||||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newSpecs, changed, err := buildVersionSpecs(crd, nil)
|
newSpecs, changed, err := buildVersionSpecs(crd, nil)
|
||||||
@ -163,7 +164,7 @@ func (c *Controller) sync(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do we have to remove all specs of this CRD?
|
// do we have to remove all specs of this CRD?
|
||||||
if errors.IsNotFound(err) || !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
if errors.IsNotFound(err) || !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||||
if _, found := c.crdSpecs[name]; !found {
|
if _, found := c.crdSpecs[name]; !found {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -194,7 +195,7 @@ func (c *Controller) sync(name string) error {
|
|||||||
return c.updateSpecLocked()
|
return c.updateSpecLocked()
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildVersionSpecs(crd *apiextensions.CustomResourceDefinition, oldSpecs map[string]*spec.Swagger) (map[string]*spec.Swagger, bool, error) {
|
func buildVersionSpecs(crd *apiextensionsv1.CustomResourceDefinition, oldSpecs map[string]*spec.Swagger) (map[string]*spec.Swagger, bool, error) {
|
||||||
newSpecs := map[string]*spec.Swagger{}
|
newSpecs := map[string]*spec.Swagger{}
|
||||||
anyChanged := false
|
anyChanged := false
|
||||||
for _, v := range crd.Spec.Versions {
|
for _, v := range crd.Spec.Versions {
|
||||||
@ -234,26 +235,26 @@ func (c *Controller) updateSpecLocked() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) addCustomResourceDefinition(obj interface{}) {
|
func (c *Controller) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
func (c *Controller) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||||
castNewObj := newObj.(*apiextensions.CustomResourceDefinition)
|
castNewObj := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Updating customresourcedefinition %s", castNewObj.Name)
|
klog.V(4).Infof("Updating customresourcedefinition %s", castNewObj.Name)
|
||||||
c.enqueue(castNewObj)
|
c.enqueue(castNewObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
||||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||||
return
|
return
|
||||||
@ -263,6 +264,6 @@ func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
|||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *Controller) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
c.queue.Add(obj.Name)
|
c.queue.Add(obj.Name)
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,9 @@ go_test(
|
|||||||
srcs = ["naming_controller_test.go"],
|
srcs = ["naming_controller_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||||
],
|
],
|
||||||
@ -24,10 +25,11 @@ go_library(
|
|||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status",
|
||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/status",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/status",
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
|
@ -34,10 +34,11 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This controller is reserving names. To avoid conflicts, be sure to run only one instance of the worker at a time.
|
// This controller is reserving names. To avoid conflicts, be sure to run only one instance of the worker at a time.
|
||||||
@ -103,7 +104,7 @@ func (c *NamingConditionController) getAcceptedNamesForGroup(group string) (allR
|
|||||||
item := curr
|
item := curr
|
||||||
obj, exists, err := c.crdMutationCache.GetByKey(curr.Name)
|
obj, exists, err := c.crdMutationCache.GetByKey(curr.Name)
|
||||||
if exists && err == nil {
|
if exists && err == nil {
|
||||||
item = obj.(*apiextensions.CustomResourceDefinition)
|
item = obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
allResources.Insert(item.Status.AcceptedNames.Plural)
|
allResources.Insert(item.Status.AcceptedNames.Plural)
|
||||||
@ -117,13 +118,13 @@ func (c *NamingConditionController) getAcceptedNamesForGroup(group string) (allR
|
|||||||
return allResources, allKinds
|
return allResources, allKinds
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NamingConditionController) calculateNamesAndConditions(in *apiextensions.CustomResourceDefinition) (apiextensions.CustomResourceDefinitionNames, apiextensions.CustomResourceDefinitionCondition, apiextensions.CustomResourceDefinitionCondition) {
|
func (c *NamingConditionController) calculateNamesAndConditions(in *apiextensionsv1.CustomResourceDefinition) (apiextensionsv1.CustomResourceDefinitionNames, apiextensionsv1.CustomResourceDefinitionCondition, apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||||
// Get the names that have already been claimed
|
// Get the names that have already been claimed
|
||||||
allResources, allKinds := c.getAcceptedNamesForGroup(in.Spec.Group)
|
allResources, allKinds := c.getAcceptedNamesForGroup(in.Spec.Group)
|
||||||
|
|
||||||
namesAcceptedCondition := apiextensions.CustomResourceDefinitionCondition{
|
namesAcceptedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.NamesAccepted,
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
Status: apiextensions.ConditionUnknown,
|
Status: apiextensionsv1.ConditionUnknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
requestedNames := in.Spec.Names
|
requestedNames := in.Spec.Names
|
||||||
@ -133,14 +134,14 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
|||||||
// Check each name for mismatches. If there's a mismatch between spec and status, then try to deconflict.
|
// Check each name for mismatches. If there's a mismatch between spec and status, then try to deconflict.
|
||||||
// Continue on errors so that the status is the best match possible
|
// Continue on errors so that the status is the best match possible
|
||||||
if err := equalToAcceptedOrFresh(requestedNames.Plural, acceptedNames.Plural, allResources); err != nil {
|
if err := equalToAcceptedOrFresh(requestedNames.Plural, acceptedNames.Plural, allResources); err != nil {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||||
namesAcceptedCondition.Reason = "PluralConflict"
|
namesAcceptedCondition.Reason = "PluralConflict"
|
||||||
namesAcceptedCondition.Message = err.Error()
|
namesAcceptedCondition.Message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
newNames.Plural = requestedNames.Plural
|
newNames.Plural = requestedNames.Plural
|
||||||
}
|
}
|
||||||
if err := equalToAcceptedOrFresh(requestedNames.Singular, acceptedNames.Singular, allResources); err != nil {
|
if err := equalToAcceptedOrFresh(requestedNames.Singular, acceptedNames.Singular, allResources); err != nil {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||||
namesAcceptedCondition.Reason = "SingularConflict"
|
namesAcceptedCondition.Reason = "SingularConflict"
|
||||||
namesAcceptedCondition.Message = err.Error()
|
namesAcceptedCondition.Message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
@ -160,7 +161,7 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
|||||||
|
|
||||||
}
|
}
|
||||||
if err := utilerrors.NewAggregate(errs); err != nil {
|
if err := utilerrors.NewAggregate(errs); err != nil {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||||
namesAcceptedCondition.Reason = "ShortNamesConflict"
|
namesAcceptedCondition.Reason = "ShortNamesConflict"
|
||||||
namesAcceptedCondition.Message = err.Error()
|
namesAcceptedCondition.Message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
@ -169,14 +170,14 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := equalToAcceptedOrFresh(requestedNames.Kind, acceptedNames.Kind, allKinds); err != nil {
|
if err := equalToAcceptedOrFresh(requestedNames.Kind, acceptedNames.Kind, allKinds); err != nil {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||||
namesAcceptedCondition.Reason = "KindConflict"
|
namesAcceptedCondition.Reason = "KindConflict"
|
||||||
namesAcceptedCondition.Message = err.Error()
|
namesAcceptedCondition.Message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
newNames.Kind = requestedNames.Kind
|
newNames.Kind = requestedNames.Kind
|
||||||
}
|
}
|
||||||
if err := equalToAcceptedOrFresh(requestedNames.ListKind, acceptedNames.ListKind, allKinds); err != nil {
|
if err := equalToAcceptedOrFresh(requestedNames.ListKind, acceptedNames.ListKind, allKinds); err != nil {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||||
namesAcceptedCondition.Reason = "ListKindConflict"
|
namesAcceptedCondition.Reason = "ListKindConflict"
|
||||||
namesAcceptedCondition.Message = err.Error()
|
namesAcceptedCondition.Message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
@ -186,8 +187,8 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
|||||||
newNames.Categories = requestedNames.Categories
|
newNames.Categories = requestedNames.Categories
|
||||||
|
|
||||||
// if we haven't changed the condition, then our names must be good.
|
// if we haven't changed the condition, then our names must be good.
|
||||||
if namesAcceptedCondition.Status == apiextensions.ConditionUnknown {
|
if namesAcceptedCondition.Status == apiextensionsv1.ConditionUnknown {
|
||||||
namesAcceptedCondition.Status = apiextensions.ConditionTrue
|
namesAcceptedCondition.Status = apiextensionsv1.ConditionTrue
|
||||||
namesAcceptedCondition.Reason = "NoConflicts"
|
namesAcceptedCondition.Reason = "NoConflicts"
|
||||||
namesAcceptedCondition.Message = "no conflicts found"
|
namesAcceptedCondition.Message = "no conflicts found"
|
||||||
}
|
}
|
||||||
@ -196,19 +197,19 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
|||||||
// The Establishing Controller will see the NamesAccepted condition when it arrives through the shared informer.
|
// The Establishing Controller will see the NamesAccepted condition when it arrives through the shared informer.
|
||||||
// At that time the API endpoint handler will serve the endpoint, avoiding a race
|
// At that time the API endpoint handler will serve the endpoint, avoiding a race
|
||||||
// which we had if we set Established to true here.
|
// which we had if we set Established to true here.
|
||||||
establishedCondition := apiextensions.CustomResourceDefinitionCondition{
|
establishedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Established,
|
Type: apiextensionsv1.Established,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "NotAccepted",
|
Reason: "NotAccepted",
|
||||||
Message: "not all names are accepted",
|
Message: "not all names are accepted",
|
||||||
}
|
}
|
||||||
if old := apiextensions.FindCRDCondition(in, apiextensions.Established); old != nil {
|
if old := apiextensionshelpers.FindCRDCondition(in, apiextensionsv1.Established); old != nil {
|
||||||
establishedCondition = *old
|
establishedCondition = *old
|
||||||
}
|
}
|
||||||
if establishedCondition.Status != apiextensions.ConditionTrue && namesAcceptedCondition.Status == apiextensions.ConditionTrue {
|
if establishedCondition.Status != apiextensionsv1.ConditionTrue && namesAcceptedCondition.Status == apiextensionsv1.ConditionTrue {
|
||||||
establishedCondition = apiextensions.CustomResourceDefinitionCondition{
|
establishedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Established,
|
Type: apiextensionsv1.Established,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "Installing",
|
Reason: "Installing",
|
||||||
Message: "the initial names have been accepted",
|
Message: "the initial names have been accepted",
|
||||||
}
|
}
|
||||||
@ -251,14 +252,14 @@ func (c *NamingConditionController) sync(key string) error {
|
|||||||
|
|
||||||
// nothing to do if accepted names and NamesAccepted condition didn't change
|
// nothing to do if accepted names and NamesAccepted condition didn't change
|
||||||
if reflect.DeepEqual(inCustomResourceDefinition.Status.AcceptedNames, acceptedNames) &&
|
if reflect.DeepEqual(inCustomResourceDefinition.Status.AcceptedNames, acceptedNames) &&
|
||||||
apiextensions.IsCRDConditionEquivalent(&namingCondition, apiextensions.FindCRDCondition(inCustomResourceDefinition, apiextensions.NamesAccepted)) {
|
apiextensionshelpers.IsCRDConditionEquivalent(&namingCondition, apiextensionshelpers.FindCRDCondition(inCustomResourceDefinition, apiextensionsv1.NamesAccepted)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
crd := inCustomResourceDefinition.DeepCopy()
|
crd := inCustomResourceDefinition.DeepCopy()
|
||||||
crd.Status.AcceptedNames = acceptedNames
|
crd.Status.AcceptedNames = acceptedNames
|
||||||
apiextensions.SetCRDCondition(crd, namingCondition)
|
apiextensionshelpers.SetCRDCondition(crd, namingCondition)
|
||||||
apiextensions.SetCRDCondition(crd, establishedCondition)
|
apiextensionshelpers.SetCRDCondition(crd, establishedCondition)
|
||||||
|
|
||||||
updatedObj, err := c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
updatedObj, err := c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||||
@ -323,7 +324,7 @@ func (c *NamingConditionController) processNextWorkItem() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NamingConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
func (c *NamingConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", obj, err))
|
||||||
@ -334,26 +335,26 @@ func (c *NamingConditionController) enqueue(obj *apiextensions.CustomResourceDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *NamingConditionController) addCustomResourceDefinition(obj interface{}) {
|
func (c *NamingConditionController) addCustomResourceDefinition(obj interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NamingConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
func (c *NamingConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||||
c.enqueue(castObj)
|
c.enqueue(castObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NamingConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
func (c *NamingConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||||
return
|
return
|
||||||
|
@ -22,24 +22,25 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
type crdBuilder struct {
|
type crdBuilder struct {
|
||||||
curr apiextensions.CustomResourceDefinition
|
curr apiextensionsv1.CustomResourceDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCRD(name string) *crdBuilder {
|
func newCRD(name string) *crdBuilder {
|
||||||
tokens := strings.SplitN(name, ".", 2)
|
tokens := strings.SplitN(name, ".", 2)
|
||||||
return &crdBuilder{
|
return &crdBuilder{
|
||||||
curr: apiextensions.CustomResourceDefinition{
|
curr: apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: tokens[1],
|
Group: tokens[1],
|
||||||
Names: apiextensions.CustomResourceDefinitionNames{
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: tokens[0],
|
Plural: tokens[0],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -67,14 +68,14 @@ func (b *crdBuilder) StatusNames(plural, singular, kind, listKind string, shortN
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *crdBuilder) Condition(c apiextensions.CustomResourceDefinitionCondition) *crdBuilder {
|
func (b *crdBuilder) Condition(c apiextensionsv1.CustomResourceDefinitionCondition) *crdBuilder {
|
||||||
b.curr.Status.Conditions = append(b.curr.Status.Conditions, c)
|
b.curr.Status.Conditions = append(b.curr.Status.Conditions, c)
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func names(plural, singular, kind, listKind string, shortNames ...string) apiextensions.CustomResourceDefinitionNames {
|
func names(plural, singular, kind, listKind string, shortNames ...string) apiextensionsv1.CustomResourceDefinitionNames {
|
||||||
ret := apiextensions.CustomResourceDefinitionNames{
|
ret := apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: plural,
|
Plural: plural,
|
||||||
Singular: singular,
|
Singular: singular,
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
@ -84,42 +85,42 @@ func names(plural, singular, kind, listKind string, shortNames ...string) apiext
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *crdBuilder) NewOrDie() *apiextensions.CustomResourceDefinition {
|
func (b *crdBuilder) NewOrDie() *apiextensionsv1.CustomResourceDefinition {
|
||||||
return &b.curr
|
return &b.curr
|
||||||
}
|
}
|
||||||
|
|
||||||
var acceptedCondition = apiextensions.CustomResourceDefinitionCondition{
|
var acceptedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.NamesAccepted,
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
Status: apiextensions.ConditionTrue,
|
Status: apiextensionsv1.ConditionTrue,
|
||||||
Reason: "NoConflicts",
|
Reason: "NoConflicts",
|
||||||
Message: "no conflicts found",
|
Message: "no conflicts found",
|
||||||
}
|
}
|
||||||
|
|
||||||
var notAcceptedCondition = apiextensions.CustomResourceDefinitionCondition{
|
var notAcceptedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.NamesAccepted,
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "NotAccepted",
|
Reason: "NotAccepted",
|
||||||
Message: "not all names are accepted",
|
Message: "not all names are accepted",
|
||||||
}
|
}
|
||||||
|
|
||||||
var installingCondition = apiextensions.CustomResourceDefinitionCondition{
|
var installingCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Established,
|
Type: apiextensionsv1.Established,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "Installing",
|
Reason: "Installing",
|
||||||
Message: "the initial names have been accepted",
|
Message: "the initial names have been accepted",
|
||||||
}
|
}
|
||||||
|
|
||||||
var notEstablishedCondition = apiextensions.CustomResourceDefinitionCondition{
|
var notEstablishedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.Established,
|
Type: apiextensionsv1.Established,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: "NotAccepted",
|
Reason: "NotAccepted",
|
||||||
Message: "not all names are accepted",
|
Message: "not all names are accepted",
|
||||||
}
|
}
|
||||||
|
|
||||||
func nameConflictCondition(reason, message string) apiextensions.CustomResourceDefinitionCondition {
|
func nameConflictCondition(reason, message string) apiextensionsv1.CustomResourceDefinitionCondition {
|
||||||
return apiextensions.CustomResourceDefinitionCondition{
|
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||||
Type: apiextensions.NamesAccepted,
|
Type: apiextensionsv1.NamesAccepted,
|
||||||
Status: apiextensions.ConditionFalse,
|
Status: apiextensionsv1.ConditionFalse,
|
||||||
Reason: reason,
|
Reason: reason,
|
||||||
Message: message,
|
Message: message,
|
||||||
}
|
}
|
||||||
@ -129,17 +130,17 @@ func TestSync(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
in *apiextensions.CustomResourceDefinition
|
in *apiextensionsv1.CustomResourceDefinition
|
||||||
existing []*apiextensions.CustomResourceDefinition
|
existing []*apiextensionsv1.CustomResourceDefinition
|
||||||
expectedNames apiextensions.CustomResourceDefinitionNames
|
expectedNames apiextensionsv1.CustomResourceDefinitionNames
|
||||||
expectedNameConflictCondition apiextensions.CustomResourceDefinitionCondition
|
expectedNameConflictCondition apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
expectedEstablishedCondition apiextensions.CustomResourceDefinitionCondition
|
expectedEstablishedCondition apiextensionsv1.CustomResourceDefinitionCondition
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "first resource",
|
name: "first resource",
|
||||||
in: newCRD("alfa.bravo.com").NewOrDie(),
|
in: newCRD("alfa.bravo.com").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{},
|
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "alfa",
|
Plural: "alfa",
|
||||||
},
|
},
|
||||||
expectedNameConflictCondition: acceptedCondition,
|
expectedNameConflictCondition: acceptedCondition,
|
||||||
@ -148,7 +149,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "different groups",
|
name: "different groups",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("alfa.charlie.com").StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
newCRD("alfa.charlie.com").StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -158,7 +159,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "conflict plural to singular",
|
name: "conflict plural to singular",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -168,7 +169,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "conflict singular to shortName",
|
name: "conflict singular to shortName",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "", "", "delta-singular").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "", "", "delta-singular").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -178,7 +179,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "conflict on shortName to shortName",
|
name: "conflict on shortName to shortName",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "", "", "hotel-shortname-2").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "", "", "hotel-shortname-2").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind"),
|
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind"),
|
||||||
@ -188,7 +189,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "conflict on kind to listkind",
|
name: "conflict on kind to listkind",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "", "echo-kind").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "", "echo-kind").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "delta-singular", "", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "delta-singular", "", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -198,7 +199,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "conflict on listkind to kind",
|
name: "conflict on listkind to kind",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "delta-singular", "echo-kind", "", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "delta-singular", "echo-kind", "", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -208,7 +209,7 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no conflict on resource and kind",
|
name: "no conflict on resource and kind",
|
||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "echo-kind", "", "").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "echo-kind", "", "").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -221,7 +222,7 @@ func TestSync(t *testing.T) {
|
|||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
StatusNames("zulu", "yankee-singular", "xray-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2").
|
StatusNames("zulu", "yankee-singular", "xray-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2").
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "", "delta-singular").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "", "delta-singular").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "yankee-singular", "echo-kind", "whiskey-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("alfa", "yankee-singular", "echo-kind", "whiskey-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -234,7 +235,7 @@ func TestSync(t *testing.T) {
|
|||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
StatusNames("zulu", "yankee-singular", "xray-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2").
|
StatusNames("zulu", "yankee-singular", "xray-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2").
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "", "delta-singular", "golf-shortname-1").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "indias", "foxtrot-listkind", "", "delta-singular", "golf-shortname-1").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("alfa", "yankee-singular", "echo-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2"),
|
expectedNames: names("alfa", "yankee-singular", "echo-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2"),
|
||||||
@ -247,7 +248,7 @@ func TestSync(t *testing.T) {
|
|||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("alfa.bravo.com").
|
newCRD("alfa.bravo.com").
|
||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
@ -263,7 +264,7 @@ func TestSync(t *testing.T) {
|
|||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1").
|
||||||
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("alfa.bravo.com").
|
newCRD("alfa.bravo.com").
|
||||||
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
StatusNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
@ -276,8 +277,8 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "installing before with true condition",
|
name: "installing before with true condition",
|
||||||
in: newCRD("alfa.bravo.com").Condition(acceptedCondition).NewOrDie(),
|
in: newCRD("alfa.bravo.com").Condition(acceptedCondition).NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{},
|
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "alfa",
|
Plural: "alfa",
|
||||||
},
|
},
|
||||||
expectedNameConflictCondition: acceptedCondition,
|
expectedNameConflictCondition: acceptedCondition,
|
||||||
@ -286,8 +287,8 @@ func TestSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "not installing before with false condition",
|
name: "not installing before with false condition",
|
||||||
in: newCRD("alfa.bravo.com").Condition(notAcceptedCondition).NewOrDie(),
|
in: newCRD("alfa.bravo.com").Condition(notAcceptedCondition).NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{},
|
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "alfa",
|
Plural: "alfa",
|
||||||
},
|
},
|
||||||
expectedNameConflictCondition: acceptedCondition,
|
expectedNameConflictCondition: acceptedCondition,
|
||||||
@ -298,7 +299,7 @@ func TestSync(t *testing.T) {
|
|||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
Condition(acceptedCondition).
|
Condition(acceptedCondition).
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -310,7 +311,7 @@ func TestSync(t *testing.T) {
|
|||||||
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
in: newCRD("alfa.bravo.com").SpecNames("alfa", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2").
|
||||||
Condition(notAcceptedCondition).
|
Condition(notAcceptedCondition).
|
||||||
NewOrDie(),
|
NewOrDie(),
|
||||||
existing: []*apiextensions.CustomResourceDefinition{
|
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||||
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
||||||
},
|
},
|
||||||
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
expectedNames: names("", "delta-singular", "echo-kind", "foxtrot-listkind", "golf-shortname-1", "hotel-shortname-2"),
|
||||||
@ -334,10 +335,10 @@ func TestSync(t *testing.T) {
|
|||||||
if e, a := tc.expectedNames, actualNames; !reflect.DeepEqual(e, a) {
|
if e, a := tc.expectedNames, actualNames; !reflect.DeepEqual(e, a) {
|
||||||
t.Errorf("%v expected %v, got %#v", tc.name, e, a)
|
t.Errorf("%v expected %v, got %#v", tc.name, e, a)
|
||||||
}
|
}
|
||||||
if e, a := tc.expectedNameConflictCondition, actualNameConflictCondition; !apiextensions.IsCRDConditionEquivalent(&e, &a) {
|
if e, a := tc.expectedNameConflictCondition, actualNameConflictCondition; !apiextensionshelpers.IsCRDConditionEquivalent(&e, &a) {
|
||||||
t.Errorf("%v expected %v, got %v", tc.name, e, a)
|
t.Errorf("%v expected %v, got %v", tc.name, e, a)
|
||||||
}
|
}
|
||||||
if e, a := tc.expectedEstablishedCondition, establishedCondition; !apiextensions.IsCRDConditionEquivalent(&e, &a) {
|
if e, a := tc.expectedEstablishedCondition, establishedCondition; !apiextensionshelpers.IsCRDConditionEquivalent(&e, &a) {
|
||||||
t.Errorf("%v expected %v, got %v", tc.name, e, a)
|
t.Errorf("%v expected %v, got %v", tc.name, e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/crdserverscheme:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/crdserverscheme:go_default_library",
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor:go_default_library",
|
||||||
|
@ -39,7 +39,8 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
|
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apiserver"
|
"k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/crdserverscheme"
|
"k8s.io/apiextensions-apiserver/pkg/crdserverscheme"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/registry/customresource"
|
"k8s.io/apiextensions-apiserver/pkg/registry/customresource"
|
||||||
@ -67,15 +68,15 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcd3testi
|
|||||||
kind := schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "Noxu"}
|
kind := schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "Noxu"}
|
||||||
|
|
||||||
labelSelectorPath := ".status.labelSelector"
|
labelSelectorPath := ".status.labelSelector"
|
||||||
scale := &apiextensions.CustomResourceSubresourceScale{
|
scale := &apiextensionsinternal.CustomResourceSubresourceScale{
|
||||||
SpecReplicasPath: ".spec.replicas",
|
SpecReplicasPath: ".spec.replicas",
|
||||||
StatusReplicasPath: ".status.replicas",
|
StatusReplicasPath: ".status.replicas",
|
||||||
LabelSelectorPath: &labelSelectorPath,
|
LabelSelectorPath: &labelSelectorPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
status := &apiextensions.CustomResourceSubresourceStatus{}
|
status := &apiextensionsinternal.CustomResourceSubresourceStatus{}
|
||||||
|
|
||||||
headers := []apiextensions.CustomResourceColumnDefinition{
|
headers := []apiextensionsv1.CustomResourceColumnDefinition{
|
||||||
{Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"},
|
{Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"},
|
||||||
{Name: "Replicas", Type: "integer", JSONPath: ".spec.replicas"},
|
{Name: "Replicas", Type: "integer", JSONPath: ".spec.replicas"},
|
||||||
{Name: "Missing", Type: "string", JSONPath: ".spec.missing"},
|
{Name: "Missing", Type: "string", JSONPath: ".spec.missing"},
|
||||||
|
@ -7,7 +7,7 @@ go_library(
|
|||||||
importpath = "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor",
|
importpath = "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metatable "k8s.io/apimachinery/pkg/api/meta/table"
|
metatable "k8s.io/apimachinery/pkg/api/meta/table"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -36,7 +36,7 @@ var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
|
|||||||
|
|
||||||
// New creates a new table convertor for the provided CRD column definition. If the printer definition cannot be parsed,
|
// New creates a new table convertor for the provided CRD column definition. If the printer definition cannot be parsed,
|
||||||
// error will be returned along with a default table convertor.
|
// error will be returned along with a default table convertor.
|
||||||
func New(crdColumns []apiextensions.CustomResourceColumnDefinition) (rest.TableConvertor, error) {
|
func New(crdColumns []apiextensionsv1.CustomResourceColumnDefinition) (rest.TableConvertor, error) {
|
||||||
headers := []metav1.TableColumnDefinition{
|
headers := []metav1.TableColumnDefinition{
|
||||||
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
|
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
|
||||||
}
|
}
|
||||||
|
@ -776,7 +776,7 @@ spec:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error waiting for NonStructuralSchema condition: %v", cond)
|
t.Fatalf("unexpected error waiting for NonStructuralSchema condition: %v", cond)
|
||||||
}
|
}
|
||||||
if v := "spec.validation.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields"; !strings.Contains(cond.Message, v) {
|
if v := "spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields"; !strings.Contains(cond.Message, v) {
|
||||||
t.Fatalf("expected violation %q, but got: %v", v, cond.Message)
|
t.Fatalf("expected violation %q, but got: %v", v, cond.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,7 +845,7 @@ spec:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error waiting for NonStructuralSchema condition: %v", cond)
|
t.Fatalf("unexpected error waiting for NonStructuralSchema condition: %v", cond)
|
||||||
}
|
}
|
||||||
if v := "spec.validation.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields"; !strings.Contains(cond.Message, v) {
|
if v := "spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields"; !strings.Contains(cond.Message, v) {
|
||||||
t.Fatalf("expected violation %q, but got: %v", v, cond.Message)
|
t.Fatalf("expected violation %q, but got: %v", v, cond.Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,12 +926,12 @@ x-kubernetes-embedded-resource: true
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
type: string
|
type: string
|
||||||
kind:
|
kind:
|
||||||
type: string
|
type: string
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{},
|
expectedViolations: []string{},
|
||||||
},
|
},
|
||||||
@ -972,7 +972,7 @@ x-kubernetes-preserve-unknown-fields: true
|
|||||||
type: ""
|
type: ""
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.type: Required value: must not be empty at the root",
|
"spec.versions[0].schema.openAPIV3Schema.type: Required value: must not be empty at the root",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -981,7 +981,7 @@ type: ""
|
|||||||
type: "integer"
|
type: "integer"
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.type: Invalid value: \"integer\": must be object at the root",
|
"spec.versions[0].schema.openAPIV3Schema.type: Invalid value: \"integer\": must be object at the root",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -989,63 +989,63 @@ type: "integer"
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
foo:
|
foo:
|
||||||
type: string
|
type: string
|
||||||
not:
|
not:
|
||||||
type: string
|
type: string
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
title: hello
|
title: hello
|
||||||
description: world
|
description: world
|
||||||
nullable: true
|
nullable: true
|
||||||
allOf:
|
allOf:
|
||||||
- properties:
|
- properties:
|
||||||
foo:
|
foo:
|
||||||
type: string
|
type: string
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
title: hello
|
title: hello
|
||||||
description: world
|
description: world
|
||||||
nullable: true
|
nullable: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- items:
|
- items:
|
||||||
type: string
|
type: string
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
title: hello
|
title: hello
|
||||||
description: world
|
description: world
|
||||||
nullable: true
|
nullable: true
|
||||||
oneOf:
|
oneOf:
|
||||||
- properties:
|
- properties:
|
||||||
foo:
|
foo:
|
||||||
type: string
|
type: string
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
title: hello
|
title: hello
|
||||||
description: world
|
description: world
|
||||||
nullable: true
|
nullable: true
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].items.type: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.type: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].items.additionalProperties: Forbidden: must be undefined to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.additionalProperties: Forbidden: must be undefined to be structural",
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].items.title: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.title: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].items.description: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.description: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].items.nullable: Forbidden: must be false to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.nullable: Forbidden: must be false to be structural",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[foo].title: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].title: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[foo].description: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].description: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[foo].title: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].title: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[foo].description: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].description: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
||||||
"spec.validation.openAPIV3Schema.not.type: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.not.type: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.not.additionalProperties: Forbidden: must be undefined to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.not.additionalProperties: Forbidden: must be undefined to be structural",
|
||||||
"spec.validation.openAPIV3Schema.not.title: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.not.title: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.not.description: Forbidden: must be empty to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.not.description: Forbidden: must be empty to be structural",
|
||||||
"spec.validation.openAPIV3Schema.not.nullable: Forbidden: must be false to be structural",
|
"spec.versions[0].schema.openAPIV3Schema.not.nullable: Forbidden: must be false to be structural",
|
||||||
"spec.validation.openAPIV3Schema.items: Required value: because it is defined in spec.validation.openAPIV3Schema.anyOf[0].items",
|
"spec.versions[0].schema.openAPIV3Schema.items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.anyOf[0].items",
|
||||||
},
|
},
|
||||||
unexpectedViolations: []string{
|
unexpectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.not.default",
|
"spec.versions[0].schema.openAPIV3Schema.not.default",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1053,12 +1053,12 @@ oneOf:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
foo:
|
foo:
|
||||||
type: string
|
type: string
|
||||||
pattern: "+"
|
pattern: "+"
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[foo].pattern: Invalid value: \"+\": must be a valid regular expression, but isn't: error parsing regexp: missing argument to repetition operator: `+`",
|
"spec.versions[0].schema.openAPIV3Schema.properties[foo].pattern: Invalid value: \"+\": must be a valid regular expression, but isn't: error parsing regexp: missing argument to repetition operator: `+`",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1066,40 +1066,40 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
embedded-resource:
|
embedded-resource:
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
embedded-resource:
|
embedded-resource:
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
allOf:
|
allOf:
|
||||||
- properties:
|
- properties:
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
embedded-resource:
|
embedded-resource:
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- properties:
|
- properties:
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
embedded-resource:
|
embedded-resource:
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
oneOf:
|
oneOf:
|
||||||
- properties:
|
- properties:
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
embedded-resource:
|
embedded-resource:
|
||||||
x-kubernetes-embedded-resource: true
|
x-kubernetes-embedded-resource: true
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
`,
|
`,
|
||||||
expectedCreateErrors: []string{
|
expectedCreateErrors: []string{
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[embedded-resource].x-kubernetes-preserve-unknown-fields: Forbidden: must be false to be structural",
|
"spec.validation.openAPIV3Schema.allOf[0].properties[embedded-resource].x-kubernetes-preserve-unknown-fields: Forbidden: must be false to be structural",
|
||||||
@ -1120,30 +1120,30 @@ oneOf:
|
|||||||
desc: "missing types with extensions",
|
desc: "missing types with extensions",
|
||||||
globalSchema: `
|
globalSchema: `
|
||||||
properties:
|
properties:
|
||||||
foo:
|
foo:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
bar:
|
bar:
|
||||||
items:
|
items:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
items: {}
|
items: {}
|
||||||
abc:
|
abc:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
items:
|
items:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
items:
|
items:
|
||||||
json:
|
json:
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
int-or-string:
|
int-or-string:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
`,
|
`,
|
||||||
expectedCreateErrors: []string{
|
expectedCreateErrors: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[foo].properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.validation.openAPIV3Schema.properties[foo].properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
@ -1167,37 +1167,37 @@ properties:
|
|||||||
desc: "missing types without extensions",
|
desc: "missing types without extensions",
|
||||||
globalSchema: `
|
globalSchema: `
|
||||||
properties:
|
properties:
|
||||||
foo:
|
foo:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
bar:
|
bar:
|
||||||
items:
|
items:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
items: {}
|
items: {}
|
||||||
abc:
|
abc:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
items:
|
items:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
items:
|
items:
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[foo].properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[foo].properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[foo].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[foo].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[abc].additionalProperties.properties[a].items.additionalProperties.type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[abc].additionalProperties.properties[a].items.additionalProperties.type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[abc].additionalProperties.properties[a].items.type: Required value: must not be empty for specified array items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[abc].additionalProperties.properties[a].items.type: Required value: must not be empty for specified array items",
|
||||||
"spec.validation.openAPIV3Schema.properties[abc].additionalProperties.properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[abc].additionalProperties.properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[abc].additionalProperties.type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[abc].additionalProperties.type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[abc].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[abc].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[bar].items.additionalProperties.items.type: Required value: must not be empty for specified array items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[bar].items.additionalProperties.items.type: Required value: must not be empty for specified array items",
|
||||||
"spec.validation.openAPIV3Schema.properties[bar].items.additionalProperties.properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[bar].items.additionalProperties.properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[bar].items.additionalProperties.type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[bar].items.additionalProperties.type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[bar].items.type: Required value: must not be empty for specified array items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[bar].items.type: Required value: must not be empty for specified array items",
|
||||||
"spec.validation.openAPIV3Schema.properties[bar].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[bar].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.type: Required value: must not be empty at the root",
|
"spec.versions[0].schema.openAPIV3Schema.type: Required value: must not be empty at the root",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1205,48 +1205,48 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
b:
|
b:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: integer
|
- type: integer
|
||||||
- type: string
|
- type: string
|
||||||
allOf:
|
allOf:
|
||||||
- pattern: abc
|
- pattern: abc
|
||||||
c:
|
c:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
allOf:
|
allOf:
|
||||||
- anyOf:
|
- anyOf:
|
||||||
- type: integer
|
- type: integer
|
||||||
- type: string
|
- type: string
|
||||||
- pattern: abc
|
- pattern: abc
|
||||||
- pattern: abc
|
- pattern: abc
|
||||||
d:
|
d:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: integer
|
- type: integer
|
||||||
- type: string
|
- type: string
|
||||||
pattern: abc
|
pattern: abc
|
||||||
e:
|
e:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
allOf:
|
allOf:
|
||||||
- anyOf:
|
- anyOf:
|
||||||
- type: integer
|
- type: integer
|
||||||
- type: string
|
- type: string
|
||||||
pattern: abc
|
pattern: abc
|
||||||
- pattern: abc
|
- pattern: abc
|
||||||
f:
|
f:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: integer
|
- type: integer
|
||||||
- type: string
|
- type: string
|
||||||
- pattern: abc
|
- pattern: abc
|
||||||
g:
|
g:
|
||||||
x-kubernetes-int-or-string: true
|
x-kubernetes-int-or-string: true
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: string
|
- type: string
|
||||||
- type: integer
|
- type: integer
|
||||||
`,
|
`,
|
||||||
expectedCreateErrors: []string{
|
expectedCreateErrors: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[d].anyOf[0].type: Forbidden: must be empty to be structural",
|
"spec.validation.openAPIV3Schema.properties[d].anyOf[0].type: Forbidden: must be empty to be structural",
|
||||||
@ -1271,7 +1271,7 @@ type: object
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.additionalProperties: Forbidden: must not be used at the root",
|
"spec.versions[0].schema.openAPIV3Schema.additionalProperties: Forbidden: must not be used at the root",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1279,53 +1279,53 @@ additionalProperties: false
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
b:
|
b:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
b:
|
b:
|
||||||
type: array
|
type: array
|
||||||
c:
|
c:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
d:
|
d:
|
||||||
type: array
|
type: array
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
b:
|
b:
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
b:
|
b:
|
||||||
items: {}
|
items: {}
|
||||||
c:
|
c:
|
||||||
items:
|
items:
|
||||||
not:
|
not:
|
||||||
items:
|
items:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
d:
|
d:
|
||||||
items: {}
|
items: {}
|
||||||
allOf:
|
allOf:
|
||||||
- properties:
|
- properties:
|
||||||
e: {}
|
e: {}
|
||||||
anyOf:
|
anyOf:
|
||||||
- properties:
|
- properties:
|
||||||
f: {}
|
f: {}
|
||||||
oneOf:
|
oneOf:
|
||||||
- properties:
|
- properties:
|
||||||
g: {}
|
g: {}
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[d].items: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[d].items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[d].items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[d].items",
|
||||||
"spec.validation.openAPIV3Schema.properties[a]: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[a]",
|
"spec.versions[0].schema.openAPIV3Schema.properties[a]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[a]",
|
||||||
"spec.validation.openAPIV3Schema.properties[b].properties[a]: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[b].not.properties[a]",
|
"spec.versions[0].schema.openAPIV3Schema.properties[b].properties[a]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[b].not.properties[a]",
|
||||||
"spec.validation.openAPIV3Schema.properties[b].properties[b].items: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[b].not.properties[b].items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[b].properties[b].items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[b].not.properties[b].items",
|
||||||
"spec.validation.openAPIV3Schema.properties[c].items.items: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[c].items.not.items",
|
"spec.versions[0].schema.openAPIV3Schema.properties[c].items.items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[c].items.not.items",
|
||||||
"spec.validation.openAPIV3Schema.properties[e]: Required value: because it is defined in spec.validation.openAPIV3Schema.allOf[0].properties[e]",
|
"spec.versions[0].schema.openAPIV3Schema.properties[e]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[e]",
|
||||||
"spec.validation.openAPIV3Schema.properties[f]: Required value: because it is defined in spec.validation.openAPIV3Schema.anyOf[0].properties[f]",
|
"spec.versions[0].schema.openAPIV3Schema.properties[f]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.anyOf[0].properties[f]",
|
||||||
"spec.validation.openAPIV3Schema.properties[g]: Required value: because it is defined in spec.validation.openAPIV3Schema.oneOf[0].properties[g]",
|
"spec.versions[0].schema.openAPIV3Schema.properties[g]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[g]",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1333,62 +1333,62 @@ oneOf:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
type: string
|
type: string
|
||||||
b:
|
b:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
type: string
|
type: string
|
||||||
b:
|
b:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
c:
|
c:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
type: string
|
type: string
|
||||||
d:
|
d:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
e:
|
e:
|
||||||
type: string
|
type: string
|
||||||
f:
|
f:
|
||||||
type: string
|
type: string
|
||||||
g:
|
g:
|
||||||
type: string
|
type: string
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
b:
|
b:
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
b:
|
b:
|
||||||
items: {}
|
items: {}
|
||||||
c:
|
c:
|
||||||
items:
|
items:
|
||||||
not:
|
not:
|
||||||
items:
|
items:
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
d:
|
d:
|
||||||
items: {}
|
items: {}
|
||||||
allOf:
|
allOf:
|
||||||
- properties:
|
- properties:
|
||||||
e: {}
|
e: {}
|
||||||
anyOf:
|
anyOf:
|
||||||
- properties:
|
- properties:
|
||||||
f: {}
|
f: {}
|
||||||
oneOf:
|
oneOf:
|
||||||
- properties:
|
- properties:
|
||||||
g: {}
|
g: {}
|
||||||
`,
|
`,
|
||||||
expectedViolations: nil,
|
expectedViolations: nil,
|
||||||
},
|
},
|
||||||
@ -1397,16 +1397,16 @@ oneOf:
|
|||||||
v1beta1Schema: `
|
v1beta1Schema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
b: {}
|
b: {}
|
||||||
`,
|
`,
|
||||||
v1Schema: `
|
v1Schema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a:
|
a:
|
||||||
type: string
|
type: string
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
@ -1418,18 +1418,18 @@ properties:
|
|||||||
v1beta1Schema: `
|
v1beta1Schema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
a: {}
|
a: {}
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
b: {}
|
b: {}
|
||||||
`,
|
`,
|
||||||
v1Schema: `
|
v1Schema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
c: {}
|
c: {}
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
d: {}
|
d: {}
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
||||||
@ -1443,12 +1443,12 @@ not:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
minimum: 42.0
|
minimum: 42.0
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[metadata]: Forbidden: must not specify anything other than name and generateName, but metadata is implicitly specified",
|
"spec.versions[0].schema.openAPIV3Schema.properties[metadata]: Forbidden: must not specify anything other than name and generateName, but metadata is implicitly specified",
|
||||||
"spec.validation.openAPIV3Schema.properties[metadata].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[metadata].type: Required value: must not be empty for specified object fields",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1456,18 +1456,18 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
labels:
|
labels:
|
||||||
type: object
|
type: object
|
||||||
maxLength: 4
|
maxLength: 4
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[metadata]: Forbidden: must not specify anything other than name and generateName, but metadata is implicitly specified",
|
"spec.versions[0].schema.openAPIV3Schema.properties[metadata]: Forbidden: must not specify anything other than name and generateName, but metadata is implicitly specified",
|
||||||
"spec.validation.openAPIV3Schema.properties[metadata].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[metadata].type: Required value: must not be empty for specified object fields",
|
||||||
"spec.validation.openAPIV3Schema.properties[metadata].properties[name].type: Required value: must not be empty for specified object fields",
|
"spec.versions[0].schema.openAPIV3Schema.properties[metadata].properties[name].type: Required value: must not be empty for specified object fields",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1475,12 +1475,12 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{},
|
expectedViolations: []string{},
|
||||||
},
|
},
|
||||||
@ -1489,12 +1489,12 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
generateName:
|
generateName:
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{},
|
expectedViolations: []string{},
|
||||||
},
|
},
|
||||||
@ -1503,15 +1503,15 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
generateName:
|
generateName:
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{},
|
expectedViolations: []string{},
|
||||||
},
|
},
|
||||||
@ -1520,30 +1520,30 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
pattern: "^[a-z]+$"
|
pattern: "^[a-z]+$"
|
||||||
allOf:
|
allOf:
|
||||||
- properties:
|
- properties:
|
||||||
metadata: {}
|
metadata: {}
|
||||||
anyOf:
|
anyOf:
|
||||||
- properties:
|
- properties:
|
||||||
metadata: {}
|
metadata: {}
|
||||||
oneOf:
|
oneOf:
|
||||||
- properties:
|
- properties:
|
||||||
metadata: {}
|
metadata: {}
|
||||||
not:
|
not:
|
||||||
properties:
|
properties:
|
||||||
metadata: {}
|
metadata: {}
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.anyOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
||||||
"spec.validation.openAPIV3Schema.allOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
||||||
"spec.validation.openAPIV3Schema.oneOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[metadata]: Forbidden: must not be specified in a nested context",
|
||||||
"spec.validation.openAPIV3Schema.not.properties[metadata]: Forbidden: must not be specified in a nested context",
|
"spec.versions[0].schema.openAPIV3Schema.not.properties[metadata]: Forbidden: must not be specified in a nested context",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1551,11 +1551,11 @@ not:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
slice:
|
slice:
|
||||||
type: array
|
type: array
|
||||||
`,
|
`,
|
||||||
expectedViolations: []string{
|
expectedViolations: []string{
|
||||||
"spec.validation.openAPIV3Schema.properties[slice].items: Required value: must be specified",
|
"spec.versions[0].schema.openAPIV3Schema.properties[slice].items: Required value: must be specified",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1563,11 +1563,11 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
slice:
|
slice:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
- type: string
|
- type: string
|
||||||
- type: integer
|
- type: integer
|
||||||
`,
|
`,
|
||||||
expectedCreateErrors: []string{"spec.validation.openAPIV3Schema.properties[slice].items: Forbidden: items must be a schema object and not an array"},
|
expectedCreateErrors: []string{"spec.validation.openAPIV3Schema.properties[slice].items: Forbidden: items must be a schema object and not an array"},
|
||||||
},
|
},
|
||||||
@ -1576,13 +1576,13 @@ properties:
|
|||||||
globalSchema: `
|
globalSchema: `
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
slice:
|
slice:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
not:
|
not:
|
||||||
items:
|
items:
|
||||||
- type: string
|
- type: string
|
||||||
`,
|
`,
|
||||||
expectedCreateErrors: []string{"spec.validation.openAPIV3Schema.properties[slice].not.items: Forbidden: items must be a schema object and not an array"},
|
expectedCreateErrors: []string{"spec.validation.openAPIV3Schema.properties[slice].not.items: Forbidden: items must be a schema object and not an array"},
|
||||||
},
|
},
|
||||||
|
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
@ -1155,19 +1155,11 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset
|
|||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme
|
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1
|
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1
|
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions
|
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions
|
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1
|
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1
|
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces
|
k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion
|
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1
|
k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1
|
||||||
k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1
|
k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1
|
||||||
k8s.io/apiextensions-apiserver/pkg/cmd/server/options
|
k8s.io/apiextensions-apiserver/pkg/cmd/server/options
|
||||||
|
Loading…
Reference in New Issue
Block a user