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