Add resource status

Signed-off-by: Rafael Leal <rafaelealdias@gmail.com>
pull/4785/head
Rafael Leal 2022-05-12 11:58:47 -03:00
parent e374eb9da4
commit 7f1f881c28
No known key found for this signature in database
GPG Key ID: 6A8C53E7546F9F5A
2 changed files with 116 additions and 71 deletions

View File

@ -86,6 +86,12 @@ type RestoreSpec struct {
// +nullable
RestorePVs *bool `json:"restorePVs,omitempty"`
// RestoreStatus specifies which resources we should restore the status
// field. If nil, no objects are included. Optional.
// +optional
// +nullable
RestoreStatus *RestoreStatusSpec
// PreserveNodePorts specifies whether to restore old nodePorts from backup.
// +optional
// +nullable
@ -113,6 +119,19 @@ type RestoreHooks struct {
Resources []RestoreResourceHookSpec `json:"resources,omitempty"`
}
type RestoreStatusSpec struct {
// IncludedResources specifies the resources to which will restore the status.
// If empty, it applies to all resources.
// +optional
// +nullable
IncludedResources []string `json:"includedResources,omitempty"`
// ExcludedResources specifies the resources to which will not restore the status.
// +optional
// +nullable
ExcludedResources []string `json:"excludedResources,omitempty"`
}
// RestoreResourceHookSpec defines one or more RestoreResrouceHooks that should be executed based on
// the rules defined for namespaces, resources, and label selector.
type RestoreResourceHookSpec struct {

View File

@ -206,6 +206,20 @@ func (kr *kubernetesRestorer) RestoreWithResolvers(
req.Restore.Spec.ExcludedResources,
)
// Get resource status includes-excludes. Defaults to excluding all resources
restoreStatusIncludesExcludes := collections.GetResourceIncludesExcludes(
kr.discoveryHelper,
[]string{},
[]string{"*"},
)
if req.Restore.Spec.RestoreStatus != nil {
restoreStatusIncludesExcludes = collections.GetResourceIncludesExcludes(
kr.discoveryHelper,
req.Restore.Spec.RestoreStatus.IncludedResources,
req.Restore.Spec.RestoreStatus.ExcludedResources,
)
}
// Get namespace includes-excludes.
namespaceIncludesExcludes := collections.NewIncludesExcludes().
Includes(req.Restore.Spec.IncludedNamespaces...).
@ -268,83 +282,85 @@ func (kr *kubernetesRestorer) RestoreWithResolvers(
}
restoreCtx := &restoreContext{
backup: req.Backup,
backupReader: req.BackupReader,
restore: req.Restore,
resourceIncludesExcludes: resourceIncludesExcludes,
namespaceIncludesExcludes: namespaceIncludesExcludes,
chosenGrpVersToRestore: make(map[string]ChosenGroupVersion),
selector: selector,
OrSelectors: OrSelectors,
log: req.Log,
dynamicFactory: kr.dynamicFactory,
fileSystem: kr.fileSystem,
namespaceClient: kr.namespaceClient,
restoreItemActions: resolvedActions,
itemSnapshotterActions: resolvedItemSnapshotterActions,
volumeSnapshotterGetter: volumeSnapshotterGetter,
resticRestorer: resticRestorer,
resticErrs: make(chan error),
pvsToProvision: sets.NewString(),
pvRestorer: pvRestorer,
volumeSnapshots: req.VolumeSnapshots,
podVolumeBackups: req.PodVolumeBackups,
resourceTerminatingTimeout: kr.resourceTerminatingTimeout,
resourceClients: make(map[resourceClientKey]client.Dynamic),
restoredItems: make(map[velero.ResourceIdentifier]struct{}),
renamedPVs: make(map[string]string),
pvRenamer: kr.pvRenamer,
discoveryHelper: kr.discoveryHelper,
resourcePriorities: kr.resourcePriorities,
resourceRestoreHooks: resourceRestoreHooks,
hooksErrs: make(chan error),
waitExecHookHandler: waitExecHookHandler,
hooksContext: hooksCtx,
hooksCancelFunc: hooksCancelFunc,
restoreClient: kr.restoreClient,
backup: req.Backup,
backupReader: req.BackupReader,
restore: req.Restore,
resourceIncludesExcludes: resourceIncludesExcludes,
resourceStatusIncludesExcludes: restoreStatusIncludesExcludes,
namespaceIncludesExcludes: namespaceIncludesExcludes,
chosenGrpVersToRestore: make(map[string]ChosenGroupVersion),
selector: selector,
OrSelectors: OrSelectors,
log: req.Log,
dynamicFactory: kr.dynamicFactory,
fileSystem: kr.fileSystem,
namespaceClient: kr.namespaceClient,
restoreItemActions: resolvedActions,
itemSnapshotterActions: resolvedItemSnapshotterActions,
volumeSnapshotterGetter: volumeSnapshotterGetter,
resticRestorer: resticRestorer,
resticErrs: make(chan error),
pvsToProvision: sets.NewString(),
pvRestorer: pvRestorer,
volumeSnapshots: req.VolumeSnapshots,
podVolumeBackups: req.PodVolumeBackups,
resourceTerminatingTimeout: kr.resourceTerminatingTimeout,
resourceClients: make(map[resourceClientKey]client.Dynamic),
restoredItems: make(map[velero.ResourceIdentifier]struct{}),
renamedPVs: make(map[string]string),
pvRenamer: kr.pvRenamer,
discoveryHelper: kr.discoveryHelper,
resourcePriorities: kr.resourcePriorities,
resourceRestoreHooks: resourceRestoreHooks,
hooksErrs: make(chan error),
waitExecHookHandler: waitExecHookHandler,
hooksContext: hooksCtx,
hooksCancelFunc: hooksCancelFunc,
restoreClient: kr.restoreClient,
}
return restoreCtx.execute()
}
type restoreContext struct {
backup *velerov1api.Backup
backupReader io.Reader
restore *velerov1api.Restore
restoreDir string
restoreClient velerov1client.RestoresGetter
resourceIncludesExcludes *collections.IncludesExcludes
namespaceIncludesExcludes *collections.IncludesExcludes
chosenGrpVersToRestore map[string]ChosenGroupVersion
selector labels.Selector
OrSelectors []labels.Selector
log logrus.FieldLogger
dynamicFactory client.DynamicFactory
fileSystem filesystem.Interface
namespaceClient corev1.NamespaceInterface
restoreItemActions []framework.RestoreItemResolvedAction
itemSnapshotterActions []framework.ItemSnapshotterResolvedAction
volumeSnapshotterGetter VolumeSnapshotterGetter
resticRestorer restic.Restorer
resticWaitGroup sync.WaitGroup
resticErrs chan error
pvsToProvision sets.String
pvRestorer PVRestorer
volumeSnapshots []*volume.Snapshot
podVolumeBackups []*velerov1api.PodVolumeBackup
resourceTerminatingTimeout time.Duration
resourceClients map[resourceClientKey]client.Dynamic
restoredItems map[velero.ResourceIdentifier]struct{}
renamedPVs map[string]string
pvRenamer func(string) (string, error)
discoveryHelper discovery.Helper
resourcePriorities []string
hooksWaitGroup sync.WaitGroup
hooksErrs chan error
resourceRestoreHooks []hook.ResourceRestoreHook
waitExecHookHandler hook.WaitExecHookHandler
hooksContext go_context.Context
hooksCancelFunc go_context.CancelFunc
backup *velerov1api.Backup
backupReader io.Reader
restore *velerov1api.Restore
restoreDir string
restoreClient velerov1client.RestoresGetter
resourceIncludesExcludes *collections.IncludesExcludes
resourceStatusIncludesExcludes *collections.IncludesExcludes
namespaceIncludesExcludes *collections.IncludesExcludes
chosenGrpVersToRestore map[string]ChosenGroupVersion
selector labels.Selector
OrSelectors []labels.Selector
log logrus.FieldLogger
dynamicFactory client.DynamicFactory
fileSystem filesystem.Interface
namespaceClient corev1.NamespaceInterface
restoreItemActions []framework.RestoreItemResolvedAction
itemSnapshotterActions []framework.ItemSnapshotterResolvedAction
volumeSnapshotterGetter VolumeSnapshotterGetter
resticRestorer restic.Restorer
resticWaitGroup sync.WaitGroup
resticErrs chan error
pvsToProvision sets.String
pvRestorer PVRestorer
volumeSnapshots []*volume.Snapshot
podVolumeBackups []*velerov1api.PodVolumeBackup
resourceTerminatingTimeout time.Duration
resourceClients map[resourceClientKey]client.Dynamic
restoredItems map[velero.ResourceIdentifier]struct{}
renamedPVs map[string]string
pvRenamer func(string) (string, error)
discoveryHelper discovery.Helper
resourcePriorities []string
hooksWaitGroup sync.WaitGroup
hooksErrs chan error
resourceRestoreHooks []hook.ResourceRestoreHook
waitExecHookHandler hook.WaitExecHookHandler
hooksContext go_context.Context
hooksCancelFunc go_context.CancelFunc
}
type resourceClientKey struct {
@ -1356,6 +1372,16 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso
return warnings, errs
}
// if it should restore status, run a UpdateStatus
if ctx.resourceStatusIncludesExcludes.ShouldInclude(groupResource.String()) {
updated, err := resourceClient.UpdateStatus(obj, metav1.UpdateOptions{})
if err != nil {
warnings.Add(namespace, err)
} else {
createdObj = updated
}
}
if groupResource == kuberesource.Pods {
pod := new(v1.Pod)
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), pod); err != nil {