diff --git a/pkg/apis/velero/v1/register.go b/pkg/apis/velero/v1/register.go index 13915293a..9b694f2b6 100644 --- a/pkg/apis/velero/v1/register.go +++ b/pkg/apis/velero/v1/register.go @@ -20,6 +20,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" ) // Resource gets a Velero GroupResource for a specified resource @@ -59,6 +60,18 @@ func CustomResources() map[string]typeInfo { } } +// CustomResourceKinds returns a list of all custom resources kinds within the Velero +func CustomResourceKinds() sets.String { + kinds := sets.NewString() + + resources := CustomResources() + for kind := range resources { + kinds.Insert(kind) + } + + return kinds +} + func addKnownTypes(scheme *runtime.Scheme) error { for _, typeInfo := range CustomResources() { scheme.AddKnownTypes(SchemeGroupVersion, typeInfo.ItemType, typeInfo.ItemListType) diff --git a/pkg/apis/velero/v2alpha1/register.go b/pkg/apis/velero/v2alpha1/register.go index 31b471281..d8945fa6a 100644 --- a/pkg/apis/velero/v2alpha1/register.go +++ b/pkg/apis/velero/v2alpha1/register.go @@ -20,6 +20,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" ) // Resource gets a Velero GroupResource for a specified resource @@ -50,6 +51,18 @@ func CustomResources() map[string]typeInfo { } } +// CustomResourceKinds returns a list of all custom resources kinds within the Velero +func CustomResourceKinds() sets.String { + kinds := sets.NewString() + + resources := CustomResources() + for kind := range resources { + kinds.Insert(kind) + } + + return kinds +} + func addKnownTypes(scheme *runtime.Scheme) error { for _, typeInfo := range CustomResources() { scheme.AddKnownTypes(SchemeGroupVersion, typeInfo.ItemType, typeInfo.ItemListType) diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index a42c0589c..5f4b6e9a6 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -475,31 +475,26 @@ func (s *server) initDiscoveryHelper() error { func (s *server) veleroResourcesExist() error { s.logger.Info("Checking existence of Velero custom resource definitions") - var veleroGroupVersion *metav1.APIResourceList - for _, gv := range s.discoveryHelper.Resources() { - if gv.GroupVersion == velerov1api.SchemeGroupVersion.String() { - veleroGroupVersion = gv - break + // add more group versions whenever available + gvResources := map[string]sets.String{ + velerov1api.SchemeGroupVersion.String(): velerov1api.CustomResourceKinds(), + velerov2alpha1api.SchemeGroupVersion.String(): velerov2alpha1api.CustomResourceKinds(), + } + + for _, lst := range s.discoveryHelper.Resources() { + if resources, found := gvResources[lst.GroupVersion]; found { + for _, resource := range lst.APIResources { + s.logger.WithField("kind", resource.Kind).Info("Found custom resource") + resources.Delete(resource.Kind) + } } } - if veleroGroupVersion == nil { - return fmt.Errorf("velero API group %s not found. Apply examples/common/00-prereqs.yaml to create it", velerov1api.SchemeGroupVersion) - } - - foundResources := sets.NewString() - for _, resource := range veleroGroupVersion.APIResources { - foundResources.Insert(resource.Kind) - } - var errs []error - for kind := range velerov1api.CustomResources() { - if foundResources.Has(kind) { - s.logger.WithField("kind", kind).Debug("Found custom resource") - continue + for gv, resources := range gvResources { + for kind := range resources { + errs = append(errs, errors.Errorf("custom resource %s not found in Velero API group %s", kind, gv)) } - - errs = append(errs, errors.Errorf("custom resource %s not found in Velero API group %s", kind, velerov1api.SchemeGroupVersion)) } if len(errs) > 0 { diff --git a/pkg/cmd/server/server_test.go b/pkg/cmd/server/server_test.go index 4d7944434..fc487d3d1 100644 --- a/pkg/cmd/server/server_test.go +++ b/pkg/cmd/server/server_test.go @@ -32,8 +32,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1" "github.com/vmware-tanzu/velero/pkg/client/mocks" "github.com/vmware-tanzu/velero/pkg/controller" discovery_mocks "github.com/vmware-tanzu/velero/pkg/discovery/mocks" @@ -64,24 +64,40 @@ func TestVeleroResourcesExist(t *testing.T) { } assert.Error(t, server.veleroResourcesExist()) - // Velero API group doesn't contain any custom resources: should error - veleroAPIResourceList := &metav1.APIResourceList{ - GroupVersion: v1.SchemeGroupVersion.String(), + // Velero v1 API group doesn't contain any custom resources: should error + veleroAPIResourceListVelerov1 := &metav1.APIResourceList{ + GroupVersion: velerov1api.SchemeGroupVersion.String(), } - fakeDiscoveryHelper.ResourceList = append(fakeDiscoveryHelper.ResourceList, veleroAPIResourceList) + fakeDiscoveryHelper.ResourceList = append(fakeDiscoveryHelper.ResourceList, veleroAPIResourceListVelerov1) assert.Error(t, server.veleroResourcesExist()) - // Velero API group contains all custom resources: should not error - for kind := range v1.CustomResources() { - veleroAPIResourceList.APIResources = append(veleroAPIResourceList.APIResources, metav1.APIResource{ + // Velero v2alpha1 API group doesn't contain any custom resources: should error + veleroAPIResourceListVeleroV2alpha1 := &metav1.APIResourceList{ + GroupVersion: velerov2alpha1api.SchemeGroupVersion.String(), + } + + fakeDiscoveryHelper.ResourceList = append(fakeDiscoveryHelper.ResourceList, veleroAPIResourceListVeleroV2alpha1) + assert.Error(t, server.veleroResourcesExist()) + + // Velero v1 API group contains all custom resources, but v2alpha1 doesn't contain any custom resources: should error + for kind := range velerov1api.CustomResources() { + veleroAPIResourceListVelerov1.APIResources = append(veleroAPIResourceListVelerov1.APIResources, metav1.APIResource{ + Kind: kind, + }) + } + assert.Error(t, server.veleroResourcesExist()) + + // Velero v1 and v2alpha1 API group contain all custom resources: should not error + for kind := range velerov2alpha1api.CustomResources() { + veleroAPIResourceListVeleroV2alpha1.APIResources = append(veleroAPIResourceListVeleroV2alpha1.APIResources, metav1.APIResource{ Kind: kind, }) } assert.NoError(t, server.veleroResourcesExist()) // Velero API group contains some but not all custom resources: should error - veleroAPIResourceList.APIResources = veleroAPIResourceList.APIResources[:3] + veleroAPIResourceListVelerov1.APIResources = veleroAPIResourceListVelerov1.APIResources[:3] assert.Error(t, server.veleroResourcesExist()) } @@ -270,6 +286,13 @@ func Test_veleroResourcesExist(t *testing.T) { {Kind: "ServerStatusRequest"}, }, }, + { + GroupVersion: velerov2alpha1api.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Kind: "DataUpload"}, + {Kind: "DataDownload"}, + }, + }, }) assert.Nil(t, server.veleroResourcesExist()) }