mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 02:11:09 +00:00
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/v1beta1: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/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
|
||||
"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"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"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)
|
||||
apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
|
||||
crdRegistrationController := crdregistration.NewCRDRegistrationController(
|
||||
apiExtensionInformers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
||||
apiExtensionInformers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||
autoRegistrationController)
|
||||
|
||||
err = aggregatorServer.GenericAPIServer.AddPostStartHook("kube-apiserver-autoregistration", func(context genericapiserver.PostStartHookContext) error {
|
||||
|
@ -11,9 +11,9 @@ go_library(
|
||||
srcs = ["crdregistration_controller.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/master/controller/crdregistration",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions: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/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/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/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",
|
||||
@ -44,8 +44,8 @@ go_test(
|
||||
srcs = ["crdregistration_controller_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions: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/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
|
@ -22,9 +22,9 @@ import (
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
crdinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
crdinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -73,24 +73,24 @@ func NewCRDRegistrationController(crdinformer crdinformers.CustomResourceDefinit
|
||||
|
||||
crdinformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
cast := obj.(*apiextensions.CustomResourceDefinition)
|
||||
cast := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
c.enqueueCRD(cast)
|
||||
},
|
||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
||||
// 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.
|
||||
c.enqueueCRD(oldObj.(*apiextensions.CustomResourceDefinition))
|
||||
c.enqueueCRD(newObj.(*apiextensions.CustomResourceDefinition))
|
||||
c.enqueueCRD(oldObj.(*apiextensionsv1.CustomResourceDefinition))
|
||||
c.enqueueCRD(newObj.(*apiextensionsv1.CustomResourceDefinition))
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
cast, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
cast, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.V(2).Infof("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
cast, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
cast, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.V(2).Infof("Tombstone contained unexpected object: %#v", obj)
|
||||
return
|
||||
@ -184,7 +184,7 @@ func (c *crdRegistrationController) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *crdRegistrationController) enqueueCRD(crd *apiextensions.CustomResourceDefinition) {
|
||||
func (c *crdRegistrationController) enqueueCRD(crd *apiextensionsv1.CustomResourceDefinition) {
|
||||
for _, version := range crd.Spec.Versions {
|
||||
c.queue.Add(schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name})
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
@ -31,7 +31,7 @@ import (
|
||||
func TestHandleVersionUpdate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
startingCRDs []*apiextensions.CustomResourceDefinition
|
||||
startingCRDs []*apiextensionsv1.CustomResourceDefinition
|
||||
version schema.GroupVersion
|
||||
|
||||
expectedAdded []*apiregistration.APIService
|
||||
@ -39,13 +39,13 @@ func TestHandleVersionUpdate(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "simple add crd",
|
||||
startingCRDs: []*apiextensions.CustomResourceDefinition{
|
||||
startingCRDs: []*apiextensionsv1.CustomResourceDefinition{
|
||||
{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
// 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.
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "v1",
|
||||
Served: true,
|
||||
@ -71,11 +71,11 @@ func TestHandleVersionUpdate(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "simple remove crd",
|
||||
startingCRDs: []*apiextensions.CustomResourceDefinition{
|
||||
startingCRDs: []*apiextensionsv1.CustomResourceDefinition{
|
||||
{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "v1",
|
||||
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/apiserver: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/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/v1beta1: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]}")/..
|
||||
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_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 \
|
||||
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 \
|
||||
"apiextensions:v1beta1,v1" \
|
||||
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
||||
|
@ -6,14 +6,20 @@ go_library(
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/apihelpers",
|
||||
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(
|
||||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
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(
|
||||
|
@ -20,8 +20,10 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"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
|
||||
@ -54,18 +56,205 @@ const (
|
||||
|
||||
// GetAPIApprovalState returns the state of the API approval and reason for that state
|
||||
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
|
||||
url, annotationURLParseErr := url.ParseRequestURI(annotation)
|
||||
switch {
|
||||
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"):
|
||||
return APIApprovalBypassed, fmt.Sprintf("not approved: %q", annotation)
|
||||
case annotationURLParseErr == nil && url != nil && len(url.Host) > 0 && len(url.Scheme) > 0:
|
||||
return APIApproved, fmt.Sprintf("approved in %v", annotation)
|
||||
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
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"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) {
|
||||
@ -76,22 +79,22 @@ func TestGetAPIApprovalState(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "bare unapproved",
|
||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "unapproved"},
|
||||
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "unapproved"},
|
||||
expected: APIApprovalBypassed,
|
||||
},
|
||||
{
|
||||
name: "unapproved with message",
|
||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "unapproved, experimental-only"},
|
||||
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "unapproved, experimental-only"},
|
||||
expected: APIApprovalBypassed,
|
||||
},
|
||||
{
|
||||
name: "mismatched case",
|
||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "Unapproved"},
|
||||
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "Unapproved"},
|
||||
expected: APIApprovalInvalid,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: ""},
|
||||
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: ""},
|
||||
expected: APIApprovalMissing,
|
||||
},
|
||||
{
|
||||
@ -101,27 +104,27 @@ func TestGetAPIApprovalState(t *testing.T) {
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
name: "url - just path",
|
||||
annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "/"},
|
||||
annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: "/"},
|
||||
expected: APIApprovalInvalid,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
}
|
||||
@ -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_controller.go",
|
||||
"customresource_handler.go",
|
||||
"helpers.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver",
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//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/install: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/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/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/internalversion: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/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/apiapproval: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",
|
||||
@ -101,9 +101,9 @@ go_test(
|
||||
srcs = ["customresource_handler_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
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/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/runtime/schema: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/v1"
|
||||
"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/internalclientset"
|
||||
_ "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/establish"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
||||
@ -109,7 +109,7 @@ type CustomResourceDefinitions struct {
|
||||
GenericAPIServer *genericapiserver.GenericAPIServer
|
||||
|
||||
// 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.
|
||||
@ -164,13 +164,13 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
crdClient, err := internalclientset.NewForConfig(s.GenericAPIServer.LoopbackClientConfig)
|
||||
crdClient, err := clientset.NewForConfig(s.GenericAPIServer.LoopbackClientConfig)
|
||||
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),
|
||||
// we need to be able to move forward
|
||||
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()
|
||||
if delegateHandler == nil {
|
||||
@ -185,11 +185,11 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
||||
discovery: map[string]*discovery.APIGroupHandler{},
|
||||
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(
|
||||
versionDiscoveryHandler,
|
||||
groupDiscoveryHandler,
|
||||
s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
||||
s.Informers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||
delegateHandler,
|
||||
c.ExtraConfig.CRDRESTOptionsGetter,
|
||||
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.HandlePrefix("/apis/", crdHandler)
|
||||
|
||||
crdController := NewDiscoveryController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler)
|
||||
namingController := status.NewNamingConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
||||
nonStructuralSchemaController := nonstructuralschema.NewConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
||||
apiApprovalController := apiapproval.NewKubernetesAPIApprovalPolicyConformantConditionController(s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), crdClient.Apiextensions())
|
||||
crdController := NewDiscoveryController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), versionDiscoveryHandler, groupDiscoveryHandler)
|
||||
namingController := status.NewNamingConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||
nonStructuralSchemaController := nonstructuralschema.NewConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||
apiApprovalController := apiapproval.NewKubernetesAPIApprovalPolicyConformantConditionController(s.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdClient.ApiextensionsV1())
|
||||
finalizingController := finalizer.NewCRDFinalizer(
|
||||
s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
||||
crdClient.Apiextensions(),
|
||||
s.Informers.Apiextensions().V1().CustomResourceDefinitions(),
|
||||
crdClient.ApiextensionsV1(),
|
||||
crdHandler,
|
||||
)
|
||||
var openapiController *openapicontroller.Controller
|
||||
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 {
|
||||
@ -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.
|
||||
s.GenericAPIServer.AddPostStartHookOrDie("crd-informer-synced", func(context genericapiserver.PostStartHookContext) 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)
|
||||
})
|
||||
|
||||
|
@ -13,7 +13,6 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//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/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
|
||||
@ -58,7 +57,6 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
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",
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
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"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"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.
|
||||
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{}
|
||||
for _, version := range crd.Spec.Versions {
|
||||
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
|
||||
switch crd.Spec.Conversion.Strategy {
|
||||
case apiextensions.NoneConverter:
|
||||
case apiextensionsv1.NoneConverter:
|
||||
converter = &nopConverter{}
|
||||
case apiextensions.WebhookConverter:
|
||||
case apiextensionsv1.WebhookConverter:
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
|
||||
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
|
||||
convertScale := false
|
||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
|
||||
convertScale = crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil
|
||||
for _, version := range crd.Spec.Versions {
|
||||
if version.Subresources != nil && version.Subresources.Scale != nil {
|
||||
convertScale = true
|
||||
@ -95,7 +94,7 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin
|
||||
unsafe = &crConverter{
|
||||
convertScale: convertScale,
|
||||
validVersions: validVersions,
|
||||
clusterScoped: crd.Spec.Scope == apiextensions.ClusterScoped,
|
||||
clusterScoped: crd.Spec.Scope == apiextensionsv1.ClusterScoped,
|
||||
converter: converter,
|
||||
}
|
||||
return &safeConverterWrapper{unsafe}, unsafe, nil
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"strings"
|
||||
"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/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -159,16 +159,16 @@ func TestConversion(t *testing.T) {
|
||||
t.Fatalf("Cannot create conversion factory: %v", err)
|
||||
}
|
||||
for _, test := range tests {
|
||||
testCRD := apiextensions.CustomResourceDefinition{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.NoneConverter,
|
||||
testCRD := apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Conversion: &apiextensionsv1.CustomResourceConversion{
|
||||
Strategy: apiextensionsv1.NoneConverter,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, v := range test.ValidVersions {
|
||||
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
|
||||
}
|
||||
safeConverter, _, err := CRConverterFactory.NewConverter(&testCRD)
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"fmt"
|
||||
"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"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
@ -73,8 +73,8 @@ type webhookConverter struct {
|
||||
conversionReviewVersions []string
|
||||
}
|
||||
|
||||
func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.ClientConfig {
|
||||
apiConfig := crd.Spec.Conversion.WebhookClientConfig
|
||||
func webhookClientConfigForCRD(crd *apiextensionsv1.CustomResourceDefinition) *webhook.ClientConfig {
|
||||
apiConfig := crd.Spec.Conversion.Webhook.ClientConfig
|
||||
ret := webhook.ClientConfig{
|
||||
Name: fmt.Sprintf("conversion_webhook_for_%s", crd.Name),
|
||||
CABundle: apiConfig.CABundle,
|
||||
@ -86,7 +86,7 @@ func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.
|
||||
ret.Service = &webhook.ClientConfigService{
|
||||
Name: apiConfig.Service.Name,
|
||||
Namespace: apiConfig.Service.Namespace,
|
||||
Port: apiConfig.Service.Port,
|
||||
Port: *apiConfig.Service.Port,
|
||||
}
|
||||
if apiConfig.Service.Path != nil {
|
||||
ret.Service.Path = *apiConfig.Service.Path
|
||||
@ -97,7 +97,7 @@ func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -108,7 +108,7 @@ func (f *webhookConverterFactory) NewWebhookConverter(crd *internal.CustomResour
|
||||
name: crd.Name,
|
||||
nopConverter: nopConverter{},
|
||||
|
||||
conversionReviewVersions: crd.Spec.Conversion.ConversionReviewVersions,
|
||||
conversionReviewVersions: crd.Spec.Conversion.Webhook.ConversionReviewVersions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,10 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
)
|
||||
|
||||
type DiscoveryController struct {
|
||||
@ -86,7 +87,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
||||
foundVersion := false
|
||||
foundGroup := false
|
||||
for _, crd := range crds {
|
||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
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"})
|
||||
// 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"})
|
||||
}
|
||||
|
||||
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
||||
Name: crd.Status.AcceptedNames.Plural,
|
||||
SingularName: crd.Status.AcceptedNames.Singular,
|
||||
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
|
||||
Namespaced: crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||
Kind: crd.Status.AcceptedNames.Kind,
|
||||
Verbs: verbs,
|
||||
ShortNames: crd.Status.AcceptedNames.ShortNames,
|
||||
@ -141,14 +142,14 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
||||
StorageVersionHash: storageVersionHash,
|
||||
})
|
||||
|
||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, version.Version)
|
||||
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, version.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subresources != nil && subresources.Status != nil {
|
||||
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
|
||||
Name: crd.Status.AcceptedNames.Plural + "/status",
|
||||
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
|
||||
Namespaced: crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||
Kind: crd.Status.AcceptedNames.Kind,
|
||||
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
|
||||
})
|
||||
@ -160,7 +161,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
|
||||
Version: "v1",
|
||||
Kind: "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"}),
|
||||
})
|
||||
}
|
||||
@ -243,21 +244,21 @@ func (c *DiscoveryController) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *DiscoveryController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *DiscoveryController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
for _, v := range obj.Spec.Versions {
|
||||
c.queue.Add(schema.GroupVersion{Group: obj.Spec.Group, Version: v.Name})
|
||||
}
|
||||
}
|
||||
|
||||
func (c *DiscoveryController) addCustomResourceDefinition(obj interface{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *DiscoveryController) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||
castNewObj := newObj.(*apiextensions.CustomResourceDefinition)
|
||||
castOldObj := oldObj.(*apiextensions.CustomResourceDefinition)
|
||||
castNewObj := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
castOldObj := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating customresourcedefinition %s", castOldObj.Name)
|
||||
// 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.
|
||||
@ -266,14 +267,14 @@ func (c *DiscoveryController) updateCustomResourceDefinition(oldObj, newObj inte
|
||||
}
|
||||
|
||||
func (c *DiscoveryController) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
|
@ -29,15 +29,17 @@ import (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"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"
|
||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||
structuraldefaulting "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting"
|
||||
schemaobjectmeta "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta"
|
||||
structuralpruning "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning"
|
||||
apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
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/establish"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
||||
@ -135,8 +137,8 @@ type crdHandler struct {
|
||||
type crdInfo struct {
|
||||
// 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.
|
||||
spec *apiextensions.CustomResourceDefinitionSpec
|
||||
acceptedNames *apiextensions.CustomResourceDefinitionNames
|
||||
spec *apiextensionsv1.CustomResourceDefinitionSpec
|
||||
acceptedNames *apiextensionsv1.CustomResourceDefinitionNames
|
||||
|
||||
// Storage per version
|
||||
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
|
||||
// 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 {
|
||||
r.delegate.ServeHTTP(w, req)
|
||||
return
|
||||
@ -287,7 +289,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !apiextensions.HasServedCRDVersion(crd, requestInfo.APIVersion) {
|
||||
if !apiextensionshelpers.HasServedCRDVersion(crd, requestInfo.APIVersion) {
|
||||
r.delegate.ServeHTTP(w, req)
|
||||
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
|
||||
// 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.
|
||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.NamesAccepted) &&
|
||||
!apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.NamesAccepted) &&
|
||||
!apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
r.delegate.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
terminating := apiextensions.IsCRDConditionTrue(crd, apiextensions.Terminating)
|
||||
terminating := apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Terminating)
|
||||
|
||||
crdInfo, err := r.getOrCreateServingInfoFor(crd.UID, crd.Name)
|
||||
if apierrors.IsNotFound(err) {
|
||||
@ -335,7 +337,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
var handlerFunc http.HandlerFunc
|
||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, requestInfo.APIVersion)
|
||||
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, requestInfo.APIVersion)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
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
|
||||
func (r *crdHandler) createCustomResourceDefinition(obj interface{}) {
|
||||
crd := obj.(*apiextensions.CustomResourceDefinition)
|
||||
crd := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
r.customStorageLock.Lock()
|
||||
defer r.customStorageLock.Unlock()
|
||||
// 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
|
||||
func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||
oldCRD := oldObj.(*apiextensions.CustomResourceDefinition)
|
||||
newCRD := newObj.(*apiextensions.CustomResourceDefinition)
|
||||
oldCRD := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
newCRD := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
|
||||
r.customStorageLock.Lock()
|
||||
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,
|
||||
// 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.
|
||||
if !apiextensions.IsCRDConditionTrue(newCRD, apiextensions.Established) &&
|
||||
apiextensions.IsCRDConditionTrue(newCRD, apiextensions.NamesAccepted) {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(newCRD, apiextensionsv1.Established) &&
|
||||
apiextensionshelpers.IsCRDConditionTrue(newCRD, apiextensionsv1.NamesAccepted) {
|
||||
if r.masterCount > 1 {
|
||||
r.establishingController.QueueCRD(newCRD.Name, 5*time.Second)
|
||||
} else {
|
||||
@ -575,7 +577,7 @@ func (r *crdHandler) tearDown(oldInfo *crdInfo) {
|
||||
|
||||
// GetCustomResourceListerCollectionDeleter returns the ListerCollectionDeleter of
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -607,7 +609,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
storageVersion, err := apiextensions.GetCRDStorageVersion(crd)
|
||||
storageVersion, err := apiextensionshelpers.GetCRDStorageVersion(crd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -622,7 +624,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
|
||||
structuralSchemas := map[string]*structuralschema.Structural{}
|
||||
for _, v := range crd.Spec.Versions {
|
||||
val, err := apiextensions.GetSchemaForVersion(crd, v.Name)
|
||||
val, err := apiextensionshelpers.GetSchemaForVersion(crd, v.Name)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
s, err := structuralschema.NewStructural(val.OpenAPIV3Schema)
|
||||
if *crd.Spec.PreserveUnknownFields == false && err != nil {
|
||||
internalValidation := &apiextensionsinternal.CustomResourceValidation{}
|
||||
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.
|
||||
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
|
||||
}
|
||||
|
||||
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.
|
||||
s = s.DeepCopy()
|
||||
|
||||
@ -679,36 +685,39 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
typer := newUnstructuredObjectTyper(parameterScheme)
|
||||
creator := unstructuredCreator{}
|
||||
|
||||
validationSchema, err := apiextensions.GetSchemaForVersion(crd, v.Name)
|
||||
validationSchema, err := apiextensionshelpers.GetSchemaForVersion(crd, v.Name)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for nil because we dereference this throughout the handler code.
|
||||
// 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 statusSpec *apiextensionsinternal.CustomResourceSubresourceStatus
|
||||
var statusValidator *validate.SchemaValidator
|
||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, v.Name)
|
||||
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, v.Name)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
return nil, fmt.Errorf("the server could not properly serve the CR subresources")
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Status != nil {
|
||||
equivalentResourceRegistry.RegisterKindFor(resource, "status", kind)
|
||||
|
||||
statusSpec = subresources.Status
|
||||
statusSpec = &apiextensionsinternal.CustomResourceSubresourceStatus{}
|
||||
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
|
||||
if validationSchema != nil && validationSchema.OpenAPIV3Schema != nil && validationSchema.OpenAPIV3Schema.Properties != nil {
|
||||
if statusSchema, ok := validationSchema.OpenAPIV3Schema.Properties["status"]; ok {
|
||||
if internalValidationSchema != nil && internalValidationSchema.OpenAPIV3Schema != nil && internalValidationSchema.OpenAPIV3Schema.Properties != nil {
|
||||
if statusSchema, ok := internalValidationSchema.OpenAPIV3Schema.Properties["status"]; ok {
|
||||
openapiSchema := &spec.Schema{}
|
||||
if err := apiservervalidation.ConvertJSONSchemaPropsWithPostProcess(&statusSchema, openapiSchema, apiservervalidation.StripUnsupportedFormatsPostProcess); err != nil {
|
||||
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 {
|
||||
equivalentResourceRegistry.RegisterKindFor(resource, "scale", autoscalingv1.SchemeGroupVersion.WithKind("Scale"))
|
||||
|
||||
scaleSpec = subresources.Scale
|
||||
scaleSpec = &apiextensionsinternal.CustomResourceSubresourceScale{}
|
||||
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 {
|
||||
utilruntime.HandleError(err)
|
||||
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},
|
||||
customresource.NewStrategy(
|
||||
typer,
|
||||
crd.Spec.Scope == apiextensions.NamespaceScoped,
|
||||
crd.Spec.Scope == apiextensionsv1.NamespaceScoped,
|
||||
kind,
|
||||
validator,
|
||||
statusValidator,
|
||||
@ -756,7 +767,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
encoderVersion: schema.GroupVersion{Group: crd.Spec.Group, Version: storageVersion},
|
||||
structuralSchemas: structuralSchemas,
|
||||
structuralSchemaGK: kind.GroupKind(),
|
||||
preserveUnknownFields: *crd.Spec.PreserveUnknownFields,
|
||||
preserveUnknownFields: crd.Spec.PreserveUnknownFields,
|
||||
},
|
||||
crd.Status.AcceptedNames.Categories,
|
||||
table,
|
||||
@ -764,13 +775,13 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
|
||||
selfLinkPrefix := ""
|
||||
switch crd.Spec.Scope {
|
||||
case apiextensions.ClusterScoped:
|
||||
case apiextensionsv1.ClusterScoped:
|
||||
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") + "/"
|
||||
}
|
||||
|
||||
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
|
||||
negotiatedSerializer := unstructuredNegotiatedSerializer{
|
||||
@ -779,7 +790,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
converter: safeConverter,
|
||||
structuralSchemas: structuralSchemas,
|
||||
structuralSchemaGK: kind.GroupKind(),
|
||||
preserveUnknownFields: *crd.Spec.PreserveUnknownFields,
|
||||
preserveUnknownFields: crd.Spec.PreserveUnknownFields,
|
||||
}
|
||||
var standardSerializers []runtime.SerializerInfo
|
||||
for _, s := range negotiatedSerializer.SupportedMediaTypes() {
|
||||
@ -830,7 +841,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
|
||||
reqScope.Creater,
|
||||
reqScope.Kind,
|
||||
reqScope.HubGroupVersion,
|
||||
*crd.Spec.PreserveUnknownFields,
|
||||
crd.Spec.PreserveUnknownFields,
|
||||
)
|
||||
if err != nil {
|
||||
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.
|
||||
func hasServedCRDVersion(spec *apiextensions.CustomResourceDefinitionSpec, version string) bool {
|
||||
func hasServedCRDVersion(spec *apiextensionsv1.CustomResourceDefinitionSpec, version string) bool {
|
||||
for _, v := range spec.Versions {
|
||||
if v.Name == version {
|
||||
return v.Served
|
||||
@ -1235,7 +1246,7 @@ func serverStartingError() error {
|
||||
// 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.
|
||||
// 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) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"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"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
|
||||
@ -78,18 +78,18 @@ func TestConvertFieldLabel(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
crd := apiextensions.CustomResourceDefinition{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
crd := apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Conversion: &apiextensionsv1.CustomResourceConversion{
|
||||
Strategy: "None",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if test.clusterScoped {
|
||||
crd.Spec.Scope = apiextensions.ClusterScoped
|
||||
crd.Spec.Scope = apiextensionsv1.ClusterScoped
|
||||
} else {
|
||||
crd.Spec.Scope = apiextensions.NamespaceScoped
|
||||
crd.Spec.Scope = apiextensionsv1.NamespaceScoped
|
||||
}
|
||||
f, err := conversion.NewCRConverterFactory(nil, 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 = [
|
||||
"//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/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/equality: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"
|
||||
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"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -43,7 +43,7 @@ func TestRoundTrip(t *testing.T) {
|
||||
if err := apiextensions.AddToScheme(scheme); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := apiextensionsv1beta1.AddToScheme(scheme); err != nil {
|
||||
if err := apiextensionsv1.AddToScheme(scheme); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ func TestRoundTrip(t *testing.T) {
|
||||
}
|
||||
|
||||
// JSON -> external
|
||||
external := &apiextensionsv1beta1.JSONSchemaProps{}
|
||||
external := &apiextensionsv1.JSONSchemaProps{}
|
||||
if err := json.Unmarshal(openAPIJSON, external); err != nil {
|
||||
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"],
|
||||
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/v1beta1: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/internalversion/apiextensions/internalversion: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/clientset/clientset/typed/apiextensions/v1: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/util/runtime: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"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//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/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -22,11 +22,10 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
@ -78,7 +77,7 @@ func NewKubernetesAPIApprovalPolicyConformantConditionController(
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return nil
|
||||
}
|
||||
@ -86,37 +85,37 @@ func calculateCondition(crd *apiextensions.CustomResourceDefinition) *apiextensi
|
||||
approvalState, reason := apihelpers.GetAPIApprovalState(crd.Annotations)
|
||||
switch approvalState {
|
||||
case apihelpers.APIApprovalInvalid:
|
||||
return &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "InvalidAnnotation",
|
||||
Message: reason,
|
||||
}
|
||||
case apihelpers.APIApprovalMissing:
|
||||
return &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "MissingAnnotation",
|
||||
Message: reason,
|
||||
}
|
||||
case apihelpers.APIApproved:
|
||||
return &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "ApprovedAnnotation",
|
||||
Message: reason,
|
||||
}
|
||||
case apihelpers.APIApprovalBypassed:
|
||||
return &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "UnapprovedAnnotation",
|
||||
Message: reason,
|
||||
}
|
||||
default:
|
||||
return &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensions.ConditionUnknown,
|
||||
return &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.KubernetesAPIApprovalPolicyConformant,
|
||||
Status: apiextensionsv1.ConditionUnknown,
|
||||
Reason: "UnknownAnnotation",
|
||||
Message: reason,
|
||||
}
|
||||
@ -133,7 +132,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) sync(key stri
|
||||
}
|
||||
|
||||
// avoid repeated calculation for the same annotation
|
||||
protectionAnnotationValue := inCustomResourceDefinition.Annotations[v1beta1.KubeAPIApprovedAnnotation]
|
||||
protectionAnnotationValue := inCustomResourceDefinition.Annotations[apiextensionsv1.KubeAPIApprovedAnnotation]
|
||||
c.lastSeenProtectedAnnotationLock.Lock()
|
||||
lastSeen, seenBefore := c.lastSeenProtectedAnnotation[inCustomResourceDefinition.Name]
|
||||
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.
|
||||
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
|
||||
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
|
||||
crd := inCustomResourceDefinition.DeepCopy()
|
||||
apiextensions.SetCRDCondition(crd, *cond)
|
||||
apihelpers.SetCRDCondition(crd, *cond)
|
||||
|
||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||
@ -221,7 +220,7 @@ func (c *KubernetesAPIApprovalPolicyConformantConditionController) processNextWo
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
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{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *KubernetesAPIApprovalPolicyConformantConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
|
@ -19,21 +19,20 @@ package apiapproval
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"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 TestCalculateCondition(t *testing.T) {
|
||||
noConditionFn := func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition) {
|
||||
noConditionFn := func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||
t.Helper()
|
||||
if condition != nil {
|
||||
t.Fatal(condition)
|
||||
}
|
||||
}
|
||||
|
||||
verifyCondition := func(status apiextensions.ConditionStatus, message string) func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition) {
|
||||
return 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 *apiextensionsv1.CustomResourceDefinitionCondition) {
|
||||
t.Helper()
|
||||
if condition == nil {
|
||||
t.Fatal("missing condition")
|
||||
@ -52,7 +51,7 @@ func TestCalculateCondition(t *testing.T) {
|
||||
|
||||
group string
|
||||
annotationValue string
|
||||
validateCondition func(t *testing.T, condition *apiextensions.CustomResourceDefinitionCondition)
|
||||
validateCondition func(t *testing.T, condition *apiextensionsv1.CustomResourceDefinitionCondition)
|
||||
}{
|
||||
{
|
||||
name: "for other group",
|
||||
@ -64,33 +63,33 @@ func TestCalculateCondition(t *testing.T) {
|
||||
name: "missing annotation",
|
||||
group: "sigs.k8s.io",
|
||||
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",
|
||||
group: "sigs.k8s.io",
|
||||
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",
|
||||
group: "sigs.k8s.io",
|
||||
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",
|
||||
group: "sigs.k8s.io",
|
||||
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 {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
crd := &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: test.annotationValue}},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Annotations: map[string]string{apiextensionsv1.KubeAPIApprovedAnnotation: test.annotationValue}},
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: test.group,
|
||||
},
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ go_library(
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/establish",
|
||||
visibility = ["//visibility:public"],
|
||||
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/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1: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/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/util/runtime: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/klog"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
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.
|
||||
@ -119,19 +120,19 @@ func (ec *EstablishingController) sync(key string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !apiextensions.IsCRDConditionTrue(cachedCRD, apiextensions.NamesAccepted) ||
|
||||
apiextensions.IsCRDConditionTrue(cachedCRD, apiextensions.Established) {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(cachedCRD, apiextensionsv1.NamesAccepted) ||
|
||||
apiextensionshelpers.IsCRDConditionTrue(cachedCRD, apiextensionsv1.Established) {
|
||||
return nil
|
||||
}
|
||||
|
||||
crd := cachedCRD.DeepCopy()
|
||||
establishedCondition := apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Established,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
establishedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Established,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InitialNamesAccepted",
|
||||
Message: "the initial names have been accepted",
|
||||
}
|
||||
apiextensions.SetCRDCondition(crd, establishedCondition)
|
||||
apiextensionshelpers.SetCRDCondition(crd, establishedCondition)
|
||||
|
||||
// Update server with new CRD condition.
|
||||
_, err = ec.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||
|
@ -11,10 +11,11 @@ go_library(
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/finalizer",
|
||||
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/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1: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/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/meta: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/util/workqueue"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
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
|
||||
@ -76,7 +77,7 @@ type ListerCollectionDeleter interface {
|
||||
type CRClientGetter interface {
|
||||
// GetCustomResourceListerCollectionDeleter gets the ListerCollectionDeleter for the given CRD
|
||||
// UID.
|
||||
GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) (ListerCollectionDeleter, error)
|
||||
GetCustomResourceListerCollectionDeleter(crd *apiextensionsv1.CustomResourceDefinition) (ListerCollectionDeleter, error)
|
||||
}
|
||||
|
||||
// NewCRDFinalizer creates a new CRDFinalizer.
|
||||
@ -113,16 +114,16 @@ func (c *CRDFinalizer) sync(key string) error {
|
||||
}
|
||||
|
||||
// no work to do
|
||||
if cachedCRD.DeletionTimestamp.IsZero() || !apiextensions.CRDHasFinalizer(cachedCRD, apiextensions.CustomResourceCleanupFinalizer) {
|
||||
if cachedCRD.DeletionTimestamp.IsZero() || !apiextensionshelpers.CRDHasFinalizer(cachedCRD, apiextensionsv1.CustomResourceCleanupFinalizer) {
|
||||
return nil
|
||||
}
|
||||
|
||||
crd := cachedCRD.DeepCopy()
|
||||
|
||||
// update the status condition. This cleanup could take a while.
|
||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InstanceDeletionInProgress",
|
||||
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.
|
||||
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
|
||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "OverlappingBuiltInResource",
|
||||
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)
|
||||
apiextensions.SetCRDCondition(crd, cond)
|
||||
apiextensionshelpers.SetCRDCondition(crd, cond)
|
||||
if deleteErr != nil {
|
||||
if _, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd); err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
@ -155,15 +156,15 @@ func (c *CRDFinalizer) sync(key string) error {
|
||||
return deleteErr
|
||||
}
|
||||
} else {
|
||||
apiextensions.SetCRDCondition(crd, apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
apiextensionshelpers.SetCRDCondition(crd, apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "NeverEstablished",
|
||||
Message: "resource was never established",
|
||||
})
|
||||
}
|
||||
|
||||
apiextensions.CRDRemoveFinalizer(crd, apiextensions.CustomResourceCleanupFinalizer)
|
||||
apiextensionshelpers.CRDRemoveFinalizer(crd, apiextensionsv1.CustomResourceCleanupFinalizer)
|
||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||
// deleted or changed in the meantime, we'll get called again
|
||||
@ -172,16 +173,16 @@ func (c *CRDFinalizer) sync(key string) error {
|
||||
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
|
||||
// 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.
|
||||
crClient, err := c.crClientGetter.GetCustomResourceListerCollectionDeleter(crd)
|
||||
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)
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InstanceDeletionFailed",
|
||||
Message: fmt.Sprintf("could not list instances: %v", err),
|
||||
}, err
|
||||
@ -190,9 +191,9 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
||||
ctx := genericapirequest.NewContext()
|
||||
allResources, err := crClient.List(ctx, nil)
|
||||
if err != nil {
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InstanceDeletionFailed",
|
||||
Message: fmt.Sprintf("could not list instances: %v", err),
|
||||
}, err
|
||||
@ -218,9 +219,9 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
||||
}
|
||||
}
|
||||
if deleteError := utilerrors.NewAggregate(deleteErrors); deleteError != nil {
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InstanceDeletionFailed",
|
||||
Message: fmt.Sprintf("could not issue all deletes: %v", deleteError),
|
||||
}, deleteError
|
||||
@ -241,16 +242,16 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "InstanceDeletionCheck",
|
||||
Message: fmt.Sprintf("could not confirm zero CustomResources remaining: %v", err),
|
||||
}, err
|
||||
}
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Terminating,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Terminating,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "InstanceDeletionCompleted",
|
||||
Message: "removed all instances",
|
||||
}, nil
|
||||
@ -299,7 +300,7 @@ func (c *CRDFinalizer) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *CRDFinalizer) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *CRDFinalizer) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
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{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CRDFinalizer) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||
oldCRD := oldObj.(*apiextensions.CustomResourceDefinition)
|
||||
newCRD := newObj.(*apiextensions.CustomResourceDefinition)
|
||||
oldCRD := oldObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
newCRD := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -339,8 +340,8 @@ func (c *CRDFinalizer) updateCustomResourceDefinition(oldObj, newObj interface{}
|
||||
newCopy := newCRD.DeepCopy()
|
||||
oldCopy.ResourceVersion = ""
|
||||
newCopy.ResourceVersion = ""
|
||||
apiextensions.RemoveCRDCondition(oldCopy, apiextensions.Terminating)
|
||||
apiextensions.RemoveCRDCondition(newCopy, apiextensions.Terminating)
|
||||
apiextensionshelpers.RemoveCRDCondition(oldCopy, apiextensionsv1.Terminating)
|
||||
apiextensionshelpers.RemoveCRDCondition(newCopy, apiextensionsv1.Terminating)
|
||||
|
||||
if !reflect.DeepEqual(oldCopy, newCopy) {
|
||||
c.enqueue(newCRD)
|
||||
|
@ -7,11 +7,13 @@ go_library(
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/nonstructuralschema",
|
||||
visibility = ["//visibility:public"],
|
||||
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/v1: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/informers/internalversion/apiextensions/internalversion: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/clientset/clientset/typed/apiextensions/v1: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/apis/meta/v1: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/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"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
)
|
||||
|
||||
// ConditionController is maintaining the NonStructuralSchema condition.
|
||||
@ -79,33 +81,25 @@ func NewConditionController(
|
||||
return c
|
||||
}
|
||||
|
||||
func calculateCondition(in *apiextensions.CustomResourceDefinition) *apiextensions.CustomResourceDefinitionCondition {
|
||||
cond := &apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.NonStructuralSchema,
|
||||
Status: apiextensions.ConditionUnknown,
|
||||
func calculateCondition(in *apiextensionsv1.CustomResourceDefinition) *apiextensionsv1.CustomResourceDefinitionCondition {
|
||||
cond := &apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.NonStructuralSchema,
|
||||
Status: apiextensionsv1.ConditionUnknown,
|
||||
}
|
||||
|
||||
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 {
|
||||
if v.Schema == nil || v.Schema.OpenAPIV3Schema == nil {
|
||||
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 {
|
||||
cond.Reason = "StructuralError"
|
||||
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
|
||||
}
|
||||
|
||||
cond.Status = apiextensions.ConditionTrue
|
||||
cond.Status = apiextensionsv1.ConditionTrue
|
||||
cond.Reason = "Violations"
|
||||
cond.Message = allErrs.ToAggregate().Error()
|
||||
|
||||
@ -147,7 +141,7 @@ func (c *ConditionController) sync(key string) error {
|
||||
|
||||
// check old condition
|
||||
cond := calculateCondition(inCustomResourceDefinition)
|
||||
old := apiextensions.FindCRDCondition(inCustomResourceDefinition, apiextensions.NonStructuralSchema)
|
||||
old := apiextensionshelpers.FindCRDCondition(inCustomResourceDefinition, apiextensionsv1.NonStructuralSchema)
|
||||
|
||||
if cond == nil && old == nil {
|
||||
return nil
|
||||
@ -159,10 +153,10 @@ func (c *ConditionController) sync(key string) error {
|
||||
// update condition
|
||||
crd := inCustomResourceDefinition.DeepCopy()
|
||||
if cond == nil {
|
||||
apiextensions.RemoveCRDCondition(crd, apiextensions.NonStructuralSchema)
|
||||
apiextensionshelpers.RemoveCRDCondition(crd, apiextensionsv1.NonStructuralSchema)
|
||||
} else {
|
||||
cond.LastTransitionTime = metav1.NewTime(time.Now())
|
||||
apiextensions.SetCRDCondition(crd, *cond)
|
||||
apiextensionshelpers.SetCRDCondition(crd, *cond)
|
||||
}
|
||||
|
||||
_, err = c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||
@ -227,7 +221,7 @@ func (c *ConditionController) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *ConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *ConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
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{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *ConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *ConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
|
@ -10,9 +10,10 @@ go_library(
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/openapi",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions: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/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers: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/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/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
|
@ -11,7 +11,9 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//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/v1: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/controller/openapi/v2:go_default_library",
|
||||
@ -40,7 +42,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//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/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
|
@ -26,7 +26,9 @@ import (
|
||||
"github.com/go-openapi/spec"
|
||||
|
||||
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"
|
||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||
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
|
||||
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
|
||||
s, err := apiextensions.GetSchemaForVersion(crd, version)
|
||||
s, err := apiextensionshelpers.GetSchemaForVersion(crd, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s != nil && s.OpenAPIV3Schema != nil {
|
||||
if !validation.SchemaHasInvalidTypes(s.OpenAPIV3Schema) {
|
||||
if ss, err := structuralschema.NewStructural(s.OpenAPIV3Schema); err == nil {
|
||||
internalCRDSchema := &apiextensionsinternal.CustomResourceValidation{}
|
||||
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
|
||||
if opts.AllowNonStructural || len(structuralschema.ValidateStructural(nil, ss)) == 0 {
|
||||
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}", "PATCH", "patch", "patch", sample).Reads(patch))
|
||||
|
||||
subresources, err := apiextensions.GetSubresourcesForVersion(crd, version)
|
||||
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, version)
|
||||
if err != nil {
|
||||
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{
|
||||
schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||
@ -512,13 +518,12 @@ func newBuilder(crd *apiextensions.CustomResourceDefinition, version string, sch
|
||||
listKind: crd.Spec.Names.ListKind,
|
||||
plural: crd.Spec.Names.Plural,
|
||||
}
|
||||
if crd.Spec.Scope == apiextensions.NamespaceScoped {
|
||||
if crd.Spec.Scope == apiextensionsv1.NamespaceScoped {
|
||||
b.namespaced = true
|
||||
}
|
||||
|
||||
// Pre-build schema with Kubernetes native properties
|
||||
preserveUnknownFields := crd.Spec.PreserveUnknownFields != nil && *crd.Spec.PreserveUnknownFields
|
||||
b.schema = b.buildKubeNative(schema, v2, preserveUnknownFields)
|
||||
b.schema = b.buildKubeNative(schema, v2, crd.Spec.PreserveUnknownFields)
|
||||
b.listSchema = b.buildListSchema()
|
||||
|
||||
return b
|
||||
|
@ -24,8 +24,8 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
@ -352,12 +352,12 @@ func TestNewBuilder(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var schema *structuralschema.Structural
|
||||
if len(tt.schema) > 0 {
|
||||
v1beta1Schema := &v1beta1.JSONSchemaProps{}
|
||||
v1beta1Schema := &apiextensionsv1.JSONSchemaProps{}
|
||||
if err := json.Unmarshal([]byte(tt.schema), &v1beta1Schema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
internalSchema := &apiextensions.JSONSchemaProps{}
|
||||
v1beta1.Convert_v1beta1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
||||
internalSchema := &apiextensionsinternal.JSONSchemaProps{}
|
||||
apiextensionsv1.Convert_v1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
||||
var err error
|
||||
schema, err = structuralschema.NewStructural(internalSchema)
|
||||
if err != nil {
|
||||
@ -369,17 +369,21 @@ func TestNewBuilder(t *testing.T) {
|
||||
schema = schema.Unfold()
|
||||
}
|
||||
|
||||
got := newBuilder(&apiextensions.CustomResourceDefinition{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Version: "v1",
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
got := newBuilder(&apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "v1",
|
||||
},
|
||||
},
|
||||
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Singular: "foo",
|
||||
Kind: "Foo",
|
||||
ListKind: "FooList",
|
||||
},
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Scope: apiextensionsv1.NamespaceScoped,
|
||||
},
|
||||
}, "v1", schema, tt.v2)
|
||||
|
||||
@ -430,7 +434,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
||||
testCRDResourceName := "foos"
|
||||
|
||||
testCases := []struct {
|
||||
scope apiextensions.ResourceScope
|
||||
scope apiextensionsv1.ResourceScope
|
||||
paths map[string]struct {
|
||||
expectNamespaceParam bool
|
||||
expectNameParam bool
|
||||
@ -438,7 +442,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
||||
}
|
||||
}{
|
||||
{
|
||||
scope: apiextensions.NamespaceScoped,
|
||||
scope: apiextensionsv1.NamespaceScoped,
|
||||
paths: map[string]struct {
|
||||
expectNamespaceParam bool
|
||||
expectNameParam bool
|
||||
@ -452,7 +456,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: apiextensions.ClusterScoped,
|
||||
scope: apiextensionsv1.ClusterScoped,
|
||||
paths: map[string]struct {
|
||||
expectNamespaceParam bool
|
||||
expectNameParam bool
|
||||
@ -467,23 +471,23 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testNamespacedCRD := &apiextensions.CustomResourceDefinition{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
testNamespacedCRD := &apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Scope: testCase.scope,
|
||||
Group: testCRDGroup,
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Kind: testCRDKind,
|
||||
Plural: testCRDResourceName,
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
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})
|
||||
@ -627,33 +631,37 @@ func TestBuildSwagger(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var validation *apiextensions.CustomResourceValidation
|
||||
var validation *apiextensionsv1.CustomResourceValidation
|
||||
if len(tt.schema) > 0 {
|
||||
v1beta1Schema := &v1beta1.JSONSchemaProps{}
|
||||
if err := json.Unmarshal([]byte(tt.schema), &v1beta1Schema); err != nil {
|
||||
v1Schema := &apiextensionsv1.JSONSchemaProps{}
|
||||
if err := json.Unmarshal([]byte(tt.schema), &v1Schema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
internalSchema := &apiextensions.JSONSchemaProps{}
|
||||
v1beta1.Convert_v1beta1_JSONSchemaProps_To_apiextensions_JSONSchemaProps(v1beta1Schema, internalSchema, nil)
|
||||
validation = &apiextensions.CustomResourceValidation{
|
||||
OpenAPIV3Schema: internalSchema,
|
||||
validation = &apiextensionsv1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: v1Schema,
|
||||
}
|
||||
}
|
||||
if tt.preserveUnknownFields != nil && *tt.preserveUnknownFields {
|
||||
validation.OpenAPIV3Schema.XPreserveUnknownFields = utilpointer.BoolPtr(true)
|
||||
}
|
||||
|
||||
// TODO: mostly copied from the test above. reuse code to cleanup
|
||||
got, err := BuildSwagger(&apiextensions.CustomResourceDefinition{
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Version: "v1",
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
got, err := BuildSwagger(&apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "v1",
|
||||
Schema: validation,
|
||||
},
|
||||
},
|
||||
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Singular: "foo",
|
||||
Kind: "Foo",
|
||||
ListKind: "FooList",
|
||||
},
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Validation: validation,
|
||||
PreserveUnknownFields: tt.preserveUnknownFields,
|
||||
Scope: apiextensionsv1.NamespaceScoped,
|
||||
},
|
||||
}, "v1", tt.opts)
|
||||
if err != nil {
|
||||
|
@ -33,9 +33,10 @@ import (
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
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"
|
||||
)
|
||||
|
||||
@ -99,7 +100,7 @@ func (c *Controller) Run(staticSpec *spec.Swagger, openAPIService *handler.OpenA
|
||||
return
|
||||
}
|
||||
for _, crd := range crds {
|
||||
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
continue
|
||||
}
|
||||
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?
|
||||
if errors.IsNotFound(err) || !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
|
||||
if errors.IsNotFound(err) || !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
if _, found := c.crdSpecs[name]; !found {
|
||||
return nil
|
||||
}
|
||||
@ -194,7 +195,7 @@ func (c *Controller) sync(name string) error {
|
||||
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{}
|
||||
anyChanged := false
|
||||
for _, v := range crd.Spec.Versions {
|
||||
@ -234,26 +235,26 @@ func (c *Controller) updateSpecLocked() error {
|
||||
}
|
||||
|
||||
func (c *Controller) addCustomResourceDefinition(obj interface{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *Controller) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||
castNewObj := newObj.(*apiextensions.CustomResourceDefinition)
|
||||
castNewObj := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating customresourcedefinition %s", castNewObj.Name)
|
||||
c.enqueue(castNewObj)
|
||||
}
|
||||
|
||||
func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
@ -263,6 +264,6 @@ func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *Controller) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *Controller) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
c.queue.Add(obj.Name)
|
||||
}
|
||||
|
@ -11,8 +11,9 @@ go_test(
|
||||
srcs = ["naming_controller_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers: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/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",
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/controller/status",
|
||||
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/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apihelpers:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1: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/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/errors: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/util/workqueue"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
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.
|
||||
@ -103,7 +104,7 @@ func (c *NamingConditionController) getAcceptedNamesForGroup(group string) (allR
|
||||
item := curr
|
||||
obj, exists, err := c.crdMutationCache.GetByKey(curr.Name)
|
||||
if exists && err == nil {
|
||||
item = obj.(*apiextensions.CustomResourceDefinition)
|
||||
item = obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
}
|
||||
|
||||
allResources.Insert(item.Status.AcceptedNames.Plural)
|
||||
@ -117,13 +118,13 @@ func (c *NamingConditionController) getAcceptedNamesForGroup(group string) (allR
|
||||
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
|
||||
allResources, allKinds := c.getAcceptedNamesForGroup(in.Spec.Group)
|
||||
|
||||
namesAcceptedCondition := apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.NamesAccepted,
|
||||
Status: apiextensions.ConditionUnknown,
|
||||
namesAcceptedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.NamesAccepted,
|
||||
Status: apiextensionsv1.ConditionUnknown,
|
||||
}
|
||||
|
||||
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.
|
||||
// Continue on errors so that the status is the best match possible
|
||||
if err := equalToAcceptedOrFresh(requestedNames.Plural, acceptedNames.Plural, allResources); err != nil {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||
namesAcceptedCondition.Reason = "PluralConflict"
|
||||
namesAcceptedCondition.Message = err.Error()
|
||||
} else {
|
||||
newNames.Plural = requestedNames.Plural
|
||||
}
|
||||
if err := equalToAcceptedOrFresh(requestedNames.Singular, acceptedNames.Singular, allResources); err != nil {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||
namesAcceptedCondition.Reason = "SingularConflict"
|
||||
namesAcceptedCondition.Message = err.Error()
|
||||
} else {
|
||||
@ -160,7 +161,7 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
||||
|
||||
}
|
||||
if err := utilerrors.NewAggregate(errs); err != nil {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||
namesAcceptedCondition.Reason = "ShortNamesConflict"
|
||||
namesAcceptedCondition.Message = err.Error()
|
||||
} else {
|
||||
@ -169,14 +170,14 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
||||
}
|
||||
|
||||
if err := equalToAcceptedOrFresh(requestedNames.Kind, acceptedNames.Kind, allKinds); err != nil {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||
namesAcceptedCondition.Reason = "KindConflict"
|
||||
namesAcceptedCondition.Message = err.Error()
|
||||
} else {
|
||||
newNames.Kind = requestedNames.Kind
|
||||
}
|
||||
if err := equalToAcceptedOrFresh(requestedNames.ListKind, acceptedNames.ListKind, allKinds); err != nil {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionFalse
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionFalse
|
||||
namesAcceptedCondition.Reason = "ListKindConflict"
|
||||
namesAcceptedCondition.Message = err.Error()
|
||||
} else {
|
||||
@ -186,8 +187,8 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension
|
||||
newNames.Categories = requestedNames.Categories
|
||||
|
||||
// if we haven't changed the condition, then our names must be good.
|
||||
if namesAcceptedCondition.Status == apiextensions.ConditionUnknown {
|
||||
namesAcceptedCondition.Status = apiextensions.ConditionTrue
|
||||
if namesAcceptedCondition.Status == apiextensionsv1.ConditionUnknown {
|
||||
namesAcceptedCondition.Status = apiextensionsv1.ConditionTrue
|
||||
namesAcceptedCondition.Reason = "NoConflicts"
|
||||
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.
|
||||
// At that time the API endpoint handler will serve the endpoint, avoiding a race
|
||||
// which we had if we set Established to true here.
|
||||
establishedCondition := apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Established,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
establishedCondition := apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Established,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "NotAccepted",
|
||||
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
|
||||
}
|
||||
if establishedCondition.Status != apiextensions.ConditionTrue && namesAcceptedCondition.Status == apiextensions.ConditionTrue {
|
||||
establishedCondition = apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Established,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
if establishedCondition.Status != apiextensionsv1.ConditionTrue && namesAcceptedCondition.Status == apiextensionsv1.ConditionTrue {
|
||||
establishedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Established,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "Installing",
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
crd := inCustomResourceDefinition.DeepCopy()
|
||||
crd.Status.AcceptedNames = acceptedNames
|
||||
apiextensions.SetCRDCondition(crd, namingCondition)
|
||||
apiextensions.SetCRDCondition(crd, establishedCondition)
|
||||
apiextensionshelpers.SetCRDCondition(crd, namingCondition)
|
||||
apiextensionshelpers.SetCRDCondition(crd, establishedCondition)
|
||||
|
||||
updatedObj, err := c.crdClient.CustomResourceDefinitions().UpdateStatus(crd)
|
||||
if apierrors.IsNotFound(err) || apierrors.IsConflict(err) {
|
||||
@ -323,7 +324,7 @@ func (c *NamingConditionController) processNextWorkItem() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *NamingConditionController) enqueue(obj *apiextensions.CustomResourceDefinition) {
|
||||
func (c *NamingConditionController) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
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{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *NamingConditionController) updateCustomResourceDefinition(obj, _ interface{}) {
|
||||
castObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *NamingConditionController) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensions.CustomResourceDefinition)
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
|
@ -22,24 +22,25 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
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"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
type crdBuilder struct {
|
||||
curr apiextensions.CustomResourceDefinition
|
||||
curr apiextensionsv1.CustomResourceDefinition
|
||||
}
|
||||
|
||||
func newCRD(name string) *crdBuilder {
|
||||
tokens := strings.SplitN(name, ".", 2)
|
||||
return &crdBuilder{
|
||||
curr: apiextensions.CustomResourceDefinition{
|
||||
curr: apiextensionsv1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: tokens[1],
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: tokens[0],
|
||||
},
|
||||
},
|
||||
@ -67,14 +68,14 @@ func (b *crdBuilder) StatusNames(plural, singular, kind, listKind string, shortN
|
||||
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)
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func names(plural, singular, kind, listKind string, shortNames ...string) apiextensions.CustomResourceDefinitionNames {
|
||||
ret := apiextensions.CustomResourceDefinitionNames{
|
||||
func names(plural, singular, kind, listKind string, shortNames ...string) apiextensionsv1.CustomResourceDefinitionNames {
|
||||
ret := apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: plural,
|
||||
Singular: singular,
|
||||
Kind: kind,
|
||||
@ -84,42 +85,42 @@ func names(plural, singular, kind, listKind string, shortNames ...string) apiext
|
||||
return ret
|
||||
}
|
||||
|
||||
func (b *crdBuilder) NewOrDie() *apiextensions.CustomResourceDefinition {
|
||||
func (b *crdBuilder) NewOrDie() *apiextensionsv1.CustomResourceDefinition {
|
||||
return &b.curr
|
||||
}
|
||||
|
||||
var acceptedCondition = apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.NamesAccepted,
|
||||
Status: apiextensions.ConditionTrue,
|
||||
var acceptedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.NamesAccepted,
|
||||
Status: apiextensionsv1.ConditionTrue,
|
||||
Reason: "NoConflicts",
|
||||
Message: "no conflicts found",
|
||||
}
|
||||
|
||||
var notAcceptedCondition = apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.NamesAccepted,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
var notAcceptedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.NamesAccepted,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "NotAccepted",
|
||||
Message: "not all names are accepted",
|
||||
}
|
||||
|
||||
var installingCondition = apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Established,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
var installingCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Established,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "Installing",
|
||||
Message: "the initial names have been accepted",
|
||||
}
|
||||
|
||||
var notEstablishedCondition = apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.Established,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
var notEstablishedCondition = apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.Established,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: "NotAccepted",
|
||||
Message: "not all names are accepted",
|
||||
}
|
||||
|
||||
func nameConflictCondition(reason, message string) apiextensions.CustomResourceDefinitionCondition {
|
||||
return apiextensions.CustomResourceDefinitionCondition{
|
||||
Type: apiextensions.NamesAccepted,
|
||||
Status: apiextensions.ConditionFalse,
|
||||
func nameConflictCondition(reason, message string) apiextensionsv1.CustomResourceDefinitionCondition {
|
||||
return apiextensionsv1.CustomResourceDefinitionCondition{
|
||||
Type: apiextensionsv1.NamesAccepted,
|
||||
Status: apiextensionsv1.ConditionFalse,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
@ -129,17 +130,17 @@ func TestSync(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
in *apiextensions.CustomResourceDefinition
|
||||
existing []*apiextensions.CustomResourceDefinition
|
||||
expectedNames apiextensions.CustomResourceDefinitionNames
|
||||
expectedNameConflictCondition apiextensions.CustomResourceDefinitionCondition
|
||||
expectedEstablishedCondition apiextensions.CustomResourceDefinitionCondition
|
||||
in *apiextensionsv1.CustomResourceDefinition
|
||||
existing []*apiextensionsv1.CustomResourceDefinition
|
||||
expectedNames apiextensionsv1.CustomResourceDefinitionNames
|
||||
expectedNameConflictCondition apiextensionsv1.CustomResourceDefinitionCondition
|
||||
expectedEstablishedCondition apiextensionsv1.CustomResourceDefinitionCondition
|
||||
}{
|
||||
{
|
||||
name: "first resource",
|
||||
in: newCRD("alfa.bravo.com").NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{},
|
||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "alfa",
|
||||
},
|
||||
expectedNameConflictCondition: acceptedCondition,
|
||||
@ -148,7 +149,7 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
name: "different groups",
|
||||
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(),
|
||||
},
|
||||
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",
|
||||
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(),
|
||||
},
|
||||
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",
|
||||
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(),
|
||||
},
|
||||
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",
|
||||
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(),
|
||||
},
|
||||
expectedNames: names("alfa", "delta-singular", "echo-kind", "foxtrot-listkind"),
|
||||
@ -188,7 +189,7 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
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(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
newCRD("india.bravo.com").StatusNames("india", "indias", "", "echo-kind").NewOrDie(),
|
||||
},
|
||||
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",
|
||||
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(),
|
||||
},
|
||||
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",
|
||||
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(),
|
||||
},
|
||||
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").
|
||||
StatusNames("zulu", "yankee-singular", "xray-kind", "whiskey-listkind", "victor-shortname-1", "uniform-shortname-2").
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
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"),
|
||||
@ -234,7 +235,7 @@ func TestSync(t *testing.T) {
|
||||
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").
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
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"),
|
||||
@ -247,7 +248,7 @@ func TestSync(t *testing.T) {
|
||||
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").
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
newCRD("alfa.bravo.com").
|
||||
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").
|
||||
@ -263,7 +264,7 @@ func TestSync(t *testing.T) {
|
||||
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").
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
newCRD("alfa.bravo.com").
|
||||
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").
|
||||
@ -276,8 +277,8 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
name: "installing before with true condition",
|
||||
in: newCRD("alfa.bravo.com").Condition(acceptedCondition).NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{},
|
||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "alfa",
|
||||
},
|
||||
expectedNameConflictCondition: acceptedCondition,
|
||||
@ -286,8 +287,8 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
name: "not installing before with false condition",
|
||||
in: newCRD("alfa.bravo.com").Condition(notAcceptedCondition).NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{},
|
||||
expectedNames: apiextensions.CustomResourceDefinitionNames{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{},
|
||||
expectedNames: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "alfa",
|
||||
},
|
||||
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").
|
||||
Condition(acceptedCondition).
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
||||
},
|
||||
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").
|
||||
Condition(notAcceptedCondition).
|
||||
NewOrDie(),
|
||||
existing: []*apiextensions.CustomResourceDefinition{
|
||||
existing: []*apiextensionsv1.CustomResourceDefinition{
|
||||
newCRD("india.bravo.com").StatusNames("india", "alfa", "", "").NewOrDie(),
|
||||
},
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ go_test(
|
||||
deps = [
|
||||
"//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/apiserver: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",
|
||||
|
@ -39,7 +39,8 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
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/crdserverscheme"
|
||||
"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"}
|
||||
|
||||
labelSelectorPath := ".status.labelSelector"
|
||||
scale := &apiextensions.CustomResourceSubresourceScale{
|
||||
scale := &apiextensionsinternal.CustomResourceSubresourceScale{
|
||||
SpecReplicasPath: ".spec.replicas",
|
||||
StatusReplicasPath: ".status.replicas",
|
||||
LabelSelectorPath: &labelSelectorPath,
|
||||
}
|
||||
|
||||
status := &apiextensions.CustomResourceSubresourceStatus{}
|
||||
status := &apiextensionsinternal.CustomResourceSubresourceStatus{}
|
||||
|
||||
headers := []apiextensions.CustomResourceColumnDefinition{
|
||||
headers := []apiextensionsv1.CustomResourceColumnDefinition{
|
||||
{Name: "Age", Type: "date", JSONPath: ".metadata.creationTimestamp"},
|
||||
{Name: "Replicas", Type: "integer", JSONPath: ".spec.replicas"},
|
||||
{Name: "Missing", Type: "string", JSONPath: ".spec.missing"},
|
||||
|
@ -7,7 +7,7 @@ go_library(
|
||||
importpath = "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor",
|
||||
visibility = ["//visibility:public"],
|
||||
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/table:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metatable "k8s.io/apimachinery/pkg/api/meta/table"
|
||||
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,
|
||||
// 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{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
|
||||
}
|
||||
|
@ -776,7 +776,7 @@ spec:
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -845,7 +845,7 @@ spec:
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -926,12 +926,12 @@ x-kubernetes-embedded-resource: true
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
`,
|
||||
expectedViolations: []string{},
|
||||
},
|
||||
@ -972,7 +972,7 @@ x-kubernetes-preserve-unknown-fields: true
|
||||
type: ""
|
||||
`,
|
||||
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"
|
||||
`,
|
||||
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: `
|
||||
type: object
|
||||
properties:
|
||||
foo:
|
||||
type: string
|
||||
foo:
|
||||
type: string
|
||||
not:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
allOf:
|
||||
- properties:
|
||||
foo:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
foo:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
anyOf:
|
||||
- items:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
oneOf:
|
||||
- properties:
|
||||
foo:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
foo:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
title: hello
|
||||
description: world
|
||||
nullable: true
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.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.validation.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.validation.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.validation.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.validation.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.validation.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.validation.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.validation.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.validation.openAPIV3Schema.not.additionalProperties: Forbidden: must be undefined to be structural",
|
||||
"spec.validation.openAPIV3Schema.not.title: Forbidden: must be empty to be structural",
|
||||
"spec.validation.openAPIV3Schema.not.description: Forbidden: must be empty to be structural",
|
||||
"spec.validation.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.anyOf[0].items.type: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.additionalProperties: Forbidden: must be undefined to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.title: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.description: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.anyOf[0].items.nullable: Forbidden: must be false to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].title: 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.versions[0].schema.openAPIV3Schema.allOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].type: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].additionalProperties: Forbidden: must be undefined to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].title: 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.versions[0].schema.openAPIV3Schema.oneOf[0].properties[foo].nullable: Forbidden: must be false to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.type: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.additionalProperties: Forbidden: must be undefined to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.title: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.description: Forbidden: must be empty to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.nullable: Forbidden: must be false to be structural",
|
||||
"spec.versions[0].schema.openAPIV3Schema.items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.anyOf[0].items",
|
||||
},
|
||||
unexpectedViolations: []string{
|
||||
"spec.validation.openAPIV3Schema.not.default",
|
||||
"spec.versions[0].schema.openAPIV3Schema.not.default",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -1053,12 +1053,12 @@ oneOf:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
foo:
|
||||
type: string
|
||||
pattern: "+"
|
||||
foo:
|
||||
type: string
|
||||
pattern: "+"
|
||||
`,
|
||||
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: `
|
||||
type: object
|
||||
properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
not:
|
||||
properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
allOf:
|
||||
- properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
anyOf:
|
||||
- properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
oneOf:
|
||||
- properties:
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
embedded-resource:
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
`,
|
||||
expectedCreateErrors: []string{
|
||||
"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",
|
||||
globalSchema: `
|
||||
properties:
|
||||
foo:
|
||||
properties:
|
||||
a: {}
|
||||
bar:
|
||||
items:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a: {}
|
||||
items: {}
|
||||
abc:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a:
|
||||
items:
|
||||
additionalProperties:
|
||||
items:
|
||||
json:
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
a: {}
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
properties:
|
||||
a: {}
|
||||
foo:
|
||||
properties:
|
||||
a: {}
|
||||
bar:
|
||||
items:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a: {}
|
||||
items: {}
|
||||
abc:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a:
|
||||
items:
|
||||
additionalProperties:
|
||||
items:
|
||||
json:
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
a: {}
|
||||
int-or-string:
|
||||
x-kubernetes-int-or-string: true
|
||||
properties:
|
||||
a: {}
|
||||
`,
|
||||
expectedCreateErrors: []string{
|
||||
"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",
|
||||
globalSchema: `
|
||||
properties:
|
||||
foo:
|
||||
properties:
|
||||
a: {}
|
||||
bar:
|
||||
items:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a: {}
|
||||
items: {}
|
||||
abc:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a:
|
||||
items:
|
||||
additionalProperties:
|
||||
items:
|
||||
foo:
|
||||
properties:
|
||||
a: {}
|
||||
bar:
|
||||
items:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a: {}
|
||||
items: {}
|
||||
abc:
|
||||
additionalProperties:
|
||||
properties:
|
||||
a:
|
||||
items:
|
||||
additionalProperties:
|
||||
items:
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.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.validation.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.validation.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.validation.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.validation.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.validation.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.validation.openAPIV3Schema.type: Required value: must not be empty at the root",
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[foo].properties[a].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.versions[0].schema.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.type: Required value: must not be empty for specified array items",
|
||||
"spec.versions[0].schema.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.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.versions[0].schema.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.properties[a].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.versions[0].schema.openAPIV3Schema.properties[bar].items.type: Required value: must not be empty for specified array items",
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[bar].type: Required value: must not be empty for specified object fields",
|
||||
"spec.versions[0].schema.openAPIV3Schema.type: Required value: must not be empty at the root",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -1205,48 +1205,48 @@ properties:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
x-kubernetes-int-or-string: true
|
||||
b:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
allOf:
|
||||
- pattern: abc
|
||||
c:
|
||||
x-kubernetes-int-or-string: true
|
||||
allOf:
|
||||
- anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- pattern: abc
|
||||
- pattern: abc
|
||||
d:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: abc
|
||||
e:
|
||||
x-kubernetes-int-or-string: true
|
||||
allOf:
|
||||
- anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: abc
|
||||
- pattern: abc
|
||||
f:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- pattern: abc
|
||||
g:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: integer
|
||||
a:
|
||||
x-kubernetes-int-or-string: true
|
||||
b:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
allOf:
|
||||
- pattern: abc
|
||||
c:
|
||||
x-kubernetes-int-or-string: true
|
||||
allOf:
|
||||
- anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- pattern: abc
|
||||
- pattern: abc
|
||||
d:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: abc
|
||||
e:
|
||||
x-kubernetes-int-or-string: true
|
||||
allOf:
|
||||
- anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: abc
|
||||
- pattern: abc
|
||||
f:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- pattern: abc
|
||||
g:
|
||||
x-kubernetes-int-or-string: true
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: integer
|
||||
`,
|
||||
expectedCreateErrors: []string{
|
||||
"spec.validation.openAPIV3Schema.properties[d].anyOf[0].type: Forbidden: must be empty to be structural",
|
||||
@ -1271,7 +1271,7 @@ type: object
|
||||
additionalProperties: false
|
||||
`,
|
||||
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: `
|
||||
type: object
|
||||
properties:
|
||||
b:
|
||||
type: object
|
||||
properties:
|
||||
b:
|
||||
type: array
|
||||
c:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
d:
|
||||
type: array
|
||||
b:
|
||||
type: object
|
||||
properties:
|
||||
b:
|
||||
type: array
|
||||
c:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
d:
|
||||
type: array
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
items: {}
|
||||
c:
|
||||
items:
|
||||
not:
|
||||
items:
|
||||
properties:
|
||||
a: {}
|
||||
d:
|
||||
items: {}
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
items: {}
|
||||
c:
|
||||
items:
|
||||
not:
|
||||
items:
|
||||
properties:
|
||||
a: {}
|
||||
d:
|
||||
items: {}
|
||||
allOf:
|
||||
- properties:
|
||||
e: {}
|
||||
e: {}
|
||||
anyOf:
|
||||
- properties:
|
||||
f: {}
|
||||
f: {}
|
||||
oneOf:
|
||||
- properties:
|
||||
g: {}
|
||||
g: {}
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.openAPIV3Schema.properties[d].items: Required value: because it is defined in spec.validation.openAPIV3Schema.not.properties[d].items",
|
||||
"spec.validation.openAPIV3Schema.properties[a]: Required value: because it is defined in spec.validation.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.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.validation.openAPIV3Schema.properties[c].items.items: Required value: because it is defined in spec.validation.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.validation.openAPIV3Schema.properties[f]: Required value: because it is defined in spec.validation.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[d].items: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.not.properties[d].items",
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[a]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.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.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.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.versions[0].schema.openAPIV3Schema.properties[e]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.allOf[0].properties[e]",
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[f]: Required value: because it is defined in spec.versions[0].schema.openAPIV3Schema.anyOf[0].properties[f]",
|
||||
"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: `
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
b:
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
b:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
c:
|
||||
type: array
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
d:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
e:
|
||||
type: string
|
||||
f:
|
||||
type: string
|
||||
g:
|
||||
type: string
|
||||
a:
|
||||
type: string
|
||||
b:
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
b:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
c:
|
||||
type: array
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
d:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
e:
|
||||
type: string
|
||||
f:
|
||||
type: string
|
||||
g:
|
||||
type: string
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
items: {}
|
||||
c:
|
||||
items:
|
||||
not:
|
||||
items:
|
||||
properties:
|
||||
a: {}
|
||||
d:
|
||||
items: {}
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
not:
|
||||
properties:
|
||||
a: {}
|
||||
b:
|
||||
items: {}
|
||||
c:
|
||||
items:
|
||||
not:
|
||||
items:
|
||||
properties:
|
||||
a: {}
|
||||
d:
|
||||
items: {}
|
||||
allOf:
|
||||
- properties:
|
||||
e: {}
|
||||
e: {}
|
||||
anyOf:
|
||||
- properties:
|
||||
f: {}
|
||||
f: {}
|
||||
oneOf:
|
||||
- properties:
|
||||
g: {}
|
||||
g: {}
|
||||
`,
|
||||
expectedViolations: nil,
|
||||
},
|
||||
@ -1397,16 +1397,16 @@ oneOf:
|
||||
v1beta1Schema: `
|
||||
type: object
|
||||
properties:
|
||||
a: {}
|
||||
a: {}
|
||||
not:
|
||||
properties:
|
||||
b: {}
|
||||
properties:
|
||||
b: {}
|
||||
`,
|
||||
v1Schema: `
|
||||
type: object
|
||||
properties:
|
||||
a:
|
||||
type: string
|
||||
a:
|
||||
type: string
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
||||
@ -1418,18 +1418,18 @@ properties:
|
||||
v1beta1Schema: `
|
||||
type: object
|
||||
properties:
|
||||
a: {}
|
||||
a: {}
|
||||
not:
|
||||
properties:
|
||||
b: {}
|
||||
properties:
|
||||
b: {}
|
||||
`,
|
||||
v1Schema: `
|
||||
type: object
|
||||
properties:
|
||||
c: {}
|
||||
c: {}
|
||||
not:
|
||||
properties:
|
||||
d: {}
|
||||
properties:
|
||||
d: {}
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[a].type: Required value: must not be empty for specified object fields",
|
||||
@ -1443,12 +1443,12 @@ not:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
minimum: 42.0
|
||||
metadata:
|
||||
minimum: 42.0
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.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]: Forbidden: must not specify anything other than name and generateName, but metadata is implicitly specified",
|
||||
"spec.versions[0].schema.openAPIV3Schema.properties[metadata].type: Required value: must not be empty for specified object fields",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -1456,18 +1456,18 @@ properties:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
properties:
|
||||
name:
|
||||
pattern: "^[a-z]+$"
|
||||
labels:
|
||||
type: object
|
||||
maxLength: 4
|
||||
metadata:
|
||||
properties:
|
||||
name:
|
||||
pattern: "^[a-z]+$"
|
||||
labels:
|
||||
type: object
|
||||
maxLength: 4
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.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.validation.openAPIV3Schema.properties[metadata].properties[name].type: Required value: must not be empty for specified object fields",
|
||||
"spec.versions[0].schema.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].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: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
`,
|
||||
expectedViolations: []string{},
|
||||
},
|
||||
@ -1489,12 +1489,12 @@ properties:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
generateName:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
generateName:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
`,
|
||||
expectedViolations: []string{},
|
||||
},
|
||||
@ -1503,15 +1503,15 @@ properties:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
generateName:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
generateName:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
`,
|
||||
expectedViolations: []string{},
|
||||
},
|
||||
@ -1520,30 +1520,30 @@ properties:
|
||||
globalSchema: `
|
||||
type: object
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
metadata:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pattern: "^[a-z]+$"
|
||||
allOf:
|
||||
- properties:
|
||||
metadata: {}
|
||||
metadata: {}
|
||||
anyOf:
|
||||
- properties:
|
||||
metadata: {}
|
||||
metadata: {}
|
||||
oneOf:
|
||||
- properties:
|
||||
metadata: {}
|
||||
metadata: {}
|
||||
not:
|
||||
properties:
|
||||
metadata: {}
|
||||
properties:
|
||||
metadata: {}
|
||||
`,
|
||||
expectedViolations: []string{
|
||||
"spec.validation.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.validation.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.anyOf[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.versions[0].schema.openAPIV3Schema.oneOf[0].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: `
|
||||
type: object
|
||||
properties:
|
||||
slice:
|
||||
type: array
|
||||
slice:
|
||||
type: array
|
||||
`,
|
||||
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: `
|
||||
type: object
|
||||
properties:
|
||||
slice:
|
||||
type: array
|
||||
items:
|
||||
- type: string
|
||||
- type: integer
|
||||
slice:
|
||||
type: array
|
||||
items:
|
||||
- type: string
|
||||
- type: integer
|
||||
`,
|
||||
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: `
|
||||
type: object
|
||||
properties:
|
||||
slice:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
not:
|
||||
items:
|
||||
- type: string
|
||||
slice:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
not:
|
||||
items:
|
||||
- type: string
|
||||
`,
|
||||
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/typed/apiextensions/v1
|
||||
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/apiextensions
|
||||
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/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/v1beta1
|
||||
k8s.io/apiextensions-apiserver/pkg/cmd/server/options
|
||||
|
Loading…
Reference in New Issue
Block a user