mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #99800 from deads2k/beta-more
remove more CRD v1beta1 client dependencies from test integration
This commit is contained in:
commit
4fccba9e06
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 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 fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"go.etcd.io/etcd/clientv3"
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
|
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
"k8s.io/client-go/dynamic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateCRDUsingRemovedAPI creates a CRD directly using etcd. This is must *ONLY* be used for checks of compatibility
|
||||||
|
// with removed data. Do not use this just because you don't want to update your test to use v1. Only use this
|
||||||
|
// when it actually matters.
|
||||||
|
func CreateCRDUsingRemovedAPI(etcdClient *clientv3.Client, etcdStoragePrefix string, betaCRD *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, dynamicClientSet dynamic.Interface) (*apiextensionsv1.CustomResourceDefinition, error) {
|
||||||
|
// attempt defaulting, best effort
|
||||||
|
apiextensionsv1beta1.SetDefaults_CustomResourceDefinition(betaCRD)
|
||||||
|
betaCRD.Kind = "CustomResourceDefinition"
|
||||||
|
betaCRD.APIVersion = apiextensionsv1beta1.SchemeGroupVersion.Group + "/" + apiextensionsv1beta1.SchemeGroupVersion.Version
|
||||||
|
|
||||||
|
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceNone)
|
||||||
|
key := path.Join("/", etcdStoragePrefix, "apiextensions.k8s.io", "customresourcedefinitions", betaCRD.Name)
|
||||||
|
val, _ := json.Marshal(betaCRD)
|
||||||
|
if _, err := etcdClient.Put(ctx, key, string(val)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
crd, err := apiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), betaCRD.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return waitForCRDReady(crd, apiExtensionsClient, dynamicClientSet)
|
||||||
|
}
|
@ -24,7 +24,6 @@ import (
|
|||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
|
|
||||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
apiextensionsv1beta1 "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/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -246,19 +245,6 @@ func NewCurletInstance(namespace, name string) *unstructured.Unstructured {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func servedVersions(crd *apiextensionsv1beta1.CustomResourceDefinition) []string {
|
|
||||||
if len(crd.Spec.Versions) == 0 {
|
|
||||||
return []string{crd.Spec.Version}
|
|
||||||
}
|
|
||||||
var versions []string
|
|
||||||
for _, v := range crd.Spec.Versions {
|
|
||||||
if v.Served {
|
|
||||||
versions = append(versions, v.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return versions
|
|
||||||
}
|
|
||||||
|
|
||||||
func servedV1Versions(crd *apiextensionsv1.CustomResourceDefinition) []string {
|
func servedV1Versions(crd *apiextensionsv1.CustomResourceDefinition) []string {
|
||||||
if len(crd.Spec.Versions) == 0 {
|
if len(crd.Spec.Versions) == 0 {
|
||||||
return []string{}
|
return []string{}
|
||||||
@ -272,22 +258,6 @@ func servedV1Versions(crd *apiextensionsv1.CustomResourceDefinition) []string {
|
|||||||
return versions
|
return versions
|
||||||
}
|
}
|
||||||
|
|
||||||
func existsInDiscovery(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, version string) (bool, error) {
|
|
||||||
groupResource, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version)
|
|
||||||
if err != nil {
|
|
||||||
if errors.IsNotFound(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
for _, g := range groupResource.APIResources {
|
|
||||||
if g.Name == crd.Spec.Names.Plural {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func existsInDiscoveryV1(crd *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, version string) (bool, error) {
|
func existsInDiscoveryV1(crd *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, version string) (bool, error) {
|
||||||
groupResource, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version)
|
groupResource, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -304,37 +274,27 @@ func existsInDiscoveryV1(crd *apiextensionsv1.CustomResourceDefinition, apiExten
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNewCustomResourceDefinitionWatchUnsafe creates the CRD and makes sure
|
// waitForCRDReadyWatchUnsafe creates the CRD and makes sure
|
||||||
// the apiextension apiserver has installed the CRD. But it's not safe to watch
|
// the apiextension apiserver has installed the CRD. But it's not safe to watch
|
||||||
// the created CR. Please call CreateNewCustomResourceDefinition if you need to
|
// the created CR. Please call CreateCRDUsingRemovedAPI if you need to
|
||||||
// watch the CR.
|
// watch the CR.
|
||||||
func CreateNewCustomResourceDefinitionWatchUnsafe(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1beta1.CustomResourceDefinition, error) {
|
func waitForCRDReadyWatchUnsafe(crd *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1.CustomResourceDefinition, error) {
|
||||||
crd, err := apiExtensionsClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait until all resources appears in discovery
|
// wait until all resources appears in discovery
|
||||||
for _, version := range servedVersions(crd) {
|
for _, version := range servedV1Versions(crd) {
|
||||||
err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
|
err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||||
return existsInDiscovery(crd, apiExtensionsClient, version)
|
return existsInDiscoveryV1(crd, apiExtensionsClient, version)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return crd, err
|
return crd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNewCustomResourceDefinition creates the given CRD and makes sure its watch cache is primed on the server.
|
// waitForCRDReady creates the given CRD and makes sure its watch cache is primed on the server.
|
||||||
func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, dynamicClientSet dynamic.Interface) (*apiextensionsv1beta1.CustomResourceDefinition, error) {
|
func waitForCRDReady(crd *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, dynamicClientSet dynamic.Interface) (*apiextensionsv1.CustomResourceDefinition, error) {
|
||||||
crd, err := CreateNewCustomResourceDefinitionWatchUnsafe(crd, apiExtensionsClient)
|
v1CRD, err := waitForCRDReadyWatchUnsafe(crd, apiExtensionsClient)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v1CRD, err := apiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), crd.Name, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -355,7 +315,7 @@ func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceD
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return crd, nil
|
return v1CRD, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNewV1CustomResourceDefinitionWatchUnsafe creates the CRD and makes sure
|
// CreateNewV1CustomResourceDefinitionWatchUnsafe creates the CRD and makes sure
|
||||||
@ -419,7 +379,7 @@ func resourceClientForVersion(crd *apiextensionsv1.CustomResourceDefinition, dyn
|
|||||||
func isWatchCachePrimed(crd *apiextensionsv1.CustomResourceDefinition, dynamicClientSet dynamic.Interface) (bool, error) {
|
func isWatchCachePrimed(crd *apiextensionsv1.CustomResourceDefinition, dynamicClientSet dynamic.Interface) (bool, error) {
|
||||||
ns := ""
|
ns := ""
|
||||||
if crd.Spec.Scope != apiextensionsv1.ClusterScoped {
|
if crd.Spec.Scope != apiextensionsv1.ClusterScoped {
|
||||||
ns = "aval"
|
ns = "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
versions := servedV1Versions(crd)
|
versions := servedV1Versions(crd)
|
||||||
|
@ -19,7 +19,6 @@ package integration
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -30,10 +29,8 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apimachinery/pkg/util/yaml"
|
"k8s.io/apimachinery/pkg/util/yaml"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
|
||||||
|
|
||||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
@ -871,7 +868,7 @@ func TestForbiddenFieldsInSchema(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNonStructuralSchemaConditionUpdate(t *testing.T) {
|
func TestNonStructuralSchemaConditionUpdate(t *testing.T) {
|
||||||
tearDown, apiExtensionClient, _, etcdclient, etcdStoragePrefix, err := fixtures.StartDefaultServerWithClientsAndEtcd(t)
|
tearDown, apiExtensionClient, dynamicClient, etcdclient, etcdStoragePrefix, err := fixtures.StartDefaultServerWithClientsAndEtcd(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -922,11 +919,8 @@ spec:
|
|||||||
|
|
||||||
// create CRDs. We cannot create these in v1, but they can exist in upgraded clusters
|
// create CRDs. We cannot create these in v1, but they can exist in upgraded clusters
|
||||||
t.Logf("Creating CRD %s", betaCRD.Name)
|
t.Logf("Creating CRD %s", betaCRD.Name)
|
||||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceNone)
|
if _, err := fixtures.CreateCRDUsingRemovedAPI(etcdclient, etcdStoragePrefix, betaCRD, apiExtensionClient, dynamicClient); err != nil {
|
||||||
key := path.Join("/", etcdStoragePrefix, "apiextensions.k8s.io", "customresourcedefinitions/foos.tests.example.com")
|
t.Fatal(err)
|
||||||
val, _ := json.Marshal(betaCRD)
|
|
||||||
if _, err := etcdclient.Put(ctx, key, string(val)); err != nil {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for condition with violations
|
// wait for condition with violations
|
||||||
|
@ -62,7 +62,7 @@ func TestInternalVersionIsHandlerVersion(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update validation via update because the cache priming in CreateNewCustomResourceDefinition will fail otherwise
|
// update validation via update because the cache priming in CreateCRDUsingRemovedAPI will fail otherwise
|
||||||
t.Logf("Updating CRD to validate apiVersion")
|
t.Logf("Updating CRD to validate apiVersion")
|
||||||
noxuDefinition, err = UpdateCustomResourceDefinitionWithRetry(apiExtensionClient, noxuDefinition.Name, func(crd *apiextensionsv1.CustomResourceDefinition) {
|
noxuDefinition, err = UpdateCustomResourceDefinitionWithRetry(apiExtensionClient, noxuDefinition.Name, func(crd *apiextensionsv1.CustomResourceDefinition) {
|
||||||
for i := range crd.Spec.Versions {
|
for i := range crd.Spec.Versions {
|
||||||
|
@ -58,15 +58,15 @@ func TestApplyCRDNoSchema(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
noxuDefinition := nearlyRemovedBetaMultipleVersionNoxuCRD(apiextensionsv1beta1.ClusterScoped)
|
noxuBetaDefinition := nearlyRemovedBetaMultipleVersionNoxuCRD(apiextensionsv1beta1.ClusterScoped)
|
||||||
|
|
||||||
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
noxuDefinition, err := fixtures.CreateCRDUsingRemovedAPI(server.EtcdClient, server.EtcdStoragePrefix, noxuBetaDefinition, apiExtensionClient, dynamicClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
kind := noxuDefinition.Spec.Names.Kind
|
kind := noxuDefinition.Spec.Names.Kind
|
||||||
apiVersion := noxuDefinition.Spec.Group + "/" + noxuDefinition.Spec.Version
|
apiVersion := noxuDefinition.Spec.Group + "/" + noxuDefinition.Spec.Versions[0].Name
|
||||||
name := "mytest"
|
name := "mytest"
|
||||||
|
|
||||||
rest := apiExtensionClient.Discovery().RESTClient()
|
rest := apiExtensionClient.Discovery().RESTClient()
|
||||||
@ -78,7 +78,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
replicas: 1`, apiVersion, kind, name))
|
replicas: 1`, apiVersion, kind, name))
|
||||||
result, err := rest.Patch(types.ApplyPatchType).
|
result, err := rest.Patch(types.ApplyPatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
Name(name).
|
Name(name).
|
||||||
Param("fieldManager", "apply_test").
|
Param("fieldManager", "apply_test").
|
||||||
Body(yamlBody).
|
Body(yamlBody).
|
||||||
@ -90,7 +90,7 @@ spec:
|
|||||||
|
|
||||||
// Patch object to change the number of replicas
|
// Patch object to change the number of replicas
|
||||||
result, err = rest.Patch(types.MergePatchType).
|
result, err = rest.Patch(types.MergePatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
Name(name).
|
Name(name).
|
||||||
Body([]byte(`{"spec":{"replicas": 5}}`)).
|
Body([]byte(`{"spec":{"replicas": 5}}`)).
|
||||||
DoRaw(context.TODO())
|
DoRaw(context.TODO())
|
||||||
@ -101,7 +101,7 @@ spec:
|
|||||||
|
|
||||||
// Re-apply, we should get conflicts now, since the number of replicas was changed.
|
// Re-apply, we should get conflicts now, since the number of replicas was changed.
|
||||||
result, err = rest.Patch(types.ApplyPatchType).
|
result, err = rest.Patch(types.ApplyPatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
Name(name).
|
Name(name).
|
||||||
Param("fieldManager", "apply_test").
|
Param("fieldManager", "apply_test").
|
||||||
Body(yamlBody).
|
Body(yamlBody).
|
||||||
@ -119,7 +119,7 @@ spec:
|
|||||||
|
|
||||||
// Re-apply with force, should work fine.
|
// Re-apply with force, should work fine.
|
||||||
result, err = rest.Patch(types.ApplyPatchType).
|
result, err = rest.Patch(types.ApplyPatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
Name(name).
|
Name(name).
|
||||||
Param("force", "true").
|
Param("force", "true").
|
||||||
Param("fieldManager", "apply_test").
|
Param("fieldManager", "apply_test").
|
||||||
@ -157,7 +157,7 @@ spec:
|
|||||||
}
|
}
|
||||||
}`)
|
}`)
|
||||||
result, err = rest.Patch(types.MergePatchType).
|
result, err = rest.Patch(types.MergePatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
SubResource("status").
|
SubResource("status").
|
||||||
Name(name).
|
Name(name).
|
||||||
Param("fieldManager", "subresource_test").
|
Param("fieldManager", "subresource_test").
|
||||||
@ -176,7 +176,7 @@ spec:
|
|||||||
|
|
||||||
// However, it is possible to modify managed fields using the main resource
|
// However, it is possible to modify managed fields using the main resource
|
||||||
result, err = rest.Patch(types.MergePatchType).
|
result, err = rest.Patch(types.MergePatchType).
|
||||||
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural).
|
AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Versions[0].Name, noxuDefinition.Spec.Names.Plural).
|
||||||
Name(name).
|
Name(name).
|
||||||
Param("fieldManager", "subresource_test").
|
Param("fieldManager", "subresource_test").
|
||||||
Body([]byte(`{"metadata":{"managedFields":[{}]}}`)).
|
Body([]byte(`{"metadata":{"managedFields":[{}]}}`)).
|
||||||
|
@ -22,9 +22,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||||
|
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/api/policy/v1beta1"
|
"k8s.io/api/policy/v1beta1"
|
||||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
|
||||||
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
@ -105,7 +108,7 @@ func TestPDBWithScaleSubresource(t *testing.T) {
|
|||||||
|
|
||||||
crdDefinition := newCustomResourceDefinition()
|
crdDefinition := newCustomResourceDefinition()
|
||||||
etcd.CreateTestCRDs(t, apiExtensionClient, true, crdDefinition)
|
etcd.CreateTestCRDs(t, apiExtensionClient, true, crdDefinition)
|
||||||
gvr := schema.GroupVersionResource{Group: crdDefinition.Spec.Group, Version: crdDefinition.Spec.Version, Resource: crdDefinition.Spec.Names.Plural}
|
gvr := schema.GroupVersionResource{Group: crdDefinition.Spec.Group, Version: crdDefinition.Spec.Versions[0].Name, Resource: crdDefinition.Spec.Names.Plural}
|
||||||
resourceClient := dynamicClient.Resource(gvr).Namespace(nsName)
|
resourceClient := dynamicClient.Resource(gvr).Namespace(nsName)
|
||||||
|
|
||||||
replicas := 4
|
replicas := 4
|
||||||
@ -115,7 +118,7 @@ func TestPDBWithScaleSubresource(t *testing.T) {
|
|||||||
resource := &unstructured.Unstructured{
|
resource := &unstructured.Unstructured{
|
||||||
Object: map[string]interface{}{
|
Object: map[string]interface{}{
|
||||||
"kind": crdDefinition.Spec.Names.Kind,
|
"kind": crdDefinition.Spec.Names.Kind,
|
||||||
"apiVersion": crdDefinition.Spec.Group + "/" + crdDefinition.Spec.Version,
|
"apiVersion": crdDefinition.Spec.Group + "/" + crdDefinition.Spec.Versions[0].Name,
|
||||||
"metadata": map[string]interface{}{
|
"metadata": map[string]interface{}{
|
||||||
"name": "resource",
|
"name": "resource",
|
||||||
"namespace": nsName,
|
"namespace": nsName,
|
||||||
@ -134,7 +137,7 @@ func TestPDBWithScaleSubresource(t *testing.T) {
|
|||||||
ownerRef := metav1.OwnerReference{
|
ownerRef := metav1.OwnerReference{
|
||||||
Name: resource.GetName(),
|
Name: resource.GetName(),
|
||||||
Kind: crdDefinition.Spec.Names.Kind,
|
Kind: crdDefinition.Spec.Names.Kind,
|
||||||
APIVersion: crdDefinition.Spec.Group + "/" + crdDefinition.Spec.Version,
|
APIVersion: crdDefinition.Spec.Group + "/" + crdDefinition.Spec.Versions[0].Name,
|
||||||
UID: createdResource.GetUID(),
|
UID: createdResource.GetUID(),
|
||||||
Controller: &trueValue,
|
Controller: &trueValue,
|
||||||
}
|
}
|
||||||
@ -232,23 +235,30 @@ func addPodConditionReady(pod *v1.Pod) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCustomResourceDefinition() *apiextensionsv1beta1.CustomResourceDefinition {
|
func newCustomResourceDefinition() *apiextensionsv1.CustomResourceDefinition {
|
||||||
return &apiextensionsv1beta1.CustomResourceDefinition{
|
return &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "crds.mygroup.example.com"},
|
ObjectMeta: metav1.ObjectMeta{Name: "crds.mygroup.example.com"},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "mygroup.example.com",
|
Group: "mygroup.example.com",
|
||||||
Version: "v1beta1",
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "crds",
|
Plural: "crds",
|
||||||
Singular: "crd",
|
Singular: "crd",
|
||||||
Kind: "Crd",
|
Kind: "Crd",
|
||||||
ListKind: "CrdList",
|
ListKind: "CrdList",
|
||||||
},
|
},
|
||||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{
|
{
|
||||||
SpecReplicasPath: ".spec.replicas",
|
Name: "v1beta1",
|
||||||
StatusReplicasPath: ".status.replicas",
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
Subresources: &apiextensionsv1.CustomResourceSubresources{
|
||||||
|
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
|
||||||
|
SpecReplicasPath: ".spec.replicas",
|
||||||
|
StatusReplicasPath: ".status.replicas",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -17,11 +17,11 @@ limitations under the License.
|
|||||||
package etcd
|
package etcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/kubernetes/test/utils/image"
|
"k8s.io/kubernetes/test/utils/image"
|
||||||
"k8s.io/utils/pointer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetEtcdStorageData returns etcd data for all persisted objects.
|
// GetEtcdStorageData returns etcd data for all persisted objects.
|
||||||
@ -589,36 +589,61 @@ type Prerequisite struct {
|
|||||||
|
|
||||||
// GetCustomResourceDefinitionData returns the resource definitions that back the custom resources
|
// GetCustomResourceDefinitionData returns the resource definitions that back the custom resources
|
||||||
// included in GetEtcdStorageData. They should be created using CreateTestCRDs before running any tests.
|
// included in GetEtcdStorageData. They should be created using CreateTestCRDs before running any tests.
|
||||||
func GetCustomResourceDefinitionData() []*apiextensionsv1beta1.CustomResourceDefinition {
|
// We can switch this to v1 CRDs based on transitive call site analysis.
|
||||||
return []*apiextensionsv1beta1.CustomResourceDefinition{
|
// Call sites:
|
||||||
// namespaced with legacy version field
|
// 1. TestDedupOwnerReferences - beta doesn't matter
|
||||||
|
// 2. TestWebhookAdmissionWithWatchCache/TestWebhookAdmissionWithoutWatchCache - beta doesn't matter
|
||||||
|
// 3. TestApplyStatus - the version fields don't matter. Pruning isn't checked, just ownership.
|
||||||
|
// 4. TestDryRun - versions and pruning don't matter
|
||||||
|
// 5. TestStorageVersionBootstrap - versions and pruning don't matter.
|
||||||
|
// 6. TestEtcdStoragePath - beta doesn't matter
|
||||||
|
// 7. TestCrossGroupStorage - beta doesn't matter
|
||||||
|
// 8. TestOverlappingCustomResourceCustomResourceDefinition - beta doesn't matter
|
||||||
|
// 9. TestOverlappingCustomResourceAPIService - beta doesn't matter
|
||||||
|
func GetCustomResourceDefinitionData() []*apiextensionsv1.CustomResourceDefinition {
|
||||||
|
return []*apiextensionsv1.CustomResourceDefinition{
|
||||||
|
// namespaced
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foos.cr.bar.com",
|
Name: "foos.cr.bar.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "cr.bar.com",
|
Group: "cr.bar.com",
|
||||||
Version: "v1",
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
},
|
},
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: "v1",
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// cluster scoped with legacy version field
|
// cluster scoped
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pants.custom.fancy.com",
|
Name: "pants.custom.fancy.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "custom.fancy.com",
|
Group: "custom.fancy.com",
|
||||||
Version: "v2",
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "pants",
|
Plural: "pants",
|
||||||
Kind: "Pant",
|
Kind: "Pant",
|
||||||
},
|
},
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: "v2",
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// cluster scoped with legacy version field and pruning.
|
// cluster scoped with legacy version field and pruning.
|
||||||
@ -626,25 +651,29 @@ func GetCustomResourceDefinitionData() []*apiextensionsv1beta1.CustomResourceDef
|
|||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "integers.random.numbers.com",
|
Name: "integers.random.numbers.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "random.numbers.com",
|
Group: "random.numbers.com",
|
||||||
Version: "v1",
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "integers",
|
Plural: "integers",
|
||||||
Kind: "Integer",
|
Kind: "Integer",
|
||||||
},
|
},
|
||||||
Validation: &apiextensionsv1beta1.CustomResourceValidation{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
{
|
||||||
Type: "object",
|
Name: "v1",
|
||||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
Served: true,
|
||||||
"value": {
|
Storage: true,
|
||||||
Type: "number",
|
Schema: &apiextensionsv1.CustomResourceValidation{
|
||||||
},
|
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
|
||||||
},
|
Type: "object",
|
||||||
|
Properties: map[string]apiextensionsv1.JSONSchemaProps{
|
||||||
|
"value": {
|
||||||
|
Type: "number",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreserveUnknownFields: pointer.BoolPtr(false),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// cluster scoped with versions field
|
// cluster scoped with versions field
|
||||||
@ -652,38 +681,57 @@ func GetCustomResourceDefinitionData() []*apiextensionsv1beta1.CustomResourceDef
|
|||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pandas.awesome.bears.com",
|
Name: "pandas.awesome.bears.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "awesome.bears.com",
|
Group: "awesome.bears.com",
|
||||||
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
{
|
{
|
||||||
Name: "v1",
|
Name: "v1",
|
||||||
Served: true,
|
Served: true,
|
||||||
Storage: true,
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
Subresources: &apiextensionsv1.CustomResourceSubresources{
|
||||||
|
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
|
||||||
|
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
|
||||||
|
SpecReplicasPath: ".spec.replicas",
|
||||||
|
StatusReplicasPath: ".status.replicas",
|
||||||
|
LabelSelectorPath: func() *string { path := ".status.selector"; return &path }(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "v2",
|
Name: "v2",
|
||||||
Served: false,
|
Served: false,
|
||||||
Storage: false,
|
Storage: false,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
Subresources: &apiextensionsv1.CustomResourceSubresources{
|
||||||
|
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
|
||||||
|
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
|
||||||
|
SpecReplicasPath: ".spec.replicas",
|
||||||
|
StatusReplicasPath: ".status.replicas",
|
||||||
|
LabelSelectorPath: func() *string { path := ".status.selector"; return &path }(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "v3",
|
Name: "v3",
|
||||||
Served: true,
|
Served: true,
|
||||||
Storage: false,
|
Storage: false,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
Subresources: &apiextensionsv1.CustomResourceSubresources{
|
||||||
|
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
|
||||||
|
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
|
||||||
|
SpecReplicasPath: ".spec.replicas",
|
||||||
|
StatusReplicasPath: ".status.replicas",
|
||||||
|
LabelSelectorPath: func() *string { path := ".status.selector"; return &path }(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Plural: "pandas",
|
Plural: "pandas",
|
||||||
Kind: "Panda",
|
Kind: "Panda",
|
||||||
},
|
},
|
||||||
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
|
|
||||||
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
|
|
||||||
Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{
|
|
||||||
SpecReplicasPath: ".spec.replicas",
|
|
||||||
StatusReplicasPath: ".status.replicas",
|
|
||||||
LabelSelectorPath: func() *string { path := ".status.selector"; return &path }(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
"go.etcd.io/etcd/clientv3"
|
"go.etcd.io/etcd/clientv3"
|
||||||
"go.etcd.io/etcd/clientv3/concurrency"
|
"go.etcd.io/etcd/clientv3/concurrency"
|
||||||
|
|
||||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -303,14 +303,14 @@ func JSONToUnstructured(stub, namespace string, mapping *meta.RESTMapping, dynam
|
|||||||
// CreateTestCRDs creates the given CRDs, any failure causes the test to Fatal.
|
// CreateTestCRDs creates the given CRDs, any failure causes the test to Fatal.
|
||||||
// If skipCrdExistsInDiscovery is true, the CRDs are only checked for the Established condition via their Status.
|
// If skipCrdExistsInDiscovery is true, the CRDs are only checked for the Established condition via their Status.
|
||||||
// If skipCrdExistsInDiscovery is false, the CRDs are checked via discovery, see CrdExistsInDiscovery.
|
// If skipCrdExistsInDiscovery is false, the CRDs are checked via discovery, see CrdExistsInDiscovery.
|
||||||
func CreateTestCRDs(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crds ...*apiextensionsv1beta1.CustomResourceDefinition) {
|
func CreateTestCRDs(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crds ...*apiextensionsv1.CustomResourceDefinition) {
|
||||||
for _, crd := range crds {
|
for _, crd := range crds {
|
||||||
createTestCRD(t, client, skipCrdExistsInDiscovery, crd)
|
createTestCRD(t, client, skipCrdExistsInDiscovery, crd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestCRD(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crd *apiextensionsv1beta1.CustomResourceDefinition) {
|
func createTestCRD(t *testing.T, client apiextensionsclientset.Interface, skipCrdExistsInDiscovery bool, crd *apiextensionsv1.CustomResourceDefinition) {
|
||||||
if _, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{}); err != nil {
|
if _, err := client.ApiextensionsV1().CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{}); err != nil {
|
||||||
t.Fatalf("Failed to create %s CRD; %v", crd.Name, err)
|
t.Fatalf("Failed to create %s CRD; %v", crd.Name, err)
|
||||||
}
|
}
|
||||||
if skipCrdExistsInDiscovery {
|
if skipCrdExistsInDiscovery {
|
||||||
@ -328,14 +328,14 @@ func createTestCRD(t *testing.T, client apiextensionsclientset.Interface, skipCr
|
|||||||
|
|
||||||
func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error {
|
func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error {
|
||||||
return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
||||||
crd, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Get(context.TODO(), name, metav1.GetOptions{})
|
crd, err := client.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
for _, cond := range crd.Status.Conditions {
|
for _, cond := range crd.Status.Conditions {
|
||||||
switch cond.Type {
|
switch cond.Type {
|
||||||
case apiextensionsv1beta1.Established:
|
case apiextensionsv1.Established:
|
||||||
if cond.Status == apiextensionsv1beta1.ConditionTrue {
|
if cond.Status == apiextensionsv1.ConditionTrue {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,11 +345,8 @@ func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CrdExistsInDiscovery checks to see if the given CRD exists in discovery at all served versions.
|
// CrdExistsInDiscovery checks to see if the given CRD exists in discovery at all served versions.
|
||||||
func CrdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition) bool {
|
func CrdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1.CustomResourceDefinition) bool {
|
||||||
var versions []string
|
var versions []string
|
||||||
if len(crd.Spec.Version) != 0 {
|
|
||||||
versions = append(versions, crd.Spec.Version)
|
|
||||||
}
|
|
||||||
for _, v := range crd.Spec.Versions {
|
for _, v := range crd.Spec.Versions {
|
||||||
if v.Served {
|
if v.Served {
|
||||||
versions = append(versions, v.Name)
|
versions = append(versions, v.Name)
|
||||||
@ -363,7 +360,7 @@ func CrdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiexten
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func crdVersionExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition, version string) bool {
|
func crdVersionExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1.CustomResourceDefinition, version string) bool {
|
||||||
resourceList, err := client.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version)
|
resourceList, err := client.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
@ -226,7 +226,7 @@ func setupWithServer(t *testing.T, result *kubeapiservertesting.TestServer, work
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating extension clientset: %v", err)
|
t.Fatalf("error creating extension clientset: %v", err)
|
||||||
}
|
}
|
||||||
// CreateNewCustomResourceDefinition wants to use this namespace for verifying
|
// CreateCRDUsingRemovedAPI wants to use this namespace for verifying
|
||||||
// namespace-scoped CRD creation.
|
// namespace-scoped CRD creation.
|
||||||
createNamespaceOrDie("aval", clientSet, t)
|
createNamespaceOrDie("aval", clientSet, t)
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||||
|
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
@ -38,7 +42,6 @@ import (
|
|||||||
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
||||||
"k8s.io/kubernetes/test/integration/etcd"
|
"k8s.io/kubernetes/test/integration/etcd"
|
||||||
"k8s.io/kubernetes/test/integration/framework"
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
utilpointer "k8s.io/utils/pointer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCRDShadowGroup(t *testing.T) {
|
func TestCRDShadowGroup(t *testing.T) {
|
||||||
@ -72,18 +75,26 @@ func TestCRDShadowGroup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Trying to shadow networking group")
|
t.Logf("Trying to shadow networking group")
|
||||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foos." + networkingv1.GroupName,
|
Name: "foos." + networkingv1.GroupName,
|
||||||
|
Annotations: map[string]string{"api-approved.kubernetes.io": "unapproved, test-only"},
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: networkingv1.GroupName,
|
Group: networkingv1.GroupName,
|
||||||
Version: networkingv1.SchemeGroupVersion.Version,
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
},
|
},
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: networkingv1.SchemeGroupVersion.Version,
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
etcd.CreateTestCRDs(t, apiextensionsclient, true, crd)
|
etcd.CreateTestCRDs(t, apiextensionsclient, true, crd)
|
||||||
@ -122,18 +133,25 @@ func TestCRD(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Trying to create a custom resource without conflict")
|
t.Logf("Trying to create a custom resource without conflict")
|
||||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foos.cr.bar.com",
|
Name: "foos.cr.bar.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "cr.bar.com",
|
Group: "cr.bar.com",
|
||||||
Version: "v1",
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
},
|
},
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: networkingv1.SchemeGroupVersion.Version,
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
etcd.CreateTestCRDs(t, apiextensionsclient, false, crd)
|
etcd.CreateTestCRDs(t, apiextensionsclient, false, crd)
|
||||||
@ -161,9 +179,13 @@ func TestCRDOpenAPI(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
dynamicClient, err := dynamic.NewForConfig(result.ClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
t.Logf("Trying to create a CustomResourceDefinitions")
|
t.Logf("Trying to create a CustomResourceDefinitions")
|
||||||
nonStructuralCRD := &apiextensionsv1beta1.CustomResourceDefinition{
|
nonStructuralBetaCRD := &apiextensionsv1beta1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foos.nonstructural.cr.bar.com",
|
Name: "foos.nonstructural.cr.bar.com",
|
||||||
},
|
},
|
||||||
@ -185,30 +207,38 @@ func TestCRDOpenAPI(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
structuralCRD := &apiextensionsv1beta1.CustomResourceDefinition{
|
structuralCRD := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foos.structural.cr.bar.com",
|
Name: "foos.structural.cr.bar.com",
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "structural.cr.bar.com",
|
Group: "structural.cr.bar.com",
|
||||||
Version: "v1",
|
Scope: apiextensionsv1.NamespaceScoped,
|
||||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "foos",
|
Plural: "foos",
|
||||||
Kind: "Foo",
|
Kind: "Foo",
|
||||||
},
|
},
|
||||||
PreserveUnknownFields: utilpointer.BoolPtr(false),
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
Validation: &apiextensionsv1beta1.CustomResourceValidation{
|
{
|
||||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
Name: "v1",
|
||||||
Type: "object",
|
Served: true,
|
||||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
Storage: true,
|
||||||
"foo": {Type: "string"},
|
Schema: &apiextensionsv1.CustomResourceValidation{
|
||||||
|
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
|
||||||
|
Type: "object",
|
||||||
|
Properties: map[string]apiextensionsv1.JSONSchemaProps{
|
||||||
|
"foo": {Type: "string"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
etcd.CreateTestCRDs(t, apiextensionsclient, false, nonStructuralCRD)
|
nonStructuralCRD, err := fixtures.CreateCRDUsingRemovedAPI(result.EtcdClient, result.EtcdStoragePrefix, nonStructuralBetaCRD, apiextensionsclient, dynamicClient)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
etcd.CreateTestCRDs(t, apiextensionsclient, false, structuralCRD)
|
etcd.CreateTestCRDs(t, apiextensionsclient, false, structuralCRD)
|
||||||
|
|
||||||
getPublishedSchema := func(defName string) (*spec.Schema, error) {
|
getPublishedSchema := func(defName string) (*spec.Schema, error) {
|
||||||
@ -230,7 +260,7 @@ func TestCRDOpenAPI(t *testing.T) {
|
|||||||
return &d, nil
|
return &d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForSpec := func(crd *apiextensionsv1beta1.CustomResourceDefinition, expectedType string) {
|
waitForSpec := func(crd *apiextensionsv1.CustomResourceDefinition, expectedType string) {
|
||||||
t.Logf(`Waiting for {properties: {"foo": {"type":"%s"}}} to show up in schema`, expectedType)
|
t.Logf(`Waiting for {properties: {"foo": {"type":"%s"}}} to show up in schema`, expectedType)
|
||||||
lastMsg := ""
|
lastMsg := ""
|
||||||
if err := wait.PollImmediate(500*time.Millisecond, 10*time.Second, func() (bool, error) {
|
if err := wait.PollImmediate(500*time.Millisecond, 10*time.Second, func() (bool, error) {
|
||||||
@ -262,14 +292,14 @@ func TestCRDOpenAPI(t *testing.T) {
|
|||||||
|
|
||||||
t.Logf("Check that structural schema is published")
|
t.Logf("Check that structural schema is published")
|
||||||
waitForSpec(structuralCRD, "string")
|
waitForSpec(structuralCRD, "string")
|
||||||
structuralCRD, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(context.TODO(), structuralCRD.Name, metav1.GetOptions{})
|
structuralCRD, err = apiextensionsclient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), structuralCRD.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
prop := structuralCRD.Spec.Validation.OpenAPIV3Schema.Properties["foo"]
|
prop := structuralCRD.Spec.Versions[0].Schema.OpenAPIV3Schema.Properties["foo"]
|
||||||
prop.Type = "boolean"
|
prop.Type = "boolean"
|
||||||
structuralCRD.Spec.Validation.OpenAPIV3Schema.Properties["foo"] = prop
|
structuralCRD.Spec.Versions[0].Schema.OpenAPIV3Schema.Properties["foo"] = prop
|
||||||
if _, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Update(context.TODO(), structuralCRD, metav1.UpdateOptions{}); err != nil {
|
if _, err = apiextensionsclient.ApiextensionsV1().CustomResourceDefinitions().Update(context.TODO(), structuralCRD, metav1.UpdateOptions{}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
waitForSpec(structuralCRD, "boolean")
|
waitForSpec(structuralCRD, "boolean")
|
||||||
@ -287,10 +317,10 @@ func TestCRDOpenAPI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func crdDefinitionName(crd *apiextensionsv1beta1.CustomResourceDefinition) string {
|
func crdDefinitionName(crd *apiextensionsv1.CustomResourceDefinition) string {
|
||||||
sgmts := strings.Split(crd.Spec.Group, ".")
|
sgmts := strings.Split(crd.Spec.Group, ".")
|
||||||
reverse(sgmts)
|
reverse(sgmts)
|
||||||
return strings.Join(append(sgmts, crd.Spec.Version, crd.Spec.Names.Kind), ".")
|
return strings.Join(append(sgmts, crd.Spec.Versions[0].Name, crd.Spec.Names.Kind), ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
func reverse(s []string) {
|
func reverse(s []string) {
|
||||||
|
@ -28,6 +28,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||||
|
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
@ -204,26 +208,32 @@ func TestOpenAPIApiextensionsOverlapProtection(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a CRD that overlaps OpenAPI path with the CRD API
|
// Create a CRD that overlaps OpenAPI path with the CRD API
|
||||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "customresourcedefinitions.apiextensions.k8s.io",
|
Name: "customresourcedefinitions.apiextensions.k8s.io",
|
||||||
Annotations: map[string]string{"api-approved.kubernetes.io": "unapproved, test-only"},
|
Annotations: map[string]string{"api-approved.kubernetes.io": "unapproved, test-only"},
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "apiextensions.k8s.io",
|
Group: "apiextensions.k8s.io",
|
||||||
Version: "v1beta1",
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "customresourcedefinitions",
|
Plural: "customresourcedefinitions",
|
||||||
Singular: "customresourcedefinition",
|
Singular: "customresourcedefinition",
|
||||||
Kind: "CustomResourceDefinition",
|
Kind: "CustomResourceDefinition",
|
||||||
ListKind: "CustomResourceDefinitionList",
|
ListKind: "CustomResourceDefinitionList",
|
||||||
},
|
},
|
||||||
Validation: &apiextensionsv1beta1.CustomResourceValidation{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
{
|
||||||
Type: "object",
|
Name: "v1beta1",
|
||||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
Served: true,
|
||||||
testApiextensionsOverlapProbeString: {Type: "boolean"},
|
Storage: true,
|
||||||
|
Schema: &apiextensionsv1.CustomResourceValidation{
|
||||||
|
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
|
||||||
|
Type: "object",
|
||||||
|
Properties: map[string]apiextensionsv1.JSONSchemaProps{
|
||||||
|
testApiextensionsOverlapProbeString: {Type: "boolean"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -263,26 +273,32 @@ func TestOpenAPIApiextensionsOverlapProtection(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a CRD that overlaps OpenAPI definition with the CRD API
|
// Create a CRD that overlaps OpenAPI definition with the CRD API
|
||||||
crd = &apiextensionsv1beta1.CustomResourceDefinition{
|
crd = &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "customresourcedefinitions.apiextensions.apis.pkg.apiextensions-apiserver.k8s.io",
|
Name: "customresourcedefinitions.apiextensions.apis.pkg.apiextensions-apiserver.k8s.io",
|
||||||
Annotations: map[string]string{"api-approved.kubernetes.io": "unapproved, test-only"},
|
Annotations: map[string]string{"api-approved.kubernetes.io": "unapproved, test-only"},
|
||||||
},
|
},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: "apiextensions.apis.pkg.apiextensions-apiserver.k8s.io",
|
Group: "apiextensions.apis.pkg.apiextensions-apiserver.k8s.io",
|
||||||
Version: "v1beta1",
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: "customresourcedefinitions",
|
Plural: "customresourcedefinitions",
|
||||||
Singular: "customresourcedefinition",
|
Singular: "customresourcedefinition",
|
||||||
Kind: "CustomResourceDefinition",
|
Kind: "CustomResourceDefinition",
|
||||||
ListKind: "CustomResourceDefinitionList",
|
ListKind: "CustomResourceDefinitionList",
|
||||||
},
|
},
|
||||||
Validation: &apiextensionsv1beta1.CustomResourceValidation{
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
{
|
||||||
Type: "object",
|
Name: "v1beta1",
|
||||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
Served: true,
|
||||||
testApiextensionsOverlapProbeString: {Type: "boolean"},
|
Storage: true,
|
||||||
|
Schema: &apiextensionsv1.CustomResourceValidation{
|
||||||
|
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
|
||||||
|
Type: "object",
|
||||||
|
Properties: map[string]apiextensionsv1.JSONSchemaProps{
|
||||||
|
testApiextensionsOverlapProbeString: {Type: "boolean"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -319,18 +335,25 @@ func triggerSpecUpdateWithProbeCRD(t *testing.T, apiextensionsclient *apiextensi
|
|||||||
name := fmt.Sprintf("integration-test-%s-crd", suffix)
|
name := fmt.Sprintf("integration-test-%s-crd", suffix)
|
||||||
kind := fmt.Sprintf("Integration-test-%s-crd", suffix)
|
kind := fmt.Sprintf("Integration-test-%s-crd", suffix)
|
||||||
group := "probe.test.com"
|
group := "probe.test.com"
|
||||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: name + "s." + group},
|
ObjectMeta: metav1.ObjectMeta{Name: name + "s." + group},
|
||||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
Group: group,
|
Group: group,
|
||||||
Version: "v1",
|
Scope: apiextensionsv1.ClusterScoped,
|
||||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
|
||||||
Plural: name + "s",
|
Plural: name + "s",
|
||||||
Singular: name,
|
Singular: name,
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
ListKind: kind + "List",
|
ListKind: kind + "List",
|
||||||
},
|
},
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: "v1",
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
Schema: fixtures.AllowAllSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
etcd.CreateTestCRDs(t, apiextensionsclient, false, crd)
|
etcd.CreateTestCRDs(t, apiextensionsclient, false, crd)
|
||||||
|
@ -99,7 +99,7 @@ func TestApiserverMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make a request to a deprecated API to ensure there's at least one data point
|
// Make a request to a deprecated API to ensure there's at least one data point
|
||||||
if _, err := client.RbacV1beta1().Roles(metav1.NamespaceDefault).List(context.TODO(), metav1.ListOptions{}); err != nil {
|
if _, err := client.PolicyV1beta1().PodSecurityPolicies().List(context.TODO(), metav1.ListOptions{}); err != nil {
|
||||||
t.Fatalf("unexpected error getting rbac roles: %v", err)
|
t.Fatalf("unexpected error getting rbac roles: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ func testBuiltinResourceWrite(t *testing.T, cfg *rest.Config, shouldBlock bool)
|
|||||||
|
|
||||||
func testCRDWrite(t *testing.T, cfg *rest.Config, shouldBlock bool) {
|
func testCRDWrite(t *testing.T, cfg *rest.Config, shouldBlock bool) {
|
||||||
crdClient := apiextensionsclientset.NewForConfigOrDie(cfg)
|
crdClient := apiextensionsclientset.NewForConfigOrDie(cfg)
|
||||||
_, err := crdClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(context.TODO(), etcd.GetCustomResourceDefinitionData()[1], metav1.CreateOptions{})
|
_, err := crdClient.ApiextensionsV1().CustomResourceDefinitions().Create(context.TODO(), etcd.GetCustomResourceDefinitionData()[1], metav1.CreateOptions{})
|
||||||
assertBlocking("writes to CRD", t, err, shouldBlock)
|
assertBlocking("writes to CRD", t, err, shouldBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user