From 1fd1e8deaa507ae11939b1225ed845f7e6badab0 Mon Sep 17 00:00:00 2001 From: Justin Nauman Date: Mon, 18 Sep 2017 22:44:33 -0500 Subject: [PATCH] Excluding nodes and endpoints from restoration - Introduced a blacklist of resources that are non-restorable. The goal being that the backup can still include these resources for logging/auditing purposes but they are explicitly added to ExcludedResources in the RestorController's "defaulting" logic to ensure that if someone were to explicitly ask for nodes that they would be expressly denied. Signed-off-by: Justin Nauman --- pkg/controller/restore_controller.go | 19 +++++++++++++++++++ pkg/controller/restore_controller_test.go | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/controller/restore_controller.go b/pkg/controller/restore_controller.go index e912ee09e..7487f2b84 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -29,6 +29,7 @@ import ( "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" @@ -44,6 +45,10 @@ import ( kubeutil "github.com/heptio/ark/pkg/util/kube" ) +// nonRestorableResources is a blacklist for the restoration process. Any resources +// included here are explicitly excluded from the restoration process. +var nonRestorableResources = []string{"nodes"} + type restoreController struct { restoreClient arkv1client.RestoresGetter backupClient arkv1client.BackupsGetter @@ -234,6 +239,13 @@ func (controller *restoreController) processRestore(key string) error { restore.Spec.IncludedResources = []string{"*"} } + excludedResources := sets.NewString(restore.Spec.ExcludedResources...) + for _, nonrestorable := range nonRestorableResources { + if !excludedResources.Has(nonrestorable) { + restore.Spec.ExcludedResources = append(restore.Spec.ExcludedResources, nonrestorable) + } + } + // validation if restore.Status.ValidationErrors = controller.getValidationErrors(restore); len(restore.Status.ValidationErrors) > 0 { restore.Status.Phase = api.RestorePhaseFailedValidation @@ -288,6 +300,13 @@ func (controller *restoreController) getValidationErrors(itm *api.Restore) []str validationErrors = append(validationErrors, "BackupName must be non-empty and correspond to the name of a backup in object storage.") } + includedResources := sets.NewString(itm.Spec.IncludedResources...) + for _, nonRestorableResource := range nonRestorableResources { + if includedResources.Has(nonRestorableResource) { + validationErrors = append(validationErrors, fmt.Sprintf("%v are a non-restorable resource", nonRestorableResource)) + } + } + for _, err := range collections.ValidateIncludesExcludes(itm.Spec.IncludedNamespaces, itm.Spec.ExcludedNamespaces) { validationErrors = append(validationErrors, fmt.Sprintf("Invalid included/excluded namespace lists: %v", err)) } diff --git a/pkg/controller/restore_controller_test.go b/pkg/controller/restore_controller_test.go index 96dddef88..d7068a491 100644 --- a/pkg/controller/restore_controller_test.go +++ b/pkg/controller/restore_controller_test.go @@ -259,6 +259,18 @@ func TestProcessRestore(t *testing.T) { Restore, }, }, + { + name: "restoration of nodes is not supported", + restore: NewRestore("foo", "bar", "backup-1", "ns-1", "nodes", api.RestorePhaseNew).Restore, + backup: NewTestBackup().WithName("backup-1").Backup, + expectedErr: false, + expectedRestoreUpdates: []*api.Restore{ + NewRestore("foo", "bar", "backup-1", "ns-1", "nodes", api.RestorePhaseFailedValidation). + WithValidationError("nodes are a non-restorable resource"). + WithValidationError("Invalid included/excluded resource lists: excludes list cannot contain an item in the includes list: nodes"). + Restore, + }, + }, } for _, test := range tests { @@ -382,6 +394,10 @@ func NewRestore(ns, name, backup, includeNS, includeResource string, phase api.R restore = restore.WithIncludedResource(includeResource) } + for _, n := range nonRestorableResources { + restore.WithExcludedResource(n) + } + return restore }