Compare commits
2 Commits
main
...
116-pitr-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
653a79bde9 | ||
|
|
a0ebe13565 |
@ -95,7 +95,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c, fs = utils.AddCommand(cmd, exchangeListCmd())
|
c, fs = utils.AddCommand(cmd, exchangeListCmd())
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, false)
|
utils.AddDetailsAndRestoreFlags(c, false)
|
||||||
addFailedItemsFN(c)
|
addFailedItemsFN(c)
|
||||||
addSkippedItemsFN(c)
|
addSkippedItemsFN(c)
|
||||||
addRecoveredErrorsFN(c)
|
addRecoveredErrorsFN(c)
|
||||||
@ -111,7 +111,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
|
|
||||||
// Flags addition ordering should follow the order we want them to appear in help and docs:
|
// Flags addition ordering should follow the order we want them to appear in help and docs:
|
||||||
// More generic (ex: --user) and more frequently used flags take precedence.
|
// More generic (ex: --user) and more frequently used flags take precedence.
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddExchangeDetailsAndRestoreFlags(c)
|
utils.AddExchangeDetailsAndRestoreFlags(c)
|
||||||
|
|
||||||
case deleteCommand:
|
case deleteCommand:
|
||||||
|
|||||||
@ -78,7 +78,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c, fs = utils.AddCommand(cmd, oneDriveListCmd())
|
c, fs = utils.AddCommand(cmd, oneDriveListCmd())
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, false)
|
utils.AddDetailsAndRestoreFlags(c, false)
|
||||||
addFailedItemsFN(c)
|
addFailedItemsFN(c)
|
||||||
addSkippedItemsFN(c)
|
addSkippedItemsFN(c)
|
||||||
addRecoveredErrorsFN(c)
|
addRecoveredErrorsFN(c)
|
||||||
@ -91,7 +91,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c.Example = oneDriveServiceCommandDetailsExamples
|
c.Example = oneDriveServiceCommandDetailsExamples
|
||||||
|
|
||||||
options.AddSkipReduceFlag(c)
|
options.AddSkipReduceFlag(c)
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddOneDriveDetailsAndRestoreFlags(c)
|
utils.AddOneDriveDetailsAndRestoreFlags(c)
|
||||||
|
|
||||||
case deleteCommand:
|
case deleteCommand:
|
||||||
|
|||||||
@ -94,7 +94,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c, fs = utils.AddCommand(cmd, sharePointListCmd())
|
c, fs = utils.AddCommand(cmd, sharePointListCmd())
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, false)
|
utils.AddDetailsAndRestoreFlags(c, false)
|
||||||
addFailedItemsFN(c)
|
addFailedItemsFN(c)
|
||||||
addSkippedItemsFN(c)
|
addSkippedItemsFN(c)
|
||||||
addRecoveredErrorsFN(c)
|
addRecoveredErrorsFN(c)
|
||||||
@ -107,7 +107,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
c.Example = sharePointServiceCommandDetailsExamples
|
c.Example = sharePointServiceCommandDetailsExamples
|
||||||
|
|
||||||
options.AddSkipReduceFlag(c)
|
options.AddSkipReduceFlag(c)
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddSharePointDetailsAndRestoreFlags(c)
|
utils.AddSharePointDetailsAndRestoreFlags(c)
|
||||||
|
|
||||||
case deleteCommand:
|
case deleteCommand:
|
||||||
|
|||||||
@ -23,6 +23,8 @@ func Control() control.Options {
|
|||||||
opt.ToggleFeatures.DisableConcurrencyLimiter = disableConcurrencyLimiterFV
|
opt.ToggleFeatures.DisableConcurrencyLimiter = disableConcurrencyLimiterFV
|
||||||
opt.Parallelism.ItemFetch = fetchParallelismFV
|
opt.Parallelism.ItemFetch = fetchParallelismFV
|
||||||
|
|
||||||
|
opt.Repo.ViewTimestamp = viewTimestampFV.Get()
|
||||||
|
|
||||||
return opt
|
return opt
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ const (
|
|||||||
DisableIncrementalsFN = "disable-incrementals"
|
DisableIncrementalsFN = "disable-incrementals"
|
||||||
EnableImmutableIDFN = "enable-immutable-id"
|
EnableImmutableIDFN = "enable-immutable-id"
|
||||||
DisableConcurrencyLimiterFN = "disable-concurrency-limiter"
|
DisableConcurrencyLimiterFN = "disable-concurrency-limiter"
|
||||||
|
ViewTimestampFN = "point-in-time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -48,6 +51,7 @@ var (
|
|||||||
noStatsFV bool
|
noStatsFV bool
|
||||||
restorePermissionsFV bool
|
restorePermissionsFV bool
|
||||||
skipReduceFV bool
|
skipReduceFV bool
|
||||||
|
viewTimestampFV timestamp
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddGlobalOperationFlags adds the global operations flag set.
|
// AddGlobalOperationFlags adds the global operations flag set.
|
||||||
@ -90,6 +94,17 @@ func AddFetchParallelismFlag(cmd *cobra.Command) {
|
|||||||
cobra.CheckErr(fs.MarkHidden(FetchParallelismFN))
|
cobra.CheckErr(fs.MarkHidden(FetchParallelismFN))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddViewTimestampFlag adds a hidden flag that allows callers to pass a
|
||||||
|
// timestamp to view the corso repo at if immutable backups are enabled.
|
||||||
|
func AddViewTimestampFlag(cmd *cobra.Command) {
|
||||||
|
fs := cmd.Flags()
|
||||||
|
fs.Var(
|
||||||
|
&viewTimestampFV,
|
||||||
|
ViewTimestampFN,
|
||||||
|
"View the repository at a previous datetime by passing an RFC3339 timestamp")
|
||||||
|
cobra.CheckErr(fs.MarkHidden(ViewTimestampFN))
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Feature Flags
|
// Feature Flags
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -32,7 +32,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
// general flags
|
// general flags
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddExchangeDetailsAndRestoreFlags(c)
|
utils.AddExchangeDetailsAndRestoreFlags(c)
|
||||||
options.AddFailFastFlag(c)
|
options.AddFailFastFlag(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
// More generic (ex: --user) and more frequently used flags take precedence.
|
// More generic (ex: --user) and more frequently used flags take precedence.
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddOneDriveDetailsAndRestoreFlags(c)
|
utils.AddOneDriveDetailsAndRestoreFlags(c)
|
||||||
|
|
||||||
// restore permissions
|
// restore permissions
|
||||||
|
|||||||
@ -31,7 +31,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
|
|||||||
// More generic (ex: --site) and more frequently used flags take precedence.
|
// More generic (ex: --site) and more frequently used flags take precedence.
|
||||||
fs.SortFlags = false
|
fs.SortFlags = false
|
||||||
|
|
||||||
utils.AddBackupIDFlag(c, true)
|
utils.AddDetailsAndRestoreFlags(c, true)
|
||||||
utils.AddSharePointDetailsAndRestoreFlags(c)
|
utils.AddSharePointDetailsAndRestoreFlags(c)
|
||||||
|
|
||||||
options.AddRestorePermissionsFlag(c)
|
options.AddRestorePermissionsFlag(c)
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/cli/options"
|
||||||
"github.com/alcionai/corso/src/internal/common/dttm"
|
"github.com/alcionai/corso/src/internal/common/dttm"
|
||||||
"github.com/alcionai/corso/src/pkg/control/repository"
|
"github.com/alcionai/corso/src/pkg/control/repository"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
@ -84,6 +85,11 @@ func AddBackupIDFlag(cmd *cobra.Command, require bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddDetailsAndRestoreFlags(cmd *cobra.Command, require bool) {
|
||||||
|
AddBackupIDFlag(cmd, require)
|
||||||
|
options.AddViewTimestampFlag(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) {
|
func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) {
|
||||||
var (
|
var (
|
||||||
allowedMsg string
|
allowedMsg string
|
||||||
|
|||||||
@ -71,7 +71,7 @@ func NewConn(s storage.Storage) *conn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *conn) Initialize(ctx context.Context, opts repository.Options) error {
|
func (w *conn) Initialize(ctx context.Context, opts repository.Options) error {
|
||||||
bst, err := blobStoreByProvider(ctx, w.storage)
|
bst, err := blobStoreByProvider(ctx, opts, w.storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Wrap(err, "initializing storage")
|
return clues.Wrap(err, "initializing storage")
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func (w *conn) Initialize(ctx context.Context, opts repository.Options) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *conn) Connect(ctx context.Context, opts repository.Options) error {
|
func (w *conn) Connect(ctx context.Context, opts repository.Options) error {
|
||||||
bst, err := blobStoreByProvider(ctx, w.storage)
|
bst, err := blobStoreByProvider(ctx, opts, w.storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Wrap(err, "initializing storage")
|
return clues.Wrap(err, "initializing storage")
|
||||||
}
|
}
|
||||||
@ -174,10 +174,14 @@ func (w *conn) commonConnect(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func blobStoreByProvider(ctx context.Context, s storage.Storage) (blob.Storage, error) {
|
func blobStoreByProvider(
|
||||||
|
ctx context.Context,
|
||||||
|
opts repository.Options,
|
||||||
|
s storage.Storage,
|
||||||
|
) (blob.Storage, error) {
|
||||||
switch s.Provider {
|
switch s.Provider {
|
||||||
case storage.ProviderS3:
|
case storage.ProviderS3:
|
||||||
return s3BlobStorage(ctx, s)
|
return s3BlobStorage(ctx, opts, s)
|
||||||
default:
|
default:
|
||||||
return nil, clues.New("storage provider details are required").WithClues(ctx)
|
return nil, clues.New("storage provider details are required").WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/kopia/kopia/repo/blob"
|
"github.com/kopia/kopia/repo/blob"
|
||||||
"github.com/kopia/kopia/repo/blob/s3"
|
"github.com/kopia/kopia/repo/blob/s3"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/pkg/control/repository"
|
||||||
"github.com/alcionai/corso/src/pkg/storage"
|
"github.com/alcionai/corso/src/pkg/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +15,11 @@ const (
|
|||||||
defaultS3Endpoint = "s3.amazonaws.com" // matches kopia's default value
|
defaultS3Endpoint = "s3.amazonaws.com" // matches kopia's default value
|
||||||
)
|
)
|
||||||
|
|
||||||
func s3BlobStorage(ctx context.Context, s storage.Storage) (blob.Storage, error) {
|
func s3BlobStorage(
|
||||||
|
ctx context.Context,
|
||||||
|
repoOpts repository.Options,
|
||||||
|
s storage.Storage,
|
||||||
|
) (blob.Storage, error) {
|
||||||
cfg, err := s.S3Config()
|
cfg, err := s.S3Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx)
|
return nil, clues.Stack(err).WithClues(ctx)
|
||||||
@ -36,6 +41,7 @@ func s3BlobStorage(ctx context.Context, s storage.Storage) (blob.Storage, error)
|
|||||||
RoleARN: s.Role,
|
RoleARN: s.Role,
|
||||||
RoleDuration: s.SessionDuration,
|
RoleDuration: s.SessionDuration,
|
||||||
TLSHandshakeTimeout: 60,
|
TLSHandshakeTimeout: 60,
|
||||||
|
PointInTime: repoOpts.ViewTimestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err := s3.New(ctx, &opts, false)
|
store, err := s3.New(ctx, &opts, false)
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Repo represents options that are specific to the repo storing backed up data.
|
// Repo represents options that are specific to the repo storing backed up data.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
|
// ViewTimestamp is the time at which the repo should be opened at if
|
||||||
|
// immutable backups are being used. If nil then the current time is used.
|
||||||
|
ViewTimestamp *time.Time `json:"viewTimestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Maintenance struct {
|
type Maintenance struct {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user