move RestoreResult from api to pkg/restore, rename to Result

Signed-off-by: Steve Kriss <krisss@vmware.com>
pull/1378/head
Steve Kriss 2019-04-16 12:57:02 -06:00
parent 39bab5ada9
commit 5bc6695109
8 changed files with 76 additions and 99 deletions

View File

@ -1,5 +1,5 @@
/*
Copyright 2017 the Velero contributors.
Copyright 2017, 2019 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -112,24 +112,6 @@ type RestoreStatus struct {
FailureReason string `json:"failureReason"`
}
// RestoreResult is a collection of messages that were generated
// during execution of a restore. This will typically store either
// warning or error messages.
type RestoreResult struct {
// Velero is a slice of messages related to the operation of Velero
// itself (for example, messages related to connecting to the
// cloud, reading a backup file, etc.)
Velero []string `json:"velero,omitempty"`
// Cluster is a slice of messages related to restoring cluster-
// scoped resources.
Cluster []string `json:"cluster,omitempty"`
// Namespaces is a map of namespace name to slice of messages
// related to restoring namespace-scoped resources.
Namespaces map[string][]string `json:"namespaces,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -974,47 +974,6 @@ func (in *RestoreList) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RestoreResult) DeepCopyInto(out *RestoreResult) {
*out = *in
if in.Velero != nil {
in, out := &in.Velero, &out.Velero
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Cluster != nil {
in, out := &in.Cluster, &out.Cluster
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Namespaces != nil {
in, out := &in.Namespaces, &out.Namespaces
*out = make(map[string][]string, len(*in))
for key, val := range *in {
var outVal []string
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]string, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreResult.
func (in *RestoreResult) DeepCopy() *RestoreResult {
if in == nil {
return nil
}
out := new(RestoreResult)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RestoreSpec) DeepCopyInto(out *RestoreSpec) {
*out = *in

View File

@ -1,5 +1,5 @@
/*
Copyright 2017 the Velero contributors.
Copyright 2017, 2019 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -27,6 +27,7 @@ import (
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
"github.com/heptio/velero/pkg/cmd/util/downloadrequest"
clientset "github.com/heptio/velero/pkg/generated/clientset/versioned"
pkgrestore "github.com/heptio/velero/pkg/restore"
)
func DescribeRestore(restore *v1.Restore, podVolumeRestores []v1.PodVolumeRestore, details bool, veleroClient clientset.Interface) string {
@ -108,7 +109,7 @@ func describeRestoreResults(d *Describer, restore *v1.Restore, veleroClient clie
}
var buf bytes.Buffer
var resultMap map[string]v1.RestoreResult
var resultMap map[string]pkgrestore.Result
if err := downloadrequest.Stream(veleroClient.VeleroV1(), restore.Namespace, restore.Name, v1.DownloadTargetKindRestoreResults, &buf, downloadRequestTimeout); err != nil {
d.Printf("Warnings:\t<error getting warnings: %v>\n\nErrors:\t<error getting errors: %v>\n", err, err)
@ -130,7 +131,7 @@ func describeRestoreResults(d *Describer, restore *v1.Restore, veleroClient clie
}
}
func describeRestoreResult(d *Describer, name string, result v1.RestoreResult) {
func describeRestoreResult(d *Describer, name string, result pkgrestore.Result) {
d.Printf("%s:\n", name)
d.DescribeSlice(1, "Velero", result.Velero)
d.DescribeSlice(1, "Cluster", result.Cluster)

View File

@ -42,7 +42,7 @@ import (
"github.com/heptio/velero/pkg/metrics"
"github.com/heptio/velero/pkg/persistence"
"github.com/heptio/velero/pkg/plugin/clientmgmt"
"github.com/heptio/velero/pkg/restore"
pkgrestore "github.com/heptio/velero/pkg/restore"
"github.com/heptio/velero/pkg/util/collections"
kubeutil "github.com/heptio/velero/pkg/util/kube"
"github.com/heptio/velero/pkg/util/logging"
@ -78,7 +78,7 @@ type restoreController struct {
namespace string
restoreClient velerov1client.RestoresGetter
backupClient velerov1client.BackupsGetter
restorer restore.Restorer
restorer pkgrestore.Restorer
backupLister listers.BackupLister
restoreLister listers.RestoreLister
backupLocationLister listers.BackupStorageLocationLister
@ -96,7 +96,7 @@ func NewRestoreController(
restoreInformer informers.RestoreInformer,
restoreClient velerov1client.RestoresGetter,
backupClient velerov1client.BackupsGetter,
restorer restore.Restorer,
restorer pkgrestore.Restorer,
backupInformer informers.BackupInformer,
backupLocationInformer informers.BackupStorageLocationInformer,
snapshotLocationInformer informers.VolumeSnapshotLocationInformer,
@ -449,7 +449,7 @@ func (c *restoreController) runValidatedRestore(restore *api.Restore, info backu
restore.Status.Errors += len(e)
}
m := map[string]api.RestoreResult{
m := map[string]pkgrestore.Result{
"warnings": restoreWarnings,
"errors": restoreErrors,
}
@ -461,7 +461,7 @@ func (c *restoreController) runValidatedRestore(restore *api.Restore, info backu
return nil
}
func putResults(restore *api.Restore, results map[string]api.RestoreResult, backupStore persistence.BackupStore, log logrus.FieldLogger) error {
func putResults(restore *api.Restore, results map[string]pkgrestore.Result, backupStore persistence.BackupStore, log logrus.FieldLogger) error {
buf := new(bytes.Buffer)
gzw := gzip.NewWriter(buf)
defer gzw.Close()

View File

@ -1,5 +1,5 @@
/*
Copyright 2017 the Velero contributors.
Copyright 2017, 2019 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -46,7 +46,7 @@ import (
"github.com/heptio/velero/pkg/plugin/clientmgmt"
pluginmocks "github.com/heptio/velero/pkg/plugin/mocks"
"github.com/heptio/velero/pkg/plugin/velero"
"github.com/heptio/velero/pkg/restore"
pkgrestore "github.com/heptio/velero/pkg/restore"
velerotest "github.com/heptio/velero/pkg/util/test"
"github.com/heptio/velero/pkg/volume"
)
@ -471,7 +471,7 @@ func TestProcessQueueItem(t *testing.T) {
sharedInformers.Velero().V1().Backups().Informer().GetStore().Add(test.backup)
}
var warnings, errors api.RestoreResult
var warnings, errors pkgrestore.Result
if test.restorerError != nil {
errors.Namespaces = map[string][]string{"ns-1": {test.restorerError.Error()}}
}
@ -817,11 +817,11 @@ func (r *fakeRestorer) Restore(
backupReader io.Reader,
actions []velero.RestoreItemAction,
snapshotLocationLister listers.VolumeSnapshotLocationLister,
volumeSnapshotterGetter restore.VolumeSnapshotterGetter,
) (api.RestoreResult, api.RestoreResult) {
volumeSnapshotterGetter pkgrestore.VolumeSnapshotterGetter,
) (pkgrestore.Result, pkgrestore.Result) {
res := r.Called(log, restore, backup, backupReader, actions)
r.calledWithArg = *restore
return res.Get(0).(api.RestoreResult), res.Get(1).(api.RestoreResult)
return res.Get(0).(pkgrestore.Result), res.Get(1).(pkgrestore.Result)
}

View File

@ -71,7 +71,7 @@ type Restorer interface {
actions []velero.RestoreItemAction,
snapshotLocationLister listers.VolumeSnapshotLocationLister,
volumeSnapshotterGetter VolumeSnapshotterGetter,
) (api.RestoreResult, api.RestoreResult)
) (Result, Result)
}
// kubernetesRestorer implements Restorer for restoring into a Kubernetes cluster.
@ -181,7 +181,7 @@ func (kr *kubernetesRestorer) Restore(
actions []velero.RestoreItemAction,
snapshotLocationLister listers.VolumeSnapshotLocationLister,
volumeSnapshotterGetter VolumeSnapshotterGetter,
) (api.RestoreResult, api.RestoreResult) {
) (Result, Result) {
// metav1.LabelSelectorAsSelector converts a nil LabelSelector to a
// Nothing Selector, i.e. a selector that matches nothing. We want
// a selector that matches everything. This can be accomplished by
@ -193,19 +193,19 @@ func (kr *kubernetesRestorer) Restore(
selector, err := metav1.LabelSelectorAsSelector(ls)
if err != nil {
return api.RestoreResult{}, api.RestoreResult{Velero: []string{err.Error()}}
return Result{}, Result{Velero: []string{err.Error()}}
}
// get resource includes-excludes
resourceIncludesExcludes := getResourceIncludesExcludes(kr.discoveryHelper, restore.Spec.IncludedResources, restore.Spec.ExcludedResources)
prioritizedResources, err := prioritizeResources(kr.discoveryHelper, kr.resourcePriorities, resourceIncludesExcludes, log)
if err != nil {
return api.RestoreResult{}, api.RestoreResult{Velero: []string{err.Error()}}
return Result{}, Result{Velero: []string{err.Error()}}
}
resolvedActions, err := resolveActions(actions, kr.discoveryHelper)
if err != nil {
return api.RestoreResult{}, api.RestoreResult{Velero: []string{err.Error()}}
return Result{}, Result{Velero: []string{err.Error()}}
}
podVolumeTimeout := kr.resticTimeout
@ -225,7 +225,7 @@ func (kr *kubernetesRestorer) Restore(
if kr.resticRestorerFactory != nil {
resticRestorer, err = kr.resticRestorerFactory.NewRestorer(ctx, restore)
if err != nil {
return api.RestoreResult{}, api.RestoreResult{Velero: []string{err.Error()}}
return Result{}, Result{Velero: []string{err.Error()}}
}
}
@ -359,13 +359,13 @@ type resourceClientKey struct {
namespace string
}
func (ctx *context) execute() (api.RestoreResult, api.RestoreResult) {
func (ctx *context) execute() (Result, Result) {
ctx.log.Infof("Starting restore of backup %s", kube.NamespaceAndName(ctx.backup))
dir, err := ctx.extractor.unzipAndExtractBackup(ctx.backupReader)
if err != nil {
ctx.log.Infof("error unzipping and extracting: %v", err)
return api.RestoreResult{}, api.RestoreResult{Velero: []string{err.Error()}}
return Result{}, Result{Velero: []string{err.Error()}}
}
defer ctx.fileSystem.RemoveAll(dir)
@ -377,8 +377,8 @@ func (ctx *context) execute() (api.RestoreResult, api.RestoreResult) {
// restoreFromDir executes a restore based on backup data contained within a local
// directory, ctx.restoreDir.
func (ctx *context) restoreFromDir() (api.RestoreResult, api.RestoreResult) {
warnings, errs := api.RestoreResult{}, api.RestoreResult{}
func (ctx *context) restoreFromDir() (Result, Result) {
warnings, errs := Result{}, Result{}
namespaceFilter := collections.NewIncludesExcludes().
Includes(ctx.restore.Spec.IncludedNamespaces...).
@ -556,7 +556,7 @@ func getNamespace(logger logrus.FieldLogger, path, remappedName string) *v1.Name
// merge combines two RestoreResult objects into one
// by appending the corresponding lists to one another.
func merge(a, b *api.RestoreResult) {
func merge(a, b *Result) {
a.Cluster = append(a.Cluster, b.Cluster...)
a.Velero = append(a.Velero, b.Velero...)
for k, v := range b.Namespaces {
@ -568,14 +568,14 @@ func merge(a, b *api.RestoreResult) {
}
// addVeleroError appends an error to the provided RestoreResult's Velero list.
func addVeleroError(r *api.RestoreResult, err error) {
func addVeleroError(r *Result, err error) {
r.Velero = append(r.Velero, err.Error())
}
// addToResult appends an error to the provided RestoreResult, either within
// the cluster-scoped list (if ns == "") or within the provided namespace's
// entry.
func addToResult(r *api.RestoreResult, ns string, e error) {
func addToResult(r *Result, ns string, e error) {
if ns == "" {
r.Cluster = append(r.Cluster, e.Error())
} else {
@ -703,8 +703,8 @@ func (ctx *context) shouldRestore(name string, pvClient client.Dynamic) (bool, e
// restoreResource restores the specified cluster or namespace scoped resource. If namespace is
// empty we are restoring a cluster level resource, otherwise into the specified namespace.
func (ctx *context) restoreResource(resource, namespace, resourcePath string) (api.RestoreResult, api.RestoreResult) {
warnings, errs := api.RestoreResult{}, api.RestoreResult{}
func (ctx *context) restoreResource(resource, namespace, resourcePath string) (Result, Result) {
warnings, errs := Result{}, Result{}
if ctx.restore.Spec.IncludeClusterResources != nil && !*ctx.restore.Spec.IncludeClusterResources && namespace == "" {
ctx.log.Infof("Skipping resource %s because it's cluster-scoped", resource)
@ -784,8 +784,8 @@ func getResourceID(groupResource schema.GroupResource, namespace, name string) s
return fmt.Sprintf("%s/%s/%s", groupResource.String(), namespace, name)
}
func (ctx *context) restoreItem(obj *unstructured.Unstructured, groupResource schema.GroupResource, namespace string) (api.RestoreResult, api.RestoreResult) {
warnings, errs := api.RestoreResult{}, api.RestoreResult{}
func (ctx *context) restoreItem(obj *unstructured.Unstructured, groupResource schema.GroupResource, namespace string) (Result, Result) {
warnings, errs := Result{}, Result{}
resourceID := getResourceID(groupResource, namespace, obj.GetName())
// make a copy of object retrieved from backup

View File

@ -221,7 +221,7 @@ func TestRestorePriority(t *testing.T) {
restore *api.Restore
baseDir string
prioritizedResources []schema.GroupResource
expectedErrors api.RestoreResult
expectedErrors Result
expectedReadDirs []string
}{
{
@ -272,7 +272,7 @@ func TestRestorePriority(t *testing.T) {
{Resource: "b"},
{Resource: "c"},
},
expectedErrors: api.RestoreResult{
expectedErrors: Result{
Namespaces: map[string][]string{
"ns-1": {"error decoding \"bak/resources/a/namespaces/ns-1/invalid-json.json\": invalid character 'i' looking for beginning of value"},
},
@ -390,7 +390,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
includeClusterResources *bool
fileSystem *velerotest.FakeFileSystem
actions []resolvedAction
expectedErrors api.RestoreResult
expectedErrors Result
expectedObjs []unstructured.Unstructured
}{
{
@ -411,7 +411,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
namespace: "ns-1",
resourcePath: "configmaps",
fileSystem: velerotest.NewFakeFileSystem(),
expectedErrors: api.RestoreResult{
expectedErrors: Result{
Namespaces: map[string][]string{
"ns-1": {"error reading \"configmaps\" resource directory: open configmaps: file does not exist"},
},
@ -431,7 +431,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
fileSystem: velerotest.NewFakeFileSystem().
WithFile("configmaps/cm-1-invalid.json", []byte("this is not valid json")).
WithFile("configmaps/cm-2.json", newNamedTestConfigMap("cm-2").ToJSON()),
expectedErrors: api.RestoreResult{
expectedErrors: Result{
Namespaces: map[string][]string{
"ns-1": {"error decoding \"configmaps/cm-1-invalid.json\": invalid character 'h' in literal true (expecting 'r')"},
},
@ -757,7 +757,7 @@ func TestRestoringExistingServiceAccount(t *testing.T) {
assert.Empty(t, warnings.Velero)
assert.Empty(t, warnings.Cluster)
assert.Empty(t, warnings.Namespaces)
assert.Equal(t, api.RestoreResult{}, errors)
assert.Equal(t, Result{}, errors)
})
}
}
@ -1031,7 +1031,7 @@ status:
assert.Empty(t, warnings.Velero)
assert.Empty(t, warnings.Namespaces)
assert.Equal(t, api.RestoreResult{}, errors)
assert.Equal(t, Result{}, errors)
assert.Empty(t, warnings.Cluster)
// Prep PVC restore
@ -1063,7 +1063,7 @@ status:
assert.Empty(t, warnings.Velero)
assert.Empty(t, warnings.Cluster)
assert.Empty(t, warnings.Namespaces)
assert.Equal(t, api.RestoreResult{}, errors)
assert.Equal(t, Result{}, errors)
})
}
}

35
pkg/restore/result.go Normal file
View File

@ -0,0 +1,35 @@
/*
Copyright 2019 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package restore
// Result is a collection of messages that were generated during
// execution of a restore. This will typically store either
// warning or error messages.
type Result struct {
// Velero is a slice of messages related to the operation of Velero
// itself (for example, messages related to connecting to the
// cloud, reading a backup file, etc.)
Velero []string `json:"velero,omitempty"`
// Cluster is a slice of messages related to restoring cluster-
// scoped resources.
Cluster []string `json:"cluster,omitempty"`
// Namespaces is a map of namespace name to slice of messages
// related to restoring namespace-scoped resources.
Namespaces map[string][]string `json:"namespaces,omitempty"`
}