diff --git a/pkg/backup/backup_test.go b/pkg/backup/backup_test.go index 06fdfbe85..0eef90cc9 100644 --- a/pkg/backup/backup_test.go +++ b/pkg/backup/backup_test.go @@ -230,7 +230,7 @@ func TestGetNamespaceIncludesExcludes(t *testing.T) { var ( v1Group = &metav1.APIResourceList{ GroupVersion: "v1", - APIResources: []metav1.APIResource{configMapsResource, podsResource}, + APIResources: []metav1.APIResource{configMapsResource, podsResource, namespacesResource}, } configMapsResource = metav1.APIResource{ @@ -266,6 +266,14 @@ var ( Verbs: metav1.Verbs([]string{"create", "update", "get", "list", "watch", "delete"}), } + namespacesResource = metav1.APIResource{ + Name: "namespaces", + SingularName: "namespace", + Namespaced: false, + Kind: "Namespace", + Verbs: metav1.Verbs([]string{"create", "update", "get", "list", "watch", "delete"}), + } + certificatesGroup = &metav1.APIResourceList{ GroupVersion: "certificates.k8s.io/v1beta1", APIResources: []metav1.APIResource{certificateSigningRequestsResource}, diff --git a/pkg/backup/resource_backupper.go b/pkg/backup/resource_backupper.go index 28d8b293d..b3e06f641 100644 --- a/pkg/backup/resource_backupper.go +++ b/pkg/backup/resource_backupper.go @@ -129,7 +129,9 @@ func (rb *defaultResourceBackupper) backupResource( // (all namespaces) backup. Note that in the case of a subset of // namespaces being backed up, some related cluster-scoped resources // may still be backed up if triggered by a custom action (e.g. PVC->PV). - if !resource.Namespaced && !rb.namespaces.IncludeEverything() { + // If we're processing namespaces themselves, we will not skip here, they may be + // filtered out later. + if !resource.Namespaced && resource.Kind != "Namespace" && !rb.namespaces.IncludeEverything() { log.Info("Skipping resource because it's cluster-scoped and only specific namespaces are included in the backup") return nil } @@ -173,6 +175,8 @@ func (rb *defaultResourceBackupper) backupResource( rb.discoveryHelper, ) + // TODO: when processing namespaces, and only including certain namespaces, we still list + // them all here. Could optimize to get specifics, but watch out for label selector. var namespacesToList []string if resource.Namespaced { namespacesToList = getNamespacesToList(rb.namespaces) diff --git a/pkg/backup/resource_backupper_test.go b/pkg/backup/resource_backupper_test.go index 78b7828df..980d83a0d 100644 --- a/pkg/backup/resource_backupper_test.go +++ b/pkg/backup/resource_backupper_test.go @@ -195,6 +195,24 @@ func TestBackupResource(t *testing.T) { }, }, }, + { + name: "should include specified namespaces if backing up subset of namespaces and --include-cluster-resources=nil", + namespaces: collections.NewIncludesExcludes().Includes("ns-1"), + resources: collections.NewIncludesExcludes(), + includeClusterResources: nil, + expectedListedNamespaces: []string{"ns-1"}, + apiGroup: v1Group, + apiResource: namespacesResource, + groupVersion: schema.GroupVersion{Group: "", Version: "v1"}, + groupResource: schema.GroupResource{Group: "", Resource: "namespaces"}, + expectSkip: false, + listResponses: [][]*unstructured.Unstructured{ + { + unstructuredOrDie(`{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"ns-1"}}`), + unstructuredOrDie(`{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"ns-2"}}`), + }, + }, + }, } for _, test := range tests { @@ -275,7 +293,11 @@ func TestBackupResource(t *testing.T) { client := &arktest.FakeDynamicClient{} defer client.AssertExpectations(t) - dynamicFactory.On("ClientForGroupVersionResource", test.groupVersion, test.apiResource, namespace).Return(client, nil) + if test.groupResource.Resource == "namespaces" { + dynamicFactory.On("ClientForGroupVersionResource", test.groupVersion, test.apiResource, "").Return(client, nil) + } else { + dynamicFactory.On("ClientForGroupVersionResource", test.groupVersion, test.apiResource, namespace).Return(client, nil) + } list := &unstructured.UnstructuredList{ Items: []unstructured.Unstructured{},