diff --git a/changelogs/unreleased/1264-carlisia b/changelogs/unreleased/1264-carlisia new file mode 100644 index 000000000..6ef6636da --- /dev/null +++ b/changelogs/unreleased/1264-carlisia @@ -0,0 +1 @@ +Move all the interfaces and associated types necessary to implement all of the Velero plugins to under the new package `velero`. \ No newline at end of file diff --git a/pkg/backup/backup.go b/pkg/backup/backup.go index 3fa01e313..a23cf35b4 100644 --- a/pkg/backup/backup.go +++ b/pkg/backup/backup.go @@ -34,8 +34,8 @@ import ( api "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/client" - "github.com/heptio/velero/pkg/cloudprovider" "github.com/heptio/velero/pkg/discovery" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/podexec" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/util/collections" @@ -49,7 +49,7 @@ const BackupVersion = 1 type Backupper interface { // Backup takes a backup using the specification in the api.Backup and writes backup and log data // to the given writers. - Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []ItemAction, blockStoreGetter BlockStoreGetter) error + Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []velero.BackupItemAction, blockStoreGetter BlockStoreGetter) error } // kubernetesBackupper implements Backupper. @@ -69,7 +69,7 @@ type itemKey struct { } type resolvedAction struct { - ItemAction + velero.BackupItemAction resourceIncludesExcludes *collections.IncludesExcludes namespaceIncludesExcludes *collections.IncludesExcludes @@ -108,7 +108,7 @@ func NewKubernetesBackupper( }, nil } -func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAction, error) { +func resolveActions(actions []velero.BackupItemAction, helper discovery.Helper) ([]resolvedAction, error) { var resolved []resolvedAction for _, action := range actions { @@ -128,7 +128,7 @@ func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAc } res := resolvedAction{ - ItemAction: action, + BackupItemAction: action, resourceIncludesExcludes: resources, namespaceIncludesExcludes: namespaces, selector: selector, @@ -210,12 +210,12 @@ func getResourceHook(hookSpec api.BackupResourceHookSpec, discoveryHelper discov } type BlockStoreGetter interface { - GetBlockStore(name string) (cloudprovider.BlockStore, error) + GetBlockStore(name string) (velero.BlockStore, error) } // Backup backs up the items specified in the Backup, placing them in a gzip-compressed tar file // written to backupFile. The finalized api.Backup is written to metadata. -func (kb *kubernetesBackupper) Backup(logger logrus.FieldLogger, backupRequest *Request, backupFile io.Writer, actions []ItemAction, blockStoreGetter BlockStoreGetter) error { +func (kb *kubernetesBackupper) Backup(logger logrus.FieldLogger, backupRequest *Request, backupFile io.Writer, actions []velero.BackupItemAction, blockStoreGetter BlockStoreGetter) error { gzippedData := gzip.NewWriter(backupFile) defer gzippedData.Close() diff --git a/pkg/backup/backup_pv_action.go b/pkg/backup/backup_pv_action.go index 46a0706f0..accac2c97 100644 --- a/pkg/backup/backup_pv_action.go +++ b/pkg/backup/backup_pv_action.go @@ -24,28 +24,29 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" ) -// backupPVAction inspects a PersistentVolumeClaim for the PersistentVolume +// PVCAction inspects a PersistentVolumeClaim for the PersistentVolume // that it references and backs it up -type backupPVAction struct { +type PVCAction struct { log logrus.FieldLogger } -func NewBackupPVAction(logger logrus.FieldLogger) ItemAction { - return &backupPVAction{log: logger} +func NewPVCAction(logger logrus.FieldLogger) *PVCAction { + return &PVCAction{log: logger} } -func (a *backupPVAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *PVCAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"persistentvolumeclaims"}, }, nil } // Execute finds the PersistentVolume bound by the provided // PersistentVolumeClaim, if any, and backs it up -func (a *backupPVAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) { - a.log.Info("Executing backupPVAction") +func (a *PVCAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { + a.log.Info("Executing PVCAction") var pvc corev1api.PersistentVolumeClaim if err := runtime.DefaultUnstructuredConverter.FromUnstructured(item.UnstructuredContent(), &pvc); err != nil { @@ -56,9 +57,9 @@ func (a *backupPVAction) Execute(item runtime.Unstructured, backup *v1.Backup) ( return item, nil, nil } - pv := ResourceIdentifier{ + pv := velero.ResourceIdentifier{ GroupResource: kuberesource.PersistentVolumes, Name: pvc.Spec.VolumeName, } - return item, []ResourceIdentifier{pv}, nil + return item, []velero.ResourceIdentifier{pv}, nil } diff --git a/pkg/backup/backup_pv_action_test.go b/pkg/backup/backup_pv_action_test.go index 73114c8b3..271ef5790 100644 --- a/pkg/backup/backup_pv_action_test.go +++ b/pkg/backup/backup_pv_action_test.go @@ -26,6 +26,7 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -39,7 +40,7 @@ func TestBackupPVAction(t *testing.T) { backup := &v1.Backup{} - a := NewBackupPVAction(velerotest.NewLogger()) + a := NewPVCAction(velerotest.NewLogger()) // no spec.volumeName should result in no error // and no additional items @@ -81,7 +82,7 @@ func TestBackupPVAction(t *testing.T) { _, additional, err = a.Execute(pvc, backup) require.NoError(t, err) require.Len(t, additional, 1) - assert.Equal(t, ResourceIdentifier{GroupResource: kuberesource.PersistentVolumes, Name: "myVolume"}, additional[0]) + assert.Equal(t, velero.ResourceIdentifier{GroupResource: kuberesource.PersistentVolumes, Name: "myVolume"}, additional[0]) // empty spec.volumeName when status.phase is 'Bound' should // result in no error and no additional items diff --git a/pkg/backup/backup_test.go b/pkg/backup/backup_test.go index c79e4f9f0..e848cbd3e 100644 --- a/pkg/backup/backup_test.go +++ b/pkg/backup/backup_test.go @@ -38,6 +38,7 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/client" "github.com/heptio/velero/pkg/discovery" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/podexec" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/util/collections" @@ -54,19 +55,19 @@ var ( ) type fakeAction struct { - selector ResourceSelector + selector velero.ResourceSelector ids []string backups []v1.Backup - additionalItems []ResourceIdentifier + additionalItems []velero.ResourceIdentifier } -var _ ItemAction = &fakeAction{} +var _ velero.BackupItemAction = &fakeAction{} func newFakeAction(resource string) *fakeAction { return (&fakeAction{}).ForResource(resource) } -func (a *fakeAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) { +func (a *fakeAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { metadata, err := meta.Accessor(item) if err != nil { return item, a.additionalItems, err @@ -77,7 +78,7 @@ func (a *fakeAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runt return item, a.additionalItems, nil } -func (a *fakeAction) AppliesTo() (ResourceSelector, error) { +func (a *fakeAction) AppliesTo() (velero.ResourceSelector, error) { return a.selector, nil } @@ -89,34 +90,34 @@ func (a *fakeAction) ForResource(resource string) *fakeAction { func TestResolveActions(t *testing.T) { tests := []struct { name string - input []ItemAction + input []velero.BackupItemAction expected []resolvedAction resourcesWithErrors []string expectError bool }{ { name: "empty input", - input: []ItemAction{}, + input: []velero.BackupItemAction{}, expected: nil, }, { name: "resolve error", - input: []ItemAction{&fakeAction{selector: ResourceSelector{LabelSelector: "=invalid-selector"}}}, + input: []velero.BackupItemAction{&fakeAction{selector: velero.ResourceSelector{LabelSelector: "=invalid-selector"}}}, expected: nil, expectError: true, }, { name: "resolved", - input: []ItemAction{newFakeAction("foo"), newFakeAction("bar")}, + input: []velero.BackupItemAction{newFakeAction("foo"), newFakeAction("bar")}, expected: []resolvedAction{ { - ItemAction: newFakeAction("foo"), + BackupItemAction: newFakeAction("foo"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("foodies.somegroup"), namespaceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), }, { - ItemAction: newFakeAction("bar"), + BackupItemAction: newFakeAction("bar"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("barnacles.anothergroup"), namespaceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), diff --git a/pkg/backup/item_backupper.go b/pkg/backup/item_backupper.go index 328e9df89..c430a75aa 100644 --- a/pkg/backup/item_backupper.go +++ b/pkg/backup/item_backupper.go @@ -34,9 +34,9 @@ import ( api "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/client" - "github.com/heptio/velero/pkg/cloudprovider" "github.com/heptio/velero/pkg/discovery" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/podexec" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/volume" @@ -106,7 +106,7 @@ type defaultItemBackupper struct { itemHookHandler itemHookHandler additionalItemBackupper ItemBackupper - snapshotLocationBlockStores map[string]cloudprovider.BlockStore + snapshotLocationBlockStores map[string]velero.BlockStore } // backupItem backs up an individual item to tarWriter. The item may be excluded based on the @@ -345,7 +345,7 @@ func (ib *defaultItemBackupper) executeActions( // blockStore instantiates and initializes a BlockStore given a VolumeSnapshotLocation, // or returns an existing one if one's already been initialized for the location. -func (ib *defaultItemBackupper) blockStore(snapshotLocation *api.VolumeSnapshotLocation) (cloudprovider.BlockStore, error) { +func (ib *defaultItemBackupper) blockStore(snapshotLocation *api.VolumeSnapshotLocation) (velero.BlockStore, error) { if bs, ok := ib.snapshotLocationBlockStores[snapshotLocation.Name]; ok { return bs, nil } @@ -360,7 +360,7 @@ func (ib *defaultItemBackupper) blockStore(snapshotLocation *api.VolumeSnapshotL } if ib.snapshotLocationBlockStores == nil { - ib.snapshotLocationBlockStores = make(map[string]cloudprovider.BlockStore) + ib.snapshotLocationBlockStores = make(map[string]velero.BlockStore) } ib.snapshotLocationBlockStores[snapshotLocation.Name] = bs @@ -405,7 +405,7 @@ func (ib *defaultItemBackupper) takePVSnapshot(obj runtime.Unstructured, log log var ( volumeID, location string - blockStore cloudprovider.BlockStore + blockStore velero.BlockStore ) for _, snapshotLocation := range ib.backupRequest.SnapshotLocations { diff --git a/pkg/backup/item_backupper_test.go b/pkg/backup/item_backupper_test.go index bd9ba5be7..01ade8931 100644 --- a/pkg/backup/item_backupper_test.go +++ b/pkg/backup/item_backupper_test.go @@ -39,7 +39,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" v1 "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/cloudprovider" + "github.com/heptio/velero/pkg/plugin/velero" resticmocks "github.com/heptio/velero/pkg/restic/mocks" "github.com/heptio/velero/pkg/util/collections" velerotest "github.com/heptio/velero/pkg/util/test" @@ -166,7 +166,7 @@ func TestBackupItemNoSkips(t *testing.T) { tarHeaderWriteError bool customAction bool expectedActionID string - customActionAdditionalItemIdentifiers []ResourceIdentifier + customActionAdditionalItemIdentifiers []velero.ResourceIdentifier customActionAdditionalItems []runtime.Unstructured groupResource string snapshottableVolumes map[string]v1.VolumeBackupInfo @@ -239,7 +239,7 @@ func TestBackupItemNoSkips(t *testing.T) { expectedTarHeaderName: "resources/resource.group/namespaces/myns/bar.json", customAction: true, expectedActionID: "myns/bar", - customActionAdditionalItemIdentifiers: []ResourceIdentifier{ + customActionAdditionalItemIdentifiers: []velero.ResourceIdentifier{ { GroupResource: schema.GroupResource{Group: "g1", Resource: "r1"}, Namespace: "ns1", @@ -265,7 +265,7 @@ func TestBackupItemNoSkips(t *testing.T) { expectedTarHeaderName: "resources/resource.group/namespaces/myns/bar.json", customAction: true, expectedActionID: "myns/bar", - customActionAdditionalItemIdentifiers: []ResourceIdentifier{ + customActionAdditionalItemIdentifiers: []velero.ResourceIdentifier{ { GroupResource: schema.GroupResource{Group: "g1", Resource: "r1"}, Namespace: "ns1", @@ -397,7 +397,7 @@ func TestBackupItemNoSkips(t *testing.T) { } backup.ResolvedActions = []resolvedAction{ { - ItemAction: action, + BackupItemAction: action, namespaceIncludesExcludes: collections.NewIncludesExcludes(), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes(groupResource.String()), selector: labels.Everything(), @@ -548,10 +548,10 @@ func TestBackupItemNoSkips(t *testing.T) { } type blockStoreGetter struct { - blockStore cloudprovider.BlockStore + blockStore velero.BlockStore } -func (b *blockStoreGetter) GetBlockStore(name string) (cloudprovider.BlockStore, error) { +func (b *blockStoreGetter) GetBlockStore(name string) (velero.BlockStore, error) { if b.blockStore != nil { return b.blockStore, nil } @@ -560,7 +560,7 @@ func (b *blockStoreGetter) GetBlockStore(name string) (cloudprovider.BlockStore, type addAnnotationAction struct{} -func (a *addAnnotationAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) { +func (a *addAnnotationAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { // since item actions run out-of-proc, do a deep-copy here to simulate passing data // across a process boundary. copy := item.(*unstructured.Unstructured).DeepCopy() @@ -580,7 +580,7 @@ func (a *addAnnotationAction) Execute(item runtime.Unstructured, backup *v1.Back return copy, nil, nil } -func (a *addAnnotationAction) AppliesTo() (ResourceSelector, error) { +func (a *addAnnotationAction) AppliesTo() (velero.ResourceSelector, error) { panic("not implemented") } @@ -600,7 +600,7 @@ func TestItemActionModificationsToItemPersist(t *testing.T) { ResourceIncludesExcludes: collections.NewIncludesExcludes(), ResolvedActions: []resolvedAction{ { - ItemAction: &addAnnotationAction{}, + BackupItemAction: &addAnnotationAction{}, namespaceIncludesExcludes: collections.NewIncludesExcludes(), resourceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), @@ -656,7 +656,7 @@ func TestResticAnnotationsPersist(t *testing.T) { ResourceIncludesExcludes: collections.NewIncludesExcludes(), ResolvedActions: []resolvedAction{ { - ItemAction: &addAnnotationAction{}, + BackupItemAction: &addAnnotationAction{}, namespaceIncludesExcludes: collections.NewIncludesExcludes(), resourceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), diff --git a/pkg/backup/mocks/item_action.go b/pkg/backup/mocks/item_action.go index 381edb30d..095e61f31 100644 --- a/pkg/backup/mocks/item_action.go +++ b/pkg/backup/mocks/item_action.go @@ -16,10 +16,13 @@ limitations under the License. // Code generated by mockery v1.0.0. DO NOT EDIT. package mocks -import backup "github.com/heptio/velero/pkg/backup" -import mock "github.com/stretchr/testify/mock" -import runtime "k8s.io/apimachinery/pkg/runtime" -import v1 "github.com/heptio/velero/pkg/apis/velero/v1" +import ( + mock "github.com/stretchr/testify/mock" + runtime "k8s.io/apimachinery/pkg/runtime" + + v1 "github.com/heptio/velero/pkg/apis/velero/v1" + "github.com/heptio/velero/pkg/plugin/velero" +) // ItemAction is an autogenerated mock type for the ItemAction type type ItemAction struct { @@ -27,14 +30,14 @@ type ItemAction struct { } // AppliesTo provides a mock function with given fields: -func (_m *ItemAction) AppliesTo() (backup.ResourceSelector, error) { +func (_m *ItemAction) AppliesTo() (velero.ResourceSelector, error) { ret := _m.Called() - var r0 backup.ResourceSelector - if rf, ok := ret.Get(0).(func() backup.ResourceSelector); ok { + var r0 velero.ResourceSelector + if rf, ok := ret.Get(0).(func() velero.ResourceSelector); ok { r0 = rf() } else { - r0 = ret.Get(0).(backup.ResourceSelector) + r0 = ret.Get(0).(velero.ResourceSelector) } var r1 error @@ -48,7 +51,7 @@ func (_m *ItemAction) AppliesTo() (backup.ResourceSelector, error) { } // Execute provides a mock function with given fields: item, _a1 -func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtime.Unstructured, []backup.ResourceIdentifier, error) { +func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { ret := _m.Called(item, _a1) var r0 runtime.Unstructured @@ -60,12 +63,12 @@ func (_m *ItemAction) Execute(item runtime.Unstructured, _a1 *v1.Backup) (runtim } } - var r1 []backup.ResourceIdentifier - if rf, ok := ret.Get(1).(func(runtime.Unstructured, *v1.Backup) []backup.ResourceIdentifier); ok { + var r1 []velero.ResourceIdentifier + if rf, ok := ret.Get(1).(func(runtime.Unstructured, *v1.Backup) []velero.ResourceIdentifier); ok { r1 = rf(item, _a1) } else { if ret.Get(1) != nil { - r1 = ret.Get(1).([]backup.ResourceIdentifier) + r1 = ret.Get(1).([]velero.ResourceIdentifier) } } diff --git a/pkg/backup/pod_action.go b/pkg/backup/pod_action.go index 4268611dc..535ada4a8 100644 --- a/pkg/backup/pod_action.go +++ b/pkg/backup/pod_action.go @@ -24,21 +24,22 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" ) -// podAction implements ItemAction. -type podAction struct { +// PodAction implements ItemAction. +type PodAction struct { log logrus.FieldLogger } // NewPodAction creates a new ItemAction for pods. -func NewPodAction(logger logrus.FieldLogger) ItemAction { - return &podAction{log: logger} +func NewPodAction(logger logrus.FieldLogger) *PodAction { + return &PodAction{log: logger} } // AppliesTo returns a ResourceSelector that applies only to pods. -func (a *podAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *PodAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"pods"}, }, nil } @@ -46,7 +47,7 @@ func (a *podAction) AppliesTo() (ResourceSelector, error) { // Execute scans the pod's spec.volumes for persistentVolumeClaim volumes and returns a // ResourceIdentifier list containing references to all of the persistentVolumeClaim volumes used by // the pod. This ensures that when a pod is backed up, all referenced PVCs are backed up too. -func (a *podAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) { +func (a *PodAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { a.log.Info("Executing podAction") defer a.log.Info("Done executing podAction") @@ -60,12 +61,12 @@ func (a *podAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runti return item, nil, nil } - var additionalItems []ResourceIdentifier + var additionalItems []velero.ResourceIdentifier for _, volume := range pod.Spec.Volumes { if volume.PersistentVolumeClaim != nil && volume.PersistentVolumeClaim.ClaimName != "" { a.log.Infof("Adding pvc %s to additionalItems", volume.PersistentVolumeClaim.ClaimName) - additionalItems = append(additionalItems, ResourceIdentifier{ + additionalItems = append(additionalItems, velero.ResourceIdentifier{ GroupResource: kuberesource.PersistentVolumeClaims, Namespace: pod.Namespace, Name: volume.PersistentVolumeClaim.ClaimName, diff --git a/pkg/backup/pod_action_test.go b/pkg/backup/pod_action_test.go index 6ce6e3daa..34a297734 100644 --- a/pkg/backup/pod_action_test.go +++ b/pkg/backup/pod_action_test.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -33,7 +34,7 @@ func TestPodActionAppliesTo(t *testing.T) { actual, err := a.AppliesTo() require.NoError(t, err) - expected := ResourceSelector{ + expected := velero.ResourceSelector{ IncludedResources: []string{"pods"}, } assert.Equal(t, expected, actual) @@ -43,7 +44,7 @@ func TestPodActionExecute(t *testing.T) { tests := []struct { name string pod runtime.Unstructured - expected []ResourceIdentifier + expected []velero.ResourceIdentifier }{ { name: "no spec.volumes", @@ -109,7 +110,7 @@ func TestPodActionExecute(t *testing.T) { } } `), - expected: []ResourceIdentifier{ + expected: []velero.ResourceIdentifier{ {GroupResource: kuberesource.PersistentVolumeClaims, Namespace: "foo", Name: "claim1"}, {GroupResource: kuberesource.PersistentVolumeClaims, Namespace: "foo", Name: "claim2"}, }, diff --git a/pkg/backup/resource_backupper_test.go b/pkg/backup/resource_backupper_test.go index ff403d2b3..1c8467ec7 100644 --- a/pkg/backup/resource_backupper_test.go +++ b/pkg/backup/resource_backupper_test.go @@ -228,7 +228,7 @@ func TestBackupResource(t *testing.T) { }, ResolvedActions: []resolvedAction{ { - ItemAction: newFakeAction("pods"), + BackupItemAction: newFakeAction("pods"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("pods"), }, }, @@ -390,7 +390,7 @@ func TestBackupResourceCohabitation(t *testing.T) { ResourceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"), ResolvedActions: []resolvedAction{ { - ItemAction: newFakeAction("pods"), + BackupItemAction: newFakeAction("pods"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("pods"), }, }, diff --git a/pkg/backup/service_account_action.go b/pkg/backup/service_account_action.go index 057f1e8b0..318f2db69 100644 --- a/pkg/backup/service_account_action.go +++ b/pkg/backup/service_account_action.go @@ -28,16 +28,17 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" velerodiscovery "github.com/heptio/velero/pkg/discovery" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" ) -// serviceAccountAction implements ItemAction. -type serviceAccountAction struct { +// ServiceAccountAction implements ItemAction. +type ServiceAccountAction struct { log logrus.FieldLogger clusterRoleBindings []ClusterRoleBinding } // NewServiceAccountAction creates a new ItemAction for service accounts. -func NewServiceAccountAction(logger logrus.FieldLogger, clusterRoleBindingListers map[string]ClusterRoleBindingLister, discoveryHelper velerodiscovery.Helper) (ItemAction, error) { +func NewServiceAccountAction(logger logrus.FieldLogger, clusterRoleBindingListers map[string]ClusterRoleBindingLister, discoveryHelper velerodiscovery.Helper) (*ServiceAccountAction, error) { // Look up the supported RBAC version var supportedAPI metav1.GroupVersionForDiscovery for _, ag := range discoveryHelper.APIGroups() { @@ -56,15 +57,15 @@ func NewServiceAccountAction(logger logrus.FieldLogger, clusterRoleBindingLister return nil, err } - return &serviceAccountAction{ + return &ServiceAccountAction{ log: logger, clusterRoleBindings: crbs, }, nil } // AppliesTo returns a ResourceSelector that applies only to service accounts. -func (a *serviceAccountAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *ServiceAccountAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"serviceaccounts"}, }, nil } @@ -72,9 +73,9 @@ func (a *serviceAccountAction) AppliesTo() (ResourceSelector, error) { // Execute checks for any ClusterRoleBindings that have this service account as a subject, and // adds the ClusterRoleBinding and associated ClusterRole to the list of additional items to // be backed up. -func (a *serviceAccountAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) { - a.log.Info("Running serviceAccountAction") - defer a.log.Info("Done running serviceAccountAction") +func (a *ServiceAccountAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { + a.log.Info("Running ServiceAccountAction") + defer a.log.Info("Done running ServiceAccountAction") objectMeta, err := meta.Accessor(item) if err != nil { @@ -101,16 +102,16 @@ func (a *serviceAccountAction) Execute(item runtime.Unstructured, backup *v1.Bac } } - var additionalItems []ResourceIdentifier + var additionalItems []velero.ResourceIdentifier for binding := range bindings { - additionalItems = append(additionalItems, ResourceIdentifier{ + additionalItems = append(additionalItems, velero.ResourceIdentifier{ GroupResource: kuberesource.ClusterRoleBindings, Name: binding, }) } for role := range roles { - additionalItems = append(additionalItems, ResourceIdentifier{ + additionalItems = append(additionalItems, velero.ResourceIdentifier{ GroupResource: kuberesource.ClusterRoles, Name: role, }) diff --git a/pkg/backup/service_account_action_test.go b/pkg/backup/service_account_action_test.go index 370ff5e3d..8e74d3a3e 100644 --- a/pkg/backup/service_account_action_test.go +++ b/pkg/backup/service_account_action_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -77,12 +78,12 @@ func (f FakeV1beta1ClusterRoleBindingLister) List() ([]ClusterRoleBinding, error func TestServiceAccountActionAppliesTo(t *testing.T) { // Instantiating the struct directly since using // NewServiceAccountAction requires a full kubernetes clientset - a := &serviceAccountAction{} + a := &ServiceAccountAction{} actual, err := a.AppliesTo() require.NoError(t, err) - expected := ResourceSelector{ + expected := velero.ResourceSelector{ IncludedResources: []string{"serviceaccounts"}, } assert.Equal(t, expected, actual) @@ -189,9 +190,7 @@ func TestNewServiceAccountAction(t *testing.T) { } action, err := NewServiceAccountAction(logger, clusterRoleBindingListers, &discoveryHelper) require.NoError(t, err) - saAction, ok := action.(*serviceAccountAction) - require.True(t, ok) - assert.Equal(t, test.expectedCRBs, saAction.clusterRoleBindings) + assert.Equal(t, test.expectedCRBs, action.clusterRoleBindings) }) } } @@ -201,7 +200,7 @@ func TestServiceAccountActionExecute(t *testing.T) { name string serviceAccount runtime.Unstructured crbs []rbac.ClusterRoleBinding - expectedAdditionalItems []ResourceIdentifier + expectedAdditionalItems []velero.ResourceIdentifier }{ { name: "no crbs", @@ -345,7 +344,7 @@ func TestServiceAccountActionExecute(t *testing.T) { }, }, }, - expectedAdditionalItems: []ResourceIdentifier{ + expectedAdditionalItems: []velero.ResourceIdentifier{ { GroupResource: kuberesource.ClusterRoleBindings, Name: "crb-2", @@ -377,7 +376,7 @@ func TestServiceAccountActionExecute(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { // Create the action struct directly so we don't need to mock a clientset - action := &serviceAccountAction{ + action := &ServiceAccountAction{ log: velerotest.NewLogger(), clusterRoleBindings: newV1ClusterRoleBindingList(test.crbs), } @@ -409,7 +408,7 @@ func TestServiceAccountActionExecuteOnBeta1(t *testing.T) { name string serviceAccount runtime.Unstructured crbs []rbacbeta.ClusterRoleBinding - expectedAdditionalItems []ResourceIdentifier + expectedAdditionalItems []velero.ResourceIdentifier }{ { name: "no crbs", @@ -553,7 +552,7 @@ func TestServiceAccountActionExecuteOnBeta1(t *testing.T) { }, }, }, - expectedAdditionalItems: []ResourceIdentifier{ + expectedAdditionalItems: []velero.ResourceIdentifier{ { GroupResource: kuberesource.ClusterRoleBindings, Name: "crb-2", @@ -585,7 +584,7 @@ func TestServiceAccountActionExecuteOnBeta1(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { // Create the action struct directly so we don't need to mock a clientset - action := &serviceAccountAction{ + action := &ServiceAccountAction{ log: velerotest.NewLogger(), clusterRoleBindings: newV1beta1ClusterRoleBindingList(test.crbs), } diff --git a/pkg/cloudprovider/aws/block_store.go b/pkg/cloudprovider/aws/block_store.go index 985e8044e..6b2c040e6 100644 --- a/pkg/cloudprovider/aws/block_store.go +++ b/pkg/cloudprovider/aws/block_store.go @@ -32,8 +32,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" - - "github.com/heptio/velero/pkg/cloudprovider" ) const regionKey = "region" @@ -43,7 +41,7 @@ const regionKey = "region" // from snapshot. var iopsVolumeTypes = sets.NewString("io1") -type blockStore struct { +type BlockStore struct { log logrus.FieldLogger ec2 *ec2.EC2 } @@ -61,11 +59,11 @@ func getSession(config *aws.Config) (*session.Session, error) { return sess, nil } -func NewBlockStore(logger logrus.FieldLogger) cloudprovider.BlockStore { - return &blockStore{log: logger} +func NewBlockStore(logger logrus.FieldLogger) *BlockStore { + return &BlockStore{log: logger} } -func (b *blockStore) Init(config map[string]string) error { +func (b *BlockStore) Init(config map[string]string) error { region := config[regionKey] if region == "" { return errors.Errorf("missing %s in aws configuration", regionKey) @@ -83,7 +81,7 @@ func (b *blockStore) Init(config map[string]string) error { return nil } -func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) { +func (b *BlockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) { // describe the snapshot so we can apply its tags to the volume snapReq := &ec2.DescribeSnapshotsInput{ SnapshotIds: []*string{&snapshotID}, @@ -124,7 +122,7 @@ func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ s return *res.VolumeId, nil } -func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { +func (b *BlockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { volumeInfo, err := b.describeVolume(volumeID) if err != nil { return "", nil, err @@ -146,7 +144,7 @@ func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, e return volumeType, iops, nil } -func (b *blockStore) describeVolume(volumeID string) (*ec2.Volume, error) { +func (b *BlockStore) describeVolume(volumeID string) (*ec2.Volume, error) { req := &ec2.DescribeVolumesInput{ VolumeIds: []*string{&volumeID}, } @@ -162,7 +160,7 @@ func (b *blockStore) describeVolume(volumeID string) (*ec2.Volume, error) { return res.Volumes[0], nil } -func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { +func (b *BlockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { // describe the volume so we can copy its tags to the snapshot volumeInfo, err := b.describeVolume(volumeID) if err != nil { @@ -234,7 +232,7 @@ func ec2Tag(key, val string) *ec2.Tag { return &ec2.Tag{Key: &key, Value: &val} } -func (b *blockStore) DeleteSnapshot(snapshotID string) error { +func (b *BlockStore) DeleteSnapshot(snapshotID string) error { req := &ec2.DeleteSnapshotInput{ SnapshotId: &snapshotID, } @@ -256,7 +254,7 @@ func (b *blockStore) DeleteSnapshot(snapshotID string) error { var ebsVolumeIDRegex = regexp.MustCompile("vol-.*") -func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { +func (b *BlockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return "", errors.WithStack(err) @@ -273,7 +271,7 @@ func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, e return ebsVolumeIDRegex.FindString(pv.Spec.AWSElasticBlockStore.VolumeID), nil } -func (b *blockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { +func (b *BlockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return nil, errors.WithStack(err) diff --git a/pkg/cloudprovider/aws/block_store_test.go b/pkg/cloudprovider/aws/block_store_test.go index f88292c72..281305eab 100644 --- a/pkg/cloudprovider/aws/block_store_test.go +++ b/pkg/cloudprovider/aws/block_store_test.go @@ -30,7 +30,7 @@ import ( ) func TestGetVolumeID(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, @@ -70,7 +70,7 @@ func TestGetVolumeID(t *testing.T) { } func TestSetVolumeID(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, @@ -105,7 +105,7 @@ func TestSetVolumeID(t *testing.T) { } func TestSetVolumeIDNoZone(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, diff --git a/pkg/cloudprovider/aws/object_store.go b/pkg/cloudprovider/aws/object_store.go index 445be734c..7317eb53c 100644 --- a/pkg/cloudprovider/aws/object_store.go +++ b/pkg/cloudprovider/aws/object_store.go @@ -24,13 +24,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/endpoints" - "github.com/aws/aws-sdk-go/aws/signer/v4" + v4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/pkg/errors" "github.com/sirupsen/logrus" - - "github.com/heptio/velero/pkg/cloudprovider" ) const ( @@ -42,7 +40,7 @@ const ( signatureVersionKey = "signatureVersion" ) -type objectStore struct { +type ObjectStore struct { log logrus.FieldLogger s3 *s3.S3 preSignS3 *s3.S3 @@ -51,8 +49,8 @@ type objectStore struct { signatureVersion string } -func NewObjectStore(logger logrus.FieldLogger) cloudprovider.ObjectStore { - return &objectStore{log: logger} +func NewObjectStore(logger logrus.FieldLogger) *ObjectStore { + return &ObjectStore{log: logger} } func isValidSignatureVersion(signatureVersion string) bool { @@ -63,7 +61,7 @@ func isValidSignatureVersion(signatureVersion string) bool { return false } -func (o *objectStore) Init(config map[string]string) error { +func (o *ObjectStore) Init(config map[string]string) error { var ( region = config[regionKey] s3URL = config[s3URLKey] @@ -162,7 +160,7 @@ func newAWSConfig(url, region string, forcePathStyle bool) (*aws.Config, error) return awsConfig, nil } -func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { +func (o *ObjectStore) PutObject(bucket, key string, body io.Reader) error { req := &s3manager.UploadInput{ Bucket: &bucket, Key: &key, @@ -180,7 +178,7 @@ func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { return errors.Wrapf(err, "error putting object %s", key) } -func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { +func (o *ObjectStore) GetObject(bucket, key string) (io.ReadCloser, error) { req := &s3.GetObjectInput{ Bucket: &bucket, Key: &key, @@ -194,7 +192,7 @@ func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { return res.Body, nil } -func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { +func (o *ObjectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { req := &s3.ListObjectsV2Input{ Bucket: &bucket, Prefix: &prefix, @@ -215,7 +213,7 @@ func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]st return ret, nil } -func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { +func (o *ObjectStore) ListObjects(bucket, prefix string) ([]string, error) { req := &s3.ListObjectsV2Input{ Bucket: &bucket, Prefix: &prefix, @@ -241,7 +239,7 @@ func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { return ret, nil } -func (o *objectStore) DeleteObject(bucket, key string) error { +func (o *ObjectStore) DeleteObject(bucket, key string) error { req := &s3.DeleteObjectInput{ Bucket: &bucket, Key: &key, @@ -252,7 +250,7 @@ func (o *objectStore) DeleteObject(bucket, key string) error { return errors.Wrapf(err, "error deleting object %s", key) } -func (o *objectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { +func (o *ObjectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { req, _ := o.preSignS3.GetObjectRequest(&s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), diff --git a/pkg/cloudprovider/azure/block_store.go b/pkg/cloudprovider/azure/block_store.go index 7b0f7cd13..126a8de56 100644 --- a/pkg/cloudprovider/azure/block_store.go +++ b/pkg/cloudprovider/azure/block_store.go @@ -34,8 +34,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - - "github.com/heptio/velero/pkg/cloudprovider" ) const ( @@ -47,7 +45,7 @@ const ( disksResource = "disks" ) -type blockStore struct { +type BlockStore struct { log logrus.FieldLogger disks *disk.DisksClient snaps *disk.SnapshotsClient @@ -67,11 +65,11 @@ func (si *snapshotIdentifier) String() string { return getComputeResourceName(si.subscription, si.resourceGroup, snapshotsResource, si.name) } -func NewBlockStore(logger logrus.FieldLogger) cloudprovider.BlockStore { - return &blockStore{log: logger} +func NewBlockStore(logger logrus.FieldLogger) *BlockStore { + return &BlockStore{log: logger} } -func (b *blockStore) Init(config map[string]string) error { +func (b *BlockStore) Init(config map[string]string) error { // 1. we need AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_RESOURCE_GROUP envVars, err := getRequiredValues(os.Getenv, tenantIDEnvVar, clientIDEnvVar, clientSecretEnvVar, subscriptionIDEnvVar, resourceGroupEnvVar) if err != nil { @@ -124,7 +122,7 @@ func (b *blockStore) Init(config map[string]string) error { return nil } -func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) { +func (b *BlockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (string, error) { snapshotIdentifier, err := b.parseSnapshotName(snapshotID) if err != nil { return "", err @@ -170,7 +168,7 @@ func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ s return diskName, nil } -func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { +func (b *BlockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { res, err := b.disks.Get(context.TODO(), b.disksResourceGroup, volumeID) if err != nil { return "", nil, errors.WithStack(err) @@ -183,7 +181,7 @@ func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, e return string(res.Sku.Name), nil, nil } -func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { +func (b *BlockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { // Lookup disk info for its Location diskInfo, err := b.disks.Get(context.TODO(), b.disksResourceGroup, volumeID) if err != nil { @@ -261,7 +259,7 @@ func stringPtr(s string) *string { return &s } -func (b *blockStore) DeleteSnapshot(snapshotID string) error { +func (b *BlockStore) DeleteSnapshot(snapshotID string) error { snapshotInfo, err := b.parseSnapshotName(snapshotID) if err != nil { return err @@ -309,7 +307,7 @@ var snapshotURIRegexp = regexp.MustCompile( // // TODO(1.0) remove this function and replace usage with `parseFullSnapshotName` since // we won't support the legacy snapshot name format for 1.0. -func (b *blockStore) parseSnapshotName(name string) (*snapshotIdentifier, error) { +func (b *BlockStore) parseSnapshotName(name string) (*snapshotIdentifier, error) { switch { // legacy format - name only (not fully-qualified) case !strings.Contains(name, "/"): @@ -359,7 +357,7 @@ func parseFullSnapshotName(name string) (*snapshotIdentifier, error) { return snapshotID, nil } -func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { +func (b *BlockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return "", errors.WithStack(err) @@ -376,7 +374,7 @@ func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, e return pv.Spec.AzureDisk.DiskName, nil } -func (b *blockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { +func (b *BlockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return nil, errors.WithStack(err) diff --git a/pkg/cloudprovider/azure/block_store_test.go b/pkg/cloudprovider/azure/block_store_test.go index 06e0c82f2..43b1af84f 100644 --- a/pkg/cloudprovider/azure/block_store_test.go +++ b/pkg/cloudprovider/azure/block_store_test.go @@ -27,7 +27,7 @@ import ( ) func TestGetVolumeID(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, @@ -55,7 +55,7 @@ func TestGetVolumeID(t *testing.T) { } func TestSetVolumeID(t *testing.T) { - b := &blockStore{ + b := &BlockStore{ disksResourceGroup: "rg", subscription: "sub", } @@ -98,7 +98,7 @@ func TestSetVolumeID(t *testing.T) { // the `parseFullSnapshotName` function, and remove case for legacy // format func TestParseSnapshotName(t *testing.T) { - b := &blockStore{ + b := &BlockStore{ subscription: "default-sub", disksResourceGroup: "default-rg-legacy", } diff --git a/pkg/cloudprovider/azure/object_store.go b/pkg/cloudprovider/azure/object_store.go index 138a406e0..bea09d3d1 100644 --- a/pkg/cloudprovider/azure/object_store.go +++ b/pkg/cloudprovider/azure/object_store.go @@ -29,21 +29,19 @@ import ( "github.com/Azure/go-autorest/autorest/azure" "github.com/pkg/errors" "github.com/sirupsen/logrus" - - "github.com/heptio/velero/pkg/cloudprovider" ) const ( storageAccountConfigKey = "storageAccount" ) -type objectStore struct { +type ObjectStore struct { blobClient *storage.BlobStorageClient log logrus.FieldLogger } -func NewObjectStore(logger logrus.FieldLogger) cloudprovider.ObjectStore { - return &objectStore{log: logger} +func NewObjectStore(logger logrus.FieldLogger) *ObjectStore { + return &ObjectStore{log: logger} } func getStorageAccountKey(config map[string]string) (string, error) { @@ -100,7 +98,7 @@ func mapLookup(data map[string]string) func(string) string { } } -func (o *objectStore) Init(config map[string]string) error { +func (o *ObjectStore) Init(config map[string]string) error { storageAccountKey, err := getStorageAccountKey(config) if err != nil { return err @@ -118,7 +116,7 @@ func (o *objectStore) Init(config map[string]string) error { return nil } -func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { +func (o *ObjectStore) PutObject(bucket, key string, body io.Reader) error { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return err @@ -132,7 +130,7 @@ func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { return errors.WithStack(blob.CreateBlockBlobFromReader(body, nil)) } -func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { +func (o *ObjectStore) GetObject(bucket, key string) (io.ReadCloser, error) { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return nil, err @@ -151,7 +149,7 @@ func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { return res, nil } -func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { +func (o *ObjectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return nil, err @@ -170,7 +168,7 @@ func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]st return res.BlobPrefixes, nil } -func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { +func (o *ObjectStore) ListObjects(bucket, prefix string) ([]string, error) { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return nil, err @@ -193,7 +191,7 @@ func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { return ret, nil } -func (o *objectStore) DeleteObject(bucket string, key string) error { +func (o *ObjectStore) DeleteObject(bucket string, key string) error { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return err @@ -207,7 +205,7 @@ func (o *objectStore) DeleteObject(bucket string, key string) error { return errors.WithStack(blob.Delete(nil)) } -func (o *objectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { +func (o *ObjectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { container, err := getContainerReference(o.blobClient, bucket) if err != nil { return "", err diff --git a/pkg/cloudprovider/gcp/block_store.go b/pkg/cloudprovider/gcp/block_store.go index 271e52fb9..a958613b0 100644 --- a/pkg/cloudprovider/gcp/block_store.go +++ b/pkg/cloudprovider/gcp/block_store.go @@ -33,8 +33,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - - "github.com/heptio/velero/pkg/cloudprovider" ) const ( @@ -42,17 +40,17 @@ const ( zoneSeparator = "__" ) -type blockStore struct { +type BlockStore struct { gce *compute.Service project string log logrus.FieldLogger } -func NewBlockStore(logger logrus.FieldLogger) cloudprovider.BlockStore { - return &blockStore{log: logger} +func NewBlockStore(logger logrus.FieldLogger) *BlockStore { + return &BlockStore{log: logger} } -func (b *blockStore) Init(config map[string]string) error { +func (b *BlockStore) Init(config map[string]string) error { project, err := extractProjectFromCreds() if err != nil { return err @@ -127,7 +125,7 @@ func parseRegion(volumeAZ string) (string, error) { } // Retrieve the URLs for zones via the GCP API. -func (b *blockStore) getZoneURLs(volumeAZ string) ([]string, error) { +func (b *BlockStore) getZoneURLs(volumeAZ string) ([]string, error) { zones := strings.Split(volumeAZ, zoneSeparator) var zoneURLs []string for _, z := range zones { @@ -142,7 +140,7 @@ func (b *blockStore) getZoneURLs(volumeAZ string) ([]string, error) { return zoneURLs, nil } -func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) { +func (b *BlockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) { // get the snapshot so we can apply its tags to the volume res, err := b.gce.Snapshots.Get(b.project, snapshotID).Do() if err != nil { @@ -187,7 +185,7 @@ func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ s return disk.Name, nil } -func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { +func (b *BlockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) { var ( res *compute.Disk err error @@ -211,7 +209,7 @@ func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, e return res.Type, nil, nil } -func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { +func (b *BlockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) { // snapshot names must adhere to RFC1035 and be 1-63 characters // long var snapshotName string @@ -234,7 +232,7 @@ func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]s } } -func (b *blockStore) createSnapshot(snapshotName, volumeID, volumeAZ string, tags map[string]string) (string, error) { +func (b *BlockStore) createSnapshot(snapshotName, volumeID, volumeAZ string, tags map[string]string) (string, error) { disk, err := b.gce.Disks.Get(b.project, volumeAZ, volumeID).Do() if err != nil { return "", errors.WithStack(err) @@ -253,7 +251,7 @@ func (b *blockStore) createSnapshot(snapshotName, volumeID, volumeAZ string, tag return gceSnap.Name, nil } -func (b *blockStore) createRegionSnapshot(snapshotName, volumeID, volumeRegion string, tags map[string]string) (string, error) { +func (b *BlockStore) createRegionSnapshot(snapshotName, volumeID, volumeRegion string, tags map[string]string) (string, error) { disk, err := b.gce.RegionDisks.Get(b.project, volumeRegion, volumeID).Do() if err != nil { return "", errors.WithStack(err) @@ -306,7 +304,7 @@ func getSnapshotTags(veleroTags map[string]string, diskDescription string, log l return string(tagsJSON) } -func (b *blockStore) DeleteSnapshot(snapshotID string) error { +func (b *BlockStore) DeleteSnapshot(snapshotID string) error { _, err := b.gce.Snapshots.Delete(b.project, snapshotID).Do() // if it's a 404 (not found) error, we don't need to return an error @@ -321,7 +319,7 @@ func (b *blockStore) DeleteSnapshot(snapshotID string) error { return nil } -func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { +func (b *BlockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return "", errors.WithStack(err) @@ -338,7 +336,7 @@ func (b *blockStore) GetVolumeID(unstructuredPV runtime.Unstructured) (string, e return pv.Spec.GCEPersistentDisk.PDName, nil } -func (b *blockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { +func (b *BlockStore) SetVolumeID(unstructuredPV runtime.Unstructured, volumeID string) (runtime.Unstructured, error) { pv := new(v1.PersistentVolume) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.UnstructuredContent(), pv); err != nil { return nil, errors.WithStack(err) diff --git a/pkg/cloudprovider/gcp/block_store_test.go b/pkg/cloudprovider/gcp/block_store_test.go index 91fac52e7..aeb9c569b 100644 --- a/pkg/cloudprovider/gcp/block_store_test.go +++ b/pkg/cloudprovider/gcp/block_store_test.go @@ -31,7 +31,7 @@ import ( ) func TestGetVolumeID(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, @@ -59,7 +59,7 @@ func TestGetVolumeID(t *testing.T) { } func TestSetVolumeID(t *testing.T) { - b := &blockStore{} + b := &BlockStore{} pv := &unstructured.Unstructured{ Object: map[string]interface{}{}, diff --git a/pkg/cloudprovider/gcp/object_store.go b/pkg/cloudprovider/gcp/object_store.go index f9dd7f428..f9bd4add5 100644 --- a/pkg/cloudprovider/gcp/object_store.go +++ b/pkg/cloudprovider/gcp/object_store.go @@ -29,8 +29,6 @@ import ( "golang.org/x/oauth2/google" "google.golang.org/api/iterator" "google.golang.org/api/option" - - "github.com/heptio/velero/pkg/cloudprovider" ) const credentialsEnvVar = "GOOGLE_APPLICATION_CREDENTIALS" @@ -49,7 +47,7 @@ func (w *writer) getWriteCloser(bucket, key string) io.WriteCloser { return w.client.Bucket(bucket).Object(key).NewWriter(context.Background()) } -type objectStore struct { +type ObjectStore struct { log logrus.FieldLogger client *storage.Client googleAccessID string @@ -57,11 +55,11 @@ type objectStore struct { bucketWriter bucketWriter } -func NewObjectStore(logger logrus.FieldLogger) cloudprovider.ObjectStore { - return &objectStore{log: logger} +func NewObjectStore(logger logrus.FieldLogger) *ObjectStore { + return &ObjectStore{log: logger} } -func (o *objectStore) Init(config map[string]string) error { +func (o *ObjectStore) Init(config map[string]string) error { credentialsFile := os.Getenv(credentialsEnvVar) if credentialsFile == "" { return errors.Errorf("%s is undefined", credentialsEnvVar) @@ -97,7 +95,7 @@ func (o *objectStore) Init(config map[string]string) error { return nil } -func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { +func (o *ObjectStore) PutObject(bucket, key string, body io.Reader) error { w := o.bucketWriter.getWriteCloser(bucket, key) // The writer returned by NewWriter is asynchronous, so errors aren't guaranteed @@ -113,7 +111,7 @@ func (o *objectStore) PutObject(bucket, key string, body io.Reader) error { return closeErr } -func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { +func (o *ObjectStore) GetObject(bucket, key string) (io.ReadCloser, error) { r, err := o.client.Bucket(bucket).Object(key).NewReader(context.Background()) if err != nil { return nil, errors.WithStack(err) @@ -122,7 +120,7 @@ func (o *objectStore) GetObject(bucket, key string) (io.ReadCloser, error) { return r, nil } -func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { +func (o *ObjectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]string, error) { q := &storage.Query{ Prefix: prefix, Delimiter: delimiter, @@ -148,7 +146,7 @@ func (o *objectStore) ListCommonPrefixes(bucket, prefix, delimiter string) ([]st return res, nil } -func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { +func (o *ObjectStore) ListObjects(bucket, prefix string) ([]string, error) { q := &storage.Query{ Prefix: prefix, } @@ -170,11 +168,11 @@ func (o *objectStore) ListObjects(bucket, prefix string) ([]string, error) { } } -func (o *objectStore) DeleteObject(bucket, key string) error { +func (o *ObjectStore) DeleteObject(bucket, key string) error { return errors.Wrapf(o.client.Bucket(bucket).Object(key).Delete(context.Background()), "error deleting object %s", key) } -func (o *objectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { +func (o *ObjectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) { return storage.SignedURL(bucket, key, &storage.SignedURLOptions{ GoogleAccessID: o.googleAccessID, PrivateKey: o.privateKey, diff --git a/pkg/cloudprovider/gcp/object_store_test.go b/pkg/cloudprovider/gcp/object_store_test.go index 1367921ef..503f86259 100644 --- a/pkg/cloudprovider/gcp/object_store_test.go +++ b/pkg/cloudprovider/gcp/object_store_test.go @@ -89,7 +89,7 @@ func TestPutObject(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { wc := newMockWriteCloser(test.writeErr, test.closeErr) - o := NewObjectStore(velerotest.NewLogger()).(*objectStore) + o := NewObjectStore(velerotest.NewLogger()) o.bucketWriter = newFakeWriter(wc) err := o.PutObject("bucket", "key", strings.NewReader("contents")) diff --git a/pkg/cmd/server/plugin/plugin.go b/pkg/cmd/server/plugin/plugin.go index f730db9c5..0bf2e0c1b 100644 --- a/pkg/cmd/server/plugin/plugin.go +++ b/pkg/cmd/server/plugin/plugin.go @@ -86,7 +86,7 @@ func newGcpBlockStore(logger logrus.FieldLogger) (interface{}, error) { } func newPVBackupItemAction(logger logrus.FieldLogger) (interface{}, error) { - return backup.NewBackupPVAction(logger), nil + return backup.NewPVCAction(logger), nil } func newPodBackupItemAction(logger logrus.FieldLogger) (interface{}, error) { diff --git a/pkg/controller/backup_controller_test.go b/pkg/controller/backup_controller_test.go index edf4fa5aa..becf87840 100644 --- a/pkg/controller/backup_controller_test.go +++ b/pkg/controller/backup_controller_test.go @@ -42,6 +42,7 @@ import ( persistencemocks "github.com/heptio/velero/pkg/persistence/mocks" "github.com/heptio/velero/pkg/plugin" pluginmocks "github.com/heptio/velero/pkg/plugin/mocks" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/util/logging" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -50,7 +51,7 @@ type fakeBackupper struct { mock.Mock } -func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []pkgbackup.ItemAction, blockStoreGetter pkgbackup.BlockStoreGetter) error { +func (b *fakeBackupper) Backup(logger logrus.FieldLogger, backup *pkgbackup.Request, backupFile io.Writer, actions []velero.BackupItemAction, blockStoreGetter pkgbackup.BlockStoreGetter) error { args := b.Called(logger, backup, backupFile, actions, blockStoreGetter) return args.Error(0) } @@ -314,7 +315,7 @@ func TestProcessBackupCompletions(t *testing.T) { pluginManager.On("GetBackupItemActions").Return(nil, nil) pluginManager.On("CleanupClients").Return(nil) - backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []pkgbackup.ItemAction(nil), pluginManager).Return(nil) + backupper.On("Backup", mock.Anything, mock.Anything, mock.Anything, []velero.BackupItemAction(nil), pluginManager).Return(nil) // Ensure we have a CompletionTimestamp when uploading. // Failures will display the bytes in buf. diff --git a/pkg/controller/backup_deletion_controller.go b/pkg/controller/backup_deletion_controller.go index 00abda099..096475eca 100644 --- a/pkg/controller/backup_deletion_controller.go +++ b/pkg/controller/backup_deletion_controller.go @@ -34,12 +34,12 @@ import ( v1 "github.com/heptio/velero/pkg/apis/velero/v1" pkgbackup "github.com/heptio/velero/pkg/backup" - "github.com/heptio/velero/pkg/cloudprovider" velerov1client "github.com/heptio/velero/pkg/generated/clientset/versioned/typed/velero/v1" informers "github.com/heptio/velero/pkg/generated/informers/externalversions/velero/v1" listers "github.com/heptio/velero/pkg/generated/listers/velero/v1" "github.com/heptio/velero/pkg/persistence" "github.com/heptio/velero/pkg/plugin" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/util/kube" ) @@ -270,7 +270,7 @@ func (c *backupDeletionController) processRequest(req *v1.DeleteBackupRequest) e if snapshots, err := backupStore.GetBackupVolumeSnapshots(backup.Name); err != nil { errs = append(errs, errors.Wrap(err, "error getting backup's volume snapshots").Error()) } else { - blockStores := make(map[string]cloudprovider.BlockStore) + blockStores := make(map[string]velero.BlockStore) for _, snapshot := range snapshots { log.WithField("providerSnapshotID", snapshot.Status.ProviderSnapshotID).Info("Removing snapshot associated with backup") @@ -365,7 +365,7 @@ func blockStoreForSnapshotLocation( namespace, snapshotLocationName string, snapshotLocationLister listers.VolumeSnapshotLocationLister, pluginManager plugin.Manager, -) (cloudprovider.BlockStore, error) { +) (velero.BlockStore, error) { snapshotLocation, err := snapshotLocationLister.VolumeSnapshotLocations(namespace).Get(snapshotLocationName) if err != nil { return nil, errors.Wrapf(err, "error getting volume snapshot location %s", snapshotLocationName) diff --git a/pkg/controller/restore_controller.go b/pkg/controller/restore_controller.go index b860e29ba..b9db63461 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -41,6 +41,7 @@ import ( "github.com/heptio/velero/pkg/metrics" "github.com/heptio/velero/pkg/persistence" "github.com/heptio/velero/pkg/plugin" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restore" "github.com/heptio/velero/pkg/util/collections" kubeutil "github.com/heptio/velero/pkg/util/kube" @@ -426,7 +427,7 @@ func (c *restoreController) fetchBackupInfo(backupName string, pluginManager plu func (c *restoreController) runRestore( restore *api.Restore, - actions []restore.ItemAction, + actions []velero.RestoreItemAction, info backupInfo, pluginManager plugin.Manager, ) (restoreResult, error) { diff --git a/pkg/controller/restore_controller_test.go b/pkg/controller/restore_controller_test.go index 331cfbfd6..ad7fe3b28 100644 --- a/pkg/controller/restore_controller_test.go +++ b/pkg/controller/restore_controller_test.go @@ -45,6 +45,7 @@ import ( persistencemocks "github.com/heptio/velero/pkg/persistence/mocks" "github.com/heptio/velero/pkg/plugin" pluginmocks "github.com/heptio/velero/pkg/plugin/mocks" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restore" velerotest "github.com/heptio/velero/pkg/util/test" "github.com/heptio/velero/pkg/volume" @@ -922,7 +923,7 @@ func (r *fakeRestorer) Restore( backup *api.Backup, volumeSnapshots []*volume.Snapshot, backupReader io.Reader, - actions []restore.ItemAction, + actions []velero.RestoreItemAction, snapshotLocationLister listers.VolumeSnapshotLocationLister, blockStoreGetter restore.BlockStoreGetter, ) (api.RestoreResult, api.RestoreResult) { diff --git a/pkg/persistence/object_store.go b/pkg/persistence/object_store.go index c1557c909..d6616fab0 100644 --- a/pkg/persistence/object_store.go +++ b/pkg/persistence/object_store.go @@ -32,8 +32,8 @@ import ( kerrors "k8s.io/apimachinery/pkg/util/errors" velerov1api "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/cloudprovider" "github.com/heptio/velero/pkg/generated/clientset/versioned/scheme" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/volume" ) @@ -62,16 +62,16 @@ type BackupStore interface { const DownloadURLTTL = 10 * time.Minute type objectBackupStore struct { - objectStore cloudprovider.ObjectStore + objectStore velero.ObjectStore bucket string layout *ObjectStoreLayout logger logrus.FieldLogger } -// ObjectStoreGetter is a type that can get a cloudprovider.ObjectStore +// ObjectStoreGetter is a type that can get a velero.ObjectStore // from a provider name. type ObjectStoreGetter interface { - GetObjectStore(provider string) (cloudprovider.ObjectStore, error) + GetObjectStore(provider string) (velero.ObjectStore, error) } func NewObjectBackupStore(location *velerov1api.BackupStorageLocation, objectStoreGetter ObjectStoreGetter, logger logrus.FieldLogger) (BackupStore, error) { @@ -152,7 +152,7 @@ func (s *objectBackupStore) ListBackups() ([]string, error) { output := make([]string, 0, len(prefixes)) for _, prefix := range prefixes { - // values returned from a call to cloudprovider.ObjectStore's + // values returned from a call to ObjectStore's // ListCommonPrefixes method return the *full* prefix, inclusive // of s.backupsPrefix, and include the delimiter ("/") as a suffix. Trim // each of those off to get the backup name. @@ -318,7 +318,7 @@ func convertMapKeys(m map[string]string, find, replace string) map[string]string return m } -func keyExists(objectStore cloudprovider.ObjectStore, bucket, prefix, key string) (bool, error) { +func keyExists(objectStore velero.ObjectStore, bucket, prefix, key string) (bool, error) { keys, err := objectStore.ListObjects(bucket, prefix) if err != nil { return false, err @@ -478,7 +478,7 @@ func seekToBeginning(r io.Reader) error { return err } -func seekAndPutObject(objectStore cloudprovider.ObjectStore, bucket, key string, file io.Reader) error { +func seekAndPutObject(objectStore velero.ObjectStore, bucket, key string, file io.Reader) error { if file == nil { return nil } diff --git a/pkg/plugin/backup_item_action.go b/pkg/plugin/backup_item_action.go index 00e422faf..47b53b6af 100644 --- a/pkg/plugin/backup_item_action.go +++ b/pkg/plugin/backup_item_action.go @@ -28,8 +28,8 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" api "github.com/heptio/velero/pkg/apis/velero/v1" - velerobackup "github.com/heptio/velero/pkg/backup" proto "github.com/heptio/velero/pkg/plugin/generated" + "github.com/heptio/velero/pkg/plugin/velero" ) // BackupItemActionPlugin is an implementation of go-plugin's Plugin @@ -70,13 +70,13 @@ func newBackupItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientConn } } -func (c *BackupItemActionGRPCClient) AppliesTo() (velerobackup.ResourceSelector, error) { +func (c *BackupItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) { res, err := c.grpcClient.AppliesTo(context.Background(), &proto.AppliesToRequest{Plugin: c.plugin}) if err != nil { - return velerobackup.ResourceSelector{}, err + return velero.ResourceSelector{}, err } - return velerobackup.ResourceSelector{ + return velero.ResourceSelector{ IncludedNamespaces: res.IncludedNamespaces, ExcludedNamespaces: res.ExcludedNamespaces, IncludedResources: res.IncludedResources, @@ -85,7 +85,7 @@ func (c *BackupItemActionGRPCClient) AppliesTo() (velerobackup.ResourceSelector, }, nil } -func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velerobackup.ResourceIdentifier, error) { +func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { itemJSON, err := json.Marshal(item.UnstructuredContent()) if err != nil { return nil, nil, err @@ -112,10 +112,10 @@ func (c *BackupItemActionGRPCClient) Execute(item runtime.Unstructured, backup * return nil, nil, err } - var additionalItems []velerobackup.ResourceIdentifier + var additionalItems []velero.ResourceIdentifier for _, itm := range res.AdditionalItems { - newItem := velerobackup.ResourceIdentifier{ + newItem := velero.ResourceIdentifier{ GroupResource: schema.GroupResource{ Group: itm.Group, Resource: itm.Resource, @@ -146,13 +146,13 @@ type BackupItemActionGRPCServer struct { mux *serverMux } -func (s *BackupItemActionGRPCServer) getImpl(name string) (velerobackup.ItemAction, error) { +func (s *BackupItemActionGRPCServer) getImpl(name string) (velero.BackupItemAction, error) { impl, err := s.mux.getHandler(name) if err != nil { return nil, err } - itemAction, ok := impl.(velerobackup.ItemAction) + itemAction, ok := impl.(velero.BackupItemAction) if !ok { return nil, errors.Errorf("%T is not a backup item action", impl) } @@ -236,7 +236,7 @@ func (s *BackupItemActionGRPCServer) Execute(ctx context.Context, req *proto.Exe return res, nil } -func backupResourceIdentifierToProto(id velerobackup.ResourceIdentifier) *proto.ResourceIdentifier { +func backupResourceIdentifierToProto(id velero.ResourceIdentifier) *proto.ResourceIdentifier { return &proto.ResourceIdentifier{ Group: id.Group, Resource: id.Resource, diff --git a/pkg/plugin/backup_item_action_test.go b/pkg/plugin/backup_item_action_test.go index 66d7e16ff..1e842dccd 100644 --- a/pkg/plugin/backup_item_action_test.go +++ b/pkg/plugin/backup_item_action_test.go @@ -29,9 +29,9 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" v1 "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/backup" "github.com/heptio/velero/pkg/backup/mocks" proto "github.com/heptio/velero/pkg/plugin/generated" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -93,7 +93,7 @@ func TestBackupItemActionGRPCServerExecute(t *testing.T) { backup []byte item []byte implUpdatedItem runtime.Unstructured - implAdditionalItems []backup.ResourceIdentifier + implAdditionalItems []velero.ResourceIdentifier implError error expectError bool skipMock bool @@ -129,7 +129,7 @@ func TestBackupItemActionGRPCServerExecute(t *testing.T) { item: validItem, backup: validBackup, implUpdatedItem: &validItemObject, - implAdditionalItems: []backup.ResourceIdentifier{ + implAdditionalItems: []velero.ResourceIdentifier{ { GroupResource: schema.GroupResource{Group: "v1", Resource: "pods"}, Namespace: "myns", diff --git a/pkg/plugin/block_store.go b/pkg/plugin/block_store.go index fc3a4a6fa..3dac19f71 100644 --- a/pkg/plugin/block_store.go +++ b/pkg/plugin/block_store.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - "github.com/heptio/velero/pkg/cloudprovider" proto "github.com/heptio/velero/pkg/plugin/generated" + "github.com/heptio/velero/pkg/plugin/velero" ) // BlockStorePlugin is an implementation of go-plugin's Plugin @@ -203,13 +203,13 @@ type BlockStoreGRPCServer struct { mux *serverMux } -func (s *BlockStoreGRPCServer) getImpl(name string) (cloudprovider.BlockStore, error) { +func (s *BlockStoreGRPCServer) getImpl(name string) (velero.BlockStore, error) { impl, err := s.mux.getHandler(name) if err != nil { return nil, err } - blockStore, ok := impl.(cloudprovider.BlockStore) + blockStore, ok := impl.(velero.BlockStore) if !ok { return nil, errors.Errorf("%T is not a block store", impl) } diff --git a/pkg/plugin/client_dispenser.go b/pkg/plugin/client_dispenser.go index 2efed9ed4..b3937f092 100644 --- a/pkg/plugin/client_dispenser.go +++ b/pkg/plugin/client_dispenser.go @@ -37,7 +37,7 @@ type clientDispenser struct { logger logrus.FieldLogger // clienConn is shared among all implementations for this client. clientConn *grpc.ClientConn - // initFunc returns a client that implements a plugin interface, such as cloudprovider.ObjectStore. + // initFunc returns a client that implements a plugin interface, such as ObjectStore. initFunc clientInitFunc // clients keeps track of all the initialized implementations. clients map[string]interface{} diff --git a/pkg/plugin/manager.go b/pkg/plugin/manager.go index be8faf207..f1001b1ea 100644 --- a/pkg/plugin/manager.go +++ b/pkg/plugin/manager.go @@ -21,30 +21,28 @@ import ( "github.com/sirupsen/logrus" - "github.com/heptio/velero/pkg/backup" - "github.com/heptio/velero/pkg/cloudprovider" - "github.com/heptio/velero/pkg/restore" + "github.com/heptio/velero/pkg/plugin/velero" ) // Manager manages the lifecycles of plugins. type Manager interface { // GetObjectStore returns the ObjectStore plugin for name. - GetObjectStore(name string) (cloudprovider.ObjectStore, error) + GetObjectStore(name string) (velero.ObjectStore, error) // GetBlockStore returns the BlockStore plugin for name. - GetBlockStore(name string) (cloudprovider.BlockStore, error) + GetBlockStore(name string) (velero.BlockStore, error) // GetBackupItemActions returns all backup item action plugins. - GetBackupItemActions() ([]backup.ItemAction, error) + GetBackupItemActions() ([]velero.BackupItemAction, error) // GetBackupItemAction returns the backup item action plugin for name. - GetBackupItemAction(name string) (backup.ItemAction, error) + GetBackupItemAction(name string) (velero.BackupItemAction, error) // GetRestoreItemActions returns all restore item action plugins. - GetRestoreItemActions() ([]restore.ItemAction, error) + GetRestoreItemActions() ([]velero.RestoreItemAction, error) // GetRestoreItemAction returns the restore item action plugin for name. - GetRestoreItemAction(name string) (restore.ItemAction, error) + GetRestoreItemAction(name string) (velero.RestoreItemAction, error) // CleanupClients terminates all of the Manager's running plugin processes. CleanupClients() @@ -124,7 +122,7 @@ func (m *manager) getRestartableProcess(kind PluginKind, name string) (Restartab } // GetObjectStore returns a restartableObjectStore for name. -func (m *manager) GetObjectStore(name string) (cloudprovider.ObjectStore, error) { +func (m *manager) GetObjectStore(name string) (velero.ObjectStore, error) { restartableProcess, err := m.getRestartableProcess(PluginKindObjectStore, name) if err != nil { return nil, err @@ -136,7 +134,7 @@ func (m *manager) GetObjectStore(name string) (cloudprovider.ObjectStore, error) } // GetBlockStore returns a restartableBlockStore for name. -func (m *manager) GetBlockStore(name string) (cloudprovider.BlockStore, error) { +func (m *manager) GetBlockStore(name string) (velero.BlockStore, error) { restartableProcess, err := m.getRestartableProcess(PluginKindBlockStore, name) if err != nil { return nil, err @@ -148,10 +146,10 @@ func (m *manager) GetBlockStore(name string) (cloudprovider.BlockStore, error) { } // GetBackupItemActions returns all backup item actions as restartableBackupItemActions. -func (m *manager) GetBackupItemActions() ([]backup.ItemAction, error) { +func (m *manager) GetBackupItemActions() ([]velero.BackupItemAction, error) { list := m.registry.List(PluginKindBackupItemAction) - actions := make([]backup.ItemAction, 0, len(list)) + actions := make([]velero.BackupItemAction, 0, len(list)) for i := range list { id := list[i] @@ -168,7 +166,7 @@ func (m *manager) GetBackupItemActions() ([]backup.ItemAction, error) { } // GetBackupItemAction returns a restartableBackupItemAction for name. -func (m *manager) GetBackupItemAction(name string) (backup.ItemAction, error) { +func (m *manager) GetBackupItemAction(name string) (velero.BackupItemAction, error) { restartableProcess, err := m.getRestartableProcess(PluginKindBackupItemAction, name) if err != nil { return nil, err @@ -179,10 +177,10 @@ func (m *manager) GetBackupItemAction(name string) (backup.ItemAction, error) { } // GetRestoreItemActions returns all restore item actions as restartableRestoreItemActions. -func (m *manager) GetRestoreItemActions() ([]restore.ItemAction, error) { +func (m *manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) { list := m.registry.List(PluginKindRestoreItemAction) - actions := make([]restore.ItemAction, 0, len(list)) + actions := make([]velero.RestoreItemAction, 0, len(list)) for i := range list { id := list[i] @@ -199,7 +197,7 @@ func (m *manager) GetRestoreItemActions() ([]restore.ItemAction, error) { } // GetRestoreItemAction returns a restartableRestoreItemAction for name. -func (m *manager) GetRestoreItemAction(name string) (restore.ItemAction, error) { +func (m *manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, error) { restartableProcess, err := m.getRestartableProcess(PluginKindRestoreItemAction, name) if err != nil { return nil, err diff --git a/pkg/plugin/mocks/manager.go b/pkg/plugin/mocks/manager.go index 73dd85fbd..d2242cfbb 100644 --- a/pkg/plugin/mocks/manager.go +++ b/pkg/plugin/mocks/manager.go @@ -16,11 +16,11 @@ limitations under the License. // Code generated by mockery v1.0.0. DO NOT EDIT. package mocks -import backup "github.com/heptio/velero/pkg/backup" -import cloudprovider "github.com/heptio/velero/pkg/cloudprovider" -import mock "github.com/stretchr/testify/mock" +import ( + mock "github.com/stretchr/testify/mock" -import restore "github.com/heptio/velero/pkg/restore" + "github.com/heptio/velero/pkg/plugin/velero" +) // Manager is an autogenerated mock type for the Manager type type Manager struct { @@ -33,15 +33,15 @@ func (_m *Manager) CleanupClients() { } // GetBackupItemAction provides a mock function with given fields: name -func (_m *Manager) GetBackupItemAction(name string) (backup.ItemAction, error) { +func (_m *Manager) GetBackupItemAction(name string) (velero.BackupItemAction, error) { ret := _m.Called(name) - var r0 backup.ItemAction - if rf, ok := ret.Get(0).(func(string) backup.ItemAction); ok { + var r0 velero.BackupItemAction + if rf, ok := ret.Get(0).(func(string) velero.BackupItemAction); ok { r0 = rf(name) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(backup.ItemAction) + r0 = ret.Get(0).(velero.BackupItemAction) } } @@ -56,15 +56,15 @@ func (_m *Manager) GetBackupItemAction(name string) (backup.ItemAction, error) { } // GetBackupItemActions provides a mock function with given fields: -func (_m *Manager) GetBackupItemActions() ([]backup.ItemAction, error) { +func (_m *Manager) GetBackupItemActions() ([]velero.BackupItemAction, error) { ret := _m.Called() - var r0 []backup.ItemAction - if rf, ok := ret.Get(0).(func() []backup.ItemAction); ok { + var r0 []velero.BackupItemAction + if rf, ok := ret.Get(0).(func() []velero.BackupItemAction); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]backup.ItemAction) + r0 = ret.Get(0).([]velero.BackupItemAction) } } @@ -79,15 +79,15 @@ func (_m *Manager) GetBackupItemActions() ([]backup.ItemAction, error) { } // GetBlockStore provides a mock function with given fields: name -func (_m *Manager) GetBlockStore(name string) (cloudprovider.BlockStore, error) { +func (_m *Manager) GetBlockStore(name string) (velero.BlockStore, error) { ret := _m.Called(name) - var r0 cloudprovider.BlockStore - if rf, ok := ret.Get(0).(func(string) cloudprovider.BlockStore); ok { + var r0 velero.BlockStore + if rf, ok := ret.Get(0).(func(string) velero.BlockStore); ok { r0 = rf(name) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(cloudprovider.BlockStore) + r0 = ret.Get(0).(velero.BlockStore) } } @@ -102,15 +102,15 @@ func (_m *Manager) GetBlockStore(name string) (cloudprovider.BlockStore, error) } // GetObjectStore provides a mock function with given fields: name -func (_m *Manager) GetObjectStore(name string) (cloudprovider.ObjectStore, error) { +func (_m *Manager) GetObjectStore(name string) (velero.ObjectStore, error) { ret := _m.Called(name) - var r0 cloudprovider.ObjectStore - if rf, ok := ret.Get(0).(func(string) cloudprovider.ObjectStore); ok { + var r0 velero.ObjectStore + if rf, ok := ret.Get(0).(func(string) velero.ObjectStore); ok { r0 = rf(name) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(cloudprovider.ObjectStore) + r0 = ret.Get(0).(velero.ObjectStore) } } @@ -125,15 +125,15 @@ func (_m *Manager) GetObjectStore(name string) (cloudprovider.ObjectStore, error } // GetRestoreItemAction provides a mock function with given fields: name -func (_m *Manager) GetRestoreItemAction(name string) (restore.ItemAction, error) { +func (_m *Manager) GetRestoreItemAction(name string) (velero.RestoreItemAction, error) { ret := _m.Called(name) - var r0 restore.ItemAction - if rf, ok := ret.Get(0).(func(string) restore.ItemAction); ok { + var r0 velero.RestoreItemAction + if rf, ok := ret.Get(0).(func(string) velero.RestoreItemAction); ok { r0 = rf(name) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(restore.ItemAction) + r0 = ret.Get(0).(velero.RestoreItemAction) } } @@ -148,15 +148,15 @@ func (_m *Manager) GetRestoreItemAction(name string) (restore.ItemAction, error) } // GetRestoreItemActions provides a mock function with given fields: -func (_m *Manager) GetRestoreItemActions() ([]restore.ItemAction, error) { +func (_m *Manager) GetRestoreItemActions() ([]velero.RestoreItemAction, error) { ret := _m.Called() - var r0 []restore.ItemAction - if rf, ok := ret.Get(0).(func() []restore.ItemAction); ok { + var r0 []velero.RestoreItemAction + if rf, ok := ret.Get(0).(func() []velero.RestoreItemAction); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]restore.ItemAction) + r0 = ret.Get(0).([]velero.RestoreItemAction) } } diff --git a/pkg/plugin/object_store.go b/pkg/plugin/object_store.go index 11aa93b88..ad8710158 100644 --- a/pkg/plugin/object_store.go +++ b/pkg/plugin/object_store.go @@ -25,8 +25,8 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" - "github.com/heptio/velero/pkg/cloudprovider" proto "github.com/heptio/velero/pkg/plugin/generated" + "github.com/heptio/velero/pkg/plugin/velero" ) const byteChunkSize = 16384 @@ -56,7 +56,7 @@ func (p *ObjectStorePlugin) GRPCClient(c *grpc.ClientConn) (interface{}, error) } -// ObjectStoreGRPCClient implements the cloudprovider.ObjectStore interface and uses a +// ObjectStoreGRPCClient implements the ObjectStore interface and uses a // gRPC client to make calls to the plugin server. type ObjectStoreGRPCClient struct { *clientBase @@ -199,13 +199,13 @@ type ObjectStoreGRPCServer struct { mux *serverMux } -func (s *ObjectStoreGRPCServer) getImpl(name string) (cloudprovider.ObjectStore, error) { +func (s *ObjectStoreGRPCServer) getImpl(name string) (velero.ObjectStore, error) { impl, err := s.mux.getHandler(name) if err != nil { return nil, err } - itemAction, ok := impl.(cloudprovider.ObjectStore) + itemAction, ok := impl.(velero.ObjectStore) if !ok { return nil, errors.Errorf("%T is not an object store", impl) } diff --git a/pkg/plugin/process.go b/pkg/plugin/process.go index 090d1ad23..fa2562829 100644 --- a/pkg/plugin/process.go +++ b/pkg/plugin/process.go @@ -79,7 +79,7 @@ func (r *process) dispense(key kindAndName) (interface{}, error) { if key.name == "" { return nil, errors.Errorf("%s plugin requested but name is missing", key.kind.String()) } - // Get the instance that implements our plugin interface (e.g. cloudprovider.ObjectStore) that is a gRPC-based + // Get the instance that implements our plugin interface (e.g. ObjectStore) that is a gRPC-based // client dispensed = clientDispenser.clientFor(key.name) } diff --git a/pkg/plugin/restartable_backup_item_action.go b/pkg/plugin/restartable_backup_item_action.go index 1c66af689..5a96443d8 100644 --- a/pkg/plugin/restartable_backup_item_action.go +++ b/pkg/plugin/restartable_backup_item_action.go @@ -20,7 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" api "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/backup" + "github.com/heptio/velero/pkg/plugin/velero" ) // restartableBackupItemAction is a backup item action for a given implementation (such as "pod"). It is associated with @@ -43,22 +43,22 @@ func newRestartableBackupItemAction(name string, sharedPluginProcess Restartable // getBackupItemAction returns the backup item action for this restartableBackupItemAction. It does *not* restart the // plugin process. -func (r *restartableBackupItemAction) getBackupItemAction() (backup.ItemAction, error) { +func (r *restartableBackupItemAction) getBackupItemAction() (velero.BackupItemAction, error) { plugin, err := r.sharedPluginProcess.getByKindAndName(r.key) if err != nil { return nil, err } - backupItemAction, ok := plugin.(backup.ItemAction) + backupItemAction, ok := plugin.(velero.BackupItemAction) if !ok { - return nil, errors.Errorf("%T is not a backup.ItemAction!", plugin) + return nil, errors.Errorf("%T is not a BackupItemAction!", plugin) } return backupItemAction, nil } // getDelegate restarts the plugin process (if needed) and returns the backup item action for this restartableBackupItemAction. -func (r *restartableBackupItemAction) getDelegate() (backup.ItemAction, error) { +func (r *restartableBackupItemAction) getDelegate() (velero.BackupItemAction, error) { if err := r.sharedPluginProcess.resetIfNeeded(); err != nil { return nil, err } @@ -67,17 +67,17 @@ func (r *restartableBackupItemAction) getDelegate() (backup.ItemAction, error) { } // AppliesTo restarts the plugin's process if needed, then delegates the call. -func (r *restartableBackupItemAction) AppliesTo() (backup.ResourceSelector, error) { +func (r *restartableBackupItemAction) AppliesTo() (velero.ResourceSelector, error) { delegate, err := r.getDelegate() if err != nil { - return backup.ResourceSelector{}, err + return velero.ResourceSelector{}, err } return delegate.AppliesTo() } // Execute restarts the plugin's process if needed, then delegates the call. -func (r *restartableBackupItemAction) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []backup.ResourceIdentifier, error) { +func (r *restartableBackupItemAction) Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) { delegate, err := r.getDelegate() if err != nil { return nil, nil, err diff --git a/pkg/plugin/restartable_backup_item_action_test.go b/pkg/plugin/restartable_backup_item_action_test.go index 10dfecbd1..fc8066933 100644 --- a/pkg/plugin/restartable_backup_item_action_test.go +++ b/pkg/plugin/restartable_backup_item_action_test.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" v1 "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/backup" "github.com/heptio/velero/pkg/backup/mocks" + "github.com/heptio/velero/pkg/plugin/velero" ) func TestRestartableGetBackupItemAction(t *testing.T) { @@ -45,7 +45,7 @@ func TestRestartableGetBackupItemAction(t *testing.T) { { name: "wrong type", plugin: 3, - expectedError: "int is not a backup.ItemAction!", + expectedError: "int is not a BackupItemAction!", }, { name: "happy path", @@ -113,7 +113,7 @@ func TestRestartableBackupItemActionDelegatedFunctions(t *testing.T) { }, } - additionalItems := []backup.ResourceIdentifier{ + additionalItems := []velero.ResourceIdentifier{ { GroupResource: schema.GroupResource{Group: "velero.io", Resource: "backups"}, }, @@ -134,13 +134,13 @@ func TestRestartableBackupItemActionDelegatedFunctions(t *testing.T) { restartableDelegateTest{ function: "AppliesTo", inputs: []interface{}{}, - expectedErrorOutputs: []interface{}{backup.ResourceSelector{}, errors.Errorf("reset error")}, - expectedDelegateOutputs: []interface{}{backup.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")}, + expectedErrorOutputs: []interface{}{velero.ResourceSelector{}, errors.Errorf("reset error")}, + expectedDelegateOutputs: []interface{}{velero.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")}, }, restartableDelegateTest{ function: "Execute", inputs: []interface{}{pv, b}, - expectedErrorOutputs: []interface{}{nil, ([]backup.ResourceIdentifier)(nil), errors.Errorf("reset error")}, + expectedErrorOutputs: []interface{}{nil, ([]velero.ResourceIdentifier)(nil), errors.Errorf("reset error")}, expectedDelegateOutputs: []interface{}{pvToReturn, additionalItems, errors.Errorf("delegate error")}, }, ) diff --git a/pkg/plugin/restartable_block_store.go b/pkg/plugin/restartable_block_store.go index 9ef86e6a9..9f7c38b36 100644 --- a/pkg/plugin/restartable_block_store.go +++ b/pkg/plugin/restartable_block_store.go @@ -19,7 +19,7 @@ import ( "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" - "github.com/heptio/velero/pkg/cloudprovider" + "github.com/heptio/velero/pkg/plugin/velero" ) // restartableBlockStore is an object store for a given implementation (such as "aws"). It is associated with @@ -48,31 +48,31 @@ func newRestartableBlockStore(name string, sharedPluginProcess RestartableProces // reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init(). func (r *restartableBlockStore) reinitialize(dispensed interface{}) error { - blockStore, ok := dispensed.(cloudprovider.BlockStore) + blockStore, ok := dispensed.(velero.BlockStore) if !ok { - return errors.Errorf("%T is not a cloudprovider.BlockStore!", dispensed) + return errors.Errorf("%T is not a BlockStore!", dispensed) } return r.init(blockStore, r.config) } // getBlockStore returns the block store for this restartableBlockStore. It does *not* restart the // plugin process. -func (r *restartableBlockStore) getBlockStore() (cloudprovider.BlockStore, error) { +func (r *restartableBlockStore) getBlockStore() (velero.BlockStore, error) { plugin, err := r.sharedPluginProcess.getByKindAndName(r.key) if err != nil { return nil, err } - blockStore, ok := plugin.(cloudprovider.BlockStore) + blockStore, ok := plugin.(velero.BlockStore) if !ok { - return nil, errors.Errorf("%T is not a cloudprovider.BlockStore!", plugin) + return nil, errors.Errorf("%T is not a BlockStore!", plugin) } return blockStore, nil } // getDelegate restarts the plugin process (if needed) and returns the block store for this restartableBlockStore. -func (r *restartableBlockStore) getDelegate() (cloudprovider.BlockStore, error) { +func (r *restartableBlockStore) getDelegate() (velero.BlockStore, error) { if err := r.sharedPluginProcess.resetIfNeeded(); err != nil { return nil, err } @@ -100,7 +100,7 @@ func (r *restartableBlockStore) Init(config map[string]string) error { // init calls Init on blockStore with config. This is split out from Init() so that both Init() and reinitialize() may // call it using a specific BlockStore. -func (r *restartableBlockStore) init(blockStore cloudprovider.BlockStore, config map[string]string) error { +func (r *restartableBlockStore) init(blockStore velero.BlockStore, config map[string]string) error { return blockStore.Init(config) } diff --git a/pkg/plugin/restartable_block_store_test.go b/pkg/plugin/restartable_block_store_test.go index 2c64eff22..ba5e7fc11 100644 --- a/pkg/plugin/restartable_block_store_test.go +++ b/pkg/plugin/restartable_block_store_test.go @@ -43,7 +43,7 @@ func TestRestartableGetBlockStore(t *testing.T) { { name: "wrong type", plugin: 3, - expectedError: "int is not a cloudprovider.BlockStore!", + expectedError: "int is not a BlockStore!", }, { name: "happy path", @@ -93,7 +93,7 @@ func TestRestartableBlockStoreReinitialize(t *testing.T) { } err := r.reinitialize(3) - assert.EqualError(t, err, "int is not a cloudprovider.BlockStore!") + assert.EqualError(t, err, "int is not a BlockStore!") blockStore := new(mocks.BlockStore) blockStore.Test(t) diff --git a/pkg/plugin/restartable_object_store.go b/pkg/plugin/restartable_object_store.go index 3684982dd..687a99ddd 100644 --- a/pkg/plugin/restartable_object_store.go +++ b/pkg/plugin/restartable_object_store.go @@ -21,7 +21,7 @@ import ( "github.com/pkg/errors" - "github.com/heptio/velero/pkg/cloudprovider" + "github.com/heptio/velero/pkg/plugin/velero" ) // restartableObjectStore is an object store for a given implementation (such as "aws"). It is associated with @@ -52,9 +52,9 @@ func newRestartableObjectStore(name string, sharedPluginProcess RestartableProce // reinitialize reinitializes a re-dispensed plugin using the initial data passed to Init(). func (r *restartableObjectStore) reinitialize(dispensed interface{}) error { - objectStore, ok := dispensed.(cloudprovider.ObjectStore) + objectStore, ok := dispensed.(velero.ObjectStore) if !ok { - return errors.Errorf("%T is not a cloudprovider.ObjectStore!", dispensed) + return errors.Errorf("%T is not a ObjectStore!", dispensed) } return r.init(objectStore, r.config) @@ -62,22 +62,22 @@ func (r *restartableObjectStore) reinitialize(dispensed interface{}) error { // getObjectStore returns the object store for this restartableObjectStore. It does *not* restart the // plugin process. -func (r *restartableObjectStore) getObjectStore() (cloudprovider.ObjectStore, error) { +func (r *restartableObjectStore) getObjectStore() (velero.ObjectStore, error) { plugin, err := r.sharedPluginProcess.getByKindAndName(r.key) if err != nil { return nil, err } - objectStore, ok := plugin.(cloudprovider.ObjectStore) + objectStore, ok := plugin.(velero.ObjectStore) if !ok { - return nil, errors.Errorf("%T is not a cloudprovider.ObjectStore!", plugin) + return nil, errors.Errorf("%T is not a ObjectStore!", plugin) } return objectStore, nil } // getDelegate restarts the plugin process (if needed) and returns the object store for this restartableObjectStore. -func (r *restartableObjectStore) getDelegate() (cloudprovider.ObjectStore, error) { +func (r *restartableObjectStore) getDelegate() (velero.ObjectStore, error) { if err := r.sharedPluginProcess.resetIfNeeded(); err != nil { return nil, err } @@ -105,7 +105,7 @@ func (r *restartableObjectStore) Init(config map[string]string) error { // init calls Init on objectStore with config. This is split out from Init() so that both Init() and reinitialize() may // call it using a specific ObjectStore. -func (r *restartableObjectStore) init(objectStore cloudprovider.ObjectStore, config map[string]string) error { +func (r *restartableObjectStore) init(objectStore velero.ObjectStore, config map[string]string) error { return objectStore.Init(config) } diff --git a/pkg/plugin/restartable_object_store_test.go b/pkg/plugin/restartable_object_store_test.go index f5146855e..3b17945fb 100644 --- a/pkg/plugin/restartable_object_store_test.go +++ b/pkg/plugin/restartable_object_store_test.go @@ -44,7 +44,7 @@ func TestRestartableGetObjectStore(t *testing.T) { { name: "wrong type", plugin: 3, - expectedError: "int is not a cloudprovider.ObjectStore!", + expectedError: "int is not a ObjectStore!", }, { name: "happy path", @@ -94,7 +94,7 @@ func TestRestartableObjectStoreReinitialize(t *testing.T) { } err := r.reinitialize(3) - assert.EqualError(t, err, "int is not a cloudprovider.ObjectStore!") + assert.EqualError(t, err, "int is not a ObjectStore!") objectStore := new(cloudprovidermocks.ObjectStore) objectStore.Test(t) diff --git a/pkg/plugin/restartable_restore_item_action.go b/pkg/plugin/restartable_restore_item_action.go index 703d85b72..1edbd7994 100644 --- a/pkg/plugin/restartable_restore_item_action.go +++ b/pkg/plugin/restartable_restore_item_action.go @@ -18,7 +18,7 @@ package plugin import ( "github.com/pkg/errors" - "github.com/heptio/velero/pkg/restore" + "github.com/heptio/velero/pkg/plugin/velero" ) // restartableRestoreItemAction is a restore item action for a given implementation (such as "pod"). It is associated with @@ -42,22 +42,22 @@ func newRestartableRestoreItemAction(name string, sharedPluginProcess Restartabl // getRestoreItemAction returns the restore item action for this restartableRestoreItemAction. It does *not* restart the // plugin process. -func (r *restartableRestoreItemAction) getRestoreItemAction() (restore.ItemAction, error) { +func (r *restartableRestoreItemAction) getRestoreItemAction() (velero.RestoreItemAction, error) { plugin, err := r.sharedPluginProcess.getByKindAndName(r.key) if err != nil { return nil, err } - restoreItemAction, ok := plugin.(restore.ItemAction) + restoreItemAction, ok := plugin.(velero.RestoreItemAction) if !ok { - return nil, errors.Errorf("%T is not a restore.ItemAction!", plugin) + return nil, errors.Errorf("%T is not a RestoreItemAction!", plugin) } return restoreItemAction, nil } // getDelegate restarts the plugin process (if needed) and returns the restore item action for this restartableRestoreItemAction. -func (r *restartableRestoreItemAction) getDelegate() (restore.ItemAction, error) { +func (r *restartableRestoreItemAction) getDelegate() (velero.RestoreItemAction, error) { if err := r.sharedPluginProcess.resetIfNeeded(); err != nil { return nil, err } @@ -66,17 +66,17 @@ func (r *restartableRestoreItemAction) getDelegate() (restore.ItemAction, error) } // AppliesTo restarts the plugin's process if needed, then delegates the call. -func (r *restartableRestoreItemAction) AppliesTo() (restore.ResourceSelector, error) { +func (r *restartableRestoreItemAction) AppliesTo() (velero.ResourceSelector, error) { delegate, err := r.getDelegate() if err != nil { - return restore.ResourceSelector{}, err + return velero.ResourceSelector{}, err } return delegate.AppliesTo() } // Execute restarts the plugin's process if needed, then delegates the call. -func (r *restartableRestoreItemAction) Execute(input *restore.RestoreItemActionExecuteInput) (*restore.RestoreItemActionExecuteOutput, error) { +func (r *restartableRestoreItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { delegate, err := r.getDelegate() if err != nil { return nil, err diff --git a/pkg/plugin/restartable_restore_item_action_test.go b/pkg/plugin/restartable_restore_item_action_test.go index 33d49df4d..d1382f2df 100644 --- a/pkg/plugin/restartable_restore_item_action_test.go +++ b/pkg/plugin/restartable_restore_item_action_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" v1 "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/restore" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restore/mocks" ) @@ -44,7 +44,7 @@ func TestRestartableGetRestoreItemAction(t *testing.T) { { name: "wrong type", plugin: 3, - expectedError: "int is not a restore.ItemAction!", + expectedError: "int is not a RestoreItemAction!", }, { name: "happy path", @@ -104,13 +104,13 @@ func TestRestartableRestoreItemActionDelegatedFunctions(t *testing.T) { }, } - input := &restore.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: pv, ItemFromBackup: pv, Restore: new(v1.Restore), } - output := &restore.RestoreItemActionExecuteOutput{ + output := &velero.RestoreItemActionExecuteOutput{ UpdatedItem: &unstructured.Unstructured{ Object: map[string]interface{}{ "color": "green", @@ -134,8 +134,8 @@ func TestRestartableRestoreItemActionDelegatedFunctions(t *testing.T) { restartableDelegateTest{ function: "AppliesTo", inputs: []interface{}{}, - expectedErrorOutputs: []interface{}{restore.ResourceSelector{}, errors.Errorf("reset error")}, - expectedDelegateOutputs: []interface{}{restore.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")}, + expectedErrorOutputs: []interface{}{velero.ResourceSelector{}, errors.Errorf("reset error")}, + expectedDelegateOutputs: []interface{}{velero.ResourceSelector{IncludedNamespaces: []string{"a"}}, errors.Errorf("delegate error")}, }, restartableDelegateTest{ function: "Execute", diff --git a/pkg/plugin/restore_item_action.go b/pkg/plugin/restore_item_action.go index dae49bf79..424fa4e0e 100644 --- a/pkg/plugin/restore_item_action.go +++ b/pkg/plugin/restore_item_action.go @@ -27,7 +27,7 @@ import ( api "github.com/heptio/velero/pkg/apis/velero/v1" proto "github.com/heptio/velero/pkg/plugin/generated" - "github.com/heptio/velero/pkg/restore" + "github.com/heptio/velero/pkg/plugin/velero" ) // RestoreItemActionPlugin is an implementation of go-plugin's Plugin @@ -38,7 +38,7 @@ type RestoreItemActionPlugin struct { *pluginBase } -var _ restore.ItemAction = &RestoreItemActionGRPCClient{} +var _ velero.RestoreItemAction = &RestoreItemActionGRPCClient{} // NewRestoreItemActionPlugin constructs a RestoreItemActionPlugin. func NewRestoreItemActionPlugin(options ...pluginOption) *RestoreItemActionPlugin { @@ -70,13 +70,13 @@ func newRestoreItemActionGRPCClient(base *clientBase, clientConn *grpc.ClientCon } } -func (c *RestoreItemActionGRPCClient) AppliesTo() (restore.ResourceSelector, error) { +func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) { res, err := c.grpcClient.AppliesTo(context.Background(), &proto.AppliesToRequest{Plugin: c.plugin}) if err != nil { - return restore.ResourceSelector{}, err + return velero.ResourceSelector{}, err } - return restore.ResourceSelector{ + return velero.ResourceSelector{ IncludedNamespaces: res.IncludedNamespaces, ExcludedNamespaces: res.ExcludedNamespaces, IncludedResources: res.IncludedResources, @@ -85,7 +85,7 @@ func (c *RestoreItemActionGRPCClient) AppliesTo() (restore.ResourceSelector, err }, nil } -func (c *RestoreItemActionGRPCClient) Execute(input *restore.RestoreItemActionExecuteInput) (*restore.RestoreItemActionExecuteOutput, error) { +func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { itemJSON, err := json.Marshal(input.Item.UnstructuredContent()) if err != nil { return nil, err @@ -123,7 +123,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *restore.RestoreItemActionEx warning = errors.New(res.Warning) } - return &restore.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: &updatedItem, Warning: warning, }, nil @@ -145,13 +145,13 @@ type RestoreItemActionGRPCServer struct { mux *serverMux } -func (s *RestoreItemActionGRPCServer) getImpl(name string) (restore.ItemAction, error) { +func (s *RestoreItemActionGRPCServer) getImpl(name string) (velero.RestoreItemAction, error) { impl, err := s.mux.getHandler(name) if err != nil { return nil, err } - itemAction, ok := impl.(restore.ItemAction) + itemAction, ok := impl.(velero.RestoreItemAction) if !ok { return nil, errors.Errorf("%T is not a restore item action", impl) } @@ -215,7 +215,7 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re return nil, err } - executeOutput, err := impl.Execute(&restore.RestoreItemActionExecuteInput{ + executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{ Item: &item, ItemFromBackup: &itemFromBackup, Restore: &restoreObj, diff --git a/pkg/plugin/velero/backup_item_action.go b/pkg/plugin/velero/backup_item_action.go new file mode 100644 index 000000000..c7d945a60 --- /dev/null +++ b/pkg/plugin/velero/backup_item_action.go @@ -0,0 +1,45 @@ +/* +Copyright 2017 the Heptio Ark 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 velero + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + api "github.com/heptio/velero/pkg/apis/velero/v1" +) + +// BackupItemAction is an actor that performs an operation on an individual item being backed up. +type BackupItemAction interface { + // AppliesTo returns information about which resources this action should be invoked for. + // A BackupItemAction's Execute function will only be invoked on items that match the returned + // selector. A zero-valued ResourceSelector matches all resources. + AppliesTo() (ResourceSelector, error) + + // Execute allows the ItemAction to perform arbitrary logic with the item being backed up, + // including mutating the item itself prior to backup. The item (unmodified or modified) + // should be returned, along with an optional slice of ResourceIdentifiers specifying + // additional related items that should be backed up. + Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []ResourceIdentifier, error) +} + +// ResourceIdentifier describes a single item by its group, resource, namespace, and name. +type ResourceIdentifier struct { + schema.GroupResource + Namespace string + Name string +} diff --git a/pkg/cloudprovider/block_store.go b/pkg/plugin/velero/block_store.go similarity index 98% rename from pkg/cloudprovider/block_store.go rename to pkg/plugin/velero/block_store.go index 52ccb4c2d..ecdeeac2d 100644 --- a/pkg/cloudprovider/block_store.go +++ b/pkg/plugin/velero/block_store.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cloudprovider +package velero import ( "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/cloudprovider/object_store.go b/pkg/plugin/velero/object_store.go similarity index 99% rename from pkg/cloudprovider/object_store.go rename to pkg/plugin/velero/object_store.go index b5edb1068..d08bab51d 100644 --- a/pkg/cloudprovider/object_store.go +++ b/pkg/plugin/velero/object_store.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cloudprovider +package velero import ( "io" diff --git a/pkg/restore/item_action.go b/pkg/plugin/velero/restore_item_action.go similarity index 61% rename from pkg/restore/item_action.go rename to pkg/plugin/velero/restore_item_action.go index 27a90b118..a89f7d8af 100644 --- a/pkg/restore/item_action.go +++ b/pkg/plugin/velero/restore_item_action.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package restore +package velero import ( "k8s.io/apimachinery/pkg/runtime" @@ -22,10 +22,10 @@ import ( api "github.com/heptio/velero/pkg/apis/velero/v1" ) -// ItemAction is an actor that performs an operation on an individual item being restored. -type ItemAction interface { +// RestoreItemAction is an actor that performs an operation on an individual item being restored. +type RestoreItemAction interface { // AppliesTo returns information about which resources this action should be invoked for. - // An ItemAction's Execute function will only be invoked on items that match the returned + // A RestoreItemAction's Execute function will only be invoked on items that match the returned // selector. A zero-valued ResourceSelector matches all resources. AppliesTo() (ResourceSelector, error) @@ -57,42 +57,15 @@ type RestoreItemActionExecuteOutput struct { Warning error } +// NewRestoreItemActionExecuteOutput creates a new RestoreItemActionExecuteOutput func NewRestoreItemActionExecuteOutput(item runtime.Unstructured) *RestoreItemActionExecuteOutput { return &RestoreItemActionExecuteOutput{ UpdatedItem: item, } } +// WithWarning returns a warning for RestoreItemActionExecuteOutput func (r *RestoreItemActionExecuteOutput) WithWarning(err error) *RestoreItemActionExecuteOutput { r.Warning = err return r } - -// ResourceSelector is a collection of included/excluded namespaces, -// included/excluded resources, and a label-selector that can be used -// to match a set of items from a cluster. -type ResourceSelector struct { - // IncludedNamespaces is a slice of namespace names to match. All - // namespaces in this slice, except those in ExcludedNamespaces, - // will be matched. A nil/empty slice matches all namespaces. - IncludedNamespaces []string - // ExcludedNamespaces is a slice of namespace names to exclude. - // All namespaces in IncludedNamespaces, *except* those in - // this slice, will be matched. - ExcludedNamespaces []string - // IncludedResources is a slice of resources to match. Resources - // may be specified as full names (e.g. "services") or abbreviations - // (e.g. "svc"). All resources in this slice, except those in - // ExcludedResources, will be matched. A nil/empty slice matches - // all resources. - IncludedResources []string - // ExcludedResources is a slice of resources to exclude. - // Resources may be specified as full names (e.g. "services") or - // abbreviations (e.g. "svc"). All resources in IncludedResources, - // *except* those in this slice, will be matched. - ExcludedResources []string - // LabelSelector is a string representation of a selector to apply - // when matching resources. See "k8s.io/apimachinery/pkg/labels".Parse() - // for details on syntax. - LabelSelector string -} diff --git a/pkg/backup/item_action.go b/pkg/plugin/velero/shared.go similarity index 61% rename from pkg/backup/item_action.go rename to pkg/plugin/velero/shared.go index 531cb1d42..668161728 100644 --- a/pkg/backup/item_action.go +++ b/pkg/plugin/velero/shared.go @@ -1,5 +1,5 @@ /* -Copyright 2017 the Heptio Ark contributors. +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. @@ -14,35 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package backup - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - api "github.com/heptio/velero/pkg/apis/velero/v1" -) - -// ItemAction is an actor that performs an operation on an individual item being backed up. -type ItemAction interface { - // AppliesTo returns information about which resources this action should be invoked for. - // An ItemAction's Execute function will only be invoked on items that match the returned - // selector. A zero-valued ResourceSelector matches all resources. - AppliesTo() (ResourceSelector, error) - - // Execute allows the ItemAction to perform arbitrary logic with the item being backed up, - // including mutating the item itself prior to backup. The item (unmodified or modified) - // should be returned, along with an optional slice of ResourceIdentifiers specifying - // additional related items that should be backed up. - Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []ResourceIdentifier, error) -} - -// ResourceIdentifier describes a single item by its group, resource, namespace, and name. -type ResourceIdentifier struct { - schema.GroupResource - Namespace string - Name string -} +// Package velero contains the interfaces necessary to implement +// all of the Velero plugins. Users create their own binary containing +// implementations of the plugin kinds in this package. Multiple +// plugins of any type can be implemented. +package velero // ResourceSelector is a collection of included/excluded namespaces, // included/excluded resources, and a label-selector that can be used diff --git a/pkg/restore/job_action.go b/pkg/restore/job_action.go index e1f22879e..fede604b7 100644 --- a/pkg/restore/job_action.go +++ b/pkg/restore/job_action.go @@ -22,23 +22,25 @@ import ( batchv1api "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/heptio/velero/pkg/plugin/velero" ) -type jobAction struct { +type JobAction struct { logger logrus.FieldLogger } -func NewJobAction(logger logrus.FieldLogger) ItemAction { - return &jobAction{logger: logger} +func NewJobAction(logger logrus.FieldLogger) *JobAction { + return &JobAction{logger: logger} } -func (a *jobAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *JobAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"jobs"}, }, nil } -func (a *jobAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { +func (a *JobAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { job := new(batchv1api.Job) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), job); err != nil { return nil, errors.WithStack(err) @@ -54,5 +56,5 @@ func (a *jobAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemA return nil, errors.WithStack(err) } - return NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/job_action_test.go b/pkg/restore/job_action_test.go index a9f433d1b..a4f503d75 100644 --- a/pkg/restore/job_action_test.go +++ b/pkg/restore/job_action_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -137,7 +138,7 @@ func TestJobActionExecute(t *testing.T) { unstructuredJob, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredJob}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredJob}, Restore: nil, diff --git a/pkg/restore/mocks/item_action.go b/pkg/restore/mocks/item_action.go index b8ef31717..c41390537 100644 --- a/pkg/restore/mocks/item_action.go +++ b/pkg/restore/mocks/item_action.go @@ -16,8 +16,11 @@ limitations under the License. // Code generated by mockery v1.0.0. DO NOT EDIT. package mocks -import mock "github.com/stretchr/testify/mock" -import restore "github.com/heptio/velero/pkg/restore" +import ( + mock "github.com/stretchr/testify/mock" + + "github.com/heptio/velero/pkg/plugin/velero" +) // ItemAction is an autogenerated mock type for the ItemAction type type ItemAction struct { @@ -25,14 +28,14 @@ type ItemAction struct { } // AppliesTo provides a mock function with given fields: -func (_m *ItemAction) AppliesTo() (restore.ResourceSelector, error) { +func (_m *ItemAction) AppliesTo() (velero.ResourceSelector, error) { ret := _m.Called() - var r0 restore.ResourceSelector - if rf, ok := ret.Get(0).(func() restore.ResourceSelector); ok { + var r0 velero.ResourceSelector + if rf, ok := ret.Get(0).(func() velero.ResourceSelector); ok { r0 = rf() } else { - r0 = ret.Get(0).(restore.ResourceSelector) + r0 = ret.Get(0).(velero.ResourceSelector) } var r1 error @@ -46,20 +49,20 @@ func (_m *ItemAction) AppliesTo() (restore.ResourceSelector, error) { } // Execute provides a mock function with given fields: input -func (_m *ItemAction) Execute(input *restore.RestoreItemActionExecuteInput) (*restore.RestoreItemActionExecuteOutput, error) { +func (_m *ItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { ret := _m.Called(input) - var r0 *restore.RestoreItemActionExecuteOutput - if rf, ok := ret.Get(0).(func(*restore.RestoreItemActionExecuteInput) *restore.RestoreItemActionExecuteOutput); ok { + var r0 *velero.RestoreItemActionExecuteOutput + if rf, ok := ret.Get(0).(func(*velero.RestoreItemActionExecuteInput) *velero.RestoreItemActionExecuteOutput); ok { r0 = rf(input) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*restore.RestoreItemActionExecuteOutput) + r0 = ret.Get(0).(*velero.RestoreItemActionExecuteOutput) } } var r1 error - if rf, ok := ret.Get(1).(func(*restore.RestoreItemActionExecuteInput) error); ok { + if rf, ok := ret.Get(1).(func(*velero.RestoreItemActionExecuteInput) error); ok { r1 = rf(input) } else { r1 = ret.Error(1) diff --git a/pkg/restore/pod_action.go b/pkg/restore/pod_action.go index 1e60573cc..e2aa226e6 100644 --- a/pkg/restore/pod_action.go +++ b/pkg/restore/pod_action.go @@ -24,23 +24,25 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + + "github.com/heptio/velero/pkg/plugin/velero" ) -type podAction struct { +type PodAction struct { logger logrus.FieldLogger } -func NewPodAction(logger logrus.FieldLogger) ItemAction { - return &podAction{logger: logger} +func NewPodAction(logger logrus.FieldLogger) *PodAction { + return &PodAction{logger: logger} } -func (a *podAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *PodAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"pods"}, }, nil } -func (a *podAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { +func (a *PodAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { pod := new(v1.Pod) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), pod); err != nil { return nil, errors.WithStack(err) @@ -84,5 +86,5 @@ func (a *podAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemA return nil, errors.WithStack(err) } - return NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/pod_action_test.go b/pkg/restore/pod_action_test.go index 0d62b0979..9ab59e1e7 100644 --- a/pkg/restore/pod_action_test.go +++ b/pkg/restore/pod_action_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -197,7 +198,7 @@ func TestPodActionExecute(t *testing.T) { unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredPod}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredPod}, Restore: nil, diff --git a/pkg/restore/pv_restorer_test.go b/pkg/restore/pv_restorer_test.go index f69f7b6b2..e6550dc89 100644 --- a/pkg/restore/pv_restorer_test.go +++ b/pkg/restore/pv_restorer_test.go @@ -26,10 +26,10 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" api "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/cloudprovider" cloudprovidermocks "github.com/heptio/velero/pkg/cloudprovider/mocks" "github.com/heptio/velero/pkg/generated/clientset/versioned/fake" informers "github.com/heptio/velero/pkg/generated/informers/externalversions" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" "github.com/heptio/velero/pkg/volume" ) @@ -230,7 +230,7 @@ func TestExecutePVAction_SnapshotRestores(t *testing.T) { t.Run(tc.name, func(t *testing.T) { var ( blockStore = new(cloudprovidermocks.BlockStore) - blockStoreGetter = providerToBlockStoreMap(map[string]cloudprovider.BlockStore{ + blockStoreGetter = providerToBlockStoreMap(map[string]velero.BlockStore{ tc.expectedProvider: blockStore, }) locationsInformer = informers.NewSharedInformerFactory(fake.NewSimpleClientset(), 0).Velero().V1().VolumeSnapshotLocations() @@ -260,9 +260,9 @@ func TestExecutePVAction_SnapshotRestores(t *testing.T) { } } -type providerToBlockStoreMap map[string]cloudprovider.BlockStore +type providerToBlockStoreMap map[string]velero.BlockStore -func (g providerToBlockStoreMap) GetBlockStore(provider string) (cloudprovider.BlockStore, error) { +func (g providerToBlockStoreMap) GetBlockStore(provider string) (velero.BlockStore, error) { if bs, ok := g[provider]; !ok { return nil, errors.New("block store not found for provider") } else { diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/restic_restore_action.go index dfce23536..7a37ee17f 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/restic_restore_action.go @@ -26,17 +26,18 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/heptio/velero/pkg/buildinfo" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/util/kube" ) -type resticRestoreAction struct { +type ResticRestoreAction struct { logger logrus.FieldLogger initContainerImage string } -func NewResticRestoreAction(logger logrus.FieldLogger) ItemAction { - return &resticRestoreAction{ +func NewResticRestoreAction(logger logrus.FieldLogger) *ResticRestoreAction { + return &ResticRestoreAction{ logger: logger, initContainerImage: initContainerImage(), } @@ -52,15 +53,15 @@ func initContainerImage() string { return fmt.Sprintf("gcr.io/heptio-images/velero-restic-restore-helper:%s", tag) } -func (a *resticRestoreAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *ResticRestoreAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"pods"}, }, nil } -func (a *resticRestoreAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { - a.logger.Info("Executing resticRestoreAction") - defer a.logger.Info("Done executing resticRestoreAction") +func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + a.logger.Info("Executing ResticRestoreAction") + defer a.logger.Info("Done executing ResticRestoreAction") var pod corev1.Pod if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), &pod); err != nil { @@ -72,7 +73,7 @@ func (a *resticRestoreAction) Execute(input *RestoreItemActionExecuteInput) (*Re volumeSnapshots := restic.GetPodSnapshotAnnotations(&pod) if len(volumeSnapshots) == 0 { log.Debug("No restic snapshot ID annotations found") - return NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } log.Info("Restic snapshot ID annotations found") @@ -120,5 +121,5 @@ func (a *resticRestoreAction) Execute(input *RestoreItemActionExecuteInput) (*Re return nil, errors.Wrap(err, "unable to convert pod to runtime.Unstructured") } - return NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index fd571c810..9f55af7d7 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -44,10 +44,10 @@ import ( api "github.com/heptio/velero/pkg/apis/velero/v1" "github.com/heptio/velero/pkg/client" - "github.com/heptio/velero/pkg/cloudprovider" "github.com/heptio/velero/pkg/discovery" listers "github.com/heptio/velero/pkg/generated/listers/velero/v1" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/restic" "github.com/heptio/velero/pkg/util/collections" "github.com/heptio/velero/pkg/util/filesystem" @@ -57,7 +57,7 @@ import ( ) type BlockStoreGetter interface { - GetBlockStore(name string) (cloudprovider.BlockStore, error) + GetBlockStore(name string) (velero.BlockStore, error) } // Restorer knows how to restore a backup. @@ -68,7 +68,7 @@ type Restorer interface { backup *api.Backup, volumeSnapshots []*volume.Snapshot, backupReader io.Reader, - actions []ItemAction, + actions []velero.RestoreItemAction, snapshotLocationLister listers.VolumeSnapshotLocationLister, blockStoreGetter BlockStoreGetter, ) (api.RestoreResult, api.RestoreResult) @@ -178,7 +178,7 @@ func (kr *kubernetesRestorer) Restore( backup *api.Backup, volumeSnapshots []*volume.Snapshot, backupReader io.Reader, - actions []ItemAction, + actions []velero.RestoreItemAction, snapshotLocationLister listers.VolumeSnapshotLocationLister, blockStoreGetter BlockStoreGetter, ) (api.RestoreResult, api.RestoreResult) { @@ -287,14 +287,14 @@ func getResourceIncludesExcludes(helper discovery.Helper, includes, excludes []s } type resolvedAction struct { - ItemAction + velero.RestoreItemAction resourceIncludesExcludes *collections.IncludesExcludes namespaceIncludesExcludes *collections.IncludesExcludes selector labels.Selector } -func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAction, error) { +func resolveActions(actions []velero.RestoreItemAction, helper discovery.Helper) ([]resolvedAction, error) { var resolved []resolvedAction for _, action := range actions { @@ -314,7 +314,7 @@ func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAc } res := resolvedAction{ - ItemAction: action, + RestoreItemAction: action, resourceIncludesExcludes: resources, namespaceIncludesExcludes: namespaces, selector: selector, @@ -834,7 +834,7 @@ func (ctx *context) restoreResource(resource, namespace, resourcePath string) (a ctx.log.Infof("Executing item action for %v", &groupResource) - executeOutput, err := action.Execute(&RestoreItemActionExecuteInput{ + executeOutput, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: obj, ItemFromBackup: itemFromBackup, Restore: ctx.restore, diff --git a/pkg/restore/restore_test.go b/pkg/restore/restore_test.go index 05d36b825..4af5b151b 100644 --- a/pkg/restore/restore_test.go +++ b/pkg/restore/restore_test.go @@ -39,10 +39,10 @@ import ( corev1 "k8s.io/client-go/kubernetes/typed/core/v1" api "github.com/heptio/velero/pkg/apis/velero/v1" - "github.com/heptio/velero/pkg/cloudprovider" "github.com/heptio/velero/pkg/generated/clientset/versioned/fake" informers "github.com/heptio/velero/pkg/generated/informers/externalversions" "github.com/heptio/velero/pkg/kuberesource" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/util/collections" "github.com/heptio/velero/pkg/util/logging" velerotest "github.com/heptio/velero/pkg/util/test" @@ -462,7 +462,7 @@ func TestRestoreResourceForNamespace(t *testing.T) { fileSystem: velerotest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()), actions: []resolvedAction{ { - ItemAction: newFakeAction("configmaps"), + RestoreItemAction: newFakeAction("configmaps"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("configmaps"), namespaceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), @@ -478,7 +478,7 @@ func TestRestoreResourceForNamespace(t *testing.T) { fileSystem: velerotest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()), actions: []resolvedAction{ { - ItemAction: newFakeAction("foo-resource"), + RestoreItemAction: newFakeAction("foo-resource"), resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("foo-resource"), namespaceIncludesExcludes: collections.NewIncludesExcludes(), selector: labels.Everything(), @@ -1805,7 +1805,7 @@ type fakeBlockStoreGetter struct { volumeID string } -func (r *fakeBlockStoreGetter) GetBlockStore(provider string) (cloudprovider.BlockStore, error) { +func (r *fakeBlockStoreGetter) GetBlockStore(provider string) (velero.BlockStore, error) { if r.fakeBlockStore == nil { r.fakeBlockStore = &velerotest.FakeBlockStore{ RestorableVolumes: r.volumeMap, @@ -1819,13 +1819,13 @@ func newFakeAction(resource string) *fakeAction { return &fakeAction{resource} } -func (r *fakeAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (r *fakeAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{r.resource}, }, nil } -func (r *fakeAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { +func (r *fakeAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { labels, found, err := unstructured.NestedMap(input.Item.UnstructuredContent(), "metadata", "labels") if err != nil { return nil, err @@ -1851,7 +1851,7 @@ func (r *fakeAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItem return nil, err } - return NewRestoreItemActionExecuteOutput(res), nil + return velero.NewRestoreItemActionExecuteOutput(res), nil } type fakeNamespaceClient struct { diff --git a/pkg/restore/service_account_action.go b/pkg/restore/service_account_action.go index bef82604d..55c377022 100644 --- a/pkg/restore/service_account_action.go +++ b/pkg/restore/service_account_action.go @@ -25,26 +25,27 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/util/kube" ) -type serviceAccountAction struct { +type ServiceAccountAction struct { logger logrus.FieldLogger } -func NewServiceAccountAction(logger logrus.FieldLogger) ItemAction { - return &serviceAccountAction{logger: logger} +func NewServiceAccountAction(logger logrus.FieldLogger) *ServiceAccountAction { + return &ServiceAccountAction{logger: logger} } -func (a *serviceAccountAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *ServiceAccountAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"serviceaccounts"}, }, nil } -func (a *serviceAccountAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { - a.logger.Info("Executing serviceAccountAction") - defer a.logger.Info("Done executing serviceAccountAction") +func (a *ServiceAccountAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + a.logger.Info("Executing ServiceAccountAction") + defer a.logger.Info("Done executing ServiceAccountAction") var serviceAccount corev1.ServiceAccount if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), &serviceAccount); err != nil { @@ -74,5 +75,5 @@ func (a *serviceAccountAction) Execute(input *RestoreItemActionExecuteInput) (*R return nil, errors.Wrap(err, "unable to convert serviceaccount to runtime.Unstructured") } - return NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/service_account_action_test.go b/pkg/restore/service_account_action_test.go index ad2812a28..7efba487f 100644 --- a/pkg/restore/service_account_action_test.go +++ b/pkg/restore/service_account_action_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/heptio/velero/pkg/plugin/velero" "github.com/heptio/velero/pkg/util/test" ) @@ -34,7 +35,7 @@ func TestServiceAccountActionAppliesTo(t *testing.T) { action := NewServiceAccountAction(test.NewLogger()) actual, err := action.AppliesTo() require.NoError(t, err) - assert.Equal(t, ResourceSelector{IncludedResources: []string{"serviceaccounts"}}, actual) + assert.Equal(t, velero.ResourceSelector{IncludedResources: []string{"serviceaccounts"}}, actual) } func TestServiceAccountActionExecute(t *testing.T) { @@ -89,7 +90,7 @@ func TestServiceAccountActionExecute(t *testing.T) { require.NoError(t, err) action := NewServiceAccountAction(test.NewLogger()) - res, err := action.Execute(&RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: saUnstructured}, ItemFromBackup: &unstructured.Unstructured{Object: saUnstructured}, Restore: nil, diff --git a/pkg/restore/service_action.go b/pkg/restore/service_action.go index 40461f9ed..463316fb6 100644 --- a/pkg/restore/service_action.go +++ b/pkg/restore/service_action.go @@ -25,25 +25,27 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" + + "github.com/heptio/velero/pkg/plugin/velero" ) const annotationLastAppliedConfig = "kubectl.kubernetes.io/last-applied-configuration" -type serviceAction struct { +type ServiceAction struct { log logrus.FieldLogger } -func NewServiceAction(logger logrus.FieldLogger) ItemAction { - return &serviceAction{log: logger} +func NewServiceAction(logger logrus.FieldLogger) *ServiceAction { + return &ServiceAction{log: logger} } -func (a *serviceAction) AppliesTo() (ResourceSelector, error) { - return ResourceSelector{ +func (a *ServiceAction) AppliesTo() (velero.ResourceSelector, error) { + return velero.ResourceSelector{ IncludedResources: []string{"services"}, }, nil } -func (a *serviceAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) { +func (a *ServiceAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { service := new(corev1api.Service) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), service); err != nil { return nil, errors.WithStack(err) @@ -62,7 +64,7 @@ func (a *serviceAction) Execute(input *RestoreItemActionExecuteInput) (*RestoreI return nil, errors.WithStack(err) } - return NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } func deleteNodePorts(service *corev1api.Service) error { diff --git a/pkg/restore/service_action_test.go b/pkg/restore/service_action_test.go index 882293cf5..fa7711599 100644 --- a/pkg/restore/service_action_test.go +++ b/pkg/restore/service_action_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "github.com/heptio/velero/pkg/plugin/velero" velerotest "github.com/heptio/velero/pkg/util/test" ) @@ -274,7 +275,7 @@ func TestServiceActionExecute(t *testing.T) { unstructuredSvc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredSvc}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredSvc}, Restore: nil,