add RestoreOperation (#211)

Adds the RestoreOperation to the /internal/operations pkg.
restoreOp.Run() is a no-op at this time since data layer
packages are not prepared to hook up e2e.
This commit is contained in:
Keepers 2022-06-15 16:10:11 -06:00 committed by GitHub
parent fcdb42bc89
commit 15e7c102a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 13 deletions

View File

@ -18,7 +18,6 @@ type BackupOperation struct {
creds credentials.M365
Targets []string // something for targets/filter/source/app&users/etc
Work []string // something to reference the artifacts created, or at least their count
}
// NewBackupOperation constructs and validates a backup operation.
@ -29,45 +28,44 @@ func NewBackupOperation(
creds credentials.M365,
targets []string,
) (BackupOperation, error) {
bo := BackupOperation{
op := BackupOperation{
operation: newOperation(opts, kw),
Version: "v0",
creds: creds,
Targets: targets,
Work: []string{},
}
if err := bo.validate(); err != nil {
if err := op.validate(); err != nil {
return BackupOperation{}, err
}
return bo, nil
return op, nil
}
func (bo BackupOperation) validate() error {
if err := bo.creds.Validate(); err != nil {
func (op BackupOperation) validate() error {
if err := op.creds.Validate(); err != nil {
return errors.Wrap(err, "invalid credentials")
}
return bo.operation.validate()
return op.operation.validate()
}
// Run begins a synchronous backup operation.
func (bo *BackupOperation) Run(ctx context.Context) (*kopia.BackupStats, error) {
gc, err := connector.NewGraphConnector(bo.creds.TenantID, bo.creds.ClientID, bo.creds.ClientSecret)
func (op *BackupOperation) Run(ctx context.Context) (*kopia.BackupStats, error) {
gc, err := connector.NewGraphConnector(op.creds.TenantID, op.creds.ClientID, op.creds.ClientSecret)
if err != nil {
return nil, errors.Wrap(err, "connecting to graph api")
}
cs, err := gc.ExchangeDataCollection(bo.Targets[0])
cs, err := gc.ExchangeDataCollection(op.Targets[0])
if err != nil {
return nil, errors.Wrap(err, "retrieving application data")
}
// todo: utilize stats
stats, err := bo.kopia.BackupCollections(ctx, cs)
stats, err := op.kopia.BackupCollections(ctx, cs)
if err != nil {
return nil, errors.Wrap(err, "backing up application data")
}
bo.Status = Successful
op.Status = Successful
return stats, nil
}

View File

@ -0,0 +1,58 @@
package operations
import (
"context"
"github.com/pkg/errors"
"github.com/alcionai/corso/internal/kopia"
"github.com/alcionai/corso/pkg/credentials"
)
// RestoreOperation wraps an operation with restore-specific props.
type RestoreOperation struct {
operation
Version string
creds credentials.M365
Targets []string // something for targets/filter/source/app&users/etc
}
// NewRestoreOperation constructs and validates a restore operation.
func NewRestoreOperation(
ctx context.Context,
opts OperationOpts,
kw *kopia.KopiaWrapper,
creds credentials.M365,
targets []string,
) (RestoreOperation, error) {
op := RestoreOperation{
operation: newOperation(opts, kw),
Version: "v0",
creds: creds,
Targets: targets,
}
if err := op.validate(); err != nil {
return RestoreOperation{}, err
}
return op, nil
}
func (op RestoreOperation) validate() error {
if err := op.creds.Validate(); err != nil {
return errors.Wrap(err, "invalid credentials")
}
return op.operation.validate()
}
// Run begins a synchronous restore operation.
// todo (keepers): return stats block in first param.
func (op *RestoreOperation) Run(ctx context.Context) (any, error) {
// todo: hook up with KW and GC restore operations.
op.Status = Successful
return nil, nil
}

View File

@ -0,0 +1,63 @@
package operations_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/internal/kopia"
"github.com/alcionai/corso/internal/operations"
ctesting "github.com/alcionai/corso/internal/testing"
"github.com/alcionai/corso/pkg/credentials"
)
type RestoreOpIntegrationSuite struct {
suite.Suite
}
func TestRestoreOpIntegrationSuite(t *testing.T) {
if err := ctesting.RunOnAny(ctesting.CorsoCITests); err != nil {
t.Skip(err)
}
suite.Run(t, new(RestoreOpIntegrationSuite))
}
func (suite *RestoreOpIntegrationSuite) SetupSuite() {
_, err := ctesting.GetRequiredEnvVars(
credentials.TenantID,
credentials.ClientID,
credentials.ClientSecret,
)
require.NoError(suite.T(), err)
}
func (suite *RestoreOpIntegrationSuite) TestNewRestoreOperation() {
kw := &kopia.KopiaWrapper{}
creds := credentials.GetM365()
table := []struct {
name string
opts operations.OperationOpts
kw *kopia.KopiaWrapper
creds credentials.M365
targets []string
errCheck assert.ErrorAssertionFunc
}{
{"good", operations.OperationOpts{}, kw, creds, nil, assert.NoError},
{"missing kopia", operations.OperationOpts{}, nil, creds, nil, assert.Error},
{"invalid creds", operations.OperationOpts{}, kw, credentials.M365{}, nil, assert.Error},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
_, err := operations.NewRestoreOperation(
context.Background(),
operations.OperationOpts{},
test.kw,
test.creds,
nil)
test.errCheck(t, err)
})
}
}