146 lines
4.1 KiB
Go
146 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
|
|
"github.com/influxdata/influxdb/v2/http"
|
|
influxlogger "github.com/influxdata/influxdb/v2/logger"
|
|
"github.com/influxdata/influxdb/v2/restore"
|
|
"github.com/influxdata/influxdb/v2/tenant"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func cmdRestore(f *globalFlags, opts genericCLIOpts) *cobra.Command {
|
|
return newCmdRestoreBuilder(f, opts).cmdRestore()
|
|
}
|
|
|
|
type cmdRestoreBuilder struct {
|
|
genericCLIOpts
|
|
*globalFlags
|
|
|
|
full bool
|
|
bucketID string
|
|
bucketName string
|
|
newBucketName string
|
|
newOrgName string
|
|
org organization
|
|
path string
|
|
}
|
|
|
|
func newCmdRestoreBuilder(f *globalFlags, opts genericCLIOpts) *cmdRestoreBuilder {
|
|
return &cmdRestoreBuilder{
|
|
genericCLIOpts: opts,
|
|
globalFlags: f,
|
|
}
|
|
}
|
|
|
|
func (b *cmdRestoreBuilder) cmdRestore() *cobra.Command {
|
|
cmd := b.newCmd("restore", b.restoreRunE)
|
|
b.org.register(b.viper, cmd, true)
|
|
cmd.Flags().BoolVar(&b.full, "full", false, "Fully restore and replace all data on server")
|
|
cmd.Flags().StringVar(&b.bucketID, "bucket-id", "", "The ID of the bucket to restore")
|
|
cmd.Flags().StringVarP(&b.bucketName, "bucket", "b", "", "The name of the bucket to restore")
|
|
cmd.Flags().StringVar(&b.newBucketName, "new-bucket", "", "The name of the bucket to restore to")
|
|
cmd.Flags().StringVar(&b.newOrgName, "new-org", "", "The name of the organization to restore to")
|
|
cmd.Flags().StringVar(&b.path, "input", "", "Local backup data path")
|
|
cmd.Flags().MarkDeprecated("input", "pass backup data path as a positional argument instead")
|
|
cmd.Use = "restore [flags] path"
|
|
cmd.Args = func(cmd *cobra.Command, args []string) error {
|
|
// Legacy: path set by --input flag.
|
|
if b.path != "" {
|
|
if len(args) != 0 {
|
|
return errors.New("cannot specify backup directory using both --input and a positional argument")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if len(args) == 0 {
|
|
return errors.New("must specify path to backup directory")
|
|
} else if len(args) > 1 {
|
|
return errors.New("only one backup directory can be specified at a time")
|
|
}
|
|
b.path = args[0]
|
|
return nil
|
|
}
|
|
cmd.Short = "Restores a backup directory to InfluxDB."
|
|
cmd.Long = `
|
|
Restore influxdb.
|
|
|
|
Examples:
|
|
# restore all data
|
|
influx restore /path/to/restore
|
|
`
|
|
return cmd
|
|
}
|
|
|
|
func (b *cmdRestoreBuilder) restoreRunE(cmd *cobra.Command, args []string) (err error) {
|
|
// Create top level logger
|
|
logconf := influxlogger.NewConfig()
|
|
logger, err := logconf.New(os.Stdout)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Ensure org/bucket filters are set if a new org/bucket name is specified.
|
|
if b.newOrgName != "" && b.org.id == "" && b.org.name == "" {
|
|
return fmt.Errorf("must specify source org id or name when renaming restored org")
|
|
} else if b.newBucketName != "" && b.bucketID == "" && b.bucketName == "" {
|
|
return fmt.Errorf("must specify source bucket id or name when renaming restored bucket")
|
|
}
|
|
|
|
ac := flags.config()
|
|
client, err := newHTTPClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
services := restore.Services{
|
|
RestoreService: &http.RestoreService{
|
|
Addr: ac.Host,
|
|
Token: ac.Token,
|
|
InsecureSkipVerify: flags.skipVerify,
|
|
},
|
|
OrgService: &tenant.OrgClientService{Client: client},
|
|
BucketService: &tenant.BucketClientService{Client: client},
|
|
}
|
|
|
|
var orgID platform.ID
|
|
if b.org.id != "" {
|
|
if err := orgID.DecodeFromString(b.org.id); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var bucketID platform.ID
|
|
if b.bucketID != "" {
|
|
if err := bucketID.DecodeFromString(b.bucketID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
request := restore.Request{
|
|
OrgID: orgID,
|
|
Org: b.org.name,
|
|
NewOrgName: b.newOrgName,
|
|
BucketID: bucketID,
|
|
Bucket: b.bucketName,
|
|
NewBucketName: b.newBucketName,
|
|
Path: b.path,
|
|
Full: b.full,
|
|
}
|
|
|
|
return restore.RunRestore(context.Background(), request, services, logger)
|
|
}
|
|
|
|
func (b *cmdRestoreBuilder) newCmd(use string, runE func(*cobra.Command, []string) error) *cobra.Command {
|
|
cmd := b.genericCLIOpts.newCmd(use, runE, true)
|
|
b.genericCLIOpts.registerPrintOptions(cmd)
|
|
b.globalFlags.registerFlags(b.viper, cmd)
|
|
return cmd
|
|
}
|