Merge pull request #4686 from reasonerjt/fix-4080

Bypass the remap CRD version plugin when v1beta1 CRD is not supported
pull/4705/head
Wenkai Yin(尹文开) 2022-02-28 10:57:52 +08:00 committed by GitHub
commit 8aaeed4411
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 10 deletions

View File

@ -0,0 +1 @@
Bypass the remap CRD version plugin when v1beta1 CRD is not supported

View File

@ -30,6 +30,8 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
velerodiscovery "github.com/vmware-tanzu/velero/pkg/discovery"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)
@ -37,13 +39,14 @@ import (
// RemapCRDVersionAction inspects CustomResourceDefinition and decides if it is a v1
// CRD that needs to be backed up as v1beta1.
type RemapCRDVersionAction struct {
logger logrus.FieldLogger
betaCRDClient apiextv1beta1client.CustomResourceDefinitionInterface
logger logrus.FieldLogger
betaCRDClient apiextv1beta1client.CustomResourceDefinitionInterface
discoveryHelper velerodiscovery.Helper
}
// NewRemapCRDVersionAction instantiates a new RemapCRDVersionAction plugin.
func NewRemapCRDVersionAction(logger logrus.FieldLogger, betaCRDClient apiextv1beta1client.CustomResourceDefinitionInterface) *RemapCRDVersionAction {
return &RemapCRDVersionAction{logger: logger, betaCRDClient: betaCRDClient}
func NewRemapCRDVersionAction(logger logrus.FieldLogger, betaCRDClient apiextv1beta1client.CustomResourceDefinitionInterface, discoveryHelper velerodiscovery.Helper) *RemapCRDVersionAction {
return &RemapCRDVersionAction{logger: logger, betaCRDClient: betaCRDClient, discoveryHelper: discoveryHelper}
}
// AppliesTo selects the resources the plugin should run against. In this case, CustomResourceDefinitions.
@ -68,7 +71,26 @@ func (a *RemapCRDVersionAction) Execute(item runtime.Unstructured, backup *v1.Ba
return item, nil, nil
}
// We've got a v1 CRD, so proceed.
// This plugin will exit if the CRD was installed via v1beta1 but the cluster does not support v1beta1 CRD
supportv1b1 := false
CheckVersion:
for _, g := range a.discoveryHelper.APIGroups() {
if g.Name == apiextv1.GroupName {
for _, v := range g.Versions {
if v.Version == apiextv1beta1.SchemeGroupVersion.Version {
supportv1b1 = true
break CheckVersion
}
}
}
}
if !supportv1b1 {
a.logger.Info("Exiting RemapCRDVersionAction, the cluster does not support v1beta1 CRD")
return item, nil, nil
}
// We've got a v1 CRD and the cluster supports v1beta1 CRD, so proceed.
var crd apiextv1.CustomResourceDefinition
// Do not use runtime.DefaultUnstructuredConverter.FromUnstructured here because it has a bug when converting integers/whole

View File

@ -32,6 +32,8 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
velerodiscovery "github.com/vmware-tanzu/velero/pkg/discovery"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
@ -48,8 +50,7 @@ func TestRemapCRDVersionAction(t *testing.T) {
c := b.Result()
_, err := betaClient.Create(context.TODO(), c, metav1.CreateOptions{})
require.NoError(t, err)
a := NewRemapCRDVersionAction(velerotest.NewLogger(), betaClient)
a := NewRemapCRDVersionAction(velerotest.NewLogger(), betaClient, fakeDiscoveryHelper())
t.Run("Test a v1 CRD without any Schema information", func(t *testing.T) {
b := builder.ForV1CustomResourceDefinition("test.velero.io")
@ -109,6 +110,33 @@ func TestRemapCRDVersionAction(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "apiextensions.k8s.io/v1beta1", item.UnstructuredContent()["apiVersion"])
})
t.Run("When the cluster only supports v1 CRD, v1 CRD will be returned even the input has Spec.PreserveUnknownFields set to true (issue 4080)", func(t *testing.T) {
a.discoveryHelper = &velerotest.FakeDiscoveryHelper{
APIGroupsList: []metav1.APIGroup{
{
Name: apiextv1.GroupName,
Versions: []metav1.GroupVersionForDiscovery{
{
Version: apiextv1.SchemeGroupVersion.Version,
},
},
},
},
}
b := builder.ForV1CustomResourceDefinition("test.velero.io")
b.PreserveUnknownFields(true)
c := b.Result()
obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&c)
require.NoError(t, err)
item, _, err := a.Execute(&unstructured.Unstructured{Object: obj}, backup)
require.NoError(t, err)
assert.Equal(t, "apiextensions.k8s.io/v1", item.UnstructuredContent()["apiVersion"])
// set it back to the default one
a.discoveryHelper = fakeDiscoveryHelper()
})
}
// TestRemapCRDVersionActionData tests the RemapCRDVersionAction plugin against actual CRD to confirm that the v1beta1 version is returned when the v1 version is passed in to the plugin.
@ -116,8 +144,7 @@ func TestRemapCRDVersionActionData(t *testing.T) {
backup := &v1.Backup{}
clientset := apiextfakes.NewSimpleClientset()
betaClient := clientset.ApiextensionsV1beta1().CustomResourceDefinitions()
a := NewRemapCRDVersionAction(velerotest.NewLogger(), betaClient)
a := NewRemapCRDVersionAction(velerotest.NewLogger(), betaClient, fakeDiscoveryHelper())
tests := []struct {
crd string
@ -192,3 +219,21 @@ func TestRemapCRDVersionActionData(t *testing.T) {
}
}
func fakeDiscoveryHelper() velerodiscovery.Helper {
return &velerotest.FakeDiscoveryHelper{
APIGroupsList: []metav1.APIGroup{
{
Name: apiextv1.GroupName,
Versions: []metav1.GroupVersionForDiscovery{
{
Version: apiextv1beta1.SchemeGroupVersion.Version,
},
{
Version: apiextv1.SchemeGroupVersion.Version,
},
},
},
},
}
}

View File

@ -110,7 +110,16 @@ func newRemapCRDVersionAction(f client.Factory) veleroplugin.HandlerInitializer
return nil, err
}
return backup.NewRemapCRDVersionAction(logger, client.ApiextensionsV1beta1().CustomResourceDefinitions()), nil
clientset, err := f.KubeClient()
if err != nil {
return nil, err
}
discoveryHelper, err := velerodiscovery.NewHelper(clientset.Discovery(), logger)
if err != nil {
return nil, err
}
return backup.NewRemapCRDVersionAction(logger, client.ApiextensionsV1beta1().CustomResourceDefinitions(), discoveryHelper), nil
}
}