add graph connector to backupOp (#165)
Adds graph connector to the backup operation implementation. This includes feeding the account credentials into the backup as well.
This commit is contained in:
parent
9043351716
commit
2104e66fea
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -13,6 +13,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Run-All:
|
Run-All:
|
||||||
|
environment: Testing
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@ -50,4 +51,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CORSO_CI_TESTS: true
|
CORSO_CI_TESTS: true
|
||||||
CORSO_PASSWORD: ${{ secrets.INTEGRATION_TEST_CORSO_PASSWORD }}
|
CORSO_PASSWORD: ${{ secrets.INTEGRATION_TEST_CORSO_PASSWORD }}
|
||||||
|
CLIENT_ID: ${{ secrets.CLIENT_ID }}
|
||||||
|
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
|
||||||
|
TENANT_ID: ${{ secrets.TENANT_ID }}
|
||||||
run: go test ./...
|
run: go test ./...
|
||||||
@ -7,6 +7,7 @@ replace github.com/kopia/kopia => github.com/alcionai/kopia v0.10.8-0.2022060816
|
|||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/kopia/kopia v0.10.7
|
github.com/kopia/kopia v0.10.7
|
||||||
github.com/microsoft/kiota-authentication-azure-go v0.3.0
|
github.com/microsoft/kiota-authentication-azure-go v0.3.0
|
||||||
github.com/microsoft/kiota-serialization-json-go v0.5.1
|
github.com/microsoft/kiota-serialization-json-go v0.5.1
|
||||||
@ -48,7 +49,6 @@ require (
|
|||||||
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
|
||||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
|||||||
@ -3,13 +3,20 @@ package operations
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/internal/connector"
|
||||||
"github.com/alcionai/corso/internal/kopia"
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
|
"github.com/alcionai/corso/pkg/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BackupOperation wraps an operation with backup-specific props.
|
// BackupOperation wraps an operation with backup-specific props.
|
||||||
type BackupOperation struct {
|
type BackupOperation struct {
|
||||||
operation
|
operation
|
||||||
Version string
|
Version string
|
||||||
|
|
||||||
|
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
|
Work []string // something to reference the artifacts created, or at least their count
|
||||||
|
|
||||||
@ -22,14 +29,13 @@ func NewBackupOperation(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
opts OperationOpts,
|
opts OperationOpts,
|
||||||
kw *kopia.KopiaWrapper,
|
kw *kopia.KopiaWrapper,
|
||||||
|
creds credentials.M365,
|
||||||
targets []string,
|
targets []string,
|
||||||
) (BackupOperation, error) {
|
) (BackupOperation, error) {
|
||||||
// todo - initialize a graphConnector
|
|
||||||
// gc, err := graphConnector.Connect(bo.account)
|
|
||||||
|
|
||||||
bo := BackupOperation{
|
bo := BackupOperation{
|
||||||
operation: newOperation(opts, kw),
|
operation: newOperation(opts, kw),
|
||||||
Version: "v0",
|
Version: "v0",
|
||||||
|
creds: creds,
|
||||||
Targets: targets,
|
Targets: targets,
|
||||||
Work: []string{},
|
Work: []string{},
|
||||||
}
|
}
|
||||||
@ -41,11 +47,19 @@ func NewBackupOperation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bo BackupOperation) validate() error {
|
func (bo BackupOperation) validate() error {
|
||||||
|
if err := bo.creds.Validate(); err != nil {
|
||||||
|
return errors.Wrap(err, "invalid credentials")
|
||||||
|
}
|
||||||
return bo.operation.validate()
|
return bo.operation.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run begins a synchronous backup operation.
|
// Run begins a synchronous backup operation.
|
||||||
func (bo BackupOperation) Run(ctx context.Context) error {
|
func (bo BackupOperation) Run(ctx context.Context) error {
|
||||||
|
_, err := connector.NewGraphConnector(bo.creds.TenantID, bo.creds.ClientID, bo.creds.ClientSecret)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "connecting to graph api")
|
||||||
|
}
|
||||||
|
|
||||||
// todo - use the graphConnector to create datastreams
|
// todo - use the graphConnector to create datastreams
|
||||||
// dStreams, err := bo.gc.BackupOp(bo.Targets)
|
// dStreams, err := bo.gc.BackupOp(bo.Targets)
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/alcionai/corso/internal/kopia"
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
"github.com/alcionai/corso/internal/operations"
|
"github.com/alcionai/corso/internal/operations"
|
||||||
ctesting "github.com/alcionai/corso/internal/testing"
|
ctesting "github.com/alcionai/corso/internal/testing"
|
||||||
|
"github.com/alcionai/corso/pkg/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BackupOpIntegrationSuite struct {
|
type BackupOpIntegrationSuite struct {
|
||||||
@ -23,24 +24,40 @@ func TestBackupOpIntegrationSuite(t *testing.T) {
|
|||||||
suite.Run(t, new(BackupOpIntegrationSuite))
|
suite.Run(t, new(BackupOpIntegrationSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *BackupOpIntegrationSuite) SetupSuite() {
|
||||||
|
if _, err := ctesting.GetRequiredEnvVars(
|
||||||
|
credentials.TenantID,
|
||||||
|
credentials.ClientID,
|
||||||
|
credentials.ClientSecret,
|
||||||
|
); err != nil {
|
||||||
|
suite.T().Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *BackupOpIntegrationSuite) TestNewBackupOperation() {
|
func (suite *BackupOpIntegrationSuite) TestNewBackupOperation() {
|
||||||
|
kw := &kopia.KopiaWrapper{}
|
||||||
|
creds := credentials.GetM365()
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
opts operations.OperationOpts
|
opts operations.OperationOpts
|
||||||
kw *kopia.KopiaWrapper
|
kw *kopia.KopiaWrapper
|
||||||
|
creds credentials.M365
|
||||||
targets []string
|
targets []string
|
||||||
|
errCheck assert.ErrorAssertionFunc
|
||||||
}{
|
}{
|
||||||
{"good", operations.OperationOpts{}, new(kopia.KopiaWrapper), nil},
|
{"good", operations.OperationOpts{}, kw, creds, nil, assert.NoError},
|
||||||
{"missing kopia", operations.OperationOpts{}, nil, nil},
|
{"missing kopia", operations.OperationOpts{}, nil, creds, nil, assert.Error},
|
||||||
|
{"invalid creds", operations.OperationOpts{}, kw, credentials.M365{}, nil, assert.Error},
|
||||||
}
|
}
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
_, err := operations.NewBackupOperation(
|
_, err := operations.NewBackupOperation(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
operations.OperationOpts{},
|
operations.OperationOpts{},
|
||||||
new(kopia.KopiaWrapper),
|
test.kw,
|
||||||
|
test.creds,
|
||||||
nil)
|
nil)
|
||||||
assert.NoError(t, err)
|
test.errCheck(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,12 @@ package operations
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alcionai/corso/internal/kopia"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
)
|
)
|
||||||
|
|
||||||
type opStatus int
|
type opStatus int
|
||||||
@ -28,9 +29,6 @@ type operation struct {
|
|||||||
options OperationOpts
|
options OperationOpts
|
||||||
kopia *kopia.KopiaWrapper
|
kopia *kopia.KopiaWrapper
|
||||||
|
|
||||||
// TODO(rkeepers) deal with circular dependencies here
|
|
||||||
// graphConn GraphConnector // m365 details
|
|
||||||
|
|
||||||
Status opStatus
|
Status opStatus
|
||||||
Errors []error
|
Errors []error
|
||||||
}
|
}
|
||||||
@ -47,7 +45,10 @@ type OperationOpts struct {
|
|||||||
Logger logger
|
Logger logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOperation(opts OperationOpts, kw *kopia.KopiaWrapper) operation {
|
func newOperation(
|
||||||
|
opts OperationOpts,
|
||||||
|
kw *kopia.KopiaWrapper,
|
||||||
|
) operation {
|
||||||
return operation{
|
return operation{
|
||||||
ID: uuid.New(),
|
ID: uuid.New(),
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
|
|||||||
@ -3,9 +3,10 @@ package operations
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alcionai/corso/internal/kopia"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperationSuite struct {
|
type OperationSuite struct {
|
||||||
@ -24,12 +25,13 @@ func (suite *OperationSuite) TestNewOperation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *OperationSuite) TestOperation_Validate() {
|
func (suite *OperationSuite) TestOperation_Validate() {
|
||||||
|
kwStub := &kopia.KopiaWrapper{}
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
kw *kopia.KopiaWrapper
|
kw *kopia.KopiaWrapper
|
||||||
errCheck assert.ErrorAssertionFunc
|
errCheck assert.ErrorAssertionFunc
|
||||||
}{
|
}{
|
||||||
{"good", new(kopia.KopiaWrapper), assert.NoError},
|
{"good", kwStub, assert.NoError},
|
||||||
{"missing kopia", nil, assert.Error},
|
{"missing kopia", nil, assert.Error},
|
||||||
}
|
}
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
|
|||||||
5
src/pkg/credentials/credentials.go
Normal file
5
src/pkg/credentials/credentials.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package credentials
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var errMissingRequired = errors.New("missing required storage configuration")
|
||||||
@ -1,6 +1,10 @@
|
|||||||
package credentials
|
package credentials
|
||||||
|
|
||||||
import "os"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
// envvar consts
|
// envvar consts
|
||||||
const (
|
const (
|
||||||
@ -26,3 +30,17 @@ func GetM365() M365 {
|
|||||||
TenantID: os.Getenv(TenantID),
|
TenantID: os.Getenv(TenantID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c M365) Validate() error {
|
||||||
|
check := map[string]string{
|
||||||
|
ClientID: c.ClientID,
|
||||||
|
ClientSecret: c.ClientSecret,
|
||||||
|
TenantID: c.TenantID,
|
||||||
|
}
|
||||||
|
for k, v := range check {
|
||||||
|
if len(v) == 0 {
|
||||||
|
return errors.Wrap(errMissingRequired, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/internal/kopia"
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
"github.com/alcionai/corso/internal/operations"
|
"github.com/alcionai/corso/internal/operations"
|
||||||
|
"github.com/alcionai/corso/pkg/credentials"
|
||||||
"github.com/alcionai/corso/pkg/storage"
|
"github.com/alcionai/corso/pkg/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -106,9 +107,15 @@ func (r *Repository) Close(ctx context.Context) error {
|
|||||||
|
|
||||||
// NewBackup generates a backupOperation runner.
|
// NewBackup generates a backupOperation runner.
|
||||||
func (r Repository) NewBackup(ctx context.Context, targets []string) (operations.BackupOperation, error) {
|
func (r Repository) NewBackup(ctx context.Context, targets []string) (operations.BackupOperation, error) {
|
||||||
|
creds := credentials.M365{
|
||||||
|
ClientID: r.Account.ClientID,
|
||||||
|
ClientSecret: r.Account.ClientSecret,
|
||||||
|
TenantID: r.Account.TenantID,
|
||||||
|
}
|
||||||
return operations.NewBackupOperation(
|
return operations.NewBackupOperation(
|
||||||
ctx,
|
ctx,
|
||||||
operations.OperationOpts{},
|
operations.OperationOpts{},
|
||||||
r.dataLayer,
|
r.dataLayer,
|
||||||
|
creds,
|
||||||
targets)
|
targets)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user