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 <justin.r.nauman@gmail.com>pull/99/head
parent
87f60ed853
commit
1fd1e8deaa
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue