Bypass the remap CRD version plugin when v1beta1 CRD is not supported

When velero is running on clusters that don't support v1beta1 CRD, the
plugin will not try to backup v1beta1 CRD.
The plugin should be kept for backward compatibility.  It will be
removed when velero drop the support for k8s v1.21

Signed-off-by: Daniel Jiang <jiangd@vmware.com>
pull/4686/head
Daniel Jiang 2022-02-22 18:15:28 +08:00
parent e08e4f380f
commit 0070138c62
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
}
}