diff --git a/Makefile.include b/Makefile.include index 677a8e54f2..e3e97e52d1 100644 --- a/Makefile.include +++ b/Makefile.include @@ -57,13 +57,15 @@ gen: clean ## Generate files. done # generate public API spec, omit agentlocalpb (always private), - # and managementpb/dbaas, managementpb/ia, managementpb/alerting, managementpb/backup , managementpb/azure and qanpb (not v1 yet) + # and managementpb/dbaas, managementpb/ia, managementpb/azure and qanpb (not v1 yet) bin/swagger mixin --output=api/swagger/swagger.json \ api/swagger/header.json \ api/serverpb/json/serverpb.json \ api/userpb/json/userpb.json \ api/inventorypb/json/inventorypb.json \ - api/managementpb/json/managementpb.json + api/managementpb/json/managementpb.json \ + api/managementpb/backup/json/backup.json \ + api/managementpb/alerting/json/alerting.json bin/swagger validate api/swagger/swagger.json bin/swagger-order --output=api/swagger/swagger.json api/swagger/swagger.json diff --git a/agent/agents/supervisor/supervisor.go b/agent/agents/supervisor/supervisor.go index ecf329b774..478fbc2308 100644 --- a/agent/agents/supervisor/supervisor.go +++ b/agent/agents/supervisor/supervisor.go @@ -213,6 +213,30 @@ func (s *Supervisor) SetState(state *agentpb.SetStateRequest) { s.setBuiltinAgents(state.BuiltinAgents) } +// RestartAgents restarts all existing agents. +func (s *Supervisor) RestartAgents() { + s.rw.Lock() + defer s.rw.Unlock() + + for id, agent := range s.agentProcesses { + agent.cancel() + <-agent.done + + if err := s.startProcess(id, agent.requestedState, agent.listenPort); err != nil { + s.l.Errorf("Failed to restart Agent: %s.", err) + } + } + + for id, agent := range s.builtinAgents { + agent.cancel() + <-agent.done + + if err := s.startBuiltin(id, agent.requestedState); err != nil { + s.l.Errorf("Failed to restart Agent: %s.", err) + } + } +} + func (s *Supervisor) storeLastStatus(agentID string, status inventorypb.AgentStatus) { s.arw.Lock() defer s.arw.Unlock() diff --git a/agent/client/client.go b/agent/client/client.go index 9d3dcfd876..ae924d9d49 100644 --- a/agent/client/client.go +++ b/agent/client/client.go @@ -543,10 +543,10 @@ func (c *Client) handleStartJobRequest(p *agentpb.StartJobRequest) error { BucketName: cfg.S3Config.BucketName, BucketRegion: cfg.S3Config.BucketRegion, } - case *agentpb.StartJobRequest_MongoDBBackup_PmmClientConfig: - locationConfig.Type = jobs.PMMClientBackupLocationType - locationConfig.LocalStorageConfig = &jobs.PMMClientBackupLocationConfig{ - Path: cfg.PmmClientConfig.Path, + case *agentpb.StartJobRequest_MongoDBBackup_FilesystemConfig: + locationConfig.Type = jobs.FilesystemBackupLocationType + locationConfig.FilesystemStorageConfig = &jobs.FilesystemBackupLocationConfig{ + Path: cfg.FilesystemConfig.Path, } default: return errors.Errorf("unknown location config: %T", j.MongodbBackup.LocationConfig) @@ -575,10 +575,10 @@ func (c *Client) handleStartJobRequest(p *agentpb.StartJobRequest) error { BucketName: cfg.S3Config.BucketName, BucketRegion: cfg.S3Config.BucketRegion, } - case *agentpb.StartJobRequest_MongoDBRestoreBackup_PmmClientConfig: - locationConfig.Type = jobs.PMMClientBackupLocationType - locationConfig.LocalStorageConfig = &jobs.PMMClientBackupLocationConfig{ - Path: cfg.PmmClientConfig.Path, + case *agentpb.StartJobRequest_MongoDBRestoreBackup_FilesystemConfig: + locationConfig.Type = jobs.FilesystemBackupLocationType + locationConfig.FilesystemStorageConfig = &jobs.FilesystemBackupLocationConfig{ + Path: cfg.FilesystemConfig.Path, } default: return errors.Errorf("unknown location config: %T", j.MongodbRestoreBackup.LocationConfig) @@ -591,7 +591,8 @@ func (c *Client) handleStartJobRequest(p *agentpb.StartJobRequest) error { Port: int(j.MongodbRestoreBackup.Port), Socket: j.MongodbRestoreBackup.Socket, } - job = jobs.NewMongoDBRestoreJob(p.JobId, timeout, j.MongodbRestoreBackup.Name, dbConnCfg, locationConfig) + + job = jobs.NewMongoDBRestoreJob(p.JobId, timeout, j.MongodbRestoreBackup.Name, j.MongodbRestoreBackup.PitrTimestamp.AsTime(), dbConnCfg, locationConfig, c.supervisor) default: return errors.Errorf("unknown job type: %T", j) } diff --git a/agent/client/deps.go b/agent/client/deps.go index 2cd2e9d9d2..b0e5d0f216 100644 --- a/agent/client/deps.go +++ b/agent/client/deps.go @@ -46,6 +46,7 @@ type supervisor interface { Changes() <-chan *agentpb.StateChangedRequest QANRequests() <-chan *agentpb.QANCollectRequest SetState(*agentpb.SetStateRequest) + RestartAgents() AgentLogByID(string) ([]string, uint) // Collector added to use client as Prometheus collector prometheus.Collector diff --git a/agent/client/mock_supervisor_test.go b/agent/client/mock_supervisor_test.go index 1460ca2df4..4e9b8418bc 100644 --- a/agent/client/mock_supervisor_test.go +++ b/agent/client/mock_supervisor_test.go @@ -79,6 +79,11 @@ func (_m *mockSupervisor) QANRequests() <-chan *agentpb.QANCollectRequest { return r0 } +// RestartAgents provides a mock function with given fields: +func (_m *mockSupervisor) RestartAgents() { + _m.Called() +} + // SetState provides a mock function with given fields: _a0 func (_m *mockSupervisor) SetState(_a0 *agentpb.SetStateRequest) { _m.Called(_a0) diff --git a/agent/runner/jobs/backup_location.go b/agent/runner/jobs/backup_location.go index 08ed79f6ea..684525ae29 100644 --- a/agent/runner/jobs/backup_location.go +++ b/agent/runner/jobs/backup_location.go @@ -19,8 +19,8 @@ type BackupLocationType string // BackupLocation types. Same as in managed/models/location_model.go. const ( - S3BackupLocationType BackupLocationType = "s3" - PMMClientBackupLocationType BackupLocationType = "pmm-client" + S3BackupLocationType BackupLocationType = "s3" + FilesystemBackupLocationType BackupLocationType = "filesystem" ) // S3LocationConfig contains required properties for accessing S3 Bucket. @@ -32,14 +32,14 @@ type S3LocationConfig struct { BucketRegion string } -// PMMClientBackupLocationConfig contains config for local storage -type PMMClientBackupLocationConfig struct { +// FilesystemBackupLocationConfig contains config for local storage +type FilesystemBackupLocationConfig struct { Path string } // BackupLocationConfig groups all backup locations configs. type BackupLocationConfig struct { - Type BackupLocationType - S3Config *S3LocationConfig - LocalStorageConfig *PMMClientBackupLocationConfig + Type BackupLocationType + S3Config *S3LocationConfig + FilesystemStorageConfig *FilesystemBackupLocationConfig } diff --git a/agent/runner/jobs/deps.go b/agent/runner/jobs/deps.go new file mode 100644 index 0000000000..b161813b47 --- /dev/null +++ b/agent/runner/jobs/deps.go @@ -0,0 +1,19 @@ +// Copyright 2019 Percona LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package jobs + +type agentsRestarter interface { + RestartAgents() +} diff --git a/agent/runner/jobs/mongodb_backup_job.go b/agent/runner/jobs/mongodb_backup_job.go index 68252549eb..53ee3b7c4d 100644 --- a/agent/runner/jobs/mongodb_backup_job.go +++ b/agent/runner/jobs/mongodb_backup_job.go @@ -19,6 +19,7 @@ import ( "context" "io" "net/url" + "os" "os/exec" "sync/atomic" "time" @@ -28,7 +29,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/percona/pmm/api/agentpb" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" ) const ( @@ -48,7 +49,7 @@ type MongoDBBackupJob struct { locationConfig BackupLocationConfig pitr bool logChunkID uint32 - dataModel backupv1beta1.DataModel + dataModel backuppb.DataModel } // NewMongoDBBackupJob creates new Job for MongoDB backup. @@ -59,12 +60,12 @@ func NewMongoDBBackupJob( dbConfig DBConnConfig, locationConfig BackupLocationConfig, pitr bool, - dataModel backupv1beta1.DataModel, + dataModel backuppb.DataModel, ) (*MongoDBBackupJob, error) { - if dataModel != backupv1beta1.DataModel_PHYSICAL && dataModel != backupv1beta1.DataModel_LOGICAL { + if dataModel != backuppb.DataModel_PHYSICAL && dataModel != backuppb.DataModel_LOGICAL { return nil, errors.Errorf("'%s' is not a supported data model for MongoDB backups", dataModel) } - if dataModel != backupv1beta1.DataModel_LOGICAL && pitr { + if dataModel != backuppb.DataModel_LOGICAL && pitr { return nil, errors.Errorf("PITR is only supported for logical backups") } return &MongoDBBackupJob{ @@ -106,12 +107,19 @@ func (j *MongoDBBackupJob) Run(ctx context.Context, send Send) error { if err != nil { return errors.WithStack(err) } - if err := pbmConfigure(ctx, j.l, j.dbURL, conf); err != nil { + + confFile, err := writePBMConfigFile(conf) + if err != nil { + return errors.WithStack(err) + } + defer os.Remove(confFile) //nolint:errcheck + + if err := pbmConfigure(ctx, j.l, j.dbURL, confFile); err != nil { return errors.Wrap(err, "failed to configure pbm") } rCtx, cancel := context.WithTimeout(ctx, resyncTimeout) - if err := waitForPBMState(rCtx, j.l, j.dbURL, pbmNoRunningOperations); err != nil { + if err := waitForPBMNoRunningOperations(rCtx, j.l, j.dbURL); err != nil { cancel() return errors.Wrap(err, "failed to wait configuration completion") } @@ -131,7 +139,7 @@ func (j *MongoDBBackupJob) Run(ctx context.Context, send Send) error { } }() - if err := waitForPBMState(ctx, j.l, j.dbURL, pbmBackupFinished(pbmBackupOut.Name)); err != nil { + if err := waitForPBMBackup(ctx, j.l, j.dbURL, pbmBackupOut.Name); err != nil { j.sendLog(send, err.Error(), false) return errors.Wrap(err, "failed to wait backup completion") } @@ -156,11 +164,11 @@ func (j *MongoDBBackupJob) startBackup(ctx context.Context) (*pbmBackup, error) pbmArgs := []string{"backup"} switch j.dataModel { - case backupv1beta1.DataModel_PHYSICAL: + case backuppb.DataModel_PHYSICAL: pbmArgs = append(pbmArgs, "--type=physical") - case backupv1beta1.DataModel_LOGICAL: + case backuppb.DataModel_LOGICAL: pbmArgs = append(pbmArgs, "--type=logical") - case backupv1beta1.DataModel_DATA_MODEL_INVALID: + case backuppb.DataModel_DATA_MODEL_INVALID: default: return nil, errors.Errorf("'%s' is not a supported data model for backups", j.dataModel) } diff --git a/agent/runner/jobs/mongodb_backup_job_test.go b/agent/runner/jobs/mongodb_backup_job_test.go index 094b9c8d83..d8cc5b1ba2 100644 --- a/agent/runner/jobs/mongodb_backup_job_test.go +++ b/agent/runner/jobs/mongodb_backup_job_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/assert" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" ) func TestCreateDBURL(t *testing.T) { @@ -83,33 +83,33 @@ func TestNewMongoDBBackupJob(t *testing.T) { tests := []struct { name string dbConfig DBConnConfig - dataModel backupv1beta1.DataModel + dataModel backuppb.DataModel pitr bool errMsg string }{ { name: "logical backup model", dbConfig: DBConnConfig{}, - dataModel: backupv1beta1.DataModel_LOGICAL, + dataModel: backuppb.DataModel_LOGICAL, errMsg: "", }, { name: "physical backup model", dbConfig: DBConnConfig{}, - dataModel: backupv1beta1.DataModel_PHYSICAL, + dataModel: backuppb.DataModel_PHYSICAL, errMsg: "", }, { name: "invalid backup model", dbConfig: DBConnConfig{}, - dataModel: backupv1beta1.DataModel_DATA_MODEL_INVALID, + dataModel: backuppb.DataModel_DATA_MODEL_INVALID, errMsg: "'DATA_MODEL_INVALID' is not a supported data model for MongoDB backups", }, { name: "pitr fails for physical backups", dbConfig: DBConnConfig{}, pitr: true, - dataModel: backupv1beta1.DataModel_PHYSICAL, + dataModel: backuppb.DataModel_PHYSICAL, errMsg: "PITR is only supported for logical backups", }, } diff --git a/agent/runner/jobs/mongodb_restore_job.go b/agent/runner/jobs/mongodb_restore_job.go index 325b7554bf..9758936e89 100644 --- a/agent/runner/jobs/mongodb_restore_job.go +++ b/agent/runner/jobs/mongodb_restore_job.go @@ -16,8 +16,11 @@ package jobs import ( "context" + "fmt" "net/url" + "os" "os/exec" + "strings" "time" "github.com/pkg/errors" @@ -27,25 +30,42 @@ import ( "github.com/percona/pmm/api/agentpb" ) +const ( + listCheckInterval = 1 * time.Second + maxListChecks = 100 +) + // MongoDBRestoreJob implements Job for MongoDB restore. type MongoDBRestoreJob struct { - id string - timeout time.Duration - l *logrus.Entry - name string - dbURL *url.URL - locationConfig BackupLocationConfig + id string + timeout time.Duration + l *logrus.Entry + name string + pitrTimestamp time.Time + dbURL *url.URL + locationConfig BackupLocationConfig + agentsRestarter agentsRestarter } // NewMongoDBRestoreJob creates new Job for MongoDB backup restore. -func NewMongoDBRestoreJob(id string, timeout time.Duration, name string, dbConfig DBConnConfig, locationConfig BackupLocationConfig) *MongoDBRestoreJob { +func NewMongoDBRestoreJob( + id string, + timeout time.Duration, + name string, + pitrTimestamp time.Time, + dbConfig DBConnConfig, + locationConfig BackupLocationConfig, + restarter agentsRestarter, +) *MongoDBRestoreJob { return &MongoDBRestoreJob{ - id: id, - timeout: timeout, - l: logrus.WithFields(logrus.Fields{"id": id, "type": "mongodb_restore", "name": name}), - name: name, - dbURL: createDBURL(dbConfig), - locationConfig: locationConfig, + id: id, + timeout: timeout, + l: logrus.WithFields(logrus.Fields{"id": id, "type": "mongodb_restore", "name": name}), + name: name, + pitrTimestamp: pitrTimestamp, + dbURL: createDBURL(dbConfig), + locationConfig: locationConfig, + agentsRestarter: restarter, } } @@ -74,28 +94,36 @@ func (j *MongoDBRestoreJob) Run(ctx context.Context, send Send) error { if err != nil { return errors.WithStack(err) } - if err := pbmConfigure(ctx, j.l, j.dbURL, conf); err != nil { + + confFile, err := writePBMConfigFile(conf) + if err != nil { + return errors.WithStack(err) + } + defer os.Remove(confFile) //nolint:errcheck + + if err := pbmConfigure(ctx, j.l, j.dbURL, confFile); err != nil { return errors.Wrap(err, "failed to configure pbm") } rCtx, cancel := context.WithTimeout(ctx, resyncTimeout) - if err := waitForPBMState(rCtx, j.l, j.dbURL, pbmNoRunningOperations); err != nil { + if err := waitForPBMNoRunningOperations(rCtx, j.l, j.dbURL); err != nil { cancel() return errors.Wrap(err, "failed to wait pbm configuration completion") } cancel() - backupName, err := j.findSnapshotName(ctx) + snapshot, err := j.findSnapshot(ctx) if err != nil { return errors.WithStack(err) } - restoreOut, err := j.startRestore(ctx, backupName) + defer j.agentsRestarter.RestartAgents() + restoreOut, err := j.startRestore(ctx, snapshot.Name) if err != nil { return errors.Wrap(err, "failed to start backup restore") } - if err := waitForPBMRestore(ctx, j.l, j.dbURL, restoreOut.Snapshot); err != nil { + if err := waitForPBMRestore(ctx, j.l, j.dbURL, restoreOut, snapshot.Type, confFile); err != nil { return errors.Wrap(err, "failed to wait backup restore completion") } @@ -110,29 +138,71 @@ func (j *MongoDBRestoreJob) Run(ctx context.Context, send Send) error { return nil } -func (j *MongoDBRestoreJob) findSnapshotName(ctx context.Context) (string, error) { +func (j *MongoDBRestoreJob) findSnapshot(ctx context.Context) (*pbmSnapshot, error) { j.l.Info("Finding backup entity name.") var list pbmList - if err := execPBMCommand(ctx, j.dbURL, &list, "list"); err != nil { - return "", err - } - - if len(list.Snapshots) == 0 { - return "", errors.New("failed to find backup entity") + ticker := time.NewTicker(listCheckInterval) + defer ticker.Stop() + + checks := 0 + for { + select { + case <-ticker.C: + checks++ + if err := execPBMCommand(ctx, j.dbURL, &list, "list"); err != nil { + return nil, err + } + + if len(list.Snapshots) == 0 { + j.l.Debugf("Try number %d of getting list of artifacts from PBM is failed.", checks) + if checks > maxListChecks { + return nil, errors.New("failed to find backup entity") + } + continue + } + + return &list.Snapshots[len(list.Snapshots)-1], nil + case <-ctx.Done(): + return nil, ctx.Err() + } } - - return list.Snapshots[len(list.Snapshots)-1].Name, nil } func (j *MongoDBRestoreJob) startRestore(ctx context.Context, backupName string) (*pbmRestore, error) { - j.l.Info("Starting backup restore.") + j.l.Infof("starting backup restore for: %s.", backupName) var restoreOutput pbmRestore - err := execPBMCommand(ctx, j.dbURL, &restoreOutput, "restore", backupName) - if err != nil { - return nil, errors.Wrapf(err, "pbm restore error: %v", err) + var err error + startTime := time.Now() + + ticker := time.NewTicker(statusCheckInterval) + defer ticker.Stop() + retryCount := 500 + + for { + select { + case <-ticker.C: + + if j.pitrTimestamp.Unix() == 0 { + err = execPBMCommand(ctx, j.dbURL, &restoreOutput, "restore", backupName) + } else { + err = execPBMCommand(ctx, j.dbURL, &restoreOutput, "restore", fmt.Sprintf(`--time=%s`, j.pitrTimestamp.Format("2006-01-02T15:04:05"))) + } + + if err != nil { + if strings.HasSuffix(err.Error(), "another operation in progress") && retryCount > 0 { + retryCount-- + continue + } + return nil, errors.Wrapf(err, "pbm restore error: %v", err) + } + + restoreOutput.StartedAt = startTime + return &restoreOutput, nil + + case <-ctx.Done(): + return nil, ctx.Err() + } } - - return &restoreOutput, nil } diff --git a/agent/runner/jobs/pbm_helpers.go b/agent/runner/jobs/pbm_helpers.go index f1f0938c0c..e516a4199b 100644 --- a/agent/runner/jobs/pbm_helpers.go +++ b/agent/runner/jobs/pbm_helpers.go @@ -22,6 +22,7 @@ import ( "os" "os/exec" "path" + "strings" "time" "github.com/pkg/errors" @@ -30,36 +31,38 @@ import ( ) const ( - // How many times check if backup/restore operation was started - maxBackupChecks = 10 - maxRestoreChecks = 10 - - cmdTimeout = time.Minute + cmdTimeout = 60 * time.Minute resyncTimeout = 5 * time.Minute - statusCheckInterval = 3 * time.Second + statusCheckInterval = 5 * time.Second + maxRestoreChecks = 100 ) type pbmSeverity int +type describeInfo struct { + Status string `json:"status"` + Error string `json:"error"` +} + const ( - pbmFatal pbmSeverity = iota - pbmError - pbmWarning - pbmInfo - pbmDebug + pbmFatalSeverity pbmSeverity = iota + pbmErrorSeverity + pbmWarningSeverity + pbmInfoSeverity + pbmDebugSeverity ) func (s pbmSeverity) String() string { switch s { - case pbmFatal: + case pbmFatalSeverity: return "F" - case pbmError: + case pbmErrorSeverity: return "E" - case pbmWarning: + case pbmWarningSeverity: return "W" - case pbmInfo: + case pbmInfoSeverity: return "I" - case pbmDebug: + case pbmDebugSeverity: return "D" default: return "" @@ -92,15 +95,18 @@ type pbmBackup struct { } type pbmRestore struct { - Snapshot string `json:"snapshot"` + StartedAt time.Time + Name string `json:"name"` + Snapshot string `json:"snapshot"` + PITR string `json:"point-in-time"` } type pbmSnapshot struct { Name string `json:"name"` Status string `json:"status"` - Error string `json:"error"` - CompleteTS int `json:"completeTS"` + RestoreTo int64 `json:"restoreTo"` PbmVersion string `json:"pbmVersion"` + Type string `json:"type"` } type pbmList struct { @@ -116,6 +122,7 @@ type pbmListRestore struct { Status string `json:"status"` Type string `json:"type"` Snapshot string `json:"snapshot"` + PITR int64 `json:"point-in-time"` Name string `json:"name"` Error string `json:"error"` } @@ -135,6 +142,7 @@ type pbmStatus struct { Nodes []struct { Host string `json:"host"` Agent string `json:"agent"` + Role string `json:"role"` Ok bool `json:"ok"` } `json:"nodes"` } `json:"cluster"` @@ -151,6 +159,10 @@ type pbmStatus struct { } `json:"running"` } +type pbmError struct { + Error string `json:"Error"` +} + func execPBMCommand(ctx context.Context, dbURL *url.URL, to interface{}, args ...string) error { nCtx, cancel := context.WithTimeout(ctx, cmdTimeout) defer cancel() @@ -160,9 +172,12 @@ func execPBMCommand(ctx context.Context, dbURL *url.URL, to interface{}, args .. b, err := cmd.Output() if err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return errors.New(string(exitErr.Stderr)) + // try to parse pbm error message + if len(b) != 0 { + var pbmErr pbmError + if e := json.Unmarshal(b, &pbmErr); e == nil { + return errors.New(pbmErr.Error) + } } return err } @@ -180,89 +195,97 @@ func retrieveLogs(ctx context.Context, dbURL *url.URL, event string) ([]pbmLogEn return logs, nil } -type pbmStatusCondition func(s pbmStatus) (bool, error) +func waitForPBMNoRunningOperations(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL) error { + l.Info("Waiting for no running pbm operations.") -func pbmNoRunningOperations(s pbmStatus) (bool, error) { - return s.Running.Status == "", nil -} + ticker := time.NewTicker(statusCheckInterval) + defer ticker.Stop() -func pbmBackupFinished(name string) pbmStatusCondition { - started := false - snapshotStarted := false - checks := 0 - return func(s pbmStatus) (bool, error) { - checks++ - if s.Running.Type == "backup" && s.Running.Name == name && s.Running.Status != "" { - started = true - } - if !started && checks > maxBackupChecks { - return false, errors.New("failed to start backup") - } - var snapshot *pbmSnapshot - for i, snap := range s.Backups.Snapshot { - if snap.Name == name { - snapshot = &s.Backups.Snapshot[i] - break + for { + select { + case <-ticker.C: + var status pbmStatus + if err := execPBMCommand(ctx, dbURL, &status, "status"); err != nil { + return errors.Wrapf(err, "pbm status error") } + if status.Running.Type == "" { + return nil + } + case <-ctx.Done(): + return ctx.Err() } - if snapshot == nil { - return false, nil - } - - switch snapshot.Status { - case "starting", "running", "dumpDone": - snapshotStarted = true - return false, nil - } - - if snapshotStarted && snapshot.Status == "error" { - return false, errors.New(snapshot.Error) - } - - return snapshot.Status == "done", nil } } -func waitForPBMState(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, cond pbmStatusCondition) error { - l.Info("Waiting for pbm state condition.") - +func waitForPBMBackup(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, name string) error { + l.Infof("waiting for pbm backup: %s", name) ticker := time.NewTicker(statusCheckInterval) defer ticker.Stop() + retryCount := 500 + for { select { case <-ticker.C: - var status pbmStatus - if err := execPBMCommand(ctx, dbURL, &status, "status"); err != nil { - return errors.Wrapf(err, "pbm status error") - } - done, err := cond(status) + var info describeInfo + err := execPBMCommand(ctx, dbURL, &info, "describe-backup", name) if err != nil { - return errors.Wrapf(err, "condition failed") + // for the first couple of seconds after backup process starts describe-backup command may return this error + if (strings.HasSuffix(err.Error(), "no such file") || + strings.HasSuffix(err.Error(), "file is empty")) && retryCount > 0 { + retryCount-- + continue + } + + return errors.Wrap(err, "failed to get backup status") } - if done { + + switch info.Status { + case "done": return nil + case "canceled": + return errors.New("backup was canceled") + case "error": + return errors.New(info.Error) } + case <-ctx.Done(): return ctx.Err() } } } -func waitForPBMRestore(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, name string) error { - l.Info("Waiting for pbm restore.") +func findPITRRestore(list []pbmListRestore, restoreInfoPITRTime int64, startedAt time.Time) *pbmListRestore { + for i := len(list) - 1; i >= 0; i-- { + // TODO when PITR restore invoked with wrong timestamp pbm marks this restore operation as "snapshot" type. + if list[i].Type == "snapshot" && list[i].Snapshot != "" { + continue + } + // list[i].Name is a string which represents time the restore was started. + restoreStartedAt, err := time.Parse(time.RFC3339Nano, list[i].Name) + if err != nil { + continue + } + // Because of https://jira.percona.com/browse/PBM-723 to find our restore record in the list of all records we're checking: + // 1. We received PITR field as a response on starting process + // 2. There is a record with the same PITR field in the list of restoring records + // 3. Start time of this record is not before the time we asked for restoring. + if list[i].PITR == restoreInfoPITRTime && !restoreStartedAt.Before(startedAt) { + return &list[i] + } + } + return nil +} + +func findPITRRestoreName(ctx context.Context, dbURL *url.URL, restoreInfo *pbmRestore) (string, error) { + restoreInfoPITRTime, err := time.Parse("2006-01-02T15:04:05", restoreInfo.PITR) + if err != nil { + return "", err + } ticker := time.NewTicker(statusCheckInterval) defer ticker.Stop() - // @TODO Find from end (the newest one) until https://jira.percona.com/browse/PBM-723 is not done. - findRestore := func(list []pbmListRestore) *pbmListRestore { - for i := len(list) - 1; i >= 0; i-- { - if list[i].Snapshot == name { - return &list[i] - } - } - return nil - } + checks := 0 for { select { @@ -270,38 +293,74 @@ func waitForPBMRestore(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL checks++ var list []pbmListRestore if err := execPBMCommand(ctx, dbURL, &list, "list", "--restore"); err != nil { - return errors.Wrapf(err, "pbm status error") + return "", errors.Wrapf(err, "pbm status error") } - entry := findRestore(list) + entry := findPITRRestore(list, restoreInfoPITRTime.Unix(), restoreInfo.StartedAt) if entry == nil { if checks > maxRestoreChecks { - return errors.Errorf("failed to start restore") + return "", errors.Errorf("failed to start restore") } continue + } else { + return entry.Name, nil } - if entry.Status == "error" { - return errors.New(entry.Error) + case <-ctx.Done(): + return "", ctx.Err() + } + } +} + +func waitForPBMRestore(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, restoreInfo *pbmRestore, backupType, confFile string) error { + l.Infof("waiting for pbm restore") + var name string + var err error + + // @TODO Do like this until https://jira.percona.com/browse/PBM-723 is not done. + if restoreInfo.PITR != "" { // TODO add more checks of PBM responses. + name, err = findPITRRestoreName(ctx, dbURL, restoreInfo) + if err != nil { + return err + } + } else { + name = restoreInfo.Name + } + + ticker := time.NewTicker(statusCheckInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + var info describeInfo + if backupType == "physical" { + err = execPBMCommand(ctx, dbURL, &info, "describe-restore", "--config="+confFile, name) + } else { + err = execPBMCommand(ctx, dbURL, &info, "describe-restore", name) } - if entry.Status == "done" { + if err != nil { + return errors.Wrap(err, "failed to get restore status") + } + + switch info.Status { + case "done": return nil + case "canceled": + return errors.New("restore was canceled") + case "error": + return errors.New(info.Error) } + case <-ctx.Done(): return ctx.Err() } } } -func pbmConfigure(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, conf *PBMConfig) error { +func pbmConfigure(ctx context.Context, l logrus.FieldLogger, dbURL *url.URL, confFile string) error { l.Info("Configuring S3 location.") nCtx, cancel := context.WithTimeout(ctx, cmdTimeout) defer cancel() - confFile, err := writePBMConfigFile(conf) - if err != nil { - return errors.WithStack(err) - } - defer os.Remove(confFile) //nolint:errcheck - output, err := exec.CommandContext( //nolint:gosec nCtx, pbmBin, @@ -398,11 +457,11 @@ func createPBMConfig(locationConfig *BackupLocationConfig, prefix string, pitr b }, }, } - case PMMClientBackupLocationType: + case FilesystemBackupLocationType: conf.Storage = Storage{ Type: "filesystem", FileSystem: FileSystem{ - Path: path.Join(locationConfig.LocalStorageConfig.Path, prefix), + Path: path.Join(locationConfig.FilesystemStorageConfig.Path, prefix), }, } default: diff --git a/agent/runner/jobs/pbm_helpers_test.go b/agent/runner/jobs/pbm_helpers_test.go index cca86df9b7..38e8022e72 100644 --- a/agent/runner/jobs/pbm_helpers_test.go +++ b/agent/runner/jobs/pbm_helpers_test.go @@ -16,8 +16,10 @@ package jobs import ( "testing" + "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCreatePBMConfig(t *testing.T) { @@ -29,7 +31,7 @@ func TestCreatePBMConfig(t *testing.T) { BucketRegion: "test_region", } - pmmClientStorageConfig := PMMClientBackupLocationConfig{ + filesystemStorageConfig := FilesystemBackupLocationConfig{ Path: "/test/path", } @@ -69,9 +71,9 @@ func TestCreatePBMConfig(t *testing.T) { { name: "invalid location type", inputLocation: BackupLocationConfig{ - Type: BackupLocationType("invalid type"), - S3Config: &s3Config, - LocalStorageConfig: nil, + Type: BackupLocationType("invalid type"), + S3Config: &s3Config, + FilesystemStorageConfig: nil, }, inputPitr: true, output: nil, @@ -80,20 +82,20 @@ func TestCreatePBMConfig(t *testing.T) { { name: "s3 config type", inputLocation: BackupLocationConfig{ - Type: S3BackupLocationType, - S3Config: &s3Config, - LocalStorageConfig: nil, + Type: S3BackupLocationType, + S3Config: &s3Config, + FilesystemStorageConfig: nil, }, inputPitr: true, output: &expectedOutput1, errString: "", }, { - name: "pmm client config type", + name: "filesystem config type", inputLocation: BackupLocationConfig{ - Type: PMMClientBackupLocationType, - S3Config: nil, - LocalStorageConfig: &pmmClientStorageConfig, + Type: FilesystemBackupLocationType, + S3Config: nil, + FilesystemStorageConfig: &filesystemStorageConfig, }, inputPitr: false, output: &expectedOutput2, @@ -102,9 +104,9 @@ func TestCreatePBMConfig(t *testing.T) { { name: "ignores filled up config instead relying on config type", inputLocation: BackupLocationConfig{ - Type: PMMClientBackupLocationType, - S3Config: &s3Config, - LocalStorageConfig: &pmmClientStorageConfig, + Type: FilesystemBackupLocationType, + S3Config: &s3Config, + FilesystemStorageConfig: &filesystemStorageConfig, }, inputPitr: false, output: &expectedOutput2, @@ -123,3 +125,73 @@ func TestCreatePBMConfig(t *testing.T) { }) } } + +func TestFindPITRRestore(t *testing.T) { + // Tested func searches from the end, so we place records to be skipped at the end. + testList := []pbmListRestore{ + { + Name: "2022-10-11T14:53:19.000000001Z", + Type: "pitr", + PITR: 1000000000, + }, + { + Name: "2022-10-11T14:53:20.000000001Z", + Type: "pitr", + PITR: 1000000000, + }, + { + Name: "2022-error-11T14:53:20.000000001Z", + Type: "pitr", + PITR: 1000000000, + }, + { + Name: "2022-10-11T14:53:20.000000001Z", + Type: "snapshot", + }, + { + Name: "2022-10-11T14:53:20.000000010Z", + Type: "pitr", + PITR: 1000000001, + }, + } + + for _, tc := range []struct { + name string + restoreInfoPITRTime int64 + startedAtString string + expected *pbmListRestore + }{ + { + name: "case1", + restoreInfoPITRTime: 1000000000, + startedAtString: "2022-10-11T14:53:20.000000000Z", + expected: &pbmListRestore{Name: "2022-10-11T14:53:20.000000001Z", Type: "pitr", PITR: 1000000000}, + }, + { + name: "case2", + restoreInfoPITRTime: 1000000001, + startedAtString: "2022-10-11T14:53:20.000000002Z", + expected: &pbmListRestore{Name: "2022-10-11T14:53:20.000000010Z", Type: "pitr", PITR: 1000000001}, + }, + { + name: "case3", + restoreInfoPITRTime: 1000000002, + startedAtString: "2022-10-11T14:53:20.000000000Z", + expected: nil, + }, + { + name: "case4", + restoreInfoPITRTime: 1000000000, + startedAtString: "2022-10-11T14:53:20.000000020Z", + expected: nil, + }, + } { + t.Run(tc.name, func(t *testing.T) { + startedAt, err := time.Parse(time.RFC3339Nano, tc.startedAtString) + require.NoError(t, err) + + res := findPITRRestore(testList, tc.restoreInfoPITRTime, startedAt) + assert.Equal(t, tc.expected, res) + }) + } +} diff --git a/api-tests/management/backup/backups_test.go b/api-tests/management/backup/backups_test.go index d5836be67f..1e4169b456 100644 --- a/api-tests/management/backup/backups_test.go +++ b/api-tests/management/backup/backups_test.go @@ -68,7 +68,7 @@ func TestScheduleBackup(t *testing.T) { Body: locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, }, diff --git a/api-tests/management/backup/locations_test.go b/api-tests/management/backup/locations_test.go index 20eff0d63e..081c8eec8c 100644 --- a/api-tests/management/backup/locations_test.go +++ b/api-tests/management/backup/locations_test.go @@ -40,7 +40,7 @@ func TestAddLocation(t *testing.T) { Body: locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, }, @@ -102,14 +102,14 @@ func TestAddWrongLocation(t *testing.T) { resp, err := client.AddLocation(&locations.AddLocationParams{ Body: locations.AddLocationBody{ - Name: gofakeit.Name(), - Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{}, + Name: gofakeit.Name(), + Description: gofakeit.Question(), + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{}, }, Context: pmmapitests.Context, }) - pmmapitests.AssertAPIErrorf(t, err, 400, codes.InvalidArgument, "invalid field PmmClientConfig.Path: value '' must not be an empty string") + pmmapitests.AssertAPIErrorf(t, err, 400, codes.InvalidArgument, "invalid field FilesystemConfig.Path: value '' must not be an empty string") assert.Nil(t, resp) }) @@ -174,7 +174,7 @@ func TestAddWrongLocation(t *testing.T) { Body: locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, S3Config: &locations.AddLocationParamsBodyS3Config{ @@ -199,7 +199,7 @@ func TestListLocations(t *testing.T) { body := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -219,7 +219,7 @@ func TestListLocations(t *testing.T) { if loc.LocationID == addResp.Payload.LocationID { assert.Equal(t, body.Name, loc.Name) assert.Equal(t, body.Description, loc.Description) - assert.Equal(t, body.PMMClientConfig.Path, loc.PMMClientConfig.Path) + assert.Equal(t, body.FilesystemConfig.Path, loc.FilesystemConfig.Path) found = true } } @@ -240,11 +240,11 @@ func TestChangeLocation(t *testing.T) { assert.Equal(t, req.Description, loc.Description) } - if req.PMMClientConfig != nil { - require.NotNil(t, loc.PMMClientConfig) - assert.Equal(t, req.PMMClientConfig.Path, loc.PMMClientConfig.Path) + if req.FilesystemConfig != nil { + require.NotNil(t, loc.FilesystemConfig) + assert.Equal(t, req.FilesystemConfig.Path, loc.FilesystemConfig.Path) } else { - assert.Nil(t, loc.PMMClientConfig) + assert.Nil(t, loc.FilesystemConfig) } if req.S3Config != nil { @@ -270,7 +270,7 @@ func TestChangeLocation(t *testing.T) { addReqBody := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -284,7 +284,7 @@ func TestChangeLocation(t *testing.T) { updateBody := locations.ChangeLocationBody{ LocationID: resp.Payload.LocationID, Name: gofakeit.Name(), - PMMClientConfig: &locations.ChangeLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.ChangeLocationParamsBodyFilesystemConfig{ Path: "/tmp/nested", }, } @@ -306,7 +306,7 @@ func TestChangeLocation(t *testing.T) { addReqBody := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -340,8 +340,8 @@ func TestChangeLocation(t *testing.T) { require.NotNil(t, location) assert.Equal(t, location.Name, updateBody.Name) - require.NotNil(t, location.PMMClientConfig) - assert.Equal(t, addReqBody.PMMClientConfig.Path, location.PMMClientConfig.Path) + require.NotNil(t, location.FilesystemConfig) + assert.Equal(t, addReqBody.FilesystemConfig.Path, location.FilesystemConfig.Path) }) t.Run("change config type", func(t *testing.T) { @@ -354,7 +354,7 @@ func TestChangeLocation(t *testing.T) { addReqBody := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -393,7 +393,7 @@ func TestChangeLocation(t *testing.T) { addReqBody1 := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -407,7 +407,7 @@ func TestChangeLocation(t *testing.T) { addReqBody2 := locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -421,7 +421,7 @@ func TestChangeLocation(t *testing.T) { updateBody := locations.ChangeLocationBody{ LocationID: resp2.Payload.LocationID, Name: addReqBody1.Name, - PMMClientConfig: &locations.ChangeLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.ChangeLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, } @@ -441,7 +441,7 @@ func TestRemoveLocation(t *testing.T) { Body: locations.AddLocationBody{ Name: gofakeit.Name(), Description: gofakeit.Question(), - PMMClientConfig: &locations.AddLocationParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.AddLocationParamsBodyFilesystemConfig{ Path: "/tmp", }, }, @@ -497,12 +497,12 @@ func TestLocationConfigValidation(t *testing.T) { resp, err := client.TestLocationConfig(&locations.TestLocationConfigParams{ Body: locations.TestLocationConfigBody{ - PMMClientConfig: &locations.TestLocationConfigParamsBodyPMMClientConfig{}, + FilesystemConfig: &locations.TestLocationConfigParamsBodyFilesystemConfig{}, }, Context: pmmapitests.Context, }) - pmmapitests.AssertAPIErrorf(t, err, 400, codes.InvalidArgument, "invalid field PmmClientConfig.Path: value '' must not be an empty string") + pmmapitests.AssertAPIErrorf(t, err, 400, codes.InvalidArgument, "invalid field FilesystemConfig.Path: value '' must not be an empty string") assert.Nil(t, resp) }) @@ -547,7 +547,7 @@ func TestLocationConfigValidation(t *testing.T) { resp, err := client.TestLocationConfig(&locations.TestLocationConfigParams{ Body: locations.TestLocationConfigBody{ - PMMClientConfig: &locations.TestLocationConfigParamsBodyPMMClientConfig{ + FilesystemConfig: &locations.TestLocationConfigParamsBodyFilesystemConfig{ Path: "/tmp", }, S3Config: &locations.TestLocationConfigParamsBodyS3Config{ diff --git a/api/agentpb/agent.pb.go b/api/agentpb/agent.pb.go index 1e3812c356..fc535ba3e7 100644 --- a/api/agentpb/agent.pb.go +++ b/api/agentpb/agent.pb.go @@ -2229,8 +2229,8 @@ func (x *S3LocationConfig) GetBucketRegion() string { return "" } -// LocalStorageConfig represents path for storing backup artifacts locally. -type PMMClientLocationConfig struct { +// FilesystemLocationConfig represents path for storing backup artifacts locally. +type FilesystemLocationConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -2238,8 +2238,8 @@ type PMMClientLocationConfig struct { Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` } -func (x *PMMClientLocationConfig) Reset() { - *x = PMMClientLocationConfig{} +func (x *FilesystemLocationConfig) Reset() { + *x = FilesystemLocationConfig{} if protoimpl.UnsafeEnabled { mi := &file_agentpb_agent_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2247,13 +2247,13 @@ func (x *PMMClientLocationConfig) Reset() { } } -func (x *PMMClientLocationConfig) String() string { +func (x *FilesystemLocationConfig) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PMMClientLocationConfig) ProtoMessage() {} +func (*FilesystemLocationConfig) ProtoMessage() {} -func (x *PMMClientLocationConfig) ProtoReflect() protoreflect.Message { +func (x *FilesystemLocationConfig) ProtoReflect() protoreflect.Message { mi := &file_agentpb_agent_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2265,12 +2265,12 @@ func (x *PMMClientLocationConfig) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PMMClientLocationConfig.ProtoReflect.Descriptor instead. -func (*PMMClientLocationConfig) Descriptor() ([]byte, []int) { +// Deprecated: Use FilesystemLocationConfig.ProtoReflect.Descriptor instead. +func (*FilesystemLocationConfig) Descriptor() ([]byte, []int) { return file_agentpb_agent_proto_rawDescGZIP(), []int{31} } -func (x *PMMClientLocationConfig) GetPath() string { +func (x *FilesystemLocationConfig) GetPath() string { if x != nil { return x.Path } @@ -5382,13 +5382,13 @@ type StartJobRequest_MongoDBBackup struct { // Enable Point-in-Time recovery feature. EnablePitr bool `protobuf:"varint,7,opt,name=enable_pitr,json=enablePitr,proto3" json:"enable_pitr,omitempty"` // Backup data model (physical or logical). - DataModel backup.DataModel `protobuf:"varint,8,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel backup.DataModel `protobuf:"varint,8,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` // Backup target location. // // Types that are assignable to LocationConfig: // // *StartJobRequest_MongoDBBackup_S3Config - // *StartJobRequest_MongoDBBackup_PmmClientConfig + // *StartJobRequest_MongoDBBackup_FilesystemConfig LocationConfig isStartJobRequest_MongoDBBackup_LocationConfig `protobuf_oneof:"location_config"` } @@ -5494,9 +5494,9 @@ func (x *StartJobRequest_MongoDBBackup) GetS3Config() *S3LocationConfig { return nil } -func (x *StartJobRequest_MongoDBBackup) GetPmmClientConfig() *PMMClientLocationConfig { - if x, ok := x.GetLocationConfig().(*StartJobRequest_MongoDBBackup_PmmClientConfig); ok { - return x.PmmClientConfig +func (x *StartJobRequest_MongoDBBackup) GetFilesystemConfig() *FilesystemLocationConfig { + if x, ok := x.GetLocationConfig().(*StartJobRequest_MongoDBBackup_FilesystemConfig); ok { + return x.FilesystemConfig } return nil } @@ -5509,13 +5509,13 @@ type StartJobRequest_MongoDBBackup_S3Config struct { S3Config *S3LocationConfig `protobuf:"bytes,10,opt,name=s3_config,json=s3Config,proto3,oneof"` } -type StartJobRequest_MongoDBBackup_PmmClientConfig struct { - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,11,opt,name=pmm_client_config,json=pmmClientConfig,proto3,oneof"` +type StartJobRequest_MongoDBBackup_FilesystemConfig struct { + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,11,opt,name=filesystem_config,json=filesystemConfig,proto3,oneof"` } func (*StartJobRequest_MongoDBBackup_S3Config) isStartJobRequest_MongoDBBackup_LocationConfig() {} -func (*StartJobRequest_MongoDBBackup_PmmClientConfig) isStartJobRequest_MongoDBBackup_LocationConfig() { +func (*StartJobRequest_MongoDBBackup_FilesystemConfig) isStartJobRequest_MongoDBBackup_LocationConfig() { } // MongoDBRestoreBackup is job for MongoDB restore backup service. @@ -5543,7 +5543,7 @@ type StartJobRequest_MongoDBRestoreBackup struct { // Types that are assignable to LocationConfig: // // *StartJobRequest_MongoDBRestoreBackup_S3Config - // *StartJobRequest_MongoDBRestoreBackup_PmmClientConfig + // *StartJobRequest_MongoDBRestoreBackup_FilesystemConfig LocationConfig isStartJobRequest_MongoDBRestoreBackup_LocationConfig `protobuf_oneof:"location_config"` } @@ -5642,9 +5642,9 @@ func (x *StartJobRequest_MongoDBRestoreBackup) GetS3Config() *S3LocationConfig { return nil } -func (x *StartJobRequest_MongoDBRestoreBackup) GetPmmClientConfig() *PMMClientLocationConfig { - if x, ok := x.GetLocationConfig().(*StartJobRequest_MongoDBRestoreBackup_PmmClientConfig); ok { - return x.PmmClientConfig +func (x *StartJobRequest_MongoDBRestoreBackup) GetFilesystemConfig() *FilesystemLocationConfig { + if x, ok := x.GetLocationConfig().(*StartJobRequest_MongoDBRestoreBackup_FilesystemConfig); ok { + return x.FilesystemConfig } return nil } @@ -5657,14 +5657,14 @@ type StartJobRequest_MongoDBRestoreBackup_S3Config struct { S3Config *S3LocationConfig `protobuf:"bytes,10,opt,name=s3_config,json=s3Config,proto3,oneof"` } -type StartJobRequest_MongoDBRestoreBackup_PmmClientConfig struct { - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,11,opt,name=pmm_client_config,json=pmmClientConfig,proto3,oneof"` +type StartJobRequest_MongoDBRestoreBackup_FilesystemConfig struct { + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,11,opt,name=filesystem_config,json=filesystemConfig,proto3,oneof"` } func (*StartJobRequest_MongoDBRestoreBackup_S3Config) isStartJobRequest_MongoDBRestoreBackup_LocationConfig() { } -func (*StartJobRequest_MongoDBRestoreBackup_PmmClientConfig) isStartJobRequest_MongoDBRestoreBackup_LocationConfig() { +func (*StartJobRequest_MongoDBRestoreBackup_FilesystemConfig) isStartJobRequest_MongoDBRestoreBackup_LocationConfig() { } // Error contains job error message. @@ -6928,108 +6928,108 @@ var file_agentpb_agent_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, - 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x2d, 0x0a, 0x17, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x22, 0xc9, 0x0c, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x33, - 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x12, 0x47, 0x0a, 0x0c, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, - 0x0b, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x5d, 0x0a, 0x14, - 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x2e, 0x0a, 0x18, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x22, 0xc8, 0x0c, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, + 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, + 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x12, 0x47, 0x0a, 0x0c, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x12, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x4d, 0x0a, 0x0e, 0x6d, - 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x6f, 0x6e, 0x67, - 0x6f, 0x44, 0x42, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x6d, 0x6f, 0x6e, - 0x67, 0x6f, 0x64, 0x62, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x63, 0x0a, 0x16, 0x6d, 0x6f, - 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x14, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, - 0x64, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x1a, - 0xe2, 0x01, 0x0a, 0x0b, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, - 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x73, 0x33, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x92, 0x01, 0x0a, 0x12, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, - 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x8d, 0x03, 0x0a, 0x0d, 0x4d, 0x6f, - 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x70, 0x69, 0x74, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x50, 0x69, 0x74, 0x72, 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, - 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x12, 0x36, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, - 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x4d, 0x4d, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xfc, 0x02, 0x0a, 0x14, 0x4d, 0x6f, - 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0e, - 0x70, 0x69, 0x74, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0d, 0x70, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x73, 0x74, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, + 0x52, 0x0b, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x5d, 0x0a, + 0x14, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x12, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x4d, 0x0a, 0x0e, + 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x6f, 0x6e, + 0x67, 0x6f, 0x44, 0x42, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x6d, 0x6f, + 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x63, 0x0a, 0x16, 0x6d, + 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x52, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x48, 0x00, 0x52, 0x14, 0x6d, 0x6f, 0x6e, 0x67, + 0x6f, 0x64, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x1a, 0xe2, 0x01, 0x0a, 0x0b, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x73, 0x33, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x92, 0x01, 0x0a, 0x12, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, - 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x4d, 0x4d, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, + 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x8a, 0x03, 0x0a, 0x0d, 0x4d, + 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x70, 0x69, 0x74, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x50, 0x69, 0x74, 0x72, 0x12, 0x33, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x09, + 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x48, 0x00, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xfe, 0x02, 0x0a, 0x14, 0x4d, 0x6f, 0x6e, 0x67, + 0x6f, 0x44, 0x42, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x69, + 0x74, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, + 0x70, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x36, 0x0a, + 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x48, 0x00, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x05, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x28, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, @@ -7351,7 +7351,7 @@ var ( (*JobStatusRequest)(nil), // 29: agent.JobStatusRequest (*JobStatusResponse)(nil), // 30: agent.JobStatusResponse (*S3LocationConfig)(nil), // 31: agent.S3LocationConfig - (*PMMClientLocationConfig)(nil), // 32: agent.PMMClientLocationConfig + (*FilesystemLocationConfig)(nil), // 32: agent.FilesystemLocationConfig (*StartJobRequest)(nil), // 33: agent.StartJobRequest (*StartJobResponse)(nil), // 34: agent.StartJobResponse (*StopJobRequest)(nil), // 35: agent.StopJobRequest @@ -7415,7 +7415,7 @@ var ( (inventorypb.ServiceType)(0), // 93: inventory.ServiceType (*status.Status)(nil), // 94: google.rpc.Status (inventorypb.AgentType)(0), // 95: inventory.AgentType - (backup.DataModel)(0), // 96: backup.v1beta1.DataModel + (backup.DataModel)(0), // 96: backup.v1.DataModel } ) @@ -7540,12 +7540,12 @@ var file_agentpb_agent_proto_depIdxs = []int32{ 1, // 117: agent.StartActionRequest.MongoDBQueryGetDiagnosticDataParams.text_files:type_name -> agent.TextFiles 31, // 118: agent.StartJobRequest.MySQLBackup.s3_config:type_name -> agent.S3LocationConfig 31, // 119: agent.StartJobRequest.MySQLRestoreBackup.s3_config:type_name -> agent.S3LocationConfig - 96, // 120: agent.StartJobRequest.MongoDBBackup.data_model:type_name -> backup.v1beta1.DataModel + 96, // 120: agent.StartJobRequest.MongoDBBackup.data_model:type_name -> backup.v1.DataModel 31, // 121: agent.StartJobRequest.MongoDBBackup.s3_config:type_name -> agent.S3LocationConfig - 32, // 122: agent.StartJobRequest.MongoDBBackup.pmm_client_config:type_name -> agent.PMMClientLocationConfig + 32, // 122: agent.StartJobRequest.MongoDBBackup.filesystem_config:type_name -> agent.FilesystemLocationConfig 89, // 123: agent.StartJobRequest.MongoDBRestoreBackup.pitr_timestamp:type_name -> google.protobuf.Timestamp 31, // 124: agent.StartJobRequest.MongoDBRestoreBackup.s3_config:type_name -> agent.S3LocationConfig - 32, // 125: agent.StartJobRequest.MongoDBRestoreBackup.pmm_client_config:type_name -> agent.PMMClientLocationConfig + 32, // 125: agent.StartJobRequest.MongoDBRestoreBackup.filesystem_config:type_name -> agent.FilesystemLocationConfig 83, // 126: agent.GetVersionsRequest.Software.mysqld:type_name -> agent.GetVersionsRequest.MySQLd 84, // 127: agent.GetVersionsRequest.Software.xtrabackup:type_name -> agent.GetVersionsRequest.Xtrabackup 85, // 128: agent.GetVersionsRequest.Software.xbcloud:type_name -> agent.GetVersionsRequest.Xbcloud @@ -7939,7 +7939,7 @@ func file_agentpb_agent_proto_init() { } } file_agentpb_agent_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PMMClientLocationConfig); i { + switch v := v.(*FilesystemLocationConfig); i { case 0: return &v.state case 1: @@ -8661,11 +8661,11 @@ func file_agentpb_agent_proto_init() { } file_agentpb_agent_proto_msgTypes[72].OneofWrappers = []interface{}{ (*StartJobRequest_MongoDBBackup_S3Config)(nil), - (*StartJobRequest_MongoDBBackup_PmmClientConfig)(nil), + (*StartJobRequest_MongoDBBackup_FilesystemConfig)(nil), } file_agentpb_agent_proto_msgTypes[73].OneofWrappers = []interface{}{ (*StartJobRequest_MongoDBRestoreBackup_S3Config)(nil), - (*StartJobRequest_MongoDBRestoreBackup_PmmClientConfig)(nil), + (*StartJobRequest_MongoDBRestoreBackup_FilesystemConfig)(nil), } file_agentpb_agent_proto_msgTypes[86].OneofWrappers = []interface{}{ (*GetVersionsRequest_Software_Mysqld)(nil), diff --git a/api/agentpb/agent.proto b/api/agentpb/agent.proto index b5418e494e..91a59ae193 100644 --- a/api/agentpb/agent.proto +++ b/api/agentpb/agent.proto @@ -474,8 +474,8 @@ message S3LocationConfig { string bucket_region = 5; } -// LocalStorageConfig represents path for storing backup artifacts locally. -message PMMClientLocationConfig { +// FilesystemLocationConfig represents path for storing backup artifacts locally. +message FilesystemLocationConfig { string path = 1; } @@ -528,11 +528,11 @@ message StartJobRequest { // Enable Point-in-Time recovery feature. bool enable_pitr = 7; // Backup data model (physical or logical). - backup.v1beta1.DataModel data_model = 8; + backup.v1.DataModel data_model = 8; // Backup target location. oneof location_config { S3LocationConfig s3_config = 10; - PMMClientLocationConfig pmm_client_config = 11; + FilesystemLocationConfig filesystem_config = 11; } } // MongoDBRestoreBackup is job for MongoDB restore backup service. @@ -554,7 +554,7 @@ message StartJobRequest { // Where backup is stored. oneof location_config { S3LocationConfig s3_config = 10; - PMMClientLocationConfig pmm_client_config = 11; + FilesystemLocationConfig filesystem_config = 11; } } string job_id = 1; diff --git a/api/agentpb/agent.validator.pb.go b/api/agentpb/agent.validator.pb.go index 36d570cdb4..a50c88d73d 100644 --- a/api/agentpb/agent.validator.pb.go +++ b/api/agentpb/agent.validator.pb.go @@ -556,7 +556,7 @@ func (this *S3LocationConfig) Validate() error { return nil } -func (this *PMMClientLocationConfig) Validate() error { +func (this *FilesystemLocationConfig) Validate() error { return nil } @@ -627,10 +627,10 @@ func (this *StartJobRequest_MongoDBBackup) Validate() error { } } } - if oneOfNester, ok := this.GetLocationConfig().(*StartJobRequest_MongoDBBackup_PmmClientConfig); ok { - if oneOfNester.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) + if oneOfNester, ok := this.GetLocationConfig().(*StartJobRequest_MongoDBBackup_FilesystemConfig); ok { + if oneOfNester.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } } @@ -650,10 +650,10 @@ func (this *StartJobRequest_MongoDBRestoreBackup) Validate() error { } } } - if oneOfNester, ok := this.GetLocationConfig().(*StartJobRequest_MongoDBRestoreBackup_PmmClientConfig); ok { - if oneOfNester.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) + if oneOfNester, ok := this.GetLocationConfig().(*StartJobRequest_MongoDBRestoreBackup_FilesystemConfig); ok { + if oneOfNester.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } } diff --git a/api/managementpb/backup/artifacts.pb.go b/api/managementpb/backup/artifacts.pb.go index f6ffe840a7..3ab76da9a0 100644 --- a/api/managementpb/backup/artifacts.pb.go +++ b/api/managementpb/backup/artifacts.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/artifacts.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -109,13 +109,13 @@ type Artifact struct { // Service name. ServiceName string `protobuf:"bytes,7,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` // Backup data model. - DataModel DataModel `protobuf:"varint,8,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel DataModel `protobuf:"varint,8,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` // Backup status. - Status BackupStatus `protobuf:"varint,9,opt,name=status,proto3,enum=backup.v1beta1.BackupStatus" json:"status,omitempty"` + Status BackupStatus `protobuf:"varint,9,opt,name=status,proto3,enum=backup.v1.BackupStatus" json:"status,omitempty"` // Artifact creation time. CreatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Backup mode. - Mode BackupMode `protobuf:"varint,11,opt,name=mode,proto3,enum=backup.v1beta1.BackupMode" json:"mode,omitempty"` + Mode BackupMode `protobuf:"varint,11,opt,name=mode,proto3,enum=backup.v1.BackupMode" json:"mode,omitempty"` } func (x *Artifact) Reset() { @@ -407,107 +407,284 @@ func (*DeleteArtifactResponse) Descriptor() ([]byte, []int) { return file_managementpb_backup_artifacts_proto_rawDescGZIP(), []int{4} } +type PitrTimerange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // start_timestamp is the time of the first event in the PITR chunk. + StartTimestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + // end_timestamp is the time of the last event in the PITR chunk. + EndTimestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` +} + +func (x *PitrTimerange) Reset() { + *x = PitrTimerange{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PitrTimerange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PitrTimerange) ProtoMessage() {} + +func (x *PitrTimerange) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PitrTimerange.ProtoReflect.Descriptor instead. +func (*PitrTimerange) Descriptor() ([]byte, []int) { + return file_managementpb_backup_artifacts_proto_rawDescGZIP(), []int{5} +} + +func (x *PitrTimerange) GetStartTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.StartTimestamp + } + return nil +} + +func (x *PitrTimerange) GetEndTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.EndTimestamp + } + return nil +} + +type ListPitrTimerangesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Artifact ID represents artifact whose location has PITR timeranges to be retrieved. + ArtifactId string `protobuf:"bytes,1,opt,name=artifact_id,json=artifactId,proto3" json:"artifact_id,omitempty"` +} + +func (x *ListPitrTimerangesRequest) Reset() { + *x = ListPitrTimerangesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListPitrTimerangesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPitrTimerangesRequest) ProtoMessage() {} + +func (x *ListPitrTimerangesRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPitrTimerangesRequest.ProtoReflect.Descriptor instead. +func (*ListPitrTimerangesRequest) Descriptor() ([]byte, []int) { + return file_managementpb_backup_artifacts_proto_rawDescGZIP(), []int{6} +} + +func (x *ListPitrTimerangesRequest) GetArtifactId() string { + if x != nil { + return x.ArtifactId + } + return "" +} + +type ListPitrTimerangesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timeranges []*PitrTimerange `protobuf:"bytes,1,rep,name=timeranges,proto3" json:"timeranges,omitempty"` +} + +func (x *ListPitrTimerangesResponse) Reset() { + *x = ListPitrTimerangesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListPitrTimerangesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPitrTimerangesResponse) ProtoMessage() {} + +func (x *ListPitrTimerangesResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_backup_artifacts_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPitrTimerangesResponse.ProtoReflect.Descriptor instead. +func (*ListPitrTimerangesResponse) Descriptor() ([]byte, []int) { + return file_managementpb_backup_artifacts_proto_rawDescGZIP(), []int{7} +} + +func (x *ListPitrTimerangesResponse) GetTimeranges() []*PitrTimerange { + if x != nil { + return x.Timeranges + } + return nil +} + var File_managementpb_backup_artifacts_proto protoreflect.FileDescriptor var file_managementpb_backup_artifacts_proto_rawDesc = []byte{ 0x0a, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x03, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, - 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, - 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, - 0x65, 0x6c, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1a, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x15, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0x5b, 0x0a, 0x15, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xab, 0x03, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, + 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, + 0x16, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x31, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x22, 0x5b, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x0d, 0x50, + 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x0f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x22, 0x3c, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x74, 0x72, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, + 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, + 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x74, 0x69, + 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2a, 0xf1, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, + 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, + 0x1d, 0x0a, 0x19, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x18, + 0x0a, 0x14, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x50, 0x41, 0x55, 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, 0x4b, + 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, + 0x53, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, + 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x41, 0x43, 0x4b, + 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, + 0x5f, 0x54, 0x4f, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x32, 0xbf, 0x03, 0x0a, + 0x09, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0d, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, + 0x12, 0x88, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x12, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2a, 0xf1, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, - 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x41, - 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, - 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x41, 0x43, - 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x55, 0x53, 0x45, - 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x04, 0x12, 0x17, - 0x0a, 0x13, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, 0x42, 0x41, 0x43, 0x4b, 0x55, - 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x32, 0xb0, 0x02, 0x0a, 0x09, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x24, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x4c, 0x69, - 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, - 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, - 0x2f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x42, 0xbb, 0x01, 0x0a, 0x12, 0x63, - 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x42, 0x0e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1a, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, + 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x2f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xa0, 0x01, 0x0a, 0x12, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, + 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x22, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x49, 0x54, + 0x52, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x42, 0x9d, + 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, + 0x42, 0x0e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, + 0x58, 0xaa, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -524,35 +701,43 @@ func file_managementpb_backup_artifacts_proto_rawDescGZIP() []byte { var ( file_managementpb_backup_artifacts_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_managementpb_backup_artifacts_proto_msgTypes = make([]protoimpl.MessageInfo, 5) + file_managementpb_backup_artifacts_proto_msgTypes = make([]protoimpl.MessageInfo, 8) file_managementpb_backup_artifacts_proto_goTypes = []interface{}{ - (BackupStatus)(0), // 0: backup.v1beta1.BackupStatus - (*Artifact)(nil), // 1: backup.v1beta1.Artifact - (*ListArtifactsRequest)(nil), // 2: backup.v1beta1.ListArtifactsRequest - (*ListArtifactsResponse)(nil), // 3: backup.v1beta1.ListArtifactsResponse - (*DeleteArtifactRequest)(nil), // 4: backup.v1beta1.DeleteArtifactRequest - (*DeleteArtifactResponse)(nil), // 5: backup.v1beta1.DeleteArtifactResponse - (DataModel)(0), // 6: backup.v1beta1.DataModel - (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp - (BackupMode)(0), // 8: backup.v1beta1.BackupMode + (BackupStatus)(0), // 0: backup.v1.BackupStatus + (*Artifact)(nil), // 1: backup.v1.Artifact + (*ListArtifactsRequest)(nil), // 2: backup.v1.ListArtifactsRequest + (*ListArtifactsResponse)(nil), // 3: backup.v1.ListArtifactsResponse + (*DeleteArtifactRequest)(nil), // 4: backup.v1.DeleteArtifactRequest + (*DeleteArtifactResponse)(nil), // 5: backup.v1.DeleteArtifactResponse + (*PitrTimerange)(nil), // 6: backup.v1.PitrTimerange + (*ListPitrTimerangesRequest)(nil), // 7: backup.v1.ListPitrTimerangesRequest + (*ListPitrTimerangesResponse)(nil), // 8: backup.v1.ListPitrTimerangesResponse + (DataModel)(0), // 9: backup.v1.DataModel + (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp + (BackupMode)(0), // 11: backup.v1.BackupMode } ) var file_managementpb_backup_artifacts_proto_depIdxs = []int32{ - 6, // 0: backup.v1beta1.Artifact.data_model:type_name -> backup.v1beta1.DataModel - 0, // 1: backup.v1beta1.Artifact.status:type_name -> backup.v1beta1.BackupStatus - 7, // 2: backup.v1beta1.Artifact.created_at:type_name -> google.protobuf.Timestamp - 8, // 3: backup.v1beta1.Artifact.mode:type_name -> backup.v1beta1.BackupMode - 1, // 4: backup.v1beta1.ListArtifactsResponse.artifacts:type_name -> backup.v1beta1.Artifact - 2, // 5: backup.v1beta1.Artifacts.ListArtifacts:input_type -> backup.v1beta1.ListArtifactsRequest - 4, // 6: backup.v1beta1.Artifacts.DeleteArtifact:input_type -> backup.v1beta1.DeleteArtifactRequest - 3, // 7: backup.v1beta1.Artifacts.ListArtifacts:output_type -> backup.v1beta1.ListArtifactsResponse - 5, // 8: backup.v1beta1.Artifacts.DeleteArtifact:output_type -> backup.v1beta1.DeleteArtifactResponse - 7, // [7:9] is the sub-list for method output_type - 5, // [5:7] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 9, // 0: backup.v1.Artifact.data_model:type_name -> backup.v1.DataModel + 0, // 1: backup.v1.Artifact.status:type_name -> backup.v1.BackupStatus + 10, // 2: backup.v1.Artifact.created_at:type_name -> google.protobuf.Timestamp + 11, // 3: backup.v1.Artifact.mode:type_name -> backup.v1.BackupMode + 1, // 4: backup.v1.ListArtifactsResponse.artifacts:type_name -> backup.v1.Artifact + 10, // 5: backup.v1.PitrTimerange.start_timestamp:type_name -> google.protobuf.Timestamp + 10, // 6: backup.v1.PitrTimerange.end_timestamp:type_name -> google.protobuf.Timestamp + 6, // 7: backup.v1.ListPitrTimerangesResponse.timeranges:type_name -> backup.v1.PitrTimerange + 2, // 8: backup.v1.Artifacts.ListArtifacts:input_type -> backup.v1.ListArtifactsRequest + 4, // 9: backup.v1.Artifacts.DeleteArtifact:input_type -> backup.v1.DeleteArtifactRequest + 7, // 10: backup.v1.Artifacts.ListPitrTimeranges:input_type -> backup.v1.ListPitrTimerangesRequest + 3, // 11: backup.v1.Artifacts.ListArtifacts:output_type -> backup.v1.ListArtifactsResponse + 5, // 12: backup.v1.Artifacts.DeleteArtifact:output_type -> backup.v1.DeleteArtifactResponse + 8, // 13: backup.v1.Artifacts.ListPitrTimeranges:output_type -> backup.v1.ListPitrTimerangesResponse + 11, // [11:14] is the sub-list for method output_type + 8, // [8:11] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_managementpb_backup_artifacts_proto_init() } @@ -622,6 +807,42 @@ func file_managementpb_backup_artifacts_proto_init() { return nil } } + file_managementpb_backup_artifacts_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PitrTimerange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_backup_artifacts_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListPitrTimerangesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_backup_artifacts_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListPitrTimerangesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -629,7 +850,7 @@ func file_managementpb_backup_artifacts_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_managementpb_backup_artifacts_proto_rawDesc, NumEnums: 1, - NumMessages: 5, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/api/managementpb/backup/artifacts.pb.gw.go b/api/managementpb/backup/artifacts.pb.gw.go index ca3cd17335..46c557ebcd 100644 --- a/api/managementpb/backup/artifacts.pb.gw.go +++ b/api/managementpb/backup/artifacts.pb.gw.go @@ -2,11 +2,11 @@ // source: managementpb/backup/artifacts.proto /* -Package backupv1beta1 is a reverse proxy. +Package backupv1 is a reverse proxy. It translates gRPC into RESTful JSON APIs. */ -package backupv1beta1 +package backupv1 import ( "context" @@ -97,6 +97,38 @@ func local_request_Artifacts_DeleteArtifact_0(ctx context.Context, marshaler run return msg, metadata, err } +func request_Artifacts_ListPitrTimeranges_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListPitrTimerangesRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListPitrTimeranges(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Artifacts_ListPitrTimeranges_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListPitrTimerangesRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListPitrTimeranges(ctx, &protoReq) + return msg, metadata, err +} + // RegisterArtifactsHandlerServer registers the http handlers for service Artifacts to "mux". // UnaryRPC :call ArtifactsServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -110,7 +142,7 @@ func RegisterArtifactsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Artifacts/ListArtifacts", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/List")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Artifacts/ListArtifacts", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -134,7 +166,7 @@ func RegisterArtifactsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Artifacts/DeleteArtifact", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/Delete")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Artifacts/DeleteArtifact", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/Delete")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -150,6 +182,30 @@ func RegisterArtifactsHandlerServer(ctx context.Context, mux *runtime.ServeMux, forward_Artifacts_DeleteArtifact_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Artifacts_ListPitrTimeranges_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Artifacts/ListPitrTimeranges", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/ListPITRTimeranges")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Artifacts_ListPitrTimeranges_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Artifacts_ListPitrTimeranges_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -196,7 +252,7 @@ func RegisterArtifactsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Artifacts/ListArtifacts", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/List")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Artifacts/ListArtifacts", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -217,7 +273,7 @@ func RegisterArtifactsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Artifacts/DeleteArtifact", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/Delete")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Artifacts/DeleteArtifact", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/Delete")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -232,6 +288,27 @@ func RegisterArtifactsHandlerClient(ctx context.Context, mux *runtime.ServeMux, forward_Artifacts_DeleteArtifact_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Artifacts_ListPitrTimeranges_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Artifacts/ListPitrTimeranges", runtime.WithHTTPPathPattern("/v1/management/backup/Artifacts/ListPITRTimeranges")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Artifacts_ListPitrTimeranges_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Artifacts_ListPitrTimeranges_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -239,10 +316,14 @@ var ( pattern_Artifacts_ListArtifacts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "backup", "Artifacts", "List"}, "")) pattern_Artifacts_DeleteArtifact_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "backup", "Artifacts", "Delete"}, "")) + + pattern_Artifacts_ListPitrTimeranges_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "backup", "Artifacts", "ListPITRTimeranges"}, "")) ) var ( forward_Artifacts_ListArtifacts_0 = runtime.ForwardResponseMessage forward_Artifacts_DeleteArtifact_0 = runtime.ForwardResponseMessage + + forward_Artifacts_ListPitrTimeranges_0 = runtime.ForwardResponseMessage ) diff --git a/api/managementpb/backup/artifacts.proto b/api/managementpb/backup/artifacts.proto index fd19b76e21..bda0dba213 100644 --- a/api/managementpb/backup/artifacts.proto +++ b/api/managementpb/backup/artifacts.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; @@ -61,6 +61,22 @@ message DeleteArtifactRequest { message DeleteArtifactResponse {} +message PitrTimerange { + // start_timestamp is the time of the first event in the PITR chunk. + google.protobuf.Timestamp start_timestamp = 1; + // end_timestamp is the time of the last event in the PITR chunk. + google.protobuf.Timestamp end_timestamp = 2; +} + +message ListPitrTimerangesRequest { + // Artifact ID represents artifact whose location has PITR timeranges to be retrieved. + string artifact_id = 1; +} + +message ListPitrTimerangesResponse { + repeated PitrTimerange timeranges = 1; +} + // Artifacts service provides public methods for managing backup artifacts. service Artifacts { // ListArtifacts returns a list of all backup artifacts. @@ -77,4 +93,12 @@ service Artifacts { body: "*" }; } + + // ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location + rpc ListPitrTimeranges(ListPitrTimerangesRequest) returns (ListPitrTimerangesResponse) { + option (google.api.http) = { + post: "/v1/management/backup/Artifacts/ListPITRTimeranges" + body: "*" + }; + } } diff --git a/api/managementpb/backup/artifacts.validator.pb.go b/api/managementpb/backup/artifacts.validator.pb.go index 953763345e..d0629e0f40 100644 --- a/api/managementpb/backup/artifacts.validator.pb.go +++ b/api/managementpb/backup/artifacts.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/artifacts.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" @@ -51,3 +51,32 @@ func (this *DeleteArtifactRequest) Validate() error { func (this *DeleteArtifactResponse) Validate() error { return nil } + +func (this *PitrTimerange) Validate() error { + if this.StartTimestamp != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.StartTimestamp); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("StartTimestamp", err) + } + } + if this.EndTimestamp != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.EndTimestamp); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("EndTimestamp", err) + } + } + return nil +} + +func (this *ListPitrTimerangesRequest) Validate() error { + return nil +} + +func (this *ListPitrTimerangesResponse) Validate() error { + for _, item := range this.Timeranges { + if item != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Timeranges", err) + } + } + } + return nil +} diff --git a/api/managementpb/backup/artifacts_grpc.pb.go b/api/managementpb/backup/artifacts_grpc.pb.go index cf412e404e..217ee737d2 100644 --- a/api/managementpb/backup/artifacts_grpc.pb.go +++ b/api/managementpb/backup/artifacts_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc (unknown) // source: managementpb/backup/artifacts.proto -package backupv1beta1 +package backupv1 import ( context "context" @@ -27,6 +27,8 @@ type ArtifactsClient interface { ListArtifacts(ctx context.Context, in *ListArtifactsRequest, opts ...grpc.CallOption) (*ListArtifactsResponse, error) // DeleteArtifact deletes specified artifact. DeleteArtifact(ctx context.Context, in *DeleteArtifactRequest, opts ...grpc.CallOption) (*DeleteArtifactResponse, error) + // ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location + ListPitrTimeranges(ctx context.Context, in *ListPitrTimerangesRequest, opts ...grpc.CallOption) (*ListPitrTimerangesResponse, error) } type artifactsClient struct { @@ -39,7 +41,7 @@ func NewArtifactsClient(cc grpc.ClientConnInterface) ArtifactsClient { func (c *artifactsClient) ListArtifacts(ctx context.Context, in *ListArtifactsRequest, opts ...grpc.CallOption) (*ListArtifactsResponse, error) { out := new(ListArtifactsResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Artifacts/ListArtifacts", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Artifacts/ListArtifacts", in, out, opts...) if err != nil { return nil, err } @@ -48,7 +50,16 @@ func (c *artifactsClient) ListArtifacts(ctx context.Context, in *ListArtifactsRe func (c *artifactsClient) DeleteArtifact(ctx context.Context, in *DeleteArtifactRequest, opts ...grpc.CallOption) (*DeleteArtifactResponse, error) { out := new(DeleteArtifactResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Artifacts/DeleteArtifact", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Artifacts/DeleteArtifact", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *artifactsClient) ListPitrTimeranges(ctx context.Context, in *ListPitrTimerangesRequest, opts ...grpc.CallOption) (*ListPitrTimerangesResponse, error) { + out := new(ListPitrTimerangesResponse) + err := c.cc.Invoke(ctx, "/backup.v1.Artifacts/ListPitrTimeranges", in, out, opts...) if err != nil { return nil, err } @@ -63,6 +74,8 @@ type ArtifactsServer interface { ListArtifacts(context.Context, *ListArtifactsRequest) (*ListArtifactsResponse, error) // DeleteArtifact deletes specified artifact. DeleteArtifact(context.Context, *DeleteArtifactRequest) (*DeleteArtifactResponse, error) + // ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location + ListPitrTimeranges(context.Context, *ListPitrTimerangesRequest) (*ListPitrTimerangesResponse, error) mustEmbedUnimplementedArtifactsServer() } @@ -76,6 +89,10 @@ func (UnimplementedArtifactsServer) ListArtifacts(context.Context, *ListArtifact func (UnimplementedArtifactsServer) DeleteArtifact(context.Context, *DeleteArtifactRequest) (*DeleteArtifactResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteArtifact not implemented") } + +func (UnimplementedArtifactsServer) ListPitrTimeranges(context.Context, *ListPitrTimerangesRequest) (*ListPitrTimerangesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPitrTimeranges not implemented") +} func (UnimplementedArtifactsServer) mustEmbedUnimplementedArtifactsServer() {} // UnsafeArtifactsServer may be embedded to opt out of forward compatibility for this service. @@ -99,7 +116,7 @@ func _Artifacts_ListArtifacts_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Artifacts/ListArtifacts", + FullMethod: "/backup.v1.Artifacts/ListArtifacts", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ArtifactsServer).ListArtifacts(ctx, req.(*ListArtifactsRequest)) @@ -117,7 +134,7 @@ func _Artifacts_DeleteArtifact_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Artifacts/DeleteArtifact", + FullMethod: "/backup.v1.Artifacts/DeleteArtifact", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ArtifactsServer).DeleteArtifact(ctx, req.(*DeleteArtifactRequest)) @@ -125,11 +142,29 @@ func _Artifacts_DeleteArtifact_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Artifacts_ListPitrTimeranges_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPitrTimerangesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactsServer).ListPitrTimeranges(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/backup.v1.Artifacts/ListPitrTimeranges", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactsServer).ListPitrTimeranges(ctx, req.(*ListPitrTimerangesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Artifacts_ServiceDesc is the grpc.ServiceDesc for Artifacts service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Artifacts_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "backup.v1beta1.Artifacts", + ServiceName: "backup.v1.Artifacts", HandlerType: (*ArtifactsServer)(nil), Methods: []grpc.MethodDesc{ { @@ -140,6 +175,10 @@ var Artifacts_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteArtifact", Handler: _Artifacts_DeleteArtifact_Handler, }, + { + MethodName: "ListPitrTimeranges", + Handler: _Artifacts_ListPitrTimeranges_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "managementpb/backup/artifacts.proto", diff --git a/api/managementpb/backup/backups.pb.go b/api/managementpb/backup/backups.pb.go index 8cfc4213c9..23cb58019a 100644 --- a/api/managementpb/backup/backups.pb.go +++ b/api/managementpb/backup/backups.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/backups.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -47,7 +47,7 @@ type StartBackupRequest struct { // How many times to retry a failed backup before giving up. Retries uint32 `protobuf:"varint,6,opt,name=retries,proto3" json:"retries,omitempty"` // DataModel represents the data model used for the backup. - DataModel DataModel `protobuf:"varint,7,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel DataModel `protobuf:"varint,7,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` } func (x *StartBackupRequest) Reset() { @@ -291,6 +291,8 @@ type RestoreBackupRequest struct { ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` // Artifact id to restore. ArtifactId string `protobuf:"bytes,2,opt,name=artifact_id,json=artifactId,proto3" json:"artifact_id,omitempty"` + // Timestamp of PITR to restore to + PitrTimestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=pitr_timestamp,json=pitrTimestamp,proto3" json:"pitr_timestamp,omitempty"` } func (x *RestoreBackupRequest) Reset() { @@ -339,6 +341,13 @@ func (x *RestoreBackupRequest) GetArtifactId() string { return "" } +func (x *RestoreBackupRequest) GetPitrTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.PitrTimestamp + } + return nil +} + type RestoreBackupResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -418,7 +427,7 @@ type ScheduledBackup struct { // If scheduling is enabled. Enabled bool `protobuf:"varint,13,opt,name=enabled,proto3" json:"enabled,omitempty"` // Backup data model (physical or logical). - DataModel DataModel `protobuf:"varint,14,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel DataModel `protobuf:"varint,14,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` // Database vendor e.g. PostgreSQL, MongoDB, MySQL. Vendor string `protobuf:"bytes,15,opt,name=vendor,proto3" json:"vendor,omitempty"` // Last run. @@ -428,7 +437,7 @@ type ScheduledBackup struct { // How many artifacts keep. 0 - unlimited. Retention uint32 `protobuf:"varint,18,opt,name=retention,proto3" json:"retention,omitempty"` // Backup mode. - Mode BackupMode `protobuf:"varint,19,opt,name=mode,proto3,enum=backup.v1beta1.BackupMode" json:"mode,omitempty"` + Mode BackupMode `protobuf:"varint,19,opt,name=mode,proto3,enum=backup.v1.BackupMode" json:"mode,omitempty"` } func (x *ScheduledBackup) Reset() { @@ -615,9 +624,9 @@ type ScheduleBackupRequest struct { // How many artifacts keep. 0 - unlimited. Retention uint32 `protobuf:"varint,10,opt,name=retention,proto3" json:"retention,omitempty"` // Backup mode. - Mode BackupMode `protobuf:"varint,11,opt,name=mode,proto3,enum=backup.v1beta1.BackupMode" json:"mode,omitempty"` + Mode BackupMode `protobuf:"varint,11,opt,name=mode,proto3,enum=backup.v1.BackupMode" json:"mode,omitempty"` // Backup data model (physical or logical). - DataModel DataModel `protobuf:"varint,12,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel DataModel `protobuf:"varint,12,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` } func (x *ScheduleBackupRequest) Reset() { @@ -1288,120 +1297,123 @@ var File_managementpb_backup_backups_proto protoreflect.FileDescriptor var file_managementpb_backup_backups_proto_rawDesc = []byte{ 0x0a, 0x21, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, - 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x69, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x70, 0x62, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb0, 0x02, 0x0a, 0x12, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x25, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, - 0x02, 0x58, 0x01, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x36, 0x0a, 0x13, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x49, 0x64, 0x22, 0x50, 0x0a, 0x25, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, - 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x49, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2d, 0x0a, 0x05, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4d, 0x79, 0x53, 0x51, - 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x05, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x12, - 0x33, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4d, 0x6f, 0x6e, - 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x6e, - 0x67, 0x6f, 0x64, 0x62, 0x22, 0x66, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0a, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, - 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x22, 0x36, 0x0a, 0x15, - 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x49, 0x64, 0x22, 0xe7, 0x05, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, - 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, - 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, - 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, - 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, - 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, - 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, - 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, - 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x75, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x6e, 0x65, 0x78, - 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, + 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, 0x74, 0x6b, + 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x70, 0x62, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xab, 0x02, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, + 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x0a, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x0a, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x14, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, + 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x22, 0x36, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x22, 0x50, 0x0a, 0x25, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, + 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x26, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x05, + 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x79, 0x2e, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x22, 0xa9, 0x01, 0x0a, 0x14, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, + 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x49, 0x64, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x69, 0x74, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x75, 0x6e, - 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, - 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x87, - 0x04, 0x0a, 0x15, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x70, 0x69, 0x74, 0x72, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x36, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x22, 0xdd, + 0x05, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, + 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, + 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, + 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x72, 0x75, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x75, 0x6e, 0x12, 0x35, + 0x0a, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x6e, 0x65, + 0x78, 0x74, 0x52, 0x75, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xfd, + 0x03, 0x0a, 0x15, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, @@ -1426,236 +1438,228 @@ var file_managementpb_backup_backups_proto_rawDesc = []byte{ 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, - 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x38, - 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, - 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x48, 0x0a, 0x16, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x49, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x6c, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4c, 0x0a, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x10, 0x73, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x22, - 0xb6, 0x04, 0x0a, 0x1c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x36, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, - 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x45, - 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x09, - 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, + 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, + 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x48, + 0x0a, 0x16, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x67, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x10, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, + 0x22, 0xb6, 0x04, 0x0a, 0x1c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x36, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, + 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x72, - 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x0a, 0x1c, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x13, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x11, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, - 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x67, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, - 0x01, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x51, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, - 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, - 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, - 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x39, - 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x75, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, - 0x75, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x80, 0x11, 0x0a, 0x07, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0xf3, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x22, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, - 0x03, 0x92, 0x41, 0xe8, 0x02, 0x1a, 0xe5, 0x02, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, - 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, - 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0a, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, - 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, - 0x45, 0x44, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, - 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, - 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x0a, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x20, 0x2d, 0x20, - 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x78, 0x62, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x0a, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, - 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x20, - 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x61, - 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x28, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x73, 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0xd8, 0x01, 0x0a, 0x1e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, - 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, - 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x22, 0x3c, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x82, 0x05, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa3, 0x04, 0x92, 0x41, 0xef, 0x03, 0x1a, 0xec, 0x03, 0x43, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, - 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, - 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, - 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, - 0x43, 0x4b, 0x55, 0x50, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, - 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x78, 0x74, 0x72, - 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x78, 0x62, 0x63, 0x6c, - 0x6f, 0x75, 0x64, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, - 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, - 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, - 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, - 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x54, 0x41, 0x52, - 0x47, 0x45, 0x54, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x20, 0x2d, 0x20, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, - 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, - 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, - 0x2f, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x92, 0x01, 0x0a, 0x0e, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x25, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x3a, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, + 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x0a, 0x1c, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x13, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, + 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x49, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, + 0x58, 0x01, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x4c, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x27, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x39, 0x0a, 0x08, 0x4c, 0x6f, + 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0xb0, 0x10, 0x0a, 0x07, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x73, 0x12, 0xe9, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x12, 0x1d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x9a, 0x03, 0x92, 0x41, 0xe8, 0x02, 0x1a, 0xe5, 0x02, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, + 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, + 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, + 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, + 0x4c, 0x4c, 0x45, 0x44, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x20, + 0x2d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x78, 0x62, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x0a, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, + 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, + 0x50, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x69, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x01, 0x2a, - 0x12, 0xa9, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x2b, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2b, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0xae, 0x01, 0x0a, - 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0xce, 0x01, + 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x12, 0x30, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x22, 0x3c, 0x2f, + 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0xf8, + 0x04, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x1f, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xa3, 0x04, 0x92, 0x41, 0xef, 0x03, 0x1a, 0xec, 0x03, 0x43, 0x6f, 0x75, + 0x6c, 0x64, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x3a, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x58, + 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, + 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, + 0x55, 0x50, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x78, 0x62, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, + 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, + 0x43, 0x4b, 0x55, 0x50, 0x20, 0x2d, 0x20, 0x78, 0x74, 0x72, 0x61, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x0a, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, + 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, + 0x54, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x20, 0x2d, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, + 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x88, 0x01, 0x0a, 0x0e, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x20, 0x2e, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x9f, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x26, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x22, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0xa4, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0xae, 0x01, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0xa4, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x22, 0x2d, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x7c, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x32, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x73, 0x2f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x42, 0xb9, 0x01, 0x0a, - 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1a, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x2f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x72, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, + 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, + 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, 0x25, + 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x2f, 0x47, 0x65, + 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x42, 0x9b, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, + 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, + 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1673,30 +1677,30 @@ func file_managementpb_backup_backups_proto_rawDescGZIP() []byte { var ( file_managementpb_backup_backups_proto_msgTypes = make([]protoimpl.MessageInfo, 18) file_managementpb_backup_backups_proto_goTypes = []interface{}{ - (*StartBackupRequest)(nil), // 0: backup.v1beta1.StartBackupRequest - (*StartBackupResponse)(nil), // 1: backup.v1beta1.StartBackupResponse - (*ListArtifactCompatibleServicesRequest)(nil), // 2: backup.v1beta1.ListArtifactCompatibleServicesRequest - (*ListArtifactCompatibleServicesResponse)(nil), // 3: backup.v1beta1.ListArtifactCompatibleServicesResponse - (*RestoreBackupRequest)(nil), // 4: backup.v1beta1.RestoreBackupRequest - (*RestoreBackupResponse)(nil), // 5: backup.v1beta1.RestoreBackupResponse - (*ScheduledBackup)(nil), // 6: backup.v1beta1.ScheduledBackup - (*ScheduleBackupRequest)(nil), // 7: backup.v1beta1.ScheduleBackupRequest - (*ScheduleBackupResponse)(nil), // 8: backup.v1beta1.ScheduleBackupResponse - (*ListScheduledBackupsRequest)(nil), // 9: backup.v1beta1.ListScheduledBackupsRequest - (*ListScheduledBackupsResponse)(nil), // 10: backup.v1beta1.ListScheduledBackupsResponse - (*ChangeScheduledBackupRequest)(nil), // 11: backup.v1beta1.ChangeScheduledBackupRequest - (*ChangeScheduledBackupResponse)(nil), // 12: backup.v1beta1.ChangeScheduledBackupResponse - (*RemoveScheduledBackupRequest)(nil), // 13: backup.v1beta1.RemoveScheduledBackupRequest - (*RemoveScheduledBackupResponse)(nil), // 14: backup.v1beta1.RemoveScheduledBackupResponse - (*GetLogsRequest)(nil), // 15: backup.v1beta1.GetLogsRequest - (*GetLogsResponse)(nil), // 16: backup.v1beta1.GetLogsResponse - (*LogChunk)(nil), // 17: backup.v1beta1.LogChunk + (*StartBackupRequest)(nil), // 0: backup.v1.StartBackupRequest + (*StartBackupResponse)(nil), // 1: backup.v1.StartBackupResponse + (*ListArtifactCompatibleServicesRequest)(nil), // 2: backup.v1.ListArtifactCompatibleServicesRequest + (*ListArtifactCompatibleServicesResponse)(nil), // 3: backup.v1.ListArtifactCompatibleServicesResponse + (*RestoreBackupRequest)(nil), // 4: backup.v1.RestoreBackupRequest + (*RestoreBackupResponse)(nil), // 5: backup.v1.RestoreBackupResponse + (*ScheduledBackup)(nil), // 6: backup.v1.ScheduledBackup + (*ScheduleBackupRequest)(nil), // 7: backup.v1.ScheduleBackupRequest + (*ScheduleBackupResponse)(nil), // 8: backup.v1.ScheduleBackupResponse + (*ListScheduledBackupsRequest)(nil), // 9: backup.v1.ListScheduledBackupsRequest + (*ListScheduledBackupsResponse)(nil), // 10: backup.v1.ListScheduledBackupsResponse + (*ChangeScheduledBackupRequest)(nil), // 11: backup.v1.ChangeScheduledBackupRequest + (*ChangeScheduledBackupResponse)(nil), // 12: backup.v1.ChangeScheduledBackupResponse + (*RemoveScheduledBackupRequest)(nil), // 13: backup.v1.RemoveScheduledBackupRequest + (*RemoveScheduledBackupResponse)(nil), // 14: backup.v1.RemoveScheduledBackupResponse + (*GetLogsRequest)(nil), // 15: backup.v1.GetLogsRequest + (*GetLogsResponse)(nil), // 16: backup.v1.GetLogsResponse + (*LogChunk)(nil), // 17: backup.v1.LogChunk (*durationpb.Duration)(nil), // 18: google.protobuf.Duration - (DataModel)(0), // 19: backup.v1beta1.DataModel + (DataModel)(0), // 19: backup.v1.DataModel (*inventorypb.MySQLService)(nil), // 20: inventory.MySQLService (*inventorypb.MongoDBService)(nil), // 21: inventory.MongoDBService (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp - (BackupMode)(0), // 23: backup.v1beta1.BackupMode + (BackupMode)(0), // 23: backup.v1.BackupMode (*wrapperspb.BoolValue)(nil), // 24: google.protobuf.BoolValue (*wrapperspb.StringValue)(nil), // 25: google.protobuf.StringValue (*wrapperspb.UInt32Value)(nil), // 26: google.protobuf.UInt32Value @@ -1704,51 +1708,52 @@ var ( ) var file_managementpb_backup_backups_proto_depIdxs = []int32{ - 18, // 0: backup.v1beta1.StartBackupRequest.retry_interval:type_name -> google.protobuf.Duration - 19, // 1: backup.v1beta1.StartBackupRequest.data_model:type_name -> backup.v1beta1.DataModel - 20, // 2: backup.v1beta1.ListArtifactCompatibleServicesResponse.mysql:type_name -> inventory.MySQLService - 21, // 3: backup.v1beta1.ListArtifactCompatibleServicesResponse.mongodb:type_name -> inventory.MongoDBService - 22, // 4: backup.v1beta1.ScheduledBackup.start_time:type_name -> google.protobuf.Timestamp - 18, // 5: backup.v1beta1.ScheduledBackup.retry_interval:type_name -> google.protobuf.Duration - 19, // 6: backup.v1beta1.ScheduledBackup.data_model:type_name -> backup.v1beta1.DataModel - 22, // 7: backup.v1beta1.ScheduledBackup.last_run:type_name -> google.protobuf.Timestamp - 22, // 8: backup.v1beta1.ScheduledBackup.next_run:type_name -> google.protobuf.Timestamp - 23, // 9: backup.v1beta1.ScheduledBackup.mode:type_name -> backup.v1beta1.BackupMode - 22, // 10: backup.v1beta1.ScheduleBackupRequest.start_time:type_name -> google.protobuf.Timestamp - 18, // 11: backup.v1beta1.ScheduleBackupRequest.retry_interval:type_name -> google.protobuf.Duration - 23, // 12: backup.v1beta1.ScheduleBackupRequest.mode:type_name -> backup.v1beta1.BackupMode - 19, // 13: backup.v1beta1.ScheduleBackupRequest.data_model:type_name -> backup.v1beta1.DataModel - 6, // 14: backup.v1beta1.ListScheduledBackupsResponse.scheduled_backups:type_name -> backup.v1beta1.ScheduledBackup - 24, // 15: backup.v1beta1.ChangeScheduledBackupRequest.enabled:type_name -> google.protobuf.BoolValue - 25, // 16: backup.v1beta1.ChangeScheduledBackupRequest.cron_expression:type_name -> google.protobuf.StringValue - 22, // 17: backup.v1beta1.ChangeScheduledBackupRequest.start_time:type_name -> google.protobuf.Timestamp - 25, // 18: backup.v1beta1.ChangeScheduledBackupRequest.name:type_name -> google.protobuf.StringValue - 25, // 19: backup.v1beta1.ChangeScheduledBackupRequest.description:type_name -> google.protobuf.StringValue - 18, // 20: backup.v1beta1.ChangeScheduledBackupRequest.retry_interval:type_name -> google.protobuf.Duration - 26, // 21: backup.v1beta1.ChangeScheduledBackupRequest.retries:type_name -> google.protobuf.UInt32Value - 26, // 22: backup.v1beta1.ChangeScheduledBackupRequest.retention:type_name -> google.protobuf.UInt32Value - 17, // 23: backup.v1beta1.GetLogsResponse.logs:type_name -> backup.v1beta1.LogChunk - 0, // 24: backup.v1beta1.Backups.StartBackup:input_type -> backup.v1beta1.StartBackupRequest - 2, // 25: backup.v1beta1.Backups.ListArtifactCompatibleServices:input_type -> backup.v1beta1.ListArtifactCompatibleServicesRequest - 4, // 26: backup.v1beta1.Backups.RestoreBackup:input_type -> backup.v1beta1.RestoreBackupRequest - 7, // 27: backup.v1beta1.Backups.ScheduleBackup:input_type -> backup.v1beta1.ScheduleBackupRequest - 9, // 28: backup.v1beta1.Backups.ListScheduledBackups:input_type -> backup.v1beta1.ListScheduledBackupsRequest - 11, // 29: backup.v1beta1.Backups.ChangeScheduledBackup:input_type -> backup.v1beta1.ChangeScheduledBackupRequest - 13, // 30: backup.v1beta1.Backups.RemoveScheduledBackup:input_type -> backup.v1beta1.RemoveScheduledBackupRequest - 15, // 31: backup.v1beta1.Backups.GetLogs:input_type -> backup.v1beta1.GetLogsRequest - 1, // 32: backup.v1beta1.Backups.StartBackup:output_type -> backup.v1beta1.StartBackupResponse - 3, // 33: backup.v1beta1.Backups.ListArtifactCompatibleServices:output_type -> backup.v1beta1.ListArtifactCompatibleServicesResponse - 5, // 34: backup.v1beta1.Backups.RestoreBackup:output_type -> backup.v1beta1.RestoreBackupResponse - 8, // 35: backup.v1beta1.Backups.ScheduleBackup:output_type -> backup.v1beta1.ScheduleBackupResponse - 10, // 36: backup.v1beta1.Backups.ListScheduledBackups:output_type -> backup.v1beta1.ListScheduledBackupsResponse - 12, // 37: backup.v1beta1.Backups.ChangeScheduledBackup:output_type -> backup.v1beta1.ChangeScheduledBackupResponse - 14, // 38: backup.v1beta1.Backups.RemoveScheduledBackup:output_type -> backup.v1beta1.RemoveScheduledBackupResponse - 16, // 39: backup.v1beta1.Backups.GetLogs:output_type -> backup.v1beta1.GetLogsResponse - 32, // [32:40] is the sub-list for method output_type - 24, // [24:32] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 18, // 0: backup.v1.StartBackupRequest.retry_interval:type_name -> google.protobuf.Duration + 19, // 1: backup.v1.StartBackupRequest.data_model:type_name -> backup.v1.DataModel + 20, // 2: backup.v1.ListArtifactCompatibleServicesResponse.mysql:type_name -> inventory.MySQLService + 21, // 3: backup.v1.ListArtifactCompatibleServicesResponse.mongodb:type_name -> inventory.MongoDBService + 22, // 4: backup.v1.RestoreBackupRequest.pitr_timestamp:type_name -> google.protobuf.Timestamp + 22, // 5: backup.v1.ScheduledBackup.start_time:type_name -> google.protobuf.Timestamp + 18, // 6: backup.v1.ScheduledBackup.retry_interval:type_name -> google.protobuf.Duration + 19, // 7: backup.v1.ScheduledBackup.data_model:type_name -> backup.v1.DataModel + 22, // 8: backup.v1.ScheduledBackup.last_run:type_name -> google.protobuf.Timestamp + 22, // 9: backup.v1.ScheduledBackup.next_run:type_name -> google.protobuf.Timestamp + 23, // 10: backup.v1.ScheduledBackup.mode:type_name -> backup.v1.BackupMode + 22, // 11: backup.v1.ScheduleBackupRequest.start_time:type_name -> google.protobuf.Timestamp + 18, // 12: backup.v1.ScheduleBackupRequest.retry_interval:type_name -> google.protobuf.Duration + 23, // 13: backup.v1.ScheduleBackupRequest.mode:type_name -> backup.v1.BackupMode + 19, // 14: backup.v1.ScheduleBackupRequest.data_model:type_name -> backup.v1.DataModel + 6, // 15: backup.v1.ListScheduledBackupsResponse.scheduled_backups:type_name -> backup.v1.ScheduledBackup + 24, // 16: backup.v1.ChangeScheduledBackupRequest.enabled:type_name -> google.protobuf.BoolValue + 25, // 17: backup.v1.ChangeScheduledBackupRequest.cron_expression:type_name -> google.protobuf.StringValue + 22, // 18: backup.v1.ChangeScheduledBackupRequest.start_time:type_name -> google.protobuf.Timestamp + 25, // 19: backup.v1.ChangeScheduledBackupRequest.name:type_name -> google.protobuf.StringValue + 25, // 20: backup.v1.ChangeScheduledBackupRequest.description:type_name -> google.protobuf.StringValue + 18, // 21: backup.v1.ChangeScheduledBackupRequest.retry_interval:type_name -> google.protobuf.Duration + 26, // 22: backup.v1.ChangeScheduledBackupRequest.retries:type_name -> google.protobuf.UInt32Value + 26, // 23: backup.v1.ChangeScheduledBackupRequest.retention:type_name -> google.protobuf.UInt32Value + 17, // 24: backup.v1.GetLogsResponse.logs:type_name -> backup.v1.LogChunk + 0, // 25: backup.v1.Backups.StartBackup:input_type -> backup.v1.StartBackupRequest + 2, // 26: backup.v1.Backups.ListArtifactCompatibleServices:input_type -> backup.v1.ListArtifactCompatibleServicesRequest + 4, // 27: backup.v1.Backups.RestoreBackup:input_type -> backup.v1.RestoreBackupRequest + 7, // 28: backup.v1.Backups.ScheduleBackup:input_type -> backup.v1.ScheduleBackupRequest + 9, // 29: backup.v1.Backups.ListScheduledBackups:input_type -> backup.v1.ListScheduledBackupsRequest + 11, // 30: backup.v1.Backups.ChangeScheduledBackup:input_type -> backup.v1.ChangeScheduledBackupRequest + 13, // 31: backup.v1.Backups.RemoveScheduledBackup:input_type -> backup.v1.RemoveScheduledBackupRequest + 15, // 32: backup.v1.Backups.GetLogs:input_type -> backup.v1.GetLogsRequest + 1, // 33: backup.v1.Backups.StartBackup:output_type -> backup.v1.StartBackupResponse + 3, // 34: backup.v1.Backups.ListArtifactCompatibleServices:output_type -> backup.v1.ListArtifactCompatibleServicesResponse + 5, // 35: backup.v1.Backups.RestoreBackup:output_type -> backup.v1.RestoreBackupResponse + 8, // 36: backup.v1.Backups.ScheduleBackup:output_type -> backup.v1.ScheduleBackupResponse + 10, // 37: backup.v1.Backups.ListScheduledBackups:output_type -> backup.v1.ListScheduledBackupsResponse + 12, // 38: backup.v1.Backups.ChangeScheduledBackup:output_type -> backup.v1.ChangeScheduledBackupResponse + 14, // 39: backup.v1.Backups.RemoveScheduledBackup:output_type -> backup.v1.RemoveScheduledBackupResponse + 16, // 40: backup.v1.Backups.GetLogs:output_type -> backup.v1.GetLogsResponse + 33, // [33:41] is the sub-list for method output_type + 25, // [25:33] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_managementpb_backup_backups_proto_init() } diff --git a/api/managementpb/backup/backups.pb.gw.go b/api/managementpb/backup/backups.pb.gw.go index 5588af913b..8bf08a13a2 100644 --- a/api/managementpb/backup/backups.pb.gw.go +++ b/api/managementpb/backup/backups.pb.gw.go @@ -2,11 +2,11 @@ // source: managementpb/backup/backups.proto /* -Package backupv1beta1 is a reverse proxy. +Package backupv1 is a reverse proxy. It translates gRPC into RESTful JSON APIs. */ -package backupv1beta1 +package backupv1 import ( "context" @@ -302,7 +302,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/StartBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Start")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/StartBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Start")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -326,7 +326,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/ListArtifactCompatibleServices", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListArtifactCompatibleServices")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/ListArtifactCompatibleServices", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListArtifactCompatibleServices")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -350,7 +350,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/RestoreBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Restore")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/RestoreBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Restore")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -374,7 +374,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/ScheduleBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Schedule")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/ScheduleBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Schedule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -398,7 +398,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/ListScheduledBackups", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListScheduled")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/ListScheduledBackups", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -422,7 +422,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/ChangeScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ChangeScheduled")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/ChangeScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ChangeScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -446,7 +446,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/RemoveScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/RemoveScheduled")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/RemoveScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/RemoveScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -470,7 +470,7 @@ func RegisterBackupsHandlerServer(ctx context.Context, mux *runtime.ServeMux, se inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Backups/GetLogs", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/GetLogs")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Backups/GetLogs", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/GetLogs")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -532,7 +532,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/StartBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Start")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/StartBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Start")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -553,7 +553,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/ListArtifactCompatibleServices", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListArtifactCompatibleServices")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/ListArtifactCompatibleServices", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListArtifactCompatibleServices")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -574,7 +574,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/RestoreBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Restore")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/RestoreBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Restore")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -595,7 +595,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/ScheduleBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Schedule")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/ScheduleBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/Schedule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -616,7 +616,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/ListScheduledBackups", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListScheduled")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/ListScheduledBackups", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ListScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -637,7 +637,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/ChangeScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ChangeScheduled")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/ChangeScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/ChangeScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -658,7 +658,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/RemoveScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/RemoveScheduled")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/RemoveScheduledBackup", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/RemoveScheduled")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -679,7 +679,7 @@ func RegisterBackupsHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Backups/GetLogs", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/GetLogs")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Backups/GetLogs", runtime.WithHTTPPathPattern("/v1/management/backup/Backups/GetLogs")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return diff --git a/api/managementpb/backup/backups.proto b/api/managementpb/backup/backups.proto index 43019e481f..84b4488766 100644 --- a/api/managementpb/backup/backups.proto +++ b/api/managementpb/backup/backups.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; import "protoc-gen-openapiv2/options/annotations.proto"; import "github.com/mwitkow/go-proto-validators/validator.proto"; @@ -70,6 +70,8 @@ message RestoreBackupRequest { string_not_empty: true } ]; + // Timestamp of PITR to restore to + google.protobuf.Timestamp pitr_timestamp = 3; } message RestoreBackupResponse { diff --git a/api/managementpb/backup/backups.validator.pb.go b/api/managementpb/backup/backups.validator.pb.go index cdddc8947d..ffb3bad316 100644 --- a/api/managementpb/backup/backups.validator.pb.go +++ b/api/managementpb/backup/backups.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/backups.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" @@ -77,6 +77,11 @@ func (this *RestoreBackupRequest) Validate() error { if this.ArtifactId == "" { return github_com_mwitkow_go_proto_validators.FieldError("ArtifactId", fmt.Errorf(`value '%v' must not be an empty string`, this.ArtifactId)) } + if this.PitrTimestamp != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PitrTimestamp); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("PitrTimestamp", err) + } + } return nil } diff --git a/api/managementpb/backup/backups_grpc.pb.go b/api/managementpb/backup/backups_grpc.pb.go index 077ba9bf31..3f0c64c6d6 100644 --- a/api/managementpb/backup/backups_grpc.pb.go +++ b/api/managementpb/backup/backups_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc (unknown) // source: managementpb/backup/backups.proto -package backupv1beta1 +package backupv1 import ( context "context" @@ -51,7 +51,7 @@ func NewBackupsClient(cc grpc.ClientConnInterface) BackupsClient { func (c *backupsClient) StartBackup(ctx context.Context, in *StartBackupRequest, opts ...grpc.CallOption) (*StartBackupResponse, error) { out := new(StartBackupResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/StartBackup", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/StartBackup", in, out, opts...) if err != nil { return nil, err } @@ -60,7 +60,7 @@ func (c *backupsClient) StartBackup(ctx context.Context, in *StartBackupRequest, func (c *backupsClient) ListArtifactCompatibleServices(ctx context.Context, in *ListArtifactCompatibleServicesRequest, opts ...grpc.CallOption) (*ListArtifactCompatibleServicesResponse, error) { out := new(ListArtifactCompatibleServicesResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/ListArtifactCompatibleServices", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/ListArtifactCompatibleServices", in, out, opts...) if err != nil { return nil, err } @@ -69,7 +69,7 @@ func (c *backupsClient) ListArtifactCompatibleServices(ctx context.Context, in * func (c *backupsClient) RestoreBackup(ctx context.Context, in *RestoreBackupRequest, opts ...grpc.CallOption) (*RestoreBackupResponse, error) { out := new(RestoreBackupResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/RestoreBackup", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/RestoreBackup", in, out, opts...) if err != nil { return nil, err } @@ -78,7 +78,7 @@ func (c *backupsClient) RestoreBackup(ctx context.Context, in *RestoreBackupRequ func (c *backupsClient) ScheduleBackup(ctx context.Context, in *ScheduleBackupRequest, opts ...grpc.CallOption) (*ScheduleBackupResponse, error) { out := new(ScheduleBackupResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/ScheduleBackup", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/ScheduleBackup", in, out, opts...) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (c *backupsClient) ScheduleBackup(ctx context.Context, in *ScheduleBackupRe func (c *backupsClient) ListScheduledBackups(ctx context.Context, in *ListScheduledBackupsRequest, opts ...grpc.CallOption) (*ListScheduledBackupsResponse, error) { out := new(ListScheduledBackupsResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/ListScheduledBackups", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/ListScheduledBackups", in, out, opts...) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func (c *backupsClient) ListScheduledBackups(ctx context.Context, in *ListSchedu func (c *backupsClient) ChangeScheduledBackup(ctx context.Context, in *ChangeScheduledBackupRequest, opts ...grpc.CallOption) (*ChangeScheduledBackupResponse, error) { out := new(ChangeScheduledBackupResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/ChangeScheduledBackup", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/ChangeScheduledBackup", in, out, opts...) if err != nil { return nil, err } @@ -105,7 +105,7 @@ func (c *backupsClient) ChangeScheduledBackup(ctx context.Context, in *ChangeSch func (c *backupsClient) RemoveScheduledBackup(ctx context.Context, in *RemoveScheduledBackupRequest, opts ...grpc.CallOption) (*RemoveScheduledBackupResponse, error) { out := new(RemoveScheduledBackupResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/RemoveScheduledBackup", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/RemoveScheduledBackup", in, out, opts...) if err != nil { return nil, err } @@ -114,7 +114,7 @@ func (c *backupsClient) RemoveScheduledBackup(ctx context.Context, in *RemoveSch func (c *backupsClient) GetLogs(ctx context.Context, in *GetLogsRequest, opts ...grpc.CallOption) (*GetLogsResponse, error) { out := new(GetLogsResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Backups/GetLogs", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Backups/GetLogs", in, out, opts...) if err != nil { return nil, err } @@ -201,7 +201,7 @@ func _Backups_StartBackup_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/StartBackup", + FullMethod: "/backup.v1.Backups/StartBackup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).StartBackup(ctx, req.(*StartBackupRequest)) @@ -219,7 +219,7 @@ func _Backups_ListArtifactCompatibleServices_Handler(srv interface{}, ctx contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/ListArtifactCompatibleServices", + FullMethod: "/backup.v1.Backups/ListArtifactCompatibleServices", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).ListArtifactCompatibleServices(ctx, req.(*ListArtifactCompatibleServicesRequest)) @@ -237,7 +237,7 @@ func _Backups_RestoreBackup_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/RestoreBackup", + FullMethod: "/backup.v1.Backups/RestoreBackup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).RestoreBackup(ctx, req.(*RestoreBackupRequest)) @@ -255,7 +255,7 @@ func _Backups_ScheduleBackup_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/ScheduleBackup", + FullMethod: "/backup.v1.Backups/ScheduleBackup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).ScheduleBackup(ctx, req.(*ScheduleBackupRequest)) @@ -273,7 +273,7 @@ func _Backups_ListScheduledBackups_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/ListScheduledBackups", + FullMethod: "/backup.v1.Backups/ListScheduledBackups", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).ListScheduledBackups(ctx, req.(*ListScheduledBackupsRequest)) @@ -291,7 +291,7 @@ func _Backups_ChangeScheduledBackup_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/ChangeScheduledBackup", + FullMethod: "/backup.v1.Backups/ChangeScheduledBackup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).ChangeScheduledBackup(ctx, req.(*ChangeScheduledBackupRequest)) @@ -309,7 +309,7 @@ func _Backups_RemoveScheduledBackup_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/RemoveScheduledBackup", + FullMethod: "/backup.v1.Backups/RemoveScheduledBackup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).RemoveScheduledBackup(ctx, req.(*RemoveScheduledBackupRequest)) @@ -327,7 +327,7 @@ func _Backups_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Backups/GetLogs", + FullMethod: "/backup.v1.Backups/GetLogs", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BackupsServer).GetLogs(ctx, req.(*GetLogsRequest)) @@ -339,7 +339,7 @@ func _Backups_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(int // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Backups_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "backup.v1beta1.Backups", + ServiceName: "backup.v1.Backups", HandlerType: (*BackupsServer)(nil), Methods: []grpc.MethodDesc{ { diff --git a/api/managementpb/backup/common.pb.go b/api/managementpb/backup/common.pb.go index ef854c20e9..099c919d2f 100644 --- a/api/managementpb/backup/common.pb.go +++ b/api/managementpb/backup/common.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/common.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -129,29 +129,27 @@ var File_managementpb_backup_common_proto protoreflect.FileDescriptor var file_managementpb_backup_common_proto_rawDesc = []byte{ 0x0a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2a, 0x3e, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, - 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x48, 0x59, 0x53, 0x49, - 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x47, 0x49, 0x43, 0x41, 0x4c, - 0x10, 0x02, 0x2a, 0x4e, 0x0a, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x17, 0x0a, 0x13, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, - 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x43, 0x52, 0x45, - 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x49, 0x54, 0x52, - 0x10, 0x03, 0x42, 0xb8, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, - 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, - 0x1a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2a, 0x3e, 0x0a, + 0x09, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, + 0x54, 0x41, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x48, 0x59, 0x53, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, + 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x47, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x02, 0x2a, 0x4e, 0x0a, + 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x42, + 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, + 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x43, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x41, + 0x4c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x49, 0x54, 0x52, 0x10, 0x03, 0x42, 0x9a, 0x01, + 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x42, + 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, + 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x09, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -169,8 +167,8 @@ func file_managementpb_backup_common_proto_rawDescGZIP() []byte { var ( file_managementpb_backup_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2) file_managementpb_backup_common_proto_goTypes = []interface{}{ - (DataModel)(0), // 0: backup.v1beta1.DataModel - (BackupMode)(0), // 1: backup.v1beta1.BackupMode + (DataModel)(0), // 0: backup.v1.DataModel + (BackupMode)(0), // 1: backup.v1.BackupMode } ) diff --git a/api/managementpb/backup/common.proto b/api/managementpb/backup/common.proto index 7fc35f2a57..4816a7c502 100644 --- a/api/managementpb/backup/common.proto +++ b/api/managementpb/backup/common.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; // DataModel is a model used for performing a backup. enum DataModel { diff --git a/api/managementpb/backup/common.validator.pb.go b/api/managementpb/backup/common.validator.pb.go index 793e08bce3..c71aefa7ed 100644 --- a/api/managementpb/backup/common.validator.pb.go +++ b/api/managementpb/backup/common.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/common.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" diff --git a/api/managementpb/backup/errors.pb.go b/api/managementpb/backup/errors.pb.go index 53c4c987dc..ab906ad3bd 100644 --- a/api/managementpb/backup/errors.pb.go +++ b/api/managementpb/backup/errors.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/errors.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -88,7 +88,7 @@ type Error struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Code ErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=backup.v1beta1.ErrorCode" json:"code,omitempty"` + Code ErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=backup.v1.ErrorCode" json:"code,omitempty"` } func (x *Error) Reset() { @@ -135,36 +135,33 @@ var File_managementpb_backup_errors_proto protoreflect.FileDescriptor var file_managementpb_backup_errors_proto_rawDesc = []byte{ 0x0a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x22, 0x36, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x2a, 0xc1, 0x01, 0x0a, 0x09, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, - 0x12, 0x27, 0x0a, 0x23, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x58, - 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, - 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, - 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, - 0x55, 0x50, 0x10, 0x03, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, - 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x10, 0x04, 0x42, 0xb8, - 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1a, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x22, 0x31, 0x0a, + 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x28, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x2a, 0xc1, 0x01, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, + 0x0a, 0x12, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x27, 0x0a, 0x23, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x58, 0x54, 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, + 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, + 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x58, 0x54, + 0x52, 0x41, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, 0x03, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, + 0x54, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x4d, 0x59, 0x53, + 0x51, 0x4c, 0x10, 0x04, 0x42, 0x9a, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -183,13 +180,13 @@ var ( file_managementpb_backup_errors_proto_enumTypes = make([]protoimpl.EnumInfo, 1) file_managementpb_backup_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 1) file_managementpb_backup_errors_proto_goTypes = []interface{}{ - (ErrorCode)(0), // 0: backup.v1beta1.ErrorCode - (*Error)(nil), // 1: backup.v1beta1.Error + (ErrorCode)(0), // 0: backup.v1.ErrorCode + (*Error)(nil), // 1: backup.v1.Error } ) var file_managementpb_backup_errors_proto_depIdxs = []int32{ - 0, // 0: backup.v1beta1.Error.code:type_name -> backup.v1beta1.ErrorCode + 0, // 0: backup.v1.Error.code:type_name -> backup.v1.ErrorCode 1, // [1:1] is the sub-list for method output_type 1, // [1:1] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name diff --git a/api/managementpb/backup/errors.proto b/api/managementpb/backup/errors.proto index 919fb3aff6..0e1b1b9e50 100644 --- a/api/managementpb/backup/errors.proto +++ b/api/managementpb/backup/errors.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; // ErrorCode is a set of specific errors that are not present in the standard set of errors // and returned in the details field of the response. diff --git a/api/managementpb/backup/errors.validator.pb.go b/api/managementpb/backup/errors.validator.pb.go index cedf20614a..1ca646ed22 100644 --- a/api/managementpb/backup/errors.validator.pb.go +++ b/api/managementpb/backup/errors.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/errors.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" diff --git a/api/managementpb/backup/json/backup.json b/api/managementpb/backup/json/backup.json index e54dce7db0..167c179c55 100644 --- a/api/managementpb/backup/json/backup.json +++ b/api/managementpb/backup/json/backup.json @@ -235,6 +235,94 @@ } } }, + "/v1/management/backup/Artifacts/ListPITRTimeranges": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location", + "operationId": "ListPitrTimeranges", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Artifact ID represents artifact whose location has PITR timeranges to be retrieved.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "timeranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "end_timestamp": { + "description": "end_timestamp is the time of the last event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 1 + }, + "start_timestamp": { + "description": "start_timestamp is the time of the first event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 0 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, "/v1/management/backup/Backups/ChangeScheduled": { "post": { "tags": [ @@ -898,6 +986,12 @@ "type": "string", "x-order": 1 }, + "pitr_timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp of PITR to restore to", + "x-order": 2 + }, "service_id": { "description": "Service identifier where backup should be restored.", "type": "string", @@ -1226,13 +1320,8 @@ "type": "string", "x-order": 1 }, - "name": { - "type": "string", - "title": "Location name", - "x-order": 0 - }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -1242,16 +1331,10 @@ }, "x-order": 2 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 3 + "name": { + "type": "string", + "title": "Location name", + "x-order": 0 }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", @@ -1274,7 +1357,7 @@ "x-order": 2 } }, - "x-order": 4 + "x-order": 3 } } } @@ -1347,18 +1430,8 @@ "type": "string", "x-order": 2 }, - "location_id": { - "description": "Machine-readable ID.", - "type": "string", - "x-order": 0 - }, - "name": { - "type": "string", - "title": "Location name", - "x-order": 1 - }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -1368,16 +1441,15 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "name": { + "type": "string", + "title": "Location name", + "x-order": 1 }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", @@ -1400,7 +1472,7 @@ "x-order": 2 } }, - "x-order": 5 + "x-order": 4 } } } @@ -1481,18 +1553,8 @@ "title": "Short description", "x-order": 2 }, - "location_id": { - "description": "Machine-readable ID.", - "type": "string", - "x-order": 0 - }, - "name": { - "type": "string", - "title": "Location name", - "x-order": 1 - }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -1502,16 +1564,15 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "name": { + "type": "string", + "title": "Location name", + "x-order": 1 }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", @@ -1534,7 +1595,7 @@ "x-order": 2 } }, - "x-order": 5 + "x-order": 4 } } }, @@ -1662,8 +1723,8 @@ "schema": { "type": "object", "properties": { - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -1673,17 +1734,6 @@ }, "x-order": 0 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 1 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -1705,7 +1755,7 @@ "x-order": 2 } }, - "x-order": 2 + "x-order": 1 } } } diff --git a/api/managementpb/backup/json/client/artifacts/artifacts_client.go b/api/managementpb/backup/json/client/artifacts/artifacts_client.go index dc0ba0e959..c423279259 100644 --- a/api/managementpb/backup/json/client/artifacts/artifacts_client.go +++ b/api/managementpb/backup/json/client/artifacts/artifacts_client.go @@ -32,6 +32,8 @@ type ClientService interface { ListArtifacts(params *ListArtifactsParams, opts ...ClientOption) (*ListArtifactsOK, error) + ListPitrTimeranges(params *ListPitrTimerangesParams, opts ...ClientOption) (*ListPitrTimerangesOK, error) + SetTransport(transport runtime.ClientTransport) } @@ -109,6 +111,43 @@ func (a *Client) ListArtifacts(params *ListArtifactsParams, opts ...ClientOption return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +ListPitrTimeranges lists pitr timeranges list the available mongo DB p i t r timeranges in a given backup location +*/ +func (a *Client) ListPitrTimeranges(params *ListPitrTimerangesParams, opts ...ClientOption) (*ListPitrTimerangesOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewListPitrTimerangesParams() + } + op := &runtime.ClientOperation{ + ID: "ListPitrTimeranges", + Method: "POST", + PathPattern: "/v1/management/backup/Artifacts/ListPITRTimeranges", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &ListPitrTimerangesReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*ListPitrTimerangesOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*ListPitrTimerangesDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + // SetTransport changes the transport on the client func (a *Client) SetTransport(transport runtime.ClientTransport) { a.transport = transport diff --git a/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_parameters.go b/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_parameters.go new file mode 100644 index 0000000000..66e1f4cf57 --- /dev/null +++ b/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package artifacts + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewListPitrTimerangesParams creates a new ListPitrTimerangesParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewListPitrTimerangesParams() *ListPitrTimerangesParams { + return &ListPitrTimerangesParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewListPitrTimerangesParamsWithTimeout creates a new ListPitrTimerangesParams object +// with the ability to set a timeout on a request. +func NewListPitrTimerangesParamsWithTimeout(timeout time.Duration) *ListPitrTimerangesParams { + return &ListPitrTimerangesParams{ + timeout: timeout, + } +} + +// NewListPitrTimerangesParamsWithContext creates a new ListPitrTimerangesParams object +// with the ability to set a context for a request. +func NewListPitrTimerangesParamsWithContext(ctx context.Context) *ListPitrTimerangesParams { + return &ListPitrTimerangesParams{ + Context: ctx, + } +} + +// NewListPitrTimerangesParamsWithHTTPClient creates a new ListPitrTimerangesParams object +// with the ability to set a custom HTTPClient for a request. +func NewListPitrTimerangesParamsWithHTTPClient(client *http.Client) *ListPitrTimerangesParams { + return &ListPitrTimerangesParams{ + HTTPClient: client, + } +} + +/* +ListPitrTimerangesParams contains all the parameters to send to the API endpoint + + for the list pitr timeranges operation. + + Typically these are written to a http.Request. +*/ +type ListPitrTimerangesParams struct { + // Body. + Body ListPitrTimerangesBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the list pitr timeranges params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ListPitrTimerangesParams) WithDefaults() *ListPitrTimerangesParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the list pitr timeranges params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ListPitrTimerangesParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the list pitr timeranges params +func (o *ListPitrTimerangesParams) WithTimeout(timeout time.Duration) *ListPitrTimerangesParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the list pitr timeranges params +func (o *ListPitrTimerangesParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the list pitr timeranges params +func (o *ListPitrTimerangesParams) WithContext(ctx context.Context) *ListPitrTimerangesParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the list pitr timeranges params +func (o *ListPitrTimerangesParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the list pitr timeranges params +func (o *ListPitrTimerangesParams) WithHTTPClient(client *http.Client) *ListPitrTimerangesParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the list pitr timeranges params +func (o *ListPitrTimerangesParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the list pitr timeranges params +func (o *ListPitrTimerangesParams) WithBody(body ListPitrTimerangesBody) *ListPitrTimerangesParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the list pitr timeranges params +func (o *ListPitrTimerangesParams) SetBody(body ListPitrTimerangesBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *ListPitrTimerangesParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_responses.go b/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_responses.go new file mode 100644 index 0000000000..1cd2d69336 --- /dev/null +++ b/api/managementpb/backup/json/client/artifacts/list_pitr_timeranges_responses.go @@ -0,0 +1,475 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package artifacts + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// ListPitrTimerangesReader is a Reader for the ListPitrTimeranges structure. +type ListPitrTimerangesReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *ListPitrTimerangesReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewListPitrTimerangesOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewListPitrTimerangesDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewListPitrTimerangesOK creates a ListPitrTimerangesOK with default headers values +func NewListPitrTimerangesOK() *ListPitrTimerangesOK { + return &ListPitrTimerangesOK{} +} + +/* +ListPitrTimerangesOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type ListPitrTimerangesOK struct { + Payload *ListPitrTimerangesOKBody +} + +func (o *ListPitrTimerangesOK) Error() string { + return fmt.Sprintf("[POST /v1/management/backup/Artifacts/ListPITRTimeranges][%d] listPitrTimerangesOk %+v", 200, o.Payload) +} + +func (o *ListPitrTimerangesOK) GetPayload() *ListPitrTimerangesOKBody { + return o.Payload +} + +func (o *ListPitrTimerangesOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(ListPitrTimerangesOKBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewListPitrTimerangesDefault creates a ListPitrTimerangesDefault with default headers values +func NewListPitrTimerangesDefault(code int) *ListPitrTimerangesDefault { + return &ListPitrTimerangesDefault{ + _statusCode: code, + } +} + +/* +ListPitrTimerangesDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type ListPitrTimerangesDefault struct { + _statusCode int + + Payload *ListPitrTimerangesDefaultBody +} + +// Code gets the status code for the list pitr timeranges default response +func (o *ListPitrTimerangesDefault) Code() int { + return o._statusCode +} + +func (o *ListPitrTimerangesDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/backup/Artifacts/ListPITRTimeranges][%d] ListPitrTimeranges default %+v", o._statusCode, o.Payload) +} + +func (o *ListPitrTimerangesDefault) GetPayload() *ListPitrTimerangesDefaultBody { + return o.Payload +} + +func (o *ListPitrTimerangesDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(ListPitrTimerangesDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +ListPitrTimerangesBody list pitr timeranges body +swagger:model ListPitrTimerangesBody +*/ +type ListPitrTimerangesBody struct { + // Artifact ID represents artifact whose location has PITR timeranges to be retrieved. + ArtifactID string `json:"artifact_id,omitempty"` +} + +// Validate validates this list pitr timeranges body +func (o *ListPitrTimerangesBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this list pitr timeranges body based on context it is used +func (o *ListPitrTimerangesBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListPitrTimerangesBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListPitrTimerangesBody) UnmarshalBinary(b []byte) error { + var res ListPitrTimerangesBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListPitrTimerangesDefaultBody list pitr timeranges default body +swagger:model ListPitrTimerangesDefaultBody +*/ +type ListPitrTimerangesDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*ListPitrTimerangesDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this list pitr timeranges default body +func (o *ListPitrTimerangesDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListPitrTimerangesDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ListPitrTimeranges default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ListPitrTimeranges default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this list pitr timeranges default body based on the context it is used +func (o *ListPitrTimerangesDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListPitrTimerangesDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ListPitrTimeranges default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ListPitrTimeranges default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ListPitrTimerangesDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListPitrTimerangesDefaultBody) UnmarshalBinary(b []byte) error { + var res ListPitrTimerangesDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListPitrTimerangesDefaultBodyDetailsItems0 list pitr timeranges default body details items0 +swagger:model ListPitrTimerangesDefaultBodyDetailsItems0 +*/ +type ListPitrTimerangesDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this list pitr timeranges default body details items0 +func (o *ListPitrTimerangesDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this list pitr timeranges default body details items0 based on context it is used +func (o *ListPitrTimerangesDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListPitrTimerangesDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListPitrTimerangesDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res ListPitrTimerangesDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListPitrTimerangesOKBody list pitr timeranges OK body +swagger:model ListPitrTimerangesOKBody +*/ +type ListPitrTimerangesOKBody struct { + // timeranges + Timeranges []*ListPitrTimerangesOKBodyTimerangesItems0 `json:"timeranges"` +} + +// Validate validates this list pitr timeranges OK body +func (o *ListPitrTimerangesOKBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateTimeranges(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListPitrTimerangesOKBody) validateTimeranges(formats strfmt.Registry) error { + if swag.IsZero(o.Timeranges) { // not required + return nil + } + + for i := 0; i < len(o.Timeranges); i++ { + if swag.IsZero(o.Timeranges[i]) { // not required + continue + } + + if o.Timeranges[i] != nil { + if err := o.Timeranges[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("listPitrTimerangesOk" + "." + "timeranges" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("listPitrTimerangesOk" + "." + "timeranges" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this list pitr timeranges OK body based on the context it is used +func (o *ListPitrTimerangesOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateTimeranges(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListPitrTimerangesOKBody) contextValidateTimeranges(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Timeranges); i++ { + if o.Timeranges[i] != nil { + if err := o.Timeranges[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("listPitrTimerangesOk" + "." + "timeranges" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("listPitrTimerangesOk" + "." + "timeranges" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ListPitrTimerangesOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListPitrTimerangesOKBody) UnmarshalBinary(b []byte) error { + var res ListPitrTimerangesOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListPitrTimerangesOKBodyTimerangesItems0 list pitr timeranges OK body timeranges items0 +swagger:model ListPitrTimerangesOKBodyTimerangesItems0 +*/ +type ListPitrTimerangesOKBodyTimerangesItems0 struct { + // start_timestamp is the time of the first event in the PITR chunk. + // Format: date-time + StartTimestamp strfmt.DateTime `json:"start_timestamp,omitempty"` + + // end_timestamp is the time of the last event in the PITR chunk. + // Format: date-time + EndTimestamp strfmt.DateTime `json:"end_timestamp,omitempty"` +} + +// Validate validates this list pitr timeranges OK body timeranges items0 +func (o *ListPitrTimerangesOKBodyTimerangesItems0) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateStartTimestamp(formats); err != nil { + res = append(res, err) + } + + if err := o.validateEndTimestamp(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListPitrTimerangesOKBodyTimerangesItems0) validateStartTimestamp(formats strfmt.Registry) error { + if swag.IsZero(o.StartTimestamp) { // not required + return nil + } + + if err := validate.FormatOf("start_timestamp", "body", "date-time", o.StartTimestamp.String(), formats); err != nil { + return err + } + + return nil +} + +func (o *ListPitrTimerangesOKBodyTimerangesItems0) validateEndTimestamp(formats strfmt.Registry) error { + if swag.IsZero(o.EndTimestamp) { // not required + return nil + } + + if err := validate.FormatOf("end_timestamp", "body", "date-time", o.EndTimestamp.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this list pitr timeranges OK body timeranges items0 based on context it is used +func (o *ListPitrTimerangesOKBodyTimerangesItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListPitrTimerangesOKBodyTimerangesItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListPitrTimerangesOKBodyTimerangesItems0) UnmarshalBinary(b []byte) error { + var res ListPitrTimerangesOKBodyTimerangesItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/backup/json/client/backups/restore_backup_responses.go b/api/managementpb/backup/json/client/backups/restore_backup_responses.go index 608b6e352c..39085e7f15 100644 --- a/api/managementpb/backup/json/client/backups/restore_backup_responses.go +++ b/api/managementpb/backup/json/client/backups/restore_backup_responses.go @@ -15,6 +15,7 @@ import ( "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" + "github.com/go-openapi/validate" ) // RestoreBackupReader is a Reader for the RestoreBackup structure. @@ -128,10 +129,35 @@ type RestoreBackupBody struct { // Artifact id to restore. ArtifactID string `json:"artifact_id,omitempty"` + + // Timestamp of PITR to restore to + // Format: date-time + PitrTimestamp strfmt.DateTime `json:"pitr_timestamp,omitempty"` } // Validate validates this restore backup body func (o *RestoreBackupBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validatePitrTimestamp(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RestoreBackupBody) validatePitrTimestamp(formats strfmt.Registry) error { + if swag.IsZero(o.PitrTimestamp) { // not required + return nil + } + + if err := validate.FormatOf("body"+"."+"pitr_timestamp", "body", "date-time", o.PitrTimestamp.String(), formats); err != nil { + return err + } + return nil } diff --git a/api/managementpb/backup/json/client/locations/add_location_responses.go b/api/managementpb/backup/json/client/locations/add_location_responses.go index 541af9a52d..9267795dda 100644 --- a/api/managementpb/backup/json/client/locations/add_location_responses.go +++ b/api/managementpb/backup/json/client/locations/add_location_responses.go @@ -129,11 +129,8 @@ type AddLocationBody struct { // description Description string `json:"description,omitempty"` - // pmm client config - PMMClientConfig *AddLocationParamsBodyPMMClientConfig `json:"pmm_client_config,omitempty"` - - // pmm server config - PMMServerConfig *AddLocationParamsBodyPMMServerConfig `json:"pmm_server_config,omitempty"` + // filesystem config + FilesystemConfig *AddLocationParamsBodyFilesystemConfig `json:"filesystem_config,omitempty"` // s3 config S3Config *AddLocationParamsBodyS3Config `json:"s3_config,omitempty"` @@ -143,11 +140,7 @@ type AddLocationBody struct { func (o *AddLocationBody) Validate(formats strfmt.Registry) error { var res []error - if err := o.validatePMMClientConfig(formats); err != nil { - res = append(res, err) - } - - if err := o.validatePMMServerConfig(formats); err != nil { + if err := o.validateFilesystemConfig(formats); err != nil { res = append(res, err) } @@ -161,36 +154,17 @@ func (o *AddLocationBody) Validate(formats strfmt.Registry) error { return nil } -func (o *AddLocationBody) validatePMMClientConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMClientConfig) { // not required +func (o *AddLocationBody) validateFilesystemConfig(formats strfmt.Registry) error { + if swag.IsZero(o.FilesystemConfig) { // not required return nil } - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.Validate(formats); err != nil { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *AddLocationBody) validatePMMServerConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMServerConfig) { // not required - return nil - } - - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -222,11 +196,7 @@ func (o *AddLocationBody) validateS3Config(formats strfmt.Registry) error { func (o *AddLocationBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := o.contextValidatePMMClientConfig(ctx, formats); err != nil { - res = append(res, err) - } - - if err := o.contextValidatePMMServerConfig(ctx, formats); err != nil { + if err := o.contextValidateFilesystemConfig(ctx, formats); err != nil { res = append(res, err) } @@ -240,28 +210,13 @@ func (o *AddLocationBody) ContextValidate(ctx context.Context, formats strfmt.Re return nil } -func (o *AddLocationBody) contextValidatePMMClientConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.ContextValidate(ctx, formats); err != nil { +func (o *AddLocationBody) contextValidateFilesystemConfig(ctx context.Context, formats strfmt.Registry) error { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *AddLocationBody) contextValidatePMMServerConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -482,63 +437,26 @@ func (o *AddLocationOKBody) UnmarshalBinary(b []byte) error { } /* -AddLocationParamsBodyPMMClientConfig PMMClientLocationConfig represents file system config inside pmm-client. -swagger:model AddLocationParamsBodyPMMClientConfig -*/ -type AddLocationParamsBodyPMMClientConfig struct { - // path - Path string `json:"path,omitempty"` -} - -// Validate validates this add location params body PMM client config -func (o *AddLocationParamsBodyPMMClientConfig) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this add location params body PMM client config based on context it is used -func (o *AddLocationParamsBodyPMMClientConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *AddLocationParamsBodyPMMClientConfig) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *AddLocationParamsBodyPMMClientConfig) UnmarshalBinary(b []byte) error { - var res AddLocationParamsBodyPMMClientConfig - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} - -/* -AddLocationParamsBodyPMMServerConfig PMMServerLocationConfig represents file system config inside pmm-server. -swagger:model AddLocationParamsBodyPMMServerConfig +AddLocationParamsBodyFilesystemConfig FilesystemLocationConfig represents file system location config. +swagger:model AddLocationParamsBodyFilesystemConfig */ -type AddLocationParamsBodyPMMServerConfig struct { +type AddLocationParamsBodyFilesystemConfig struct { // path Path string `json:"path,omitempty"` } -// Validate validates this add location params body PMM server config -func (o *AddLocationParamsBodyPMMServerConfig) Validate(formats strfmt.Registry) error { +// Validate validates this add location params body filesystem config +func (o *AddLocationParamsBodyFilesystemConfig) Validate(formats strfmt.Registry) error { return nil } -// ContextValidate validates this add location params body PMM server config based on context it is used -func (o *AddLocationParamsBodyPMMServerConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { +// ContextValidate validates this add location params body filesystem config based on context it is used +func (o *AddLocationParamsBodyFilesystemConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { return nil } // MarshalBinary interface implementation -func (o *AddLocationParamsBodyPMMServerConfig) MarshalBinary() ([]byte, error) { +func (o *AddLocationParamsBodyFilesystemConfig) MarshalBinary() ([]byte, error) { if o == nil { return nil, nil } @@ -546,8 +464,8 @@ func (o *AddLocationParamsBodyPMMServerConfig) MarshalBinary() ([]byte, error) { } // UnmarshalBinary interface implementation -func (o *AddLocationParamsBodyPMMServerConfig) UnmarshalBinary(b []byte) error { - var res AddLocationParamsBodyPMMServerConfig +func (o *AddLocationParamsBodyFilesystemConfig) UnmarshalBinary(b []byte) error { + var res AddLocationParamsBodyFilesystemConfig if err := swag.ReadJSON(b, &res); err != nil { return err } diff --git a/api/managementpb/backup/json/client/locations/change_location_responses.go b/api/managementpb/backup/json/client/locations/change_location_responses.go index 9f71cf16f4..fa79790e0f 100644 --- a/api/managementpb/backup/json/client/locations/change_location_responses.go +++ b/api/managementpb/backup/json/client/locations/change_location_responses.go @@ -130,11 +130,8 @@ type ChangeLocationBody struct { // description Description string `json:"description,omitempty"` - // pmm client config - PMMClientConfig *ChangeLocationParamsBodyPMMClientConfig `json:"pmm_client_config,omitempty"` - - // pmm server config - PMMServerConfig *ChangeLocationParamsBodyPMMServerConfig `json:"pmm_server_config,omitempty"` + // filesystem config + FilesystemConfig *ChangeLocationParamsBodyFilesystemConfig `json:"filesystem_config,omitempty"` // s3 config S3Config *ChangeLocationParamsBodyS3Config `json:"s3_config,omitempty"` @@ -144,11 +141,7 @@ type ChangeLocationBody struct { func (o *ChangeLocationBody) Validate(formats strfmt.Registry) error { var res []error - if err := o.validatePMMClientConfig(formats); err != nil { - res = append(res, err) - } - - if err := o.validatePMMServerConfig(formats); err != nil { + if err := o.validateFilesystemConfig(formats); err != nil { res = append(res, err) } @@ -162,36 +155,17 @@ func (o *ChangeLocationBody) Validate(formats strfmt.Registry) error { return nil } -func (o *ChangeLocationBody) validatePMMClientConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMClientConfig) { // not required +func (o *ChangeLocationBody) validateFilesystemConfig(formats strfmt.Registry) error { + if swag.IsZero(o.FilesystemConfig) { // not required return nil } - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.Validate(formats); err != nil { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *ChangeLocationBody) validatePMMServerConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMServerConfig) { // not required - return nil - } - - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -223,11 +197,7 @@ func (o *ChangeLocationBody) validateS3Config(formats strfmt.Registry) error { func (o *ChangeLocationBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := o.contextValidatePMMClientConfig(ctx, formats); err != nil { - res = append(res, err) - } - - if err := o.contextValidatePMMServerConfig(ctx, formats); err != nil { + if err := o.contextValidateFilesystemConfig(ctx, formats); err != nil { res = append(res, err) } @@ -241,28 +211,13 @@ func (o *ChangeLocationBody) ContextValidate(ctx context.Context, formats strfmt return nil } -func (o *ChangeLocationBody) contextValidatePMMClientConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.ContextValidate(ctx, formats); err != nil { +func (o *ChangeLocationBody) contextValidateFilesystemConfig(ctx context.Context, formats strfmt.Registry) error { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *ChangeLocationBody) contextValidatePMMServerConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -446,63 +401,26 @@ func (o *ChangeLocationDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error } /* -ChangeLocationParamsBodyPMMClientConfig PMMClientLocationConfig represents file system config inside pmm-client. -swagger:model ChangeLocationParamsBodyPMMClientConfig -*/ -type ChangeLocationParamsBodyPMMClientConfig struct { - // path - Path string `json:"path,omitempty"` -} - -// Validate validates this change location params body PMM client config -func (o *ChangeLocationParamsBodyPMMClientConfig) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this change location params body PMM client config based on context it is used -func (o *ChangeLocationParamsBodyPMMClientConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *ChangeLocationParamsBodyPMMClientConfig) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *ChangeLocationParamsBodyPMMClientConfig) UnmarshalBinary(b []byte) error { - var res ChangeLocationParamsBodyPMMClientConfig - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} - -/* -ChangeLocationParamsBodyPMMServerConfig PMMServerLocationConfig represents file system config inside pmm-server. -swagger:model ChangeLocationParamsBodyPMMServerConfig +ChangeLocationParamsBodyFilesystemConfig FilesystemLocationConfig represents file system location config. +swagger:model ChangeLocationParamsBodyFilesystemConfig */ -type ChangeLocationParamsBodyPMMServerConfig struct { +type ChangeLocationParamsBodyFilesystemConfig struct { // path Path string `json:"path,omitempty"` } -// Validate validates this change location params body PMM server config -func (o *ChangeLocationParamsBodyPMMServerConfig) Validate(formats strfmt.Registry) error { +// Validate validates this change location params body filesystem config +func (o *ChangeLocationParamsBodyFilesystemConfig) Validate(formats strfmt.Registry) error { return nil } -// ContextValidate validates this change location params body PMM server config based on context it is used -func (o *ChangeLocationParamsBodyPMMServerConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { +// ContextValidate validates this change location params body filesystem config based on context it is used +func (o *ChangeLocationParamsBodyFilesystemConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { return nil } // MarshalBinary interface implementation -func (o *ChangeLocationParamsBodyPMMServerConfig) MarshalBinary() ([]byte, error) { +func (o *ChangeLocationParamsBodyFilesystemConfig) MarshalBinary() ([]byte, error) { if o == nil { return nil, nil } @@ -510,8 +428,8 @@ func (o *ChangeLocationParamsBodyPMMServerConfig) MarshalBinary() ([]byte, error } // UnmarshalBinary interface implementation -func (o *ChangeLocationParamsBodyPMMServerConfig) UnmarshalBinary(b []byte) error { - var res ChangeLocationParamsBodyPMMServerConfig +func (o *ChangeLocationParamsBodyFilesystemConfig) UnmarshalBinary(b []byte) error { + var res ChangeLocationParamsBodyFilesystemConfig if err := swag.ReadJSON(b, &res); err != nil { return err } diff --git a/api/managementpb/backup/json/client/locations/list_locations_responses.go b/api/managementpb/backup/json/client/locations/list_locations_responses.go index 4400e58783..a005e9b029 100644 --- a/api/managementpb/backup/json/client/locations/list_locations_responses.go +++ b/api/managementpb/backup/json/client/locations/list_locations_responses.go @@ -371,11 +371,8 @@ type ListLocationsOKBodyLocationsItems0 struct { // Short description Description string `json:"description,omitempty"` - // pmm client config - PMMClientConfig *ListLocationsOKBodyLocationsItems0PMMClientConfig `json:"pmm_client_config,omitempty"` - - // pmm server config - PMMServerConfig *ListLocationsOKBodyLocationsItems0PMMServerConfig `json:"pmm_server_config,omitempty"` + // filesystem config + FilesystemConfig *ListLocationsOKBodyLocationsItems0FilesystemConfig `json:"filesystem_config,omitempty"` // s3 config S3Config *ListLocationsOKBodyLocationsItems0S3Config `json:"s3_config,omitempty"` @@ -385,11 +382,7 @@ type ListLocationsOKBodyLocationsItems0 struct { func (o *ListLocationsOKBodyLocationsItems0) Validate(formats strfmt.Registry) error { var res []error - if err := o.validatePMMClientConfig(formats); err != nil { - res = append(res, err) - } - - if err := o.validatePMMServerConfig(formats); err != nil { + if err := o.validateFilesystemConfig(formats); err != nil { res = append(res, err) } @@ -403,36 +396,17 @@ func (o *ListLocationsOKBodyLocationsItems0) Validate(formats strfmt.Registry) e return nil } -func (o *ListLocationsOKBodyLocationsItems0) validatePMMClientConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMClientConfig) { // not required +func (o *ListLocationsOKBodyLocationsItems0) validateFilesystemConfig(formats strfmt.Registry) error { + if swag.IsZero(o.FilesystemConfig) { // not required return nil } - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.Validate(formats); err != nil { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("pmm_client_config") + return ve.ValidateName("filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *ListLocationsOKBodyLocationsItems0) validatePMMServerConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMServerConfig) { // not required - return nil - } - - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("pmm_server_config") + return ce.ValidateName("filesystem_config") } return err } @@ -464,11 +438,7 @@ func (o *ListLocationsOKBodyLocationsItems0) validateS3Config(formats strfmt.Reg func (o *ListLocationsOKBodyLocationsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := o.contextValidatePMMClientConfig(ctx, formats); err != nil { - res = append(res, err) - } - - if err := o.contextValidatePMMServerConfig(ctx, formats); err != nil { + if err := o.contextValidateFilesystemConfig(ctx, formats); err != nil { res = append(res, err) } @@ -482,28 +452,13 @@ func (o *ListLocationsOKBodyLocationsItems0) ContextValidate(ctx context.Context return nil } -func (o *ListLocationsOKBodyLocationsItems0) contextValidatePMMClientConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.ContextValidate(ctx, formats); err != nil { +func (o *ListLocationsOKBodyLocationsItems0) contextValidateFilesystemConfig(ctx context.Context, formats strfmt.Registry) error { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("pmm_client_config") + return ve.ValidateName("filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *ListLocationsOKBodyLocationsItems0) contextValidatePMMServerConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("pmm_server_config") + return ce.ValidateName("filesystem_config") } return err } @@ -546,63 +501,26 @@ func (o *ListLocationsOKBodyLocationsItems0) UnmarshalBinary(b []byte) error { } /* -ListLocationsOKBodyLocationsItems0PMMClientConfig PMMClientLocationConfig represents file system config inside pmm-client. -swagger:model ListLocationsOKBodyLocationsItems0PMMClientConfig -*/ -type ListLocationsOKBodyLocationsItems0PMMClientConfig struct { - // path - Path string `json:"path,omitempty"` -} - -// Validate validates this list locations OK body locations items0 PMM client config -func (o *ListLocationsOKBodyLocationsItems0PMMClientConfig) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this list locations OK body locations items0 PMM client config based on context it is used -func (o *ListLocationsOKBodyLocationsItems0PMMClientConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *ListLocationsOKBodyLocationsItems0PMMClientConfig) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *ListLocationsOKBodyLocationsItems0PMMClientConfig) UnmarshalBinary(b []byte) error { - var res ListLocationsOKBodyLocationsItems0PMMClientConfig - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} - -/* -ListLocationsOKBodyLocationsItems0PMMServerConfig PMMServerLocationConfig represents file system config inside pmm-server. -swagger:model ListLocationsOKBodyLocationsItems0PMMServerConfig +ListLocationsOKBodyLocationsItems0FilesystemConfig FilesystemLocationConfig represents file system location config. +swagger:model ListLocationsOKBodyLocationsItems0FilesystemConfig */ -type ListLocationsOKBodyLocationsItems0PMMServerConfig struct { +type ListLocationsOKBodyLocationsItems0FilesystemConfig struct { // path Path string `json:"path,omitempty"` } -// Validate validates this list locations OK body locations items0 PMM server config -func (o *ListLocationsOKBodyLocationsItems0PMMServerConfig) Validate(formats strfmt.Registry) error { +// Validate validates this list locations OK body locations items0 filesystem config +func (o *ListLocationsOKBodyLocationsItems0FilesystemConfig) Validate(formats strfmt.Registry) error { return nil } -// ContextValidate validates this list locations OK body locations items0 PMM server config based on context it is used -func (o *ListLocationsOKBodyLocationsItems0PMMServerConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { +// ContextValidate validates this list locations OK body locations items0 filesystem config based on context it is used +func (o *ListLocationsOKBodyLocationsItems0FilesystemConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { return nil } // MarshalBinary interface implementation -func (o *ListLocationsOKBodyLocationsItems0PMMServerConfig) MarshalBinary() ([]byte, error) { +func (o *ListLocationsOKBodyLocationsItems0FilesystemConfig) MarshalBinary() ([]byte, error) { if o == nil { return nil, nil } @@ -610,8 +528,8 @@ func (o *ListLocationsOKBodyLocationsItems0PMMServerConfig) MarshalBinary() ([]b } // UnmarshalBinary interface implementation -func (o *ListLocationsOKBodyLocationsItems0PMMServerConfig) UnmarshalBinary(b []byte) error { - var res ListLocationsOKBodyLocationsItems0PMMServerConfig +func (o *ListLocationsOKBodyLocationsItems0FilesystemConfig) UnmarshalBinary(b []byte) error { + var res ListLocationsOKBodyLocationsItems0FilesystemConfig if err := swag.ReadJSON(b, &res); err != nil { return err } diff --git a/api/managementpb/backup/json/client/locations/test_location_config_responses.go b/api/managementpb/backup/json/client/locations/test_location_config_responses.go index 30b30ae21d..42948149c1 100644 --- a/api/managementpb/backup/json/client/locations/test_location_config_responses.go +++ b/api/managementpb/backup/json/client/locations/test_location_config_responses.go @@ -121,11 +121,8 @@ TestLocationConfigBody test location config body swagger:model TestLocationConfigBody */ type TestLocationConfigBody struct { - // pmm client config - PMMClientConfig *TestLocationConfigParamsBodyPMMClientConfig `json:"pmm_client_config,omitempty"` - - // pmm server config - PMMServerConfig *TestLocationConfigParamsBodyPMMServerConfig `json:"pmm_server_config,omitempty"` + // filesystem config + FilesystemConfig *TestLocationConfigParamsBodyFilesystemConfig `json:"filesystem_config,omitempty"` // s3 config S3Config *TestLocationConfigParamsBodyS3Config `json:"s3_config,omitempty"` @@ -135,11 +132,7 @@ type TestLocationConfigBody struct { func (o *TestLocationConfigBody) Validate(formats strfmt.Registry) error { var res []error - if err := o.validatePMMClientConfig(formats); err != nil { - res = append(res, err) - } - - if err := o.validatePMMServerConfig(formats); err != nil { + if err := o.validateFilesystemConfig(formats); err != nil { res = append(res, err) } @@ -153,36 +146,17 @@ func (o *TestLocationConfigBody) Validate(formats strfmt.Registry) error { return nil } -func (o *TestLocationConfigBody) validatePMMClientConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMClientConfig) { // not required +func (o *TestLocationConfigBody) validateFilesystemConfig(formats strfmt.Registry) error { + if swag.IsZero(o.FilesystemConfig) { // not required return nil } - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.Validate(formats); err != nil { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *TestLocationConfigBody) validatePMMServerConfig(formats strfmt.Registry) error { - if swag.IsZero(o.PMMServerConfig) { // not required - return nil - } - - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -214,11 +188,7 @@ func (o *TestLocationConfigBody) validateS3Config(formats strfmt.Registry) error func (o *TestLocationConfigBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := o.contextValidatePMMClientConfig(ctx, formats); err != nil { - res = append(res, err) - } - - if err := o.contextValidatePMMServerConfig(ctx, formats); err != nil { + if err := o.contextValidateFilesystemConfig(ctx, formats); err != nil { res = append(res, err) } @@ -232,28 +202,13 @@ func (o *TestLocationConfigBody) ContextValidate(ctx context.Context, formats st return nil } -func (o *TestLocationConfigBody) contextValidatePMMClientConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMClientConfig != nil { - if err := o.PMMClientConfig.ContextValidate(ctx, formats); err != nil { +func (o *TestLocationConfigBody) contextValidateFilesystemConfig(ctx context.Context, formats strfmt.Registry) error { + if o.FilesystemConfig != nil { + if err := o.FilesystemConfig.ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_client_config") + return ve.ValidateName("body" + "." + "filesystem_config") } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_client_config") - } - return err - } - } - - return nil -} - -func (o *TestLocationConfigBody) contextValidatePMMServerConfig(ctx context.Context, formats strfmt.Registry) error { - if o.PMMServerConfig != nil { - if err := o.PMMServerConfig.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("body" + "." + "pmm_server_config") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("body" + "." + "pmm_server_config") + return ce.ValidateName("body" + "." + "filesystem_config") } return err } @@ -437,63 +392,26 @@ func (o *TestLocationConfigDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) e } /* -TestLocationConfigParamsBodyPMMClientConfig PMMClientLocationConfig represents file system config inside pmm-client. -swagger:model TestLocationConfigParamsBodyPMMClientConfig -*/ -type TestLocationConfigParamsBodyPMMClientConfig struct { - // path - Path string `json:"path,omitempty"` -} - -// Validate validates this test location config params body PMM client config -func (o *TestLocationConfigParamsBodyPMMClientConfig) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this test location config params body PMM client config based on context it is used -func (o *TestLocationConfigParamsBodyPMMClientConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *TestLocationConfigParamsBodyPMMClientConfig) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *TestLocationConfigParamsBodyPMMClientConfig) UnmarshalBinary(b []byte) error { - var res TestLocationConfigParamsBodyPMMClientConfig - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} - -/* -TestLocationConfigParamsBodyPMMServerConfig PMMServerLocationConfig represents file system config inside pmm-server. -swagger:model TestLocationConfigParamsBodyPMMServerConfig +TestLocationConfigParamsBodyFilesystemConfig FilesystemLocationConfig represents file system location config. +swagger:model TestLocationConfigParamsBodyFilesystemConfig */ -type TestLocationConfigParamsBodyPMMServerConfig struct { +type TestLocationConfigParamsBodyFilesystemConfig struct { // path Path string `json:"path,omitempty"` } -// Validate validates this test location config params body PMM server config -func (o *TestLocationConfigParamsBodyPMMServerConfig) Validate(formats strfmt.Registry) error { +// Validate validates this test location config params body filesystem config +func (o *TestLocationConfigParamsBodyFilesystemConfig) Validate(formats strfmt.Registry) error { return nil } -// ContextValidate validates this test location config params body PMM server config based on context it is used -func (o *TestLocationConfigParamsBodyPMMServerConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { +// ContextValidate validates this test location config params body filesystem config based on context it is used +func (o *TestLocationConfigParamsBodyFilesystemConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { return nil } // MarshalBinary interface implementation -func (o *TestLocationConfigParamsBodyPMMServerConfig) MarshalBinary() ([]byte, error) { +func (o *TestLocationConfigParamsBodyFilesystemConfig) MarshalBinary() ([]byte, error) { if o == nil { return nil, nil } @@ -501,8 +419,8 @@ func (o *TestLocationConfigParamsBodyPMMServerConfig) MarshalBinary() ([]byte, e } // UnmarshalBinary interface implementation -func (o *TestLocationConfigParamsBodyPMMServerConfig) UnmarshalBinary(b []byte) error { - var res TestLocationConfigParamsBodyPMMServerConfig +func (o *TestLocationConfigParamsBodyFilesystemConfig) UnmarshalBinary(b []byte) error { + var res TestLocationConfigParamsBodyFilesystemConfig if err := swag.ReadJSON(b, &res); err != nil { return err } diff --git a/api/managementpb/backup/locations.pb.go b/api/managementpb/backup/locations.pb.go index 1acd5309f7..5e01d3c555 100644 --- a/api/managementpb/backup/locations.pb.go +++ b/api/managementpb/backup/locations.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/locations.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -23,8 +23,8 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// PMMServerLocationConfig represents file system config inside pmm-server. -type PMMServerLocationConfig struct { +// FilesystemLocationConfig represents file system location config. +type FilesystemLocationConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -32,8 +32,8 @@ type PMMServerLocationConfig struct { Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` } -func (x *PMMServerLocationConfig) Reset() { - *x = PMMServerLocationConfig{} +func (x *FilesystemLocationConfig) Reset() { + *x = FilesystemLocationConfig{} if protoimpl.UnsafeEnabled { mi := &file_managementpb_backup_locations_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -41,13 +41,13 @@ func (x *PMMServerLocationConfig) Reset() { } } -func (x *PMMServerLocationConfig) String() string { +func (x *FilesystemLocationConfig) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PMMServerLocationConfig) ProtoMessage() {} +func (*FilesystemLocationConfig) ProtoMessage() {} -func (x *PMMServerLocationConfig) ProtoReflect() protoreflect.Message { +func (x *FilesystemLocationConfig) ProtoReflect() protoreflect.Message { mi := &file_managementpb_backup_locations_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -59,60 +59,12 @@ func (x *PMMServerLocationConfig) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PMMServerLocationConfig.ProtoReflect.Descriptor instead. -func (*PMMServerLocationConfig) Descriptor() ([]byte, []int) { +// Deprecated: Use FilesystemLocationConfig.ProtoReflect.Descriptor instead. +func (*FilesystemLocationConfig) Descriptor() ([]byte, []int) { return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{0} } -func (x *PMMServerLocationConfig) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -// PMMClientLocationConfig represents file system config inside pmm-client. -type PMMClientLocationConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -func (x *PMMClientLocationConfig) Reset() { - *x = PMMClientLocationConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PMMClientLocationConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PMMClientLocationConfig) ProtoMessage() {} - -func (x *PMMClientLocationConfig) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PMMClientLocationConfig.ProtoReflect.Descriptor instead. -func (*PMMClientLocationConfig) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{1} -} - -func (x *PMMClientLocationConfig) GetPath() string { +func (x *FilesystemLocationConfig) GetPath() string { if x != nil { return x.Path } @@ -134,7 +86,7 @@ type S3LocationConfig struct { func (x *S3LocationConfig) Reset() { *x = S3LocationConfig{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[2] + mi := &file_managementpb_backup_locations_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -147,7 +99,7 @@ func (x *S3LocationConfig) String() string { func (*S3LocationConfig) ProtoMessage() {} func (x *S3LocationConfig) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[2] + mi := &file_managementpb_backup_locations_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -160,7 +112,7 @@ func (x *S3LocationConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use S3LocationConfig.ProtoReflect.Descriptor instead. func (*S3LocationConfig) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{2} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{1} } func (x *S3LocationConfig) GetEndpoint() string { @@ -205,8 +157,7 @@ type Location struct { Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Types that are assignable to Config: // - // *Location_PmmClientConfig - // *Location_PmmServerConfig + // *Location_FilesystemConfig // *Location_S3Config Config isLocation_Config `protobuf_oneof:"config"` } @@ -214,7 +165,7 @@ type Location struct { func (x *Location) Reset() { *x = Location{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[3] + mi := &file_managementpb_backup_locations_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -227,7 +178,7 @@ func (x *Location) String() string { func (*Location) ProtoMessage() {} func (x *Location) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[3] + mi := &file_managementpb_backup_locations_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -240,7 +191,7 @@ func (x *Location) ProtoReflect() protoreflect.Message { // Deprecated: Use Location.ProtoReflect.Descriptor instead. func (*Location) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{3} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{2} } func (x *Location) GetLocationId() string { @@ -271,17 +222,9 @@ func (m *Location) GetConfig() isLocation_Config { return nil } -func (x *Location) GetPmmClientConfig() *PMMClientLocationConfig { - if x, ok := x.GetConfig().(*Location_PmmClientConfig); ok { - return x.PmmClientConfig - } - return nil -} - -// Deprecated: Do not use. -func (x *Location) GetPmmServerConfig() *PMMServerLocationConfig { - if x, ok := x.GetConfig().(*Location_PmmServerConfig); ok { - return x.PmmServerConfig +func (x *Location) GetFilesystemConfig() *FilesystemLocationConfig { + if x, ok := x.GetConfig().(*Location_FilesystemConfig); ok { + return x.FilesystemConfig } return nil } @@ -297,22 +240,15 @@ type isLocation_Config interface { isLocation_Config() } -type Location_PmmClientConfig struct { - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,4,opt,name=pmm_client_config,json=pmmClientConfig,proto3,oneof"` -} - -type Location_PmmServerConfig struct { - // Deprecated: Do not use. - PmmServerConfig *PMMServerLocationConfig `protobuf:"bytes,5,opt,name=pmm_server_config,json=pmmServerConfig,proto3,oneof"` +type Location_FilesystemConfig struct { + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,4,opt,name=filesystem_config,json=filesystemConfig,proto3,oneof"` } type Location_S3Config struct { - S3Config *S3LocationConfig `protobuf:"bytes,6,opt,name=s3_config,json=s3Config,proto3,oneof"` + S3Config *S3LocationConfig `protobuf:"bytes,5,opt,name=s3_config,json=s3Config,proto3,oneof"` } -func (*Location_PmmClientConfig) isLocation_Config() {} - -func (*Location_PmmServerConfig) isLocation_Config() {} +func (*Location_FilesystemConfig) isLocation_Config() {} func (*Location_S3Config) isLocation_Config() {} @@ -325,7 +261,7 @@ type ListLocationsRequest struct { func (x *ListLocationsRequest) Reset() { *x = ListLocationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[4] + mi := &file_managementpb_backup_locations_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -338,7 +274,7 @@ func (x *ListLocationsRequest) String() string { func (*ListLocationsRequest) ProtoMessage() {} func (x *ListLocationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[4] + mi := &file_managementpb_backup_locations_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -351,7 +287,7 @@ func (x *ListLocationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLocationsRequest.ProtoReflect.Descriptor instead. func (*ListLocationsRequest) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{4} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{3} } type ListLocationsResponse struct { @@ -365,7 +301,7 @@ type ListLocationsResponse struct { func (x *ListLocationsResponse) Reset() { *x = ListLocationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[5] + mi := &file_managementpb_backup_locations_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -378,7 +314,7 @@ func (x *ListLocationsResponse) String() string { func (*ListLocationsResponse) ProtoMessage() {} func (x *ListLocationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[5] + mi := &file_managementpb_backup_locations_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -391,7 +327,7 @@ func (x *ListLocationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLocationsResponse.ProtoReflect.Descriptor instead. func (*ListLocationsResponse) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{5} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{4} } func (x *ListLocationsResponse) GetLocations() []*Location { @@ -409,20 +345,16 @@ type AddLocationRequest struct { // Location name Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // PMM-client file system configuration. Exactly one config should be set. - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,3,opt,name=pmm_client_config,json=pmmClientConfig,proto3" json:"pmm_client_config,omitempty"` - // PMM-server file system configuration. Exactly one config should be set. - // - // Deprecated: Do not use. - PmmServerConfig *PMMServerLocationConfig `protobuf:"bytes,4,opt,name=pmm_server_config,json=pmmServerConfig,proto3" json:"pmm_server_config,omitempty"` + // Filesystem location configuration. Exactly one config should be set. + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,3,opt,name=filesystem_config,json=filesystemConfig,proto3" json:"filesystem_config,omitempty"` // S3 Bucket configuration. Exactly one config should be set. - S3Config *S3LocationConfig `protobuf:"bytes,5,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` + S3Config *S3LocationConfig `protobuf:"bytes,4,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` } func (x *AddLocationRequest) Reset() { *x = AddLocationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[6] + mi := &file_managementpb_backup_locations_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -435,7 +367,7 @@ func (x *AddLocationRequest) String() string { func (*AddLocationRequest) ProtoMessage() {} func (x *AddLocationRequest) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[6] + mi := &file_managementpb_backup_locations_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -448,7 +380,7 @@ func (x *AddLocationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddLocationRequest.ProtoReflect.Descriptor instead. func (*AddLocationRequest) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{6} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{5} } func (x *AddLocationRequest) GetName() string { @@ -465,17 +397,9 @@ func (x *AddLocationRequest) GetDescription() string { return "" } -func (x *AddLocationRequest) GetPmmClientConfig() *PMMClientLocationConfig { - if x != nil { - return x.PmmClientConfig - } - return nil -} - -// Deprecated: Do not use. -func (x *AddLocationRequest) GetPmmServerConfig() *PMMServerLocationConfig { +func (x *AddLocationRequest) GetFilesystemConfig() *FilesystemLocationConfig { if x != nil { - return x.PmmServerConfig + return x.FilesystemConfig } return nil } @@ -499,7 +423,7 @@ type AddLocationResponse struct { func (x *AddLocationResponse) Reset() { *x = AddLocationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[7] + mi := &file_managementpb_backup_locations_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -512,7 +436,7 @@ func (x *AddLocationResponse) String() string { func (*AddLocationResponse) ProtoMessage() {} func (x *AddLocationResponse) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[7] + mi := &file_managementpb_backup_locations_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -525,7 +449,7 @@ func (x *AddLocationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddLocationResponse.ProtoReflect.Descriptor instead. func (*AddLocationResponse) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{7} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{6} } func (x *AddLocationResponse) GetLocationId() string { @@ -545,20 +469,16 @@ type ChangeLocationRequest struct { // Location name Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - // PMM-client file system configuration. Exactly one config should be set. - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,4,opt,name=pmm_client_config,json=pmmClientConfig,proto3" json:"pmm_client_config,omitempty"` - // PMM-server file system configuration. Exactly one config should be set. - // - // Deprecated: Do not use. - PmmServerConfig *PMMServerLocationConfig `protobuf:"bytes,5,opt,name=pmm_server_config,json=pmmServerConfig,proto3" json:"pmm_server_config,omitempty"` + // Filesystem location configuration. Exactly one config should be set. + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,4,opt,name=filesystem_config,json=filesystemConfig,proto3" json:"filesystem_config,omitempty"` // S3 Bucket configuration. Exactly one config should be set. - S3Config *S3LocationConfig `protobuf:"bytes,6,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` + S3Config *S3LocationConfig `protobuf:"bytes,5,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` } func (x *ChangeLocationRequest) Reset() { *x = ChangeLocationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[8] + mi := &file_managementpb_backup_locations_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -571,7 +491,7 @@ func (x *ChangeLocationRequest) String() string { func (*ChangeLocationRequest) ProtoMessage() {} func (x *ChangeLocationRequest) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[8] + mi := &file_managementpb_backup_locations_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -584,7 +504,7 @@ func (x *ChangeLocationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeLocationRequest.ProtoReflect.Descriptor instead. func (*ChangeLocationRequest) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{8} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{7} } func (x *ChangeLocationRequest) GetLocationId() string { @@ -608,17 +528,9 @@ func (x *ChangeLocationRequest) GetDescription() string { return "" } -func (x *ChangeLocationRequest) GetPmmClientConfig() *PMMClientLocationConfig { - if x != nil { - return x.PmmClientConfig - } - return nil -} - -// Deprecated: Do not use. -func (x *ChangeLocationRequest) GetPmmServerConfig() *PMMServerLocationConfig { +func (x *ChangeLocationRequest) GetFilesystemConfig() *FilesystemLocationConfig { if x != nil { - return x.PmmServerConfig + return x.FilesystemConfig } return nil } @@ -639,7 +551,7 @@ type ChangeLocationResponse struct { func (x *ChangeLocationResponse) Reset() { *x = ChangeLocationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[9] + mi := &file_managementpb_backup_locations_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -652,7 +564,7 @@ func (x *ChangeLocationResponse) String() string { func (*ChangeLocationResponse) ProtoMessage() {} func (x *ChangeLocationResponse) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[9] + mi := &file_managementpb_backup_locations_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -665,7 +577,7 @@ func (x *ChangeLocationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeLocationResponse.ProtoReflect.Descriptor instead. func (*ChangeLocationResponse) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{9} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{8} } type RemoveLocationRequest struct { @@ -682,7 +594,7 @@ type RemoveLocationRequest struct { func (x *RemoveLocationRequest) Reset() { *x = RemoveLocationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[10] + mi := &file_managementpb_backup_locations_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -695,7 +607,7 @@ func (x *RemoveLocationRequest) String() string { func (*RemoveLocationRequest) ProtoMessage() {} func (x *RemoveLocationRequest) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[10] + mi := &file_managementpb_backup_locations_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -708,7 +620,7 @@ func (x *RemoveLocationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveLocationRequest.ProtoReflect.Descriptor instead. func (*RemoveLocationRequest) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{10} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{9} } func (x *RemoveLocationRequest) GetLocationId() string { @@ -734,7 +646,7 @@ type RemoveLocationResponse struct { func (x *RemoveLocationResponse) Reset() { *x = RemoveLocationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[11] + mi := &file_managementpb_backup_locations_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -747,7 +659,7 @@ func (x *RemoveLocationResponse) String() string { func (*RemoveLocationResponse) ProtoMessage() {} func (x *RemoveLocationResponse) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[11] + mi := &file_managementpb_backup_locations_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -760,7 +672,7 @@ func (x *RemoveLocationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveLocationResponse.ProtoReflect.Descriptor instead. func (*RemoveLocationResponse) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{11} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{10} } type TestLocationConfigRequest struct { @@ -768,20 +680,16 @@ type TestLocationConfigRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // PMM-client file system configuration. Exactly one config should be set. - PmmClientConfig *PMMClientLocationConfig `protobuf:"bytes,1,opt,name=pmm_client_config,json=pmmClientConfig,proto3" json:"pmm_client_config,omitempty"` - // PMM-server file system configuration. Exactly one config should be set. - // - // Deprecated: Do not use. - PmmServerConfig *PMMServerLocationConfig `protobuf:"bytes,2,opt,name=pmm_server_config,json=pmmServerConfig,proto3" json:"pmm_server_config,omitempty"` + // Filesystem location configuration. Exactly one config should be set. + FilesystemConfig *FilesystemLocationConfig `protobuf:"bytes,1,opt,name=filesystem_config,json=filesystemConfig,proto3" json:"filesystem_config,omitempty"` // S3 Bucket configuration. Exactly one config should be set. - S3Config *S3LocationConfig `protobuf:"bytes,3,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` + S3Config *S3LocationConfig `protobuf:"bytes,2,opt,name=s3_config,json=s3Config,proto3" json:"s3_config,omitempty"` } func (x *TestLocationConfigRequest) Reset() { *x = TestLocationConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[12] + mi := &file_managementpb_backup_locations_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -794,7 +702,7 @@ func (x *TestLocationConfigRequest) String() string { func (*TestLocationConfigRequest) ProtoMessage() {} func (x *TestLocationConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[12] + mi := &file_managementpb_backup_locations_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -807,20 +715,12 @@ func (x *TestLocationConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TestLocationConfigRequest.ProtoReflect.Descriptor instead. func (*TestLocationConfigRequest) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{12} -} - -func (x *TestLocationConfigRequest) GetPmmClientConfig() *PMMClientLocationConfig { - if x != nil { - return x.PmmClientConfig - } - return nil + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{11} } -// Deprecated: Do not use. -func (x *TestLocationConfigRequest) GetPmmServerConfig() *PMMServerLocationConfig { +func (x *TestLocationConfigRequest) GetFilesystemConfig() *FilesystemLocationConfig { if x != nil { - return x.PmmServerConfig + return x.FilesystemConfig } return nil } @@ -841,7 +741,7 @@ type TestLocationConfigResponse struct { func (x *TestLocationConfigResponse) Reset() { *x = TestLocationConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_managementpb_backup_locations_proto_msgTypes[13] + mi := &file_managementpb_backup_locations_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -854,7 +754,7 @@ func (x *TestLocationConfigResponse) String() string { func (*TestLocationConfigResponse) ProtoMessage() {} func (x *TestLocationConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_managementpb_backup_locations_proto_msgTypes[13] + mi := &file_managementpb_backup_locations_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -867,7 +767,7 @@ func (x *TestLocationConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TestLocationConfigResponse.ProtoReflect.Descriptor instead. func (*TestLocationConfigResponse) Descriptor() ([]byte, []int) { - return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{13} + return file_managementpb_backup_locations_proto_rawDescGZIP(), []int{12} } var File_managementpb_backup_locations_proto protoreflect.FileDescriptor @@ -875,192 +775,159 @@ var File_managementpb_backup_locations_proto protoreflect.FileDescriptor var file_managementpb_backup_locations_proto_rawDesc = []byte{ 0x0a, 0x23, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x17, 0x50, - 0x4d, 0x4d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x22, 0x35, 0x0a, 0x17, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, - 0x02, 0x58, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xad, 0x01, 0x0a, 0x10, 0x53, 0x33, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, - 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, - 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x12, 0x27, 0x0a, 0x0b, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x0a, 0x62, - 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x08, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, - 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x4d, 0x4d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x0f, - 0x70, 0x6d, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x3f, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x16, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xbf, 0x02, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x70, 0x6d, - 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, - 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x36, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xe3, 0x02, - 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, - 0x1f, 0x02, 0x58, 0x01, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, 0x11, 0x70, - 0x6d, 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, - 0x02, 0x18, 0x01, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x18, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, - 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, - 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x02, 0x0a, 0x19, 0x54, 0x65, 0x73, 0x74, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x11, 0x70, 0x6d, 0x6d, 0x5f, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x6d, - 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x4d, 0x4d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x0f, 0x70, 0x6d, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x32, 0xf3, 0x05, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x8d, - 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, + 0x1a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x18, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xad, + 0x01, 0x0a, 0x10, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x08, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, + 0x02, 0x58, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x25, + 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0b, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, + 0x58, 0x01, 0x52, 0x0a, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xfb, + 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x48, 0x00, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x16, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0xde, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x22, 0x36, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x15, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, + 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x18, + 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x50, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x38, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x33, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x1c, 0x0a, 0x1a, + 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc0, 0x05, 0x0a, 0x09, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, + 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x86, - 0x01, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x22, - 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x41, 0x64, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x7c, + 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x28, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x88, 0x01, 0x0a, + 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x26, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2b, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x92, 0x01, 0x0a, - 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x3a, 0x01, - 0x2a, 0x12, 0xa2, 0x01, 0x0a, 0x12, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, + 0x74, 0x1a, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, + 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x88, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x3a, 0x01, 0x2a, 0x42, 0xbb, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, 0x4c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, - 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, - 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x3a, + 0x01, 0x2a, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x2a, + 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x01, 0x2a, 0x42, 0x9d, 0x01, + 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x42, + 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, + 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, + 0xaa, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1076,54 +943,49 @@ func file_managementpb_backup_locations_proto_rawDescGZIP() []byte { } var ( - file_managementpb_backup_locations_proto_msgTypes = make([]protoimpl.MessageInfo, 14) + file_managementpb_backup_locations_proto_msgTypes = make([]protoimpl.MessageInfo, 13) file_managementpb_backup_locations_proto_goTypes = []interface{}{ - (*PMMServerLocationConfig)(nil), // 0: backup.v1beta1.PMMServerLocationConfig - (*PMMClientLocationConfig)(nil), // 1: backup.v1beta1.PMMClientLocationConfig - (*S3LocationConfig)(nil), // 2: backup.v1beta1.S3LocationConfig - (*Location)(nil), // 3: backup.v1beta1.Location - (*ListLocationsRequest)(nil), // 4: backup.v1beta1.ListLocationsRequest - (*ListLocationsResponse)(nil), // 5: backup.v1beta1.ListLocationsResponse - (*AddLocationRequest)(nil), // 6: backup.v1beta1.AddLocationRequest - (*AddLocationResponse)(nil), // 7: backup.v1beta1.AddLocationResponse - (*ChangeLocationRequest)(nil), // 8: backup.v1beta1.ChangeLocationRequest - (*ChangeLocationResponse)(nil), // 9: backup.v1beta1.ChangeLocationResponse - (*RemoveLocationRequest)(nil), // 10: backup.v1beta1.RemoveLocationRequest - (*RemoveLocationResponse)(nil), // 11: backup.v1beta1.RemoveLocationResponse - (*TestLocationConfigRequest)(nil), // 12: backup.v1beta1.TestLocationConfigRequest - (*TestLocationConfigResponse)(nil), // 13: backup.v1beta1.TestLocationConfigResponse + (*FilesystemLocationConfig)(nil), // 0: backup.v1.FilesystemLocationConfig + (*S3LocationConfig)(nil), // 1: backup.v1.S3LocationConfig + (*Location)(nil), // 2: backup.v1.Location + (*ListLocationsRequest)(nil), // 3: backup.v1.ListLocationsRequest + (*ListLocationsResponse)(nil), // 4: backup.v1.ListLocationsResponse + (*AddLocationRequest)(nil), // 5: backup.v1.AddLocationRequest + (*AddLocationResponse)(nil), // 6: backup.v1.AddLocationResponse + (*ChangeLocationRequest)(nil), // 7: backup.v1.ChangeLocationRequest + (*ChangeLocationResponse)(nil), // 8: backup.v1.ChangeLocationResponse + (*RemoveLocationRequest)(nil), // 9: backup.v1.RemoveLocationRequest + (*RemoveLocationResponse)(nil), // 10: backup.v1.RemoveLocationResponse + (*TestLocationConfigRequest)(nil), // 11: backup.v1.TestLocationConfigRequest + (*TestLocationConfigResponse)(nil), // 12: backup.v1.TestLocationConfigResponse } ) var file_managementpb_backup_locations_proto_depIdxs = []int32{ - 1, // 0: backup.v1beta1.Location.pmm_client_config:type_name -> backup.v1beta1.PMMClientLocationConfig - 0, // 1: backup.v1beta1.Location.pmm_server_config:type_name -> backup.v1beta1.PMMServerLocationConfig - 2, // 2: backup.v1beta1.Location.s3_config:type_name -> backup.v1beta1.S3LocationConfig - 3, // 3: backup.v1beta1.ListLocationsResponse.locations:type_name -> backup.v1beta1.Location - 1, // 4: backup.v1beta1.AddLocationRequest.pmm_client_config:type_name -> backup.v1beta1.PMMClientLocationConfig - 0, // 5: backup.v1beta1.AddLocationRequest.pmm_server_config:type_name -> backup.v1beta1.PMMServerLocationConfig - 2, // 6: backup.v1beta1.AddLocationRequest.s3_config:type_name -> backup.v1beta1.S3LocationConfig - 1, // 7: backup.v1beta1.ChangeLocationRequest.pmm_client_config:type_name -> backup.v1beta1.PMMClientLocationConfig - 0, // 8: backup.v1beta1.ChangeLocationRequest.pmm_server_config:type_name -> backup.v1beta1.PMMServerLocationConfig - 2, // 9: backup.v1beta1.ChangeLocationRequest.s3_config:type_name -> backup.v1beta1.S3LocationConfig - 1, // 10: backup.v1beta1.TestLocationConfigRequest.pmm_client_config:type_name -> backup.v1beta1.PMMClientLocationConfig - 0, // 11: backup.v1beta1.TestLocationConfigRequest.pmm_server_config:type_name -> backup.v1beta1.PMMServerLocationConfig - 2, // 12: backup.v1beta1.TestLocationConfigRequest.s3_config:type_name -> backup.v1beta1.S3LocationConfig - 4, // 13: backup.v1beta1.Locations.ListLocations:input_type -> backup.v1beta1.ListLocationsRequest - 6, // 14: backup.v1beta1.Locations.AddLocation:input_type -> backup.v1beta1.AddLocationRequest - 8, // 15: backup.v1beta1.Locations.ChangeLocation:input_type -> backup.v1beta1.ChangeLocationRequest - 10, // 16: backup.v1beta1.Locations.RemoveLocation:input_type -> backup.v1beta1.RemoveLocationRequest - 12, // 17: backup.v1beta1.Locations.TestLocationConfig:input_type -> backup.v1beta1.TestLocationConfigRequest - 5, // 18: backup.v1beta1.Locations.ListLocations:output_type -> backup.v1beta1.ListLocationsResponse - 7, // 19: backup.v1beta1.Locations.AddLocation:output_type -> backup.v1beta1.AddLocationResponse - 9, // 20: backup.v1beta1.Locations.ChangeLocation:output_type -> backup.v1beta1.ChangeLocationResponse - 11, // 21: backup.v1beta1.Locations.RemoveLocation:output_type -> backup.v1beta1.RemoveLocationResponse - 13, // 22: backup.v1beta1.Locations.TestLocationConfig:output_type -> backup.v1beta1.TestLocationConfigResponse - 18, // [18:23] is the sub-list for method output_type - 13, // [13:18] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 0, // 0: backup.v1.Location.filesystem_config:type_name -> backup.v1.FilesystemLocationConfig + 1, // 1: backup.v1.Location.s3_config:type_name -> backup.v1.S3LocationConfig + 2, // 2: backup.v1.ListLocationsResponse.locations:type_name -> backup.v1.Location + 0, // 3: backup.v1.AddLocationRequest.filesystem_config:type_name -> backup.v1.FilesystemLocationConfig + 1, // 4: backup.v1.AddLocationRequest.s3_config:type_name -> backup.v1.S3LocationConfig + 0, // 5: backup.v1.ChangeLocationRequest.filesystem_config:type_name -> backup.v1.FilesystemLocationConfig + 1, // 6: backup.v1.ChangeLocationRequest.s3_config:type_name -> backup.v1.S3LocationConfig + 0, // 7: backup.v1.TestLocationConfigRequest.filesystem_config:type_name -> backup.v1.FilesystemLocationConfig + 1, // 8: backup.v1.TestLocationConfigRequest.s3_config:type_name -> backup.v1.S3LocationConfig + 3, // 9: backup.v1.Locations.ListLocations:input_type -> backup.v1.ListLocationsRequest + 5, // 10: backup.v1.Locations.AddLocation:input_type -> backup.v1.AddLocationRequest + 7, // 11: backup.v1.Locations.ChangeLocation:input_type -> backup.v1.ChangeLocationRequest + 9, // 12: backup.v1.Locations.RemoveLocation:input_type -> backup.v1.RemoveLocationRequest + 11, // 13: backup.v1.Locations.TestLocationConfig:input_type -> backup.v1.TestLocationConfigRequest + 4, // 14: backup.v1.Locations.ListLocations:output_type -> backup.v1.ListLocationsResponse + 6, // 15: backup.v1.Locations.AddLocation:output_type -> backup.v1.AddLocationResponse + 8, // 16: backup.v1.Locations.ChangeLocation:output_type -> backup.v1.ChangeLocationResponse + 10, // 17: backup.v1.Locations.RemoveLocation:output_type -> backup.v1.RemoveLocationResponse + 12, // 18: backup.v1.Locations.TestLocationConfig:output_type -> backup.v1.TestLocationConfigResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_managementpb_backup_locations_proto_init() } @@ -1133,7 +995,7 @@ func file_managementpb_backup_locations_proto_init() { } if !protoimpl.UnsafeEnabled { file_managementpb_backup_locations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PMMServerLocationConfig); i { + switch v := v.(*FilesystemLocationConfig); i { case 0: return &v.state case 1: @@ -1145,18 +1007,6 @@ func file_managementpb_backup_locations_proto_init() { } } file_managementpb_backup_locations_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PMMClientLocationConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_managementpb_backup_locations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*S3LocationConfig); i { case 0: return &v.state @@ -1168,7 +1018,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Location); i { case 0: return &v.state @@ -1180,7 +1030,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListLocationsRequest); i { case 0: return &v.state @@ -1192,7 +1042,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListLocationsResponse); i { case 0: return &v.state @@ -1204,7 +1054,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AddLocationRequest); i { case 0: return &v.state @@ -1216,7 +1066,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AddLocationResponse); i { case 0: return &v.state @@ -1228,7 +1078,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeLocationRequest); i { case 0: return &v.state @@ -1240,7 +1090,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeLocationResponse); i { case 0: return &v.state @@ -1252,7 +1102,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveLocationRequest); i { case 0: return &v.state @@ -1264,7 +1114,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveLocationResponse); i { case 0: return &v.state @@ -1276,7 +1126,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TestLocationConfigRequest); i { case 0: return &v.state @@ -1288,7 +1138,7 @@ func file_managementpb_backup_locations_proto_init() { return nil } } - file_managementpb_backup_locations_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_managementpb_backup_locations_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TestLocationConfigResponse); i { case 0: return &v.state @@ -1301,9 +1151,8 @@ func file_managementpb_backup_locations_proto_init() { } } } - file_managementpb_backup_locations_proto_msgTypes[3].OneofWrappers = []interface{}{ - (*Location_PmmClientConfig)(nil), - (*Location_PmmServerConfig)(nil), + file_managementpb_backup_locations_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*Location_FilesystemConfig)(nil), (*Location_S3Config)(nil), } type x struct{} @@ -1312,7 +1161,7 @@ func file_managementpb_backup_locations_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_managementpb_backup_locations_proto_rawDesc, NumEnums: 0, - NumMessages: 14, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/api/managementpb/backup/locations.pb.gw.go b/api/managementpb/backup/locations.pb.gw.go index 1551fc8548..75eec019b6 100644 --- a/api/managementpb/backup/locations.pb.gw.go +++ b/api/managementpb/backup/locations.pb.gw.go @@ -2,11 +2,11 @@ // source: managementpb/backup/locations.proto /* -Package backupv1beta1 is a reverse proxy. +Package backupv1 is a reverse proxy. It translates gRPC into RESTful JSON APIs. */ -package backupv1beta1 +package backupv1 import ( "context" @@ -206,7 +206,7 @@ func RegisterLocationsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Locations/ListLocations", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/List")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Locations/ListLocations", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -230,7 +230,7 @@ func RegisterLocationsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Locations/AddLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Add")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Locations/AddLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Add")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -254,7 +254,7 @@ func RegisterLocationsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Locations/ChangeLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Change")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Locations/ChangeLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Change")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -278,7 +278,7 @@ func RegisterLocationsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Locations/RemoveLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Remove")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Locations/RemoveLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Remove")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -302,7 +302,7 @@ func RegisterLocationsHandlerServer(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.Locations/TestLocationConfig", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/TestConfig")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.Locations/TestLocationConfig", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/TestConfig")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -364,7 +364,7 @@ func RegisterLocationsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Locations/ListLocations", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/List")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Locations/ListLocations", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -385,7 +385,7 @@ func RegisterLocationsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Locations/AddLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Add")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Locations/AddLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Add")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -406,7 +406,7 @@ func RegisterLocationsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Locations/ChangeLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Change")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Locations/ChangeLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Change")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -427,7 +427,7 @@ func RegisterLocationsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Locations/RemoveLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Remove")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Locations/RemoveLocation", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/Remove")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -448,7 +448,7 @@ func RegisterLocationsHandlerClient(ctx context.Context, mux *runtime.ServeMux, inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.Locations/TestLocationConfig", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/TestConfig")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.Locations/TestLocationConfig", runtime.WithHTTPPathPattern("/v1/management/backup/Locations/TestConfig")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return diff --git a/api/managementpb/backup/locations.proto b/api/managementpb/backup/locations.proto index daedd951f4..d00daf3f82 100644 --- a/api/managementpb/backup/locations.proto +++ b/api/managementpb/backup/locations.proto @@ -1,23 +1,14 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; import "github.com/mwitkow/go-proto-validators/validator.proto"; import "google/api/annotations.proto"; -// PMMServerLocationConfig represents file system config inside pmm-server. -message PMMServerLocationConfig { - string path = 1 [ - (validator.field) = { - string_not_empty: true - } - ]; -} - -// PMMClientLocationConfig represents file system config inside pmm-client. -message PMMClientLocationConfig { +// FilesystemLocationConfig represents file system location config. +message FilesystemLocationConfig { string path = 1 [ (validator.field) = { string_not_empty: true @@ -58,9 +49,8 @@ message Location { // Short description string description = 3; oneof config { - PMMClientLocationConfig pmm_client_config = 4; - PMMServerLocationConfig pmm_server_config = 5 [deprecated = true]; - S3LocationConfig s3_config = 6; + FilesystemLocationConfig filesystem_config = 4; + S3LocationConfig s3_config = 5; } } @@ -78,12 +68,10 @@ message AddLocationRequest { } ]; string description = 2; - // PMM-client file system configuration. Exactly one config should be set. - PMMClientLocationConfig pmm_client_config = 3; - // PMM-server file system configuration. Exactly one config should be set. - PMMServerLocationConfig pmm_server_config = 4 [deprecated = true]; + // Filesystem location configuration. Exactly one config should be set. + FilesystemLocationConfig filesystem_config = 3; // S3 Bucket configuration. Exactly one config should be set. - S3LocationConfig s3_config = 5; + S3LocationConfig s3_config = 4; } message AddLocationResponse { @@ -101,12 +89,10 @@ message ChangeLocationRequest { // Location name string name = 2; string description = 3; - // PMM-client file system configuration. Exactly one config should be set. - PMMClientLocationConfig pmm_client_config = 4; - // PMM-server file system configuration. Exactly one config should be set. - PMMServerLocationConfig pmm_server_config = 5 [deprecated = true]; + // Filesystem location configuration. Exactly one config should be set. + FilesystemLocationConfig filesystem_config = 4; // S3 Bucket configuration. Exactly one config should be set. - S3LocationConfig s3_config = 6; + S3LocationConfig s3_config = 5; } message ChangeLocationResponse {} @@ -121,12 +107,10 @@ message RemoveLocationRequest { message RemoveLocationResponse {} message TestLocationConfigRequest { - // PMM-client file system configuration. Exactly one config should be set. - PMMClientLocationConfig pmm_client_config = 1; - // PMM-server file system configuration. Exactly one config should be set. - PMMServerLocationConfig pmm_server_config = 2 [deprecated = true]; + // Filesystem location configuration. Exactly one config should be set. + FilesystemLocationConfig filesystem_config = 1; // S3 Bucket configuration. Exactly one config should be set. - S3LocationConfig s3_config = 3; + S3LocationConfig s3_config = 2; } message TestLocationConfigResponse {} diff --git a/api/managementpb/backup/locations.validator.pb.go b/api/managementpb/backup/locations.validator.pb.go index 23252104e5..621e29fcb3 100644 --- a/api/managementpb/backup/locations.validator.pb.go +++ b/api/managementpb/backup/locations.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/locations.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" @@ -20,14 +20,7 @@ var ( _ = math.Inf ) -func (this *PMMServerLocationConfig) Validate() error { - if this.Path == "" { - return github_com_mwitkow_go_proto_validators.FieldError("Path", fmt.Errorf(`value '%v' must not be an empty string`, this.Path)) - } - return nil -} - -func (this *PMMClientLocationConfig) Validate() error { +func (this *FilesystemLocationConfig) Validate() error { if this.Path == "" { return github_com_mwitkow_go_proto_validators.FieldError("Path", fmt.Errorf(`value '%v' must not be an empty string`, this.Path)) } @@ -51,17 +44,10 @@ func (this *S3LocationConfig) Validate() error { } func (this *Location) Validate() error { - if oneOfNester, ok := this.GetConfig().(*Location_PmmClientConfig); ok { - if oneOfNester.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) - } - } - } - if oneOfNester, ok := this.GetConfig().(*Location_PmmServerConfig); ok { - if oneOfNester.PmmServerConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.PmmServerConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmServerConfig", err) + if oneOfNester, ok := this.GetConfig().(*Location_FilesystemConfig); ok { + if oneOfNester.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(oneOfNester.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } } @@ -94,14 +80,9 @@ func (this *AddLocationRequest) Validate() error { if this.Name == "" { return github_com_mwitkow_go_proto_validators.FieldError("Name", fmt.Errorf(`value '%v' must not be an empty string`, this.Name)) } - if this.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) - } - } - if this.PmmServerConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmServerConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmServerConfig", err) + if this.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } if this.S3Config != nil { @@ -120,14 +101,9 @@ func (this *ChangeLocationRequest) Validate() error { if this.LocationId == "" { return github_com_mwitkow_go_proto_validators.FieldError("LocationId", fmt.Errorf(`value '%v' must not be an empty string`, this.LocationId)) } - if this.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) - } - } - if this.PmmServerConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmServerConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmServerConfig", err) + if this.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } if this.S3Config != nil { @@ -151,14 +127,9 @@ func (this *RemoveLocationResponse) Validate() error { } func (this *TestLocationConfigRequest) Validate() error { - if this.PmmClientConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmClientConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmClientConfig", err) - } - } - if this.PmmServerConfig != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PmmServerConfig); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("PmmServerConfig", err) + if this.FilesystemConfig != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.FilesystemConfig); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("FilesystemConfig", err) } } if this.S3Config != nil { diff --git a/api/managementpb/backup/locations_grpc.pb.go b/api/managementpb/backup/locations_grpc.pb.go index 54c7ee33d8..1202d08527 100644 --- a/api/managementpb/backup/locations_grpc.pb.go +++ b/api/managementpb/backup/locations_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc (unknown) // source: managementpb/backup/locations.proto -package backupv1beta1 +package backupv1 import ( context "context" @@ -45,7 +45,7 @@ func NewLocationsClient(cc grpc.ClientConnInterface) LocationsClient { func (c *locationsClient) ListLocations(ctx context.Context, in *ListLocationsRequest, opts ...grpc.CallOption) (*ListLocationsResponse, error) { out := new(ListLocationsResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Locations/ListLocations", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Locations/ListLocations", in, out, opts...) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func (c *locationsClient) ListLocations(ctx context.Context, in *ListLocationsRe func (c *locationsClient) AddLocation(ctx context.Context, in *AddLocationRequest, opts ...grpc.CallOption) (*AddLocationResponse, error) { out := new(AddLocationResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Locations/AddLocation", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Locations/AddLocation", in, out, opts...) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func (c *locationsClient) AddLocation(ctx context.Context, in *AddLocationReques func (c *locationsClient) ChangeLocation(ctx context.Context, in *ChangeLocationRequest, opts ...grpc.CallOption) (*ChangeLocationResponse, error) { out := new(ChangeLocationResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Locations/ChangeLocation", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Locations/ChangeLocation", in, out, opts...) if err != nil { return nil, err } @@ -72,7 +72,7 @@ func (c *locationsClient) ChangeLocation(ctx context.Context, in *ChangeLocation func (c *locationsClient) RemoveLocation(ctx context.Context, in *RemoveLocationRequest, opts ...grpc.CallOption) (*RemoveLocationResponse, error) { out := new(RemoveLocationResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Locations/RemoveLocation", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Locations/RemoveLocation", in, out, opts...) if err != nil { return nil, err } @@ -81,7 +81,7 @@ func (c *locationsClient) RemoveLocation(ctx context.Context, in *RemoveLocation func (c *locationsClient) TestLocationConfig(ctx context.Context, in *TestLocationConfigRequest, opts ...grpc.CallOption) (*TestLocationConfigResponse, error) { out := new(TestLocationConfigResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.Locations/TestLocationConfig", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.Locations/TestLocationConfig", in, out, opts...) if err != nil { return nil, err } @@ -150,7 +150,7 @@ func _Locations_ListLocations_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Locations/ListLocations", + FullMethod: "/backup.v1.Locations/ListLocations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LocationsServer).ListLocations(ctx, req.(*ListLocationsRequest)) @@ -168,7 +168,7 @@ func _Locations_AddLocation_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Locations/AddLocation", + FullMethod: "/backup.v1.Locations/AddLocation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LocationsServer).AddLocation(ctx, req.(*AddLocationRequest)) @@ -186,7 +186,7 @@ func _Locations_ChangeLocation_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Locations/ChangeLocation", + FullMethod: "/backup.v1.Locations/ChangeLocation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LocationsServer).ChangeLocation(ctx, req.(*ChangeLocationRequest)) @@ -204,7 +204,7 @@ func _Locations_RemoveLocation_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Locations/RemoveLocation", + FullMethod: "/backup.v1.Locations/RemoveLocation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LocationsServer).RemoveLocation(ctx, req.(*RemoveLocationRequest)) @@ -222,7 +222,7 @@ func _Locations_TestLocationConfig_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.Locations/TestLocationConfig", + FullMethod: "/backup.v1.Locations/TestLocationConfig", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LocationsServer).TestLocationConfig(ctx, req.(*TestLocationConfigRequest)) @@ -234,7 +234,7 @@ func _Locations_TestLocationConfig_Handler(srv interface{}, ctx context.Context, // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Locations_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "backup.v1beta1.Locations", + ServiceName: "backup.v1.Locations", HandlerType: (*LocationsServer)(nil), Methods: []grpc.MethodDesc{ { diff --git a/api/managementpb/backup/restores.pb.go b/api/managementpb/backup/restores.pb.go index 70699f5ffa..afd47285f7 100644 --- a/api/managementpb/backup/restores.pb.go +++ b/api/managementpb/backup/restores.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: managementpb/backup/restores.proto -package backupv1beta1 +package backupv1 import ( reflect "reflect" @@ -99,9 +99,9 @@ type RestoreHistoryItem struct { // Service name. ServiceName string `protobuf:"bytes,8,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` // Backup data model. - DataModel DataModel `protobuf:"varint,9,opt,name=data_model,json=dataModel,proto3,enum=backup.v1beta1.DataModel" json:"data_model,omitempty"` + DataModel DataModel `protobuf:"varint,9,opt,name=data_model,json=dataModel,proto3,enum=backup.v1.DataModel" json:"data_model,omitempty"` // Restore status. - Status RestoreStatus `protobuf:"varint,10,opt,name=status,proto3,enum=backup.v1beta1.RestoreStatus" json:"status,omitempty"` + Status RestoreStatus `protobuf:"varint,10,opt,name=status,proto3,enum=backup.v1.RestoreStatus" json:"status,omitempty"` // Restore start time. StartedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"` // Restore finish time. @@ -314,84 +314,81 @@ var File_managementpb_backup_restores_proto protoreflect.FileDescriptor var file_managementpb_backup_restores_proto_rawDesc = []byte{ 0x0a, 0x22, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, - 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x03, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, - 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x38, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, - 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, 0x0a, 0x0b, - 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x66, - 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x74, 0x22, 0x1b, 0x0a, 0x19, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2a, 0x81, - 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, - 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, - 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, - 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, - 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x54, - 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x10, 0x03, 0x32, 0xb4, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, - 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0xa1, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x2e, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x1a, + 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xe7, 0x03, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, + 0x64, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x14, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x18, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, 0x0a, + 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, + 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x74, 0x22, 0x1b, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22, 0x29, 0x2f, 0x76, 0x31, - 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x2f, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, - 0x79, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x42, 0xba, 0x01, 0x0a, 0x12, 0x63, 0x6f, - 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x42, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, - 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, - 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x51, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, + 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2a, 0x81, 0x01, 0x0a, 0x0d, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, + 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x54, + 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, + 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x45, 0x53, 0x54, + 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, 0xaa, + 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x97, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22, 0x29, 0x2f, + 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x01, 0x2a, 0x42, 0x9c, 0x01, 0x0a, 0x0d, + 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, + 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x42, 0x58, 0x58, 0xaa, 0x02, 0x09, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -410,23 +407,23 @@ var ( file_managementpb_backup_restores_proto_enumTypes = make([]protoimpl.EnumInfo, 1) file_managementpb_backup_restores_proto_msgTypes = make([]protoimpl.MessageInfo, 3) file_managementpb_backup_restores_proto_goTypes = []interface{}{ - (RestoreStatus)(0), // 0: backup.v1beta1.RestoreStatus - (*RestoreHistoryItem)(nil), // 1: backup.v1beta1.RestoreHistoryItem - (*ListRestoreHistoryRequest)(nil), // 2: backup.v1beta1.ListRestoreHistoryRequest - (*ListRestoreHistoryResponse)(nil), // 3: backup.v1beta1.ListRestoreHistoryResponse - (DataModel)(0), // 4: backup.v1beta1.DataModel + (RestoreStatus)(0), // 0: backup.v1.RestoreStatus + (*RestoreHistoryItem)(nil), // 1: backup.v1.RestoreHistoryItem + (*ListRestoreHistoryRequest)(nil), // 2: backup.v1.ListRestoreHistoryRequest + (*ListRestoreHistoryResponse)(nil), // 3: backup.v1.ListRestoreHistoryResponse + (DataModel)(0), // 4: backup.v1.DataModel (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp } ) var file_managementpb_backup_restores_proto_depIdxs = []int32{ - 4, // 0: backup.v1beta1.RestoreHistoryItem.data_model:type_name -> backup.v1beta1.DataModel - 0, // 1: backup.v1beta1.RestoreHistoryItem.status:type_name -> backup.v1beta1.RestoreStatus - 5, // 2: backup.v1beta1.RestoreHistoryItem.started_at:type_name -> google.protobuf.Timestamp - 5, // 3: backup.v1beta1.RestoreHistoryItem.finished_at:type_name -> google.protobuf.Timestamp - 1, // 4: backup.v1beta1.ListRestoreHistoryResponse.items:type_name -> backup.v1beta1.RestoreHistoryItem - 2, // 5: backup.v1beta1.RestoreHistory.ListRestoreHistory:input_type -> backup.v1beta1.ListRestoreHistoryRequest - 3, // 6: backup.v1beta1.RestoreHistory.ListRestoreHistory:output_type -> backup.v1beta1.ListRestoreHistoryResponse + 4, // 0: backup.v1.RestoreHistoryItem.data_model:type_name -> backup.v1.DataModel + 0, // 1: backup.v1.RestoreHistoryItem.status:type_name -> backup.v1.RestoreStatus + 5, // 2: backup.v1.RestoreHistoryItem.started_at:type_name -> google.protobuf.Timestamp + 5, // 3: backup.v1.RestoreHistoryItem.finished_at:type_name -> google.protobuf.Timestamp + 1, // 4: backup.v1.ListRestoreHistoryResponse.items:type_name -> backup.v1.RestoreHistoryItem + 2, // 5: backup.v1.RestoreHistory.ListRestoreHistory:input_type -> backup.v1.ListRestoreHistoryRequest + 3, // 6: backup.v1.RestoreHistory.ListRestoreHistory:output_type -> backup.v1.ListRestoreHistoryResponse 6, // [6:7] is the sub-list for method output_type 5, // [5:6] is the sub-list for method input_type 5, // [5:5] is the sub-list for extension type_name diff --git a/api/managementpb/backup/restores.pb.gw.go b/api/managementpb/backup/restores.pb.gw.go index c564f3251b..0c2265442b 100644 --- a/api/managementpb/backup/restores.pb.gw.go +++ b/api/managementpb/backup/restores.pb.gw.go @@ -2,11 +2,11 @@ // source: managementpb/backup/restores.proto /* -Package backupv1beta1 is a reverse proxy. +Package backupv1 is a reverse proxy. It translates gRPC into RESTful JSON APIs. */ -package backupv1beta1 +package backupv1 import ( "context" @@ -78,7 +78,7 @@ func RegisterRestoreHistoryHandlerServer(ctx context.Context, mux *runtime.Serve inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1beta1.RestoreHistory/ListRestoreHistory", runtime.WithHTTPPathPattern("/v1/management/backup/RestoreHistory/List")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/backup.v1.RestoreHistory/ListRestoreHistory", runtime.WithHTTPPathPattern("/v1/management/backup/RestoreHistory/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -140,7 +140,7 @@ func RegisterRestoreHistoryHandlerClient(ctx context.Context, mux *runtime.Serve inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1beta1.RestoreHistory/ListRestoreHistory", runtime.WithHTTPPathPattern("/v1/management/backup/RestoreHistory/List")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/backup.v1.RestoreHistory/ListRestoreHistory", runtime.WithHTTPPathPattern("/v1/management/backup/RestoreHistory/List")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return diff --git a/api/managementpb/backup/restores.proto b/api/managementpb/backup/restores.proto index 5526462ef1..abf52da594 100644 --- a/api/managementpb/backup/restores.proto +++ b/api/managementpb/backup/restores.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package backup.v1beta1; +package backup.v1; -option go_package = "api/managementpb/backup;backupv1beta1"; +option go_package = "api/managementpb/backup;backupv1"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/managementpb/backup/restores.validator.pb.go b/api/managementpb/backup/restores.validator.pb.go index e9080d17b4..878dbf322b 100644 --- a/api/managementpb/backup/restores.validator.pb.go +++ b/api/managementpb/backup/restores.validator.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: managementpb/backup/restores.proto -package backupv1beta1 +package backupv1 import ( fmt "fmt" diff --git a/api/managementpb/backup/restores_grpc.pb.go b/api/managementpb/backup/restores_grpc.pb.go index 0b9ff8c078..e89355fff9 100644 --- a/api/managementpb/backup/restores_grpc.pb.go +++ b/api/managementpb/backup/restores_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc (unknown) // source: managementpb/backup/restores.proto -package backupv1beta1 +package backupv1 import ( context "context" @@ -37,7 +37,7 @@ func NewRestoreHistoryClient(cc grpc.ClientConnInterface) RestoreHistoryClient { func (c *restoreHistoryClient) ListRestoreHistory(ctx context.Context, in *ListRestoreHistoryRequest, opts ...grpc.CallOption) (*ListRestoreHistoryResponse, error) { out := new(ListRestoreHistoryResponse) - err := c.cc.Invoke(ctx, "/backup.v1beta1.RestoreHistory/ListRestoreHistory", in, out, opts...) + err := c.cc.Invoke(ctx, "/backup.v1.RestoreHistory/ListRestoreHistory", in, out, opts...) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func _RestoreHistory_ListRestoreHistory_Handler(srv interface{}, ctx context.Con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/backup.v1beta1.RestoreHistory/ListRestoreHistory", + FullMethod: "/backup.v1.RestoreHistory/ListRestoreHistory", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RestoreHistoryServer).ListRestoreHistory(ctx, req.(*ListRestoreHistoryRequest)) @@ -94,7 +94,7 @@ func _RestoreHistory_ListRestoreHistory_Handler(srv interface{}, ctx context.Con // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var RestoreHistory_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "backup.v1beta1.RestoreHistory", + ServiceName: "backup.v1.RestoreHistory", HandlerType: (*RestoreHistoryServer)(nil), Methods: []grpc.MethodDesc{ { diff --git a/api/swagger/swagger-dev-only.json b/api/swagger/swagger-dev-only.json index e62a4dd408..3ae3b9b180 100644 --- a/api/swagger/swagger-dev-only.json +++ b/api/swagger/swagger-dev-only.json @@ -7379,6 +7379,94 @@ } } }, + "/v1/management/backup/Artifacts/ListPITRTimeranges": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location", + "operationId": "ListPitrTimeranges", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Artifact ID represents artifact whose location has PITR timeranges to be retrieved.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "timeranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "start_timestamp": { + "description": "start_timestamp is the time of the first event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 0 + }, + "end_timestamp": { + "description": "end_timestamp is the time of the last event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 1 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/management/backup/Backups/ChangeScheduled": { "post": { "tags": [ @@ -8046,6 +8134,12 @@ "description": "Artifact id to restore.", "type": "string", "x-order": 1 + }, + "pitr_timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp of PITR to restore to", + "x-order": 2 } } } @@ -8375,8 +8469,8 @@ "type": "string", "x-order": 1 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -8386,17 +8480,6 @@ }, "x-order": 2 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 3 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -8418,7 +8501,7 @@ "x-order": 3 } }, - "x-order": 4 + "x-order": 3 } } } @@ -8501,8 +8584,8 @@ "type": "string", "x-order": 2 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -8512,17 +8595,6 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -8544,7 +8616,7 @@ "x-order": 3 } }, - "x-order": 5 + "x-order": 4 } } } @@ -8635,8 +8707,8 @@ "title": "Short description", "x-order": 2 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -8646,17 +8718,6 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -8678,7 +8739,7 @@ "x-order": 3 } }, - "x-order": 5 + "x-order": 4 } } }, @@ -8806,8 +8867,8 @@ "schema": { "type": "object", "properties": { - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -8817,17 +8878,6 @@ }, "x-order": 0 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 1 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -8849,7 +8899,7 @@ "x-order": 3 } }, - "x-order": 2 + "x-order": 1 } } } diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index ef34cb4187..508f06e970 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -27855,6 +27855,94 @@ } } }, + "/v1/management/backup/Artifacts/ListPITRTimeranges": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location", + "operationId": "ListPitrTimeranges", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Artifact ID represents artifact whose location has PITR timeranges to be retrieved.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "timeranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "start_timestamp": { + "description": "start_timestamp is the time of the first event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 0 + }, + "end_timestamp": { + "description": "end_timestamp is the time of the last event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 1 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/management/backup/Backups/ChangeScheduled": { "post": { "tags": [ @@ -28522,6 +28610,12 @@ "description": "Artifact id to restore.", "type": "string", "x-order": 1 + }, + "pitr_timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp of PITR to restore to", + "x-order": 2 } } } @@ -28851,8 +28945,8 @@ "type": "string", "x-order": 1 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -28862,17 +28956,6 @@ }, "x-order": 2 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 3 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -28894,7 +28977,7 @@ "x-order": 3 } }, - "x-order": 4 + "x-order": 3 } } } @@ -28977,8 +29060,8 @@ "type": "string", "x-order": 2 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -28988,17 +29071,6 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -29020,7 +29092,7 @@ "x-order": 3 } }, - "x-order": 5 + "x-order": 4 } } } @@ -29111,8 +29183,8 @@ "title": "Short description", "x-order": 2 }, - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -29122,17 +29194,6 @@ }, "x-order": 3 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 4 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -29154,7 +29215,7 @@ "x-order": 3 } }, - "x-order": 5 + "x-order": 4 } } }, @@ -29282,8 +29343,8 @@ "schema": { "type": "object", "properties": { - "pmm_client_config": { - "description": "PMMClientLocationConfig represents file system config inside pmm-client.", + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", "type": "object", "properties": { "path": { @@ -29293,17 +29354,6 @@ }, "x-order": 0 }, - "pmm_server_config": { - "description": "PMMServerLocationConfig represents file system config inside pmm-server.", - "type": "object", - "properties": { - "path": { - "type": "string", - "x-order": 0 - } - }, - "x-order": 1 - }, "s3_config": { "description": "S3LocationConfig represents S3 bucket configuration.", "type": "object", @@ -29325,7 +29375,7 @@ "x-order": 3 } }, - "x-order": 2 + "x-order": 1 } } } diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 46252169d7..5002f16c96 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -20491,6 +20491,2632 @@ } } }, + "/v1/management/alerting/Rules/Create": { + "post": { + "tags": [ + "Alerting" + ], + "summary": "CreateRule creates alerting rule from the given template.", + "operationId": "CreateRule", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "template_name": { + "description": "Template name.", + "type": "string", + "x-order": 0 + }, + "name": { + "description": "Rule name.", + "type": "string", + "x-order": 1 + }, + "group": { + "description": "Rule group name.", + "type": "string", + "x-order": 2 + }, + "folder_uid": { + "description": "Folder UID.", + "type": "string", + "x-order": 3 + }, + "params": { + "description": "Rule parameters. All template parameters should be set.", + "type": "array", + "items": { + "description": "ParamValue represents a single rule parameter value.", + "type": "object", + "properties": { + "name": { + "description": "Machine-readable name (ID) that is used in expression.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "ParamType represents template parameter type.", + "type": "string", + "default": "PARAM_TYPE_INVALID", + "enum": [ + "PARAM_TYPE_INVALID", + "BOOL", + "FLOAT", + "STRING" + ], + "x-order": 1 + }, + "bool": { + "description": "Bool value.", + "type": "boolean", + "x-order": 2 + }, + "float": { + "description": "Float value.", + "type": "number", + "format": "double", + "x-order": 3 + }, + "string": { + "description": "String value.", + "type": "string", + "x-order": 4 + } + } + }, + "x-order": 4 + }, + "for": { + "description": "Rule duration. Should be set.", + "type": "string", + "x-order": 5 + }, + "severity": { + "description": "Severity represents severity level of the check result or alert.", + "type": "string", + "default": "SEVERITY_INVALID", + "enum": [ + "SEVERITY_INVALID", + "SEVERITY_EMERGENCY", + "SEVERITY_ALERT", + "SEVERITY_CRITICAL", + "SEVERITY_ERROR", + "SEVERITY_WARNING", + "SEVERITY_NOTICE", + "SEVERITY_INFO", + "SEVERITY_DEBUG" + ], + "x-order": 6 + }, + "custom_labels": { + "description": "All custom labels to add or remove (with empty values) to default labels from template.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 7 + }, + "filters": { + "description": "Filters.", + "type": "array", + "items": { + "description": "Filter represents a single filter condition.", + "type": "object", + "properties": { + "type": { + "description": "FilterType represents filter matching type.", + "type": "string", + "default": "FILTER_TYPE_INVALID", + "enum": [ + "FILTER_TYPE_INVALID", + "MATCH", + "MISMATCH" + ], + "x-order": 0 + }, + "label": { + "type": "string", + "x-order": 1 + }, + "regexp": { + "type": "string", + "x-order": 2 + } + } + }, + "x-order": 8 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/alerting/Templates/Create": { + "post": { + "tags": [ + "Alerting" + ], + "summary": "CreateTemplate creates a new template.", + "operationId": "CreateTemplate", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "yaml": { + "description": "YAML (or JSON) template file content.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/alerting/Templates/Delete": { + "post": { + "tags": [ + "Alerting" + ], + "summary": "DeleteTemplate deletes existing, previously created via API.", + "operationId": "DeleteTemplate", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/alerting/Templates/List": { + "post": { + "tags": [ + "Alerting" + ], + "summary": "ListTemplates returns a list of all collected alert rule templates.", + "operationId": "ListTemplates", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "reload": { + "description": "If true, template files will be re-read from disk.", + "type": "boolean", + "x-order": 0 + }, + "page_params": { + "description": "PageParams represents page request parameters for pagination.", + "type": "object", + "properties": { + "page_size": { + "description": "Maximum number of results per page.", + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "index": { + "description": "Index of the requested page, starts from 0.", + "type": "integer", + "format": "int32", + "x-order": 1 + } + }, + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "templates": { + "type": "array", + "items": { + "description": "Template represents Alert Template that is used to create Alert Rule.", + "type": "object", + "properties": { + "name": { + "description": "Machine-readable name (ID).", + "type": "string", + "x-order": 0 + }, + "summary": { + "description": "Short human-readable summary.", + "type": "string", + "x-order": 1 + }, + "expr": { + "description": "PromQL query expression with templating parameters.", + "type": "string", + "x-order": 2 + }, + "params": { + "description": "Query parameters definitions.", + "type": "array", + "items": { + "description": "ParamDefinition represents a single query parameter.", + "type": "object", + "properties": { + "name": { + "description": "Machine-readable name (ID) that is used in expression.", + "type": "string", + "x-order": 0 + }, + "summary": { + "description": "Short human-readable parameter summary.", + "type": "string", + "x-order": 1 + }, + "unit": { + "description": "ParamUnit represents template parameter unit.\n\n - PARAM_UNIT_INVALID: Invalid, unknown or absent.\n - PERCENTAGE: %\n - SECONDS: s", + "type": "string", + "default": "PARAM_UNIT_INVALID", + "enum": [ + "PARAM_UNIT_INVALID", + "PERCENTAGE", + "SECONDS" + ], + "x-order": 2 + }, + "type": { + "description": "ParamType represents template parameter type.", + "type": "string", + "default": "PARAM_TYPE_INVALID", + "enum": [ + "PARAM_TYPE_INVALID", + "BOOL", + "FLOAT", + "STRING" + ], + "x-order": 3 + }, + "bool": { + "description": "BoolParamDefinition represents boolean parameter's default value.", + "type": "object", + "properties": { + "default": { + "description": "BooleanFlag represent a command to set some boolean property to true,\nto false, or avoid changing that property.\n\n - DO_NOT_CHANGE: Do not change boolean property. Default value.\n - TRUE: True.\n - FALSE: False.", + "type": "string", + "default": "DO_NOT_CHANGE", + "enum": [ + "DO_NOT_CHANGE", + "TRUE", + "FALSE" + ], + "x-order": 0 + } + }, + "x-order": 4 + }, + "float": { + "description": "FloatParamDefinition represents float parameter's default value and valid range.", + "type": "object", + "properties": { + "has_default": { + "description": "True if default value is set.", + "type": "boolean", + "x-order": 0 + }, + "default": { + "description": "Default value if has_default is true.", + "type": "number", + "format": "double", + "x-order": 1 + }, + "has_min": { + "description": "True if minimal valid value is set.", + "type": "boolean", + "x-order": 2 + }, + "min": { + "description": "Minimal valid value (inclusive) if has_min is true.", + "type": "number", + "format": "double", + "x-order": 3 + }, + "has_max": { + "description": "True if maximal valid value is set.", + "type": "boolean", + "x-order": 4 + }, + "max": { + "description": "Maximal valid value (inclusive) if has_max is true.", + "type": "number", + "format": "double", + "x-order": 5 + } + }, + "x-order": 5 + }, + "string": { + "description": "StringParamDefinition represents string parameter's default value.", + "type": "object", + "properties": { + "has_default": { + "description": "True if default value is set.", + "type": "boolean", + "x-order": 0 + }, + "default": { + "description": "Default value if has_default is true.", + "type": "string", + "x-order": 1 + } + }, + "x-order": 6 + } + } + }, + "x-order": 3 + }, + "for": { + "description": "Default duration value.", + "type": "string", + "x-order": 4 + }, + "severity": { + "description": "Severity represents severity level of the check result or alert.", + "type": "string", + "default": "SEVERITY_INVALID", + "enum": [ + "SEVERITY_INVALID", + "SEVERITY_EMERGENCY", + "SEVERITY_ALERT", + "SEVERITY_CRITICAL", + "SEVERITY_ERROR", + "SEVERITY_WARNING", + "SEVERITY_NOTICE", + "SEVERITY_INFO", + "SEVERITY_DEBUG" + ], + "x-order": 5 + }, + "labels": { + "description": "Labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "annotations": { + "description": "Annotations.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 7 + }, + "source": { + "description": "TemplateSource defines template source.\n\n - BUILT_IN: Template that is shipped with PMM Server releases.\n - SAAS: Template that is downloaded from check.percona.com.\n - USER_FILE: Templated loaded from user-suplied file.\n - USER_API: Templated created via API.", + "type": "string", + "default": "TEMPLATE_SOURCE_INVALID", + "enum": [ + "TEMPLATE_SOURCE_INVALID", + "BUILT_IN", + "SAAS", + "USER_FILE", + "USER_API" + ], + "x-order": 8 + }, + "created_at": { + "description": "Template creation time. Empty for built-in and SaaS templates.", + "type": "string", + "format": "date-time", + "x-order": 9 + }, + "yaml": { + "description": "YAML (or JSON) template file content. Empty for built-in and SaaS templates.", + "type": "string", + "x-order": 10 + } + } + }, + "x-order": 0 + }, + "totals": { + "description": "PageTotals represents total values for pagination.", + "type": "object", + "properties": { + "total_items": { + "description": "Total number of results.", + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "total_pages": { + "description": "Total number of pages.", + "type": "integer", + "format": "int32", + "x-order": 1 + } + }, + "x-order": 1 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/alerting/Templates/Update": { + "post": { + "tags": [ + "Alerting" + ], + "summary": "UpdateTemplate updates existing template, previously created via API.", + "operationId": "UpdateTemplate", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "description": "Machine-readable name (ID).", + "type": "string", + "x-order": 0 + }, + "yaml": { + "description": "YAML (or JSON) template file content.", + "type": "string", + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Artifacts/Delete": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "DeleteArtifact deletes specified artifact.", + "operationId": "DeleteArtifact", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Machine-readable artifact ID.", + "type": "string", + "x-order": 0 + }, + "remove_files": { + "description": "Removes all the backup files associated with artifact if flag is set.", + "type": "boolean", + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Artifacts/List": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "ListArtifacts returns a list of all backup artifacts.", + "operationId": "ListArtifacts", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "artifacts": { + "type": "array", + "items": { + "description": "Artifact represents single backup artifact.", + "type": "object", + "properties": { + "artifact_id": { + "description": "Machine-readable artifact ID.", + "type": "string", + "x-order": 0 + }, + "name": { + "type": "string", + "title": "Artifact name", + "x-order": 1 + }, + "vendor": { + "description": "Database vendor e.g. PostgreSQL, MongoDB, MySQL.", + "type": "string", + "x-order": 2 + }, + "location_id": { + "description": "Machine-readable location ID.", + "type": "string", + "x-order": 3 + }, + "location_name": { + "description": "Location name.", + "type": "string", + "x-order": 4 + }, + "service_id": { + "description": "Machine-readable service ID.", + "type": "string", + "x-order": 5 + }, + "service_name": { + "description": "Service name.", + "type": "string", + "x-order": 6 + }, + "data_model": { + "description": "DataModel is a model used for performing a backup.", + "type": "string", + "default": "DATA_MODEL_INVALID", + "enum": [ + "DATA_MODEL_INVALID", + "PHYSICAL", + "LOGICAL" + ], + "x-order": 7 + }, + "status": { + "description": "BackupStatus shows the current status of execution of backup.", + "type": "string", + "default": "BACKUP_STATUS_INVALID", + "enum": [ + "BACKUP_STATUS_INVALID", + "BACKUP_STATUS_PENDING", + "BACKUP_STATUS_IN_PROGRESS", + "BACKUP_STATUS_PAUSED", + "BACKUP_STATUS_SUCCESS", + "BACKUP_STATUS_ERROR", + "BACKUP_STATUS_DELETING", + "BACKUP_STATUS_FAILED_TO_DELETE" + ], + "x-order": 8 + }, + "created_at": { + "description": "Artifact creation time.", + "type": "string", + "format": "date-time", + "x-order": 9 + }, + "mode": { + "description": "BackupMode specifies backup mode.", + "type": "string", + "default": "BACKUP_MODE_INVALID", + "enum": [ + "BACKUP_MODE_INVALID", + "SNAPSHOT", + "INCREMENTAL", + "PITR" + ], + "x-order": 10 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Artifacts/ListPITRTimeranges": { + "post": { + "tags": [ + "Artifacts" + ], + "summary": "ListPitrTimeranges list the available MongoDB PITR timeranges in a given backup location", + "operationId": "ListPitrTimeranges", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Artifact ID represents artifact whose location has PITR timeranges to be retrieved.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "timeranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "start_timestamp": { + "description": "start_timestamp is the time of the first event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 0 + }, + "end_timestamp": { + "description": "end_timestamp is the time of the last event in the PITR chunk.", + "type": "string", + "format": "date-time", + "x-order": 1 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/ChangeScheduled": { + "post": { + "tags": [ + "Backups" + ], + "summary": "ChangeScheduledBackup changes existing scheduled backup.", + "operationId": "ChangeScheduledBackup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "scheduled_backup_id": { + "type": "string", + "x-order": 0 + }, + "enabled": { + "type": "boolean", + "x-order": 1 + }, + "cron_expression": { + "description": "How often backup should be run in cron format.", + "type": "string", + "x-order": 2 + }, + "start_time": { + "description": "First backup wouldn't happen before this time.", + "type": "string", + "format": "date-time", + "x-order": 3 + }, + "name": { + "description": "Name of backup.", + "type": "string", + "x-order": 4 + }, + "description": { + "description": "Human-readable description.", + "type": "string", + "x-order": 5 + }, + "retry_interval": { + "description": "Delay between each retry. Should have a suffix in JSON: 1s, 1m, 1h.", + "type": "string", + "x-order": 6 + }, + "retries": { + "description": "How many times to retry a failed backup before giving up.", + "type": "integer", + "format": "int64", + "x-order": 7 + }, + "retention": { + "description": "How many artifacts keep. 0 - unlimited.", + "type": "integer", + "format": "int64", + "x-order": 8 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/GetLogs": { + "post": { + "tags": [ + "Backups" + ], + "summary": "GetLogs returns logs for provided artifact.", + "operationId": "GetLogs", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "type": "string", + "x-order": 0 + }, + "offset": { + "type": "integer", + "format": "int64", + "x-order": 1 + }, + "limit": { + "type": "integer", + "format": "int64", + "x-order": 2 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "logs": { + "type": "array", + "items": { + "description": "LogChunk represent one chunk of logs.", + "type": "object", + "properties": { + "chunk_id": { + "type": "integer", + "format": "int64", + "x-order": 0 + }, + "data": { + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 0 + }, + "end": { + "type": "boolean", + "x-order": 1 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/ListArtifactCompatibleServices": { + "post": { + "tags": [ + "Backups" + ], + "summary": "ListArtifactCompatibleServices lists compatible services for restoring a backup.", + "operationId": "ListArtifactCompatibleServices", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Artifact id used to determine restore compatibility.", + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "mysql": { + "type": "array", + "items": { + "description": "MySQLService represents a generic MySQL instance.", + "type": "object", + "properties": { + "service_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "service_name": { + "description": "Unique across all Services user-defined name.", + "type": "string", + "x-order": 1 + }, + "node_id": { + "description": "Node identifier where this instance runs.", + "type": "string", + "x-order": 2 + }, + "address": { + "description": "Access address (DNS name or IP).\nAddress (and port) or socket is required.", + "type": "string", + "x-order": 3 + }, + "port": { + "description": "Access port.\nPort is required when the address present.", + "type": "integer", + "format": "int64", + "x-order": 4 + }, + "socket": { + "description": "Access unix socket.\nAddress (and port) or socket is required.", + "type": "string", + "x-order": 5 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 6 + }, + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 7 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 8 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 9 + } + } + }, + "x-order": 0 + }, + "mongodb": { + "type": "array", + "items": { + "description": "MongoDBService represents a generic MongoDB instance.", + "type": "object", + "properties": { + "service_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "service_name": { + "description": "Unique across all Services user-defined name.", + "type": "string", + "x-order": 1 + }, + "node_id": { + "description": "Node identifier where this instance runs.", + "type": "string", + "x-order": 2 + }, + "address": { + "description": "Access address (DNS name or IP).\nAddress (and port) or socket is required.", + "type": "string", + "x-order": 3 + }, + "port": { + "description": "Access port.\nPort is required when the address present.", + "type": "integer", + "format": "int64", + "x-order": 4 + }, + "socket": { + "description": "Access unix socket.\nAddress (and port) or socket is required.", + "type": "string", + "x-order": 5 + }, + "environment": { + "description": "Environment name.", + "type": "string", + "x-order": 6 + }, + "cluster": { + "description": "Cluster name.", + "type": "string", + "x-order": 7 + }, + "replication_set": { + "description": "Replication set name.", + "type": "string", + "x-order": 8 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 9 + } + } + }, + "x-order": 1 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/ListScheduled": { + "post": { + "tags": [ + "Backups" + ], + "summary": "ListScheduledBackups returns all scheduled backups.", + "operationId": "ListScheduledBackups", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "scheduled_backups": { + "type": "array", + "items": { + "description": "ScheduledBackup represents scheduled task for backup.", + "type": "object", + "properties": { + "scheduled_backup_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "service_id": { + "description": "Machine-readable service ID.", + "type": "string", + "x-order": 1 + }, + "service_name": { + "description": "Service name.", + "type": "string", + "x-order": 2 + }, + "location_id": { + "description": "Machine-readable location ID.", + "type": "string", + "x-order": 3 + }, + "location_name": { + "description": "Location name.", + "type": "string", + "x-order": 4 + }, + "cron_expression": { + "description": "How often backup will be run in cron format.", + "type": "string", + "x-order": 5 + }, + "start_time": { + "description": "First backup wouldn't happen before this time.", + "type": "string", + "format": "date-time", + "x-order": 6 + }, + "name": { + "description": "Artifact name.", + "type": "string", + "x-order": 7 + }, + "description": { + "description": "Description.", + "type": "string", + "x-order": 8 + }, + "retry_interval": { + "description": "Delay between each retry. Should have a suffix in JSON: 1s, 1m, 1h.", + "type": "string", + "x-order": 9 + }, + "retries": { + "description": "How many times to retry a failed backup before giving up.", + "type": "integer", + "format": "int64", + "x-order": 10 + }, + "enabled": { + "description": "If scheduling is enabled.", + "type": "boolean", + "x-order": 11 + }, + "data_model": { + "description": "DataModel is a model used for performing a backup.", + "type": "string", + "default": "DATA_MODEL_INVALID", + "enum": [ + "DATA_MODEL_INVALID", + "PHYSICAL", + "LOGICAL" + ], + "x-order": 12 + }, + "vendor": { + "description": "Database vendor e.g. PostgreSQL, MongoDB, MySQL.", + "type": "string", + "x-order": 13 + }, + "last_run": { + "description": "Last run.", + "type": "string", + "format": "date-time", + "x-order": 14 + }, + "next_run": { + "description": "Next run.", + "type": "string", + "format": "date-time", + "x-order": 15 + }, + "retention": { + "description": "How many artifacts keep. 0 - unlimited.", + "type": "integer", + "format": "int64", + "x-order": 16 + }, + "mode": { + "description": "BackupMode specifies backup mode.", + "type": "string", + "default": "BACKUP_MODE_INVALID", + "enum": [ + "BACKUP_MODE_INVALID", + "SNAPSHOT", + "INCREMENTAL", + "PITR" + ], + "x-order": 17 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/RemoveScheduled": { + "post": { + "tags": [ + "Backups" + ], + "summary": "RemoveScheduledBackup removes existing scheduled backup.", + "operationId": "RemoveScheduledBackup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "scheduled_backup_id": { + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/Restore": { + "post": { + "description": "Could return the Error message in the details containing specific ErrorCode indicating failure reason:\nERROR_CODE_XTRABACKUP_NOT_INSTALLED - xtrabackup is not installed on the service\nERROR_CODE_INVALID_XTRABACKUP - different versions of xtrabackup and xbcloud\nERROR_CODE_INCOMPATIBLE_XTRABACKUP - xtrabackup is not compatible with MySQL for taking a backup\nERROR_CODE_INCOMPATIBLE_TARGET_MYSQL - target MySQL version is not compatible with the artifact for performing a restore of the backup", + "tags": [ + "Backups" + ], + "summary": "RestoreBackup requests the backup restore.", + "operationId": "RestoreBackup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_id": { + "description": "Service identifier where backup should be restored.", + "type": "string", + "x-order": 0 + }, + "artifact_id": { + "description": "Artifact id to restore.", + "type": "string", + "x-order": 1 + }, + "pitr_timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp of PITR to restore to", + "x-order": 2 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "restore_id": { + "description": "Unique restore identifier.", + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/Schedule": { + "post": { + "tags": [ + "Backups" + ], + "summary": "ScheduleBackup schedules repeated backup.", + "operationId": "ScheduleBackup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_id": { + "description": "Service identifier where backup should be performed.", + "type": "string", + "x-order": 0 + }, + "location_id": { + "description": "Machine-readable location ID.", + "type": "string", + "x-order": 1 + }, + "cron_expression": { + "description": "How often backup should be run in cron format.", + "type": "string", + "x-order": 2 + }, + "start_time": { + "description": "First backup wouldn't happen before this time.", + "type": "string", + "format": "date-time", + "x-order": 3 + }, + "name": { + "description": "Name of backup.", + "type": "string", + "x-order": 4 + }, + "description": { + "description": "Human-readable description.", + "type": "string", + "x-order": 5 + }, + "retry_interval": { + "description": "Delay between each retry. Should have a suffix in JSON: 1s, 1m, 1h.", + "type": "string", + "x-order": 6 + }, + "retries": { + "description": "How many times to retry a failed backup before giving up.", + "type": "integer", + "format": "int64", + "x-order": 7 + }, + "enabled": { + "description": "If scheduling is enabled.", + "type": "boolean", + "x-order": 8 + }, + "retention": { + "description": "How many artifacts keep. 0 - unlimited.", + "type": "integer", + "format": "int64", + "x-order": 9 + }, + "mode": { + "description": "BackupMode specifies backup mode.", + "type": "string", + "default": "BACKUP_MODE_INVALID", + "enum": [ + "BACKUP_MODE_INVALID", + "SNAPSHOT", + "INCREMENTAL", + "PITR" + ], + "x-order": 10 + }, + "data_model": { + "description": "DataModel is a model used for performing a backup.", + "type": "string", + "default": "DATA_MODEL_INVALID", + "enum": [ + "DATA_MODEL_INVALID", + "PHYSICAL", + "LOGICAL" + ], + "x-order": 11 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "scheduled_backup_id": { + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Backups/Start": { + "post": { + "description": "Could return the Error message in the details containing specific ErrorCode indicating failure reason:\nERROR_CODE_XTRABACKUP_NOT_INSTALLED - xtrabackup is not installed on the service\nERROR_CODE_INVALID_XTRABACKUP - different versions of xtrabackup and xbcloud\nERROR_CODE_INCOMPATIBLE_XTRABACKUP - xtrabackup is not compatible with MySQL for taking a backup", + "tags": [ + "Backups" + ], + "summary": "StartBackup request backup specified service to location.", + "operationId": "StartBackup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 0 + }, + "location_id": { + "description": "Machine-readable location ID.", + "type": "string", + "x-order": 1 + }, + "name": { + "description": "If empty then name is auto-generated.", + "type": "string", + "x-order": 2 + }, + "description": { + "description": "Human-readable description.", + "type": "string", + "x-order": 3 + }, + "retry_interval": { + "description": "Delay between each retry. Should have a suffix in JSON: 1s, 1m, 1h.", + "type": "string", + "x-order": 4 + }, + "retries": { + "description": "How many times to retry a failed backup before giving up.", + "type": "integer", + "format": "int64", + "x-order": 5 + }, + "data_model": { + "description": "DataModel is a model used for performing a backup.", + "type": "string", + "default": "DATA_MODEL_INVALID", + "enum": [ + "DATA_MODEL_INVALID", + "PHYSICAL", + "LOGICAL" + ], + "x-order": 6 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "artifact_id": { + "description": "Unique identifier.", + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Locations/Add": { + "post": { + "tags": [ + "Locations" + ], + "summary": "AddLocation adds backup location.", + "operationId": "AddLocation", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Location name", + "x-order": 0 + }, + "description": { + "type": "string", + "x-order": 1 + }, + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", + "type": "object", + "properties": { + "path": { + "type": "string", + "x-order": 0 + } + }, + "x-order": 2 + }, + "s3_config": { + "description": "S3LocationConfig represents S3 bucket configuration.", + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "x-order": 0 + }, + "access_key": { + "type": "string", + "x-order": 1 + }, + "secret_key": { + "type": "string", + "x-order": 2 + }, + "bucket_name": { + "type": "string", + "x-order": 3 + } + }, + "x-order": 3 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Locations/Change": { + "post": { + "tags": [ + "Locations" + ], + "summary": "ChangeLocation changes backup location.", + "operationId": "ChangeLocation", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "name": { + "type": "string", + "title": "Location name", + "x-order": 1 + }, + "description": { + "type": "string", + "x-order": 2 + }, + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", + "type": "object", + "properties": { + "path": { + "type": "string", + "x-order": 0 + } + }, + "x-order": 3 + }, + "s3_config": { + "description": "S3LocationConfig represents S3 bucket configuration.", + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "x-order": 0 + }, + "access_key": { + "type": "string", + "x-order": 1 + }, + "secret_key": { + "type": "string", + "x-order": 2 + }, + "bucket_name": { + "type": "string", + "x-order": 3 + } + }, + "x-order": 4 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Locations/List": { + "post": { + "tags": [ + "Locations" + ], + "summary": "ListLocations returns a list of all backup locations.", + "operationId": "ListLocations", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "locations": { + "type": "array", + "items": { + "description": "Location represents single Backup Location.", + "type": "object", + "properties": { + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "name": { + "type": "string", + "title": "Location name", + "x-order": 1 + }, + "description": { + "type": "string", + "title": "Short description", + "x-order": 2 + }, + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", + "type": "object", + "properties": { + "path": { + "type": "string", + "x-order": 0 + } + }, + "x-order": 3 + }, + "s3_config": { + "description": "S3LocationConfig represents S3 bucket configuration.", + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "x-order": 0 + }, + "access_key": { + "type": "string", + "x-order": 1 + }, + "secret_key": { + "type": "string", + "x-order": 2 + }, + "bucket_name": { + "type": "string", + "x-order": 3 + } + }, + "x-order": 4 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Locations/Remove": { + "post": { + "tags": [ + "Locations" + ], + "summary": "RemoveLocation removes existing backup location.", + "operationId": "RemoveLocation", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "location_id": { + "description": "Machine-readable ID.", + "type": "string", + "x-order": 0 + }, + "force": { + "type": "boolean", + "title": "Force mode", + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/Locations/TestConfig": { + "post": { + "tags": [ + "Locations" + ], + "summary": "TestLocationConfig tests backup location and credentials.", + "operationId": "TestLocationConfig", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "filesystem_config": { + "description": "FilesystemLocationConfig represents file system location config.", + "type": "object", + "properties": { + "path": { + "type": "string", + "x-order": 0 + } + }, + "x-order": 0 + }, + "s3_config": { + "description": "S3LocationConfig represents S3 bucket configuration.", + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "x-order": 0 + }, + "access_key": { + "type": "string", + "x-order": 1 + }, + "secret_key": { + "type": "string", + "x-order": 2 + }, + "bucket_name": { + "type": "string", + "x-order": 3 + } + }, + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/backup/RestoreHistory/List": { + "post": { + "tags": [ + "RestoreHistory" + ], + "summary": "ListRestoreHistory returns a list of all backup restore history items.", + "operationId": "ListRestoreHistory", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "description": "RestoreHistoryItem represents single backup restore item.", + "type": "object", + "properties": { + "restore_id": { + "description": "Machine-readable restore id.", + "type": "string", + "x-order": 0 + }, + "artifact_id": { + "description": "ID of the artifact used for restore.", + "type": "string", + "x-order": 1 + }, + "name": { + "description": "Artifact name used for restore.", + "type": "string", + "x-order": 2 + }, + "vendor": { + "description": "Database vendor e.g. PostgreSQL, MongoDB, MySQL.", + "type": "string", + "x-order": 3 + }, + "location_id": { + "description": "Machine-readable location ID.", + "type": "string", + "x-order": 4 + }, + "location_name": { + "description": "Location name.", + "type": "string", + "x-order": 5 + }, + "service_id": { + "description": "Machine-readable service ID.", + "type": "string", + "x-order": 6 + }, + "service_name": { + "description": "Service name.", + "type": "string", + "x-order": 7 + }, + "data_model": { + "description": "DataModel is a model used for performing a backup.", + "type": "string", + "default": "DATA_MODEL_INVALID", + "enum": [ + "DATA_MODEL_INVALID", + "PHYSICAL", + "LOGICAL" + ], + "x-order": 8 + }, + "status": { + "description": "RestoreStatus shows the current status of execution of restore.", + "type": "string", + "default": "RESTORE_STATUS_INVALID", + "enum": [ + "RESTORE_STATUS_INVALID", + "RESTORE_STATUS_IN_PROGRESS", + "RESTORE_STATUS_SUCCESS", + "RESTORE_STATUS_ERROR" + ], + "x-order": 9 + }, + "started_at": { + "description": "Restore start time.", + "type": "string", + "format": "date-time", + "x-order": 10 + }, + "finished_at": { + "description": "Restore finish time.", + "type": "string", + "format": "date-time", + "x-order": 11 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/readyz": { "get": { "description": "Returns an error when Server components being restarted are not ready yet. Use this API for checking the health of Docker containers and for probing Kubernetes readiness.", @@ -20869,6 +23495,21 @@ }, { "name": "Service" + }, + { + "name": "Artifacts" + }, + { + "name": "Backups" + }, + { + "name": "Locations" + }, + { + "name": "RestoreHistory" + }, + { + "name": "Alerting" } ], "x-readme": { diff --git a/descriptor.bin b/descriptor.bin index 3a0d49cd03..24f860ea22 100644 Binary files a/descriptor.bin and b/descriptor.bin differ diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go index 0a5c9654f0..12a9095551 100644 --- a/managed/cmd/pmm-managed/main.go +++ b/managed/cmd/pmm-managed/main.go @@ -59,7 +59,7 @@ import ( "github.com/percona/pmm/api/managementpb" alertingpb "github.com/percona/pmm/api/managementpb/alerting" azurev1beta1 "github.com/percona/pmm/api/managementpb/azure" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas" iav1beta1 "github.com/percona/pmm/api/managementpb/ia" "github.com/percona/pmm/api/platformpb" @@ -191,7 +191,8 @@ type gRPCServerDeps struct { backupService *backup.Service compatibilityService *backup.CompatibilityService backupRemovalService *backup.RemovalService - minioService *minio.Service + pitrTimerangeService *backup.PITRTimerangeService + minioClient *minio.Client versionCache *versioncache.Service supervisord *supervisord.Service config *config.Config @@ -258,10 +259,10 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) { iav1beta1.RegisterAlertsServer(gRPCServer, deps.alertsService) alertingpb.RegisterAlertingServer(gRPCServer, deps.templatesService) - backupv1beta1.RegisterBackupsServer(gRPCServer, managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService)) - backupv1beta1.RegisterLocationsServer(gRPCServer, managementbackup.NewLocationsService(deps.db, deps.minioService)) - backupv1beta1.RegisterArtifactsServer(gRPCServer, managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService)) - backupv1beta1.RegisterRestoreHistoryServer(gRPCServer, managementbackup.NewRestoreHistoryService(deps.db)) + backuppb.RegisterBackupsServer(gRPCServer, managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService)) + backuppb.RegisterLocationsServer(gRPCServer, managementbackup.NewLocationsService(deps.db, deps.minioClient)) + backuppb.RegisterArtifactsServer(gRPCServer, managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService, deps.pitrTimerangeService)) + backuppb.RegisterRestoreHistoryServer(gRPCServer, managementbackup.NewRestoreHistoryService(deps.db)) k8sServer := managementdbaas.NewKubernetesServer(deps.db, deps.dbaasClient, deps.versionServiceClient, deps.grafanaClient) deps.dbaasInitializer.RegisterKubernetesServer(k8sServer) @@ -388,10 +389,10 @@ func runHTTP1Server(ctx context.Context, deps *http1ServerDeps) { iav1beta1.RegisterRulesHandlerFromEndpoint, alertingpb.RegisterAlertingHandlerFromEndpoint, - backupv1beta1.RegisterBackupsHandlerFromEndpoint, - backupv1beta1.RegisterLocationsHandlerFromEndpoint, - backupv1beta1.RegisterArtifactsHandlerFromEndpoint, - backupv1beta1.RegisterRestoreHistoryHandlerFromEndpoint, + backuppb.RegisterBackupsHandlerFromEndpoint, + backuppb.RegisterLocationsHandlerFromEndpoint, + backuppb.RegisterArtifactsHandlerFromEndpoint, + backuppb.RegisterRestoreHistoryHandlerFromEndpoint, dbaasv1beta1.RegisterKubernetesHandlerFromEndpoint, dbaasv1beta1.RegisterDBClustersHandlerFromEndpoint, @@ -733,12 +734,13 @@ func main() { } prom.MustRegister(vmalert) - minioService := minio.New() + minioClient := minio.New() qanClient := getQANClient(ctx, sqlDB, *postgresDBNameF, *qanAPIAddrF) agentsRegistry := agents.NewRegistry(db) - backupRemovalService := backup.NewRemovalService(db, minioService) + backupRemovalService := backup.NewRemovalService(db, minioClient) + pitrTimerangeService := backup.NewPITRTimerangeService(minioClient) backupRetentionService := backup.NewRetentionService(db, backupRemovalService) prom.MustRegister(agentsRegistry) @@ -802,7 +804,7 @@ func main() { versioner := agents.NewVersionerService(agentsRegistry) dbaasClient := dbaas.NewClient(*dbaasControllerAPIAddrF) compatibilityService := backup.NewCompatibilityService(db, versioner) - backupService := backup.NewService(db, jobsService, agentService, compatibilityService) + backupService := backup.NewService(db, jobsService, agentService, compatibilityService, pitrTimerangeService) schedulerService := scheduler.New(db, backupService) versionCache := versioncache.New(db, versioner) emailer := alertmanager.NewEmailer(logrus.WithField("component", "alertmanager-emailer").Logger) @@ -989,7 +991,8 @@ func main() { backupService: backupService, compatibilityService: compatibilityService, backupRemovalService: backupRemovalService, - minioService: minioService, + pitrTimerangeService: pitrTimerangeService, + minioClient: minioClient, versionCache: versionCache, supervisord: supervisord, config: &cfg.Config, diff --git a/managed/models/database.go b/managed/models/database.go index 181670f889..c84ff6a122 100644 --- a/managed/models/database.go +++ b/managed/models/database.go @@ -753,6 +753,14 @@ var databaseSchema = [][]string{ `ALTER TABLE backup_locations DROP COLUMN pmm_server_config`, }, + 70: { + `ALTER TABLE restore_history + ADD COLUMN pitr_timestamp TIMESTAMP`, + }, + 71: { + `ALTER TABLE backup_locations + RENAME COLUMN pmm_client_config TO filesystem_config`, + }, } // ^^^ Avoid default values in schema definition. ^^^ diff --git a/managed/models/location_helpers.go b/managed/models/location_helpers.go index c774e5e11d..c94626dcb8 100644 --- a/managed/models/location_helpers.go +++ b/managed/models/location_helpers.go @@ -59,7 +59,7 @@ func checkUniqueBackupLocationName(q *reform.Querier, name string) error { } } -func checkPMMClientLocationConfig(c *PMMClientLocationConfig) error { +func checkFilesystemLocationConfig(c *FilesystemLocationConfig) error { if c == nil { return status.Error(codes.InvalidArgument, "PMM client location config is empty.") } @@ -194,8 +194,8 @@ func FindBackupLocationsByIDs(q *reform.Querier, ids []string) (map[string]*Back // BackupLocationConfig groups all backup locations configs. type BackupLocationConfig struct { - PMMClientConfig *PMMClientLocationConfig - S3Config *S3LocationConfig + FilesystemConfig *FilesystemLocationConfig + S3Config *S3LocationConfig } // BackupLocationValidationParams contains typed params for backup location validate. @@ -213,9 +213,9 @@ func (c BackupLocationConfig) Validate(params BackupLocationValidationParams) er err = checkS3Config(c.S3Config, params.WithBucketRegion) } - if c.PMMClientConfig != nil { + if c.FilesystemConfig != nil { configCount++ - err = checkPMMClientLocationConfig(c.PMMClientConfig) + err = checkFilesystemLocationConfig(c.FilesystemConfig) } if configCount > 1 { @@ -235,10 +235,10 @@ func (c BackupLocationConfig) FillLocationModel(locationModel *BackupLocation) { case c.S3Config != nil: locationModel.Type = S3BackupLocationType locationModel.S3Config = c.S3Config - locationModel.PMMClientConfig = nil - case c.PMMClientConfig != nil: - locationModel.Type = PMMClientBackupLocationType - locationModel.PMMClientConfig = c.PMMClientConfig + locationModel.FilesystemConfig = nil + case c.FilesystemConfig != nil: + locationModel.Type = FilesystemBackupLocationType + locationModel.FilesystemConfig = c.FilesystemConfig locationModel.S3Config = nil } } diff --git a/managed/models/location_helpers_test.go b/managed/models/location_helpers_test.go index fb1b665f8d..51acb5f189 100644 --- a/managed/models/location_helpers_test.go +++ b/managed/models/location_helpers_test.go @@ -54,7 +54,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -62,10 +62,10 @@ func TestBackupLocations(t *testing.T) { location, err := models.CreateBackupLocation(q, params) require.NoError(t, err) - assert.Equal(t, models.PMMClientBackupLocationType, location.Type) + assert.Equal(t, models.FilesystemBackupLocationType, location.Type) assert.Equal(t, params.Name, location.Name) assert.Equal(t, params.Description, location.Description) - assert.Equal(t, params.PMMClientConfig.Path, location.PMMClientConfig.Path) + assert.Equal(t, params.FilesystemConfig.Path, location.FilesystemConfig.Path) assert.NotEmpty(t, location.ID) }) @@ -118,7 +118,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, S3Config: &models.S3LocationConfig{ @@ -148,7 +148,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -203,7 +203,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -232,7 +232,7 @@ func TestBackupLocations(t *testing.T) { // empty description in request, we expect no change assert.Equal(t, createParams.Description, updatedLoc.Description) assert.Equal(t, models.S3BackupLocationType, updatedLoc.Type) - assert.Nil(t, updatedLoc.PMMClientConfig) + assert.Nil(t, updatedLoc.FilesystemConfig) assert.Equal(t, changeParams.S3Config, updatedLoc.S3Config) findLoc, err := models.FindBackupLocationByID(q, location.ID) @@ -254,7 +254,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -283,7 +283,7 @@ func TestBackupLocations(t *testing.T) { Name: "some name", Description: "some desc", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -364,7 +364,7 @@ func TestCreateBackupLocationValidation(t *testing.T) { params: models.CreateBackupLocationParams{ Name: "client-1", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "/tmp", }, }, @@ -376,7 +376,7 @@ func TestCreateBackupLocationValidation(t *testing.T) { params: models.CreateBackupLocationParams{ Name: "client-2", BackupLocationConfig: models.BackupLocationConfig{ - PMMClientConfig: &models.PMMClientLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ Path: "", }, }, diff --git a/managed/models/location_model.go b/managed/models/location_model.go index f7e9743de3..ddde641b1b 100644 --- a/managed/models/location_model.go +++ b/managed/models/location_model.go @@ -29,20 +29,20 @@ type BackupLocationType string // BackupLocation types. Same as in agent/runner/jobs/backup_location.go const ( - S3BackupLocationType BackupLocationType = "s3" - PMMClientBackupLocationType BackupLocationType = "pmm-client" + S3BackupLocationType BackupLocationType = "s3" + FilesystemBackupLocationType BackupLocationType = "filesystem" ) // BackupLocation represents destination for backup. // //reform:backup_locations type BackupLocation struct { - ID string `reform:"id,pk"` - Name string `reform:"name"` - Description string `reform:"description"` - Type BackupLocationType `reform:"type"` - S3Config *S3LocationConfig `reform:"s3_config"` - PMMClientConfig *PMMClientLocationConfig `reform:"pmm_client_config"` + ID string `reform:"id,pk"` + Name string `reform:"name"` + Description string `reform:"description"` + Type BackupLocationType `reform:"type"` + S3Config *S3LocationConfig `reform:"s3_config"` + FilesystemConfig *FilesystemLocationConfig `reform:"filesystem_config"` CreatedAt time.Time `reform:"created_at"` UpdatedAt time.Time `reform:"updated_at"` @@ -84,16 +84,16 @@ func (c S3LocationConfig) Value() (driver.Value, error) { return jsonValue(c) } // Scan implements database/sql.Scanner interface. Should be defined on the pointer. func (c *S3LocationConfig) Scan(src interface{}) error { return jsonScan(c, src) } -// PMMClientLocationConfig contains require properties for accessing file system on pmm-client-node. -type PMMClientLocationConfig struct { +// FilesystemLocationConfig contains require properties for accessing file system on pmm-client-node. +type FilesystemLocationConfig struct { Path string `json:"path"` } // Value implements database/sql/driver.Valuer interface. Should be defined on the value. -func (c PMMClientLocationConfig) Value() (driver.Value, error) { return jsonValue(c) } +func (c FilesystemLocationConfig) Value() (driver.Value, error) { return jsonValue(c) } // Scan implements database/sql.Scanner interface. Should be defined on the pointer. -func (c *PMMClientLocationConfig) Scan(src interface{}) error { return jsonScan(c, src) } +func (c *FilesystemLocationConfig) Scan(src interface{}) error { return jsonScan(c, src) } // check interfaces. var ( diff --git a/managed/models/location_model_reform.go b/managed/models/location_model_reform.go index 9286ea78c6..96184e6dc9 100644 --- a/managed/models/location_model_reform.go +++ b/managed/models/location_model_reform.go @@ -33,7 +33,7 @@ func (v *backupLocationTableType) Columns() []string { "description", "type", "s3_config", - "pmm_client_config", + "filesystem_config", "created_at", "updated_at", } @@ -65,7 +65,7 @@ var BackupLocationTable = &backupLocationTableType{ {Name: "Description", Type: "string", Column: "description"}, {Name: "Type", Type: "BackupLocationType", Column: "type"}, {Name: "S3Config", Type: "*S3LocationConfig", Column: "s3_config"}, - {Name: "PMMClientConfig", Type: "*PMMClientLocationConfig", Column: "pmm_client_config"}, + {Name: "FilesystemConfig", Type: "*FilesystemLocationConfig", Column: "filesystem_config"}, {Name: "CreatedAt", Type: "time.Time", Column: "created_at"}, {Name: "UpdatedAt", Type: "time.Time", Column: "updated_at"}, }, @@ -82,7 +82,7 @@ func (s BackupLocation) String() string { res[2] = "Description: " + reform.Inspect(s.Description, true) res[3] = "Type: " + reform.Inspect(s.Type, true) res[4] = "S3Config: " + reform.Inspect(s.S3Config, true) - res[5] = "PMMClientConfig: " + reform.Inspect(s.PMMClientConfig, true) + res[5] = "FilesystemConfig: " + reform.Inspect(s.FilesystemConfig, true) res[6] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) res[7] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) return strings.Join(res, ", ") @@ -97,7 +97,7 @@ func (s *BackupLocation) Values() []interface{} { s.Description, s.Type, s.S3Config, - s.PMMClientConfig, + s.FilesystemConfig, s.CreatedAt, s.UpdatedAt, } @@ -112,7 +112,7 @@ func (s *BackupLocation) Pointers() []interface{} { &s.Description, &s.Type, &s.S3Config, - &s.PMMClientConfig, + &s.FilesystemConfig, &s.CreatedAt, &s.UpdatedAt, } diff --git a/managed/models/restore_history_helpers.go b/managed/models/restore_history_helpers.go index 81ad66a26d..f7a30cc1ce 100644 --- a/managed/models/restore_history_helpers.go +++ b/managed/models/restore_history_helpers.go @@ -102,9 +102,10 @@ func FindRestoreHistoryItemByID(q *reform.Querier, id string) (*RestoreHistoryIt // CreateRestoreHistoryItemParams are params for creating a new restore history item. type CreateRestoreHistoryItemParams struct { - ArtifactID string - ServiceID string - Status RestoreStatus + ArtifactID string + ServiceID string + PITRTimestamp *time.Time + Status RestoreStatus } // Validate validates params used for creating a restore history item. @@ -136,10 +137,11 @@ func CreateRestoreHistoryItem(q *reform.Querier, params CreateRestoreHistoryItem } row := &RestoreHistoryItem{ - ID: id, - ArtifactID: params.ArtifactID, - ServiceID: params.ServiceID, - Status: params.Status, + ID: id, + ArtifactID: params.ArtifactID, + ServiceID: params.ServiceID, + PITRTimestamp: params.PITRTimestamp, + Status: params.Status, } if err := q.Insert(row); err != nil { return nil, errors.Wrap(err, "failed to insert restore history item") diff --git a/managed/models/restore_history_helpers_test.go b/managed/models/restore_history_helpers_test.go index b13eb67975..3e50495081 100644 --- a/managed/models/restore_history_helpers_test.go +++ b/managed/models/restore_history_helpers_test.go @@ -123,6 +123,7 @@ func TestRestoreHistory(t *testing.T) { require.NoError(t, err) assert.Equal(t, params.ArtifactID, i.ArtifactID) assert.Equal(t, params.ServiceID, i.ServiceID) + assert.Equal(t, params.PITRTimestamp, i.PITRTimestamp) assert.Equal(t, params.Status, i.Status) assert.Less(t, time.Now().UTC().Unix()-i.StartedAt.Unix(), int64(5)) }) @@ -137,16 +138,20 @@ func TestRestoreHistory(t *testing.T) { q := tx.Querier prepareArtifactsAndService(q) + now := time.Now().Round(time.Second) + params := models.CreateRestoreHistoryItemParams{ - ArtifactID: artifactID1, - ServiceID: serviceID1, - Status: models.InProgressRestoreStatus, + ArtifactID: artifactID1, + ServiceID: serviceID1, + PITRTimestamp: &now, + Status: models.InProgressRestoreStatus, } i, err := models.CreateRestoreHistoryItem(q, params) require.NoError(t, err) assert.Equal(t, params.ArtifactID, i.ArtifactID) assert.Equal(t, params.ServiceID, i.ServiceID) + assert.Equal(t, params.PITRTimestamp, i.PITRTimestamp) assert.Equal(t, params.Status, i.Status) assert.Less(t, time.Now().UTC().Unix()-i.StartedAt.Unix(), int64(5)) @@ -156,6 +161,7 @@ func TestRestoreHistory(t *testing.T) { require.NoError(t, err) assert.Equal(t, params.ArtifactID, i.ArtifactID) assert.Equal(t, params.ServiceID, i.ServiceID) + assert.WithinDuration(t, *params.PITRTimestamp, *i.PITRTimestamp, 0) assert.Equal(t, models.ErrorRestoreStatus, i.Status) assert.Less(t, time.Now().UTC().Unix()-i.StartedAt.Unix(), int64(5)) }) diff --git a/managed/models/restore_history_model.go b/managed/models/restore_history_model.go index d93923047c..d294ff144f 100644 --- a/managed/models/restore_history_model.go +++ b/managed/models/restore_history_model.go @@ -50,12 +50,13 @@ func (rs RestoreStatus) Validate() error { // //reform:restore_history type RestoreHistoryItem struct { - ID string `reform:"id,pk"` - ArtifactID string `reform:"artifact_id"` - ServiceID string `reform:"service_id"` - Status RestoreStatus `reform:"status"` - StartedAt time.Time `reform:"started_at"` - FinishedAt *time.Time `reform:"finished_at"` + ID string `reform:"id,pk"` + ArtifactID string `reform:"artifact_id"` + ServiceID string `reform:"service_id"` + PITRTimestamp *time.Time `reform:"pitr_timestamp"` + Status RestoreStatus `reform:"status"` + StartedAt time.Time `reform:"started_at"` + FinishedAt *time.Time `reform:"finished_at"` } // BeforeInsert implements reform.BeforeInserter interface. diff --git a/managed/models/restore_history_model_reform.go b/managed/models/restore_history_model_reform.go index 4390dda843..e9d80ae2f5 100644 --- a/managed/models/restore_history_model_reform.go +++ b/managed/models/restore_history_model_reform.go @@ -31,6 +31,7 @@ func (v *restoreHistoryItemTableType) Columns() []string { "id", "artifact_id", "service_id", + "pitr_timestamp", "status", "started_at", "finished_at", @@ -61,6 +62,7 @@ var RestoreHistoryItemTable = &restoreHistoryItemTableType{ {Name: "ID", Type: "string", Column: "id"}, {Name: "ArtifactID", Type: "string", Column: "artifact_id"}, {Name: "ServiceID", Type: "string", Column: "service_id"}, + {Name: "PITRTimestamp", Type: "*time.Time", Column: "pitr_timestamp"}, {Name: "Status", Type: "RestoreStatus", Column: "status"}, {Name: "StartedAt", Type: "time.Time", Column: "started_at"}, {Name: "FinishedAt", Type: "*time.Time", Column: "finished_at"}, @@ -72,13 +74,14 @@ var RestoreHistoryItemTable = &restoreHistoryItemTableType{ // String returns a string representation of this struct or record. func (s RestoreHistoryItem) String() string { - res := make([]string, 6) + res := make([]string, 7) res[0] = "ID: " + reform.Inspect(s.ID, true) res[1] = "ArtifactID: " + reform.Inspect(s.ArtifactID, true) res[2] = "ServiceID: " + reform.Inspect(s.ServiceID, true) - res[3] = "Status: " + reform.Inspect(s.Status, true) - res[4] = "StartedAt: " + reform.Inspect(s.StartedAt, true) - res[5] = "FinishedAt: " + reform.Inspect(s.FinishedAt, true) + res[3] = "PITRTimestamp: " + reform.Inspect(s.PITRTimestamp, true) + res[4] = "Status: " + reform.Inspect(s.Status, true) + res[5] = "StartedAt: " + reform.Inspect(s.StartedAt, true) + res[6] = "FinishedAt: " + reform.Inspect(s.FinishedAt, true) return strings.Join(res, ", ") } @@ -89,6 +92,7 @@ func (s *RestoreHistoryItem) Values() []interface{} { s.ID, s.ArtifactID, s.ServiceID, + s.PITRTimestamp, s.Status, s.StartedAt, s.FinishedAt, @@ -102,6 +106,7 @@ func (s *RestoreHistoryItem) Pointers() []interface{} { &s.ID, &s.ArtifactID, &s.ServiceID, + &s.PITRTimestamp, &s.Status, &s.StartedAt, &s.FinishedAt, diff --git a/managed/services/agents/jobs.go b/managed/services/agents/jobs.go index b4846385f2..af677e5f7d 100644 --- a/managed/services/agents/jobs.go +++ b/managed/services/agents/jobs.go @@ -24,10 +24,11 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" "gopkg.in/reform.v1" "github.com/percona/pmm/api/agentpb" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" ) @@ -35,10 +36,11 @@ var ( // ErrRetriesExhausted is returned when remaining retries are 0. ErrRetriesExhausted = errors.New("retries exhausted") - pmmAgentMinVersionForMongoLogicalBackupAndRestore = version.Must(version.NewVersion("2.19")) - pmmAgentMinVersionForMySQLBackupAndRestore = version.Must(version.NewVersion("2.23")) - pmmAgentMinVersionForMongoPhysicalBackupAndRestore = version.Must(version.NewVersion("2.31.0-0")) - pmmAgentMinVersionForMongoDBUsePMMClientLocalStorage = version.Must(version.NewVersion("2.32.0-0")) + pmmAgentMinVersionForMongoLogicalBackupAndRestore = version.Must(version.NewVersion("2.19")) + pmmAgentMinVersionForMySQLBackupAndRestore = version.Must(version.NewVersion("2.23")) + pmmAgentMinVersionForMongoPhysicalBackupAndRestore = version.Must(version.NewVersion("2.31.0-0")) + pmmAgentMinVersionForMongoDBUseFilesystemStorage = version.Must(version.NewVersion("2.32.0-0")) + pmmAgentMinVersionForMongoPITRRestore = version.Must(version.NewVersion("2.32.0-0")) ) const ( @@ -131,8 +133,8 @@ func (s *JobsService) RestartJob(ctx context.Context, jobID string) error { if locationModel != nil { locationConfig = &models.BackupLocationConfig{ - PMMClientConfig: locationModel.PMMClientConfig, - S3Config: locationModel.S3Config, + FilesystemConfig: locationModel.FilesystemConfig, + S3Config: locationModel.S3Config, } } @@ -402,14 +404,14 @@ func (s *JobsService) StartMongoDBBackupJob( mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBBackup_S3Config{ S3Config: convertS3ConfigModel(locationConfig.S3Config), } - case locationConfig.PMMClientConfig != nil: + case locationConfig.FilesystemConfig != nil: if err := PMMAgentSupported(s.r.db.Querier, pmmAgentID, "mongodb backup to client local storage", - pmmAgentMinVersionForMongoDBUsePMMClientLocalStorage); err != nil { + pmmAgentMinVersionForMongoDBUseFilesystemStorage); err != nil { return err } - mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBBackup_PmmClientConfig{ - PmmClientConfig: &agentpb.PMMClientLocationConfig{Path: locationConfig.PMMClientConfig.Path}, + mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBBackup_FilesystemConfig{ + FilesystemConfig: &agentpb.FilesystemLocationConfig{Path: locationConfig.FilesystemConfig.Path}, } default: return errors.Errorf("unsupported location config") @@ -495,6 +497,7 @@ func (s *JobsService) StartMongoDBRestoreBackupJob( dbConfig *models.DBConfig, dataModel models.DataModel, locationConfig *models.BackupLocationConfig, + pitrTimestamp time.Time, ) error { var err error switch dataModel { @@ -511,13 +514,23 @@ func (s *JobsService) StartMongoDBRestoreBackupJob( return err } + if pitrTimestamp.Unix() != 0 { + // TODO refactor pmm agent version checking. First detect minimum required version needed for operations and + // then invoke PMMAgentSupported + if err = PMMAgentSupported(s.r.db.Querier, pmmAgentID, + "mongodb pitr restore", pmmAgentMinVersionForMongoPITRRestore); err != nil { + return err + } + } + mongoDBReq := &agentpb.StartJobRequest_MongoDBRestoreBackup{ - Name: name, - User: dbConfig.User, - Password: dbConfig.Password, - Address: dbConfig.Address, - Port: int32(dbConfig.Port), - Socket: dbConfig.Socket, + Name: name, + User: dbConfig.User, + Password: dbConfig.Password, + Address: dbConfig.Address, + Port: int32(dbConfig.Port), + Socket: dbConfig.Socket, + PitrTimestamp: timestamppb.New(pitrTimestamp), } switch { @@ -525,14 +538,14 @@ func (s *JobsService) StartMongoDBRestoreBackupJob( mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBRestoreBackup_S3Config{ S3Config: convertS3ConfigModel(locationConfig.S3Config), } - case locationConfig.PMMClientConfig != nil: + case locationConfig.FilesystemConfig != nil: if err := PMMAgentSupported(s.r.db.Querier, pmmAgentID, "mongodb restore from client local storage", - pmmAgentMinVersionForMongoDBUsePMMClientLocalStorage); err != nil { + pmmAgentMinVersionForMongoDBUseFilesystemStorage); err != nil { return err } - mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBRestoreBackup_PmmClientConfig{ - PmmClientConfig: &agentpb.PMMClientLocationConfig{Path: locationConfig.PMMClientConfig.Path}, + mongoDBReq.LocationConfig = &agentpb.StartJobRequest_MongoDBRestoreBackup_FilesystemConfig{ + FilesystemConfig: &agentpb.FilesystemLocationConfig{Path: locationConfig.FilesystemConfig.Path}, } default: return errors.Errorf("unsupported location config") @@ -594,12 +607,12 @@ func convertS3ConfigModel(config *models.S3LocationConfig) *agentpb.S3LocationCo } } -func convertDataModel(model models.DataModel) (backupv1beta1.DataModel, error) { +func convertDataModel(model models.DataModel) (backuppb.DataModel, error) { switch model { case models.PhysicalDataModel: - return backupv1beta1.DataModel_PHYSICAL, nil + return backuppb.DataModel_PHYSICAL, nil case models.LogicalDataModel: - return backupv1beta1.DataModel_LOGICAL, nil + return backuppb.DataModel_LOGICAL, nil default: return 0, errors.Errorf("unknown data model: %s", model) } diff --git a/managed/services/backup/backup_service.go b/managed/services/backup/backup_service.go index 01f90e300c..a875d6c7d8 100644 --- a/managed/services/backup/backup_service.go +++ b/managed/services/backup/backup_service.go @@ -22,6 +22,7 @@ import ( "github.com/AlekSi/pointer" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gopkg.in/reform.v1" @@ -31,19 +32,23 @@ import ( // Service represents core logic for db backup. type Service struct { + l *logrus.Entry db *reform.DB jobsService jobsService agentService agentService compatibilityService compatibilityService + pitrTimerangeService pitrTimerangeService } // NewService creates new backups logic service. -func NewService(db *reform.DB, jobsService jobsService, agentService agentService, cSvc compatibilityService) *Service { +func NewService(db *reform.DB, jobsService jobsService, agentService agentService, cSvc compatibilityService, pitrSvc pitrTimerangeService) *Service { return &Service{ + l: logrus.WithField("component", "management/backup/backup"), db: db, jobsService: jobsService, agentService: agentService, compatibilityService: cSvc, + pitrTimerangeService: pitrSvc, } } @@ -97,6 +102,11 @@ func (s *Service) PerformBackup(ctx context.Context, params PerformBackupParams) if params.DataModel != models.PhysicalDataModel { return errors.WithMessage(ErrIncompatibleDataModel, "the only supported data model for mySQL is physical") } + + if locationModel.Type != models.S3BackupLocationType { + return errors.WithMessage(ErrIncompatibleLocationType, "the only supported location type for mySQL is s3") + } + if params.Mode != models.Snapshot { return errors.New("the only supported backup mode for mySQL is snapshot") } @@ -165,8 +175,8 @@ func (s *Service) PerformBackup(ctx context.Context, params PerformBackupParams) } locationConfig := &models.BackupLocationConfig{ - PMMClientConfig: locationModel.PMMClientConfig, - S3Config: locationModel.S3Config, + FilesystemConfig: locationModel.FilesystemConfig, + S3Config: locationModel.S3Config, } switch svc.ServiceType { @@ -183,6 +193,12 @@ func (s *Service) PerformBackup(ctx context.Context, params PerformBackupParams) err = status.Errorf(codes.Unknown, "Unknown service: %s", svc.ServiceType) } if err != nil { + if _, e := models.UpdateArtifact(s.db.Querier, artifact.ID, models.UpdateArtifactParams{ + Status: models.BackupStatusPointer(models.ErrorBackupStatus), + }); e != nil { + s.l.WithError(e).Warnf("failed to mark artifact %s as failed", artifact.ID) + } + return "", err } @@ -217,10 +233,15 @@ type prepareRestoreJobParams struct { ServiceType models.ServiceType DBConfig *models.DBConfig DataModel models.DataModel + PITRTimestamp time.Time } // RestoreBackup starts restore backup job. -func (s *Service) RestoreBackup(ctx context.Context, serviceID, artifactID string) (string, error) { +func (s *Service) RestoreBackup(ctx context.Context, serviceID, artifactID string, pitrTimestamp time.Time) (string, error) { + if err := s.checkArtifactModePreconditions(ctx, artifactID, pitrTimestamp); err != nil { + return "", err + } + dbVersion, err := s.compatibilityService.CheckSoftwareCompatibilityForService(ctx, serviceID) if err != nil { return "", err @@ -228,9 +249,9 @@ func (s *Service) RestoreBackup(ctx context.Context, serviceID, artifactID strin var params *prepareRestoreJobParams var jobID, restoreID string - if err := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error { + if errTx := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error { var err error - params, err = s.prepareRestoreJob(tx.Querier, serviceID, artifactID) + params, err = s.prepareRestoreJob(tx.Querier, serviceID, artifactID, pitrTimestamp) if err != nil { return err } @@ -243,9 +264,10 @@ func (s *Service) RestoreBackup(ctx context.Context, serviceID, artifactID strin } restore, err := models.CreateRestoreHistoryItem(tx.Querier, models.CreateRestoreHistoryItemParams{ - ArtifactID: artifactID, - ServiceID: serviceID, - Status: models.InProgressRestoreStatus, + ArtifactID: artifactID, + ServiceID: serviceID, + PITRTimestamp: &pitrTimestamp, + Status: models.InProgressRestoreStatus, }) if err != nil { return err @@ -296,8 +318,8 @@ func (s *Service) RestoreBackup(ctx context.Context, serviceID, artifactID strin jobID = job.ID return err - }); err != nil { - return "", err + }); errTx != nil { + return "", errTx } if err := s.startRestoreJob(jobID, serviceID, params); err != nil { @@ -356,6 +378,7 @@ func (s *Service) prepareRestoreJob( q *reform.Querier, serviceID string, artifactID string, + pitrTimestamp time.Time, ) (*prepareRestoreJobParams, error) { service, err := models.FindServiceByID(q, serviceID) if err != nil { @@ -367,11 +390,7 @@ func (s *Service) prepareRestoreJob( return nil, err } if artifact.Status != models.SuccessBackupStatus { - return nil, errors.Errorf("artifact %q status is not successful, status: %q", artifactID, artifact.Status) - } - - if artifact.Vendor == string(models.MongoDBServiceType) && artifact.DataModel == models.PhysicalDataModel { - return nil, errors.Wrapf(ErrIncompatibleService, "restore of physical backups is not supported for MongoDB yet") + return nil, errors.Wrapf(ErrArtifactNotReady, "artifact %q in status: %q", artifactID, artifact.Status) } location, err := models.FindBackupLocationByID(q, artifact.LocationID) @@ -400,13 +419,14 @@ func (s *Service) prepareRestoreJob( ServiceType: service.ServiceType, DBConfig: dbConfig, DataModel: artifact.DataModel, + PITRTimestamp: pitrTimestamp, }, nil } func (s *Service) startRestoreJob(jobID, serviceID string, params *prepareRestoreJobParams) error { locationConfig := &models.BackupLocationConfig{ - PMMClientConfig: params.LocationModel.PMMClientConfig, - S3Config: params.LocationModel.S3Config, + FilesystemConfig: params.LocationModel.FilesystemConfig, + S3Config: params.LocationModel.S3Config, } switch params.ServiceType { @@ -428,7 +448,8 @@ func (s *Service) startRestoreJob(jobID, serviceID string, params *prepareRestor params.ArtifactName, params.DBConfig, params.DataModel, - locationConfig); err != nil { + locationConfig, + params.PITRTimestamp); err != nil { return err } case models.PostgreSQLServiceType, @@ -505,3 +526,73 @@ func (s *Service) prepareBackupJob( return res, dbConfig, nil } + +// checkArtifactModePreconditions checks that artifact params and requested restore mode satisfy each other. +func (s *Service) checkArtifactModePreconditions(ctx context.Context, artifactID string, pitrTimestamp time.Time) error { + artifact, err := models.FindArtifactByID(s.db.Querier, artifactID) + if err != nil { + return err + } + + if err := checkArtifactMode(artifact, pitrTimestamp); err != nil { + return err + } + + // Continue checks only if user requested PITR restore. + if pitrTimestamp.Unix() == 0 { + return nil + } + + location, err := models.FindBackupLocationByID(s.db.Querier, artifact.LocationID) + if err != nil { + return err + } + + if location.Type != models.S3BackupLocationType { + return errors.Wrapf(ErrIncompatibleLocationType, "point in time recovery available only for S3 locations") + } + + timeRanges, err := s.pitrTimerangeService.ListPITRTimeranges(ctx, artifact.Name, location) + if err != nil { + return err + } + + for _, tRange := range timeRanges { + if inTimeSpan(time.Unix(int64(tRange.Start), 0), time.Unix(int64(tRange.End), 0), pitrTimestamp) { + return nil + } + } + + return errors.Wrapf(ErrTimestampOutOfRange, "point in time recovery value %s", pitrTimestamp.String()) +} + +// checkArtifactMode crosschecks artifact params and requested restore mode. +func checkArtifactMode(artifact *models.Artifact, pitrTimestamp time.Time) error { + if artifact.Vendor != string(models.MongoDBServiceType) && artifact.Mode == models.PITR { + return errors.Wrapf(ErrIncompatibleService, "restore to point in time is only available for MongoDB") + } + + if artifact.Mode == models.PITR { + if pitrTimestamp.Unix() == 0 { + return errors.Wrapf(ErrIncompatibleArtifactMode, "artifact of type '%s' requires 'time' parameter to be restored to", artifact.Mode) + } + if artifact.DataModel == models.PhysicalDataModel { + return errors.Wrap(ErrIncompatibleArtifactMode, "point in time recovery is only available for Logical data model") + } + } else if pitrTimestamp.Unix() != 0 { + return errors.Wrapf(ErrIncompatibleArtifactMode, "artifact of type '%s' cannot be use to restore to point in time", artifact.Mode) + } + + return nil +} + +// inTimeSpan checks whether given time is in the given range +func inTimeSpan(start, end, check time.Time) bool { + if start.Before(end) { + return !check.Before(start) && !check.After(end) + } + if start.Equal(end) { + return check.Equal(start) + } + return !start.After(check) || !end.Before(check) +} diff --git a/managed/services/backup/backup_service_test.go b/managed/services/backup/backup_service_test.go index 65eccf18c3..f6aed8bdb5 100644 --- a/managed/services/backup/backup_service_test.go +++ b/managed/services/backup/backup_service_test.go @@ -18,6 +18,7 @@ package backup import ( "context" "testing" + "time" "github.com/AlekSi/pointer" "github.com/stretchr/testify/assert" @@ -78,11 +79,11 @@ func TestPerformBackup(t *testing.T) { mockedJobsService := &mockJobsService{} mockedAgentService := &mockAgentService{} mockedCompatibilityService := &mockCompatibilityService{} - backupService := NewService(db, mockedJobsService, mockedAgentService, mockedCompatibilityService) + backupService := NewService(db, mockedJobsService, mockedAgentService, mockedCompatibilityService, nil) - locationRes, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ - Name: "Test location", - Description: "Test description", + s3Location, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ + Name: "Test s3 location", + Description: "Test s3 description", BackupLocationConfig: models.BackupLocationConfig{ S3Config: &models.S3LocationConfig{ Endpoint: "https://s3.us-west-2.amazonaws.com/", @@ -95,6 +96,17 @@ func TestPerformBackup(t *testing.T) { }) require.NoError(t, err) + localLocation, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ + Name: "Test local location", + Description: "Test local description", + BackupLocationConfig: models.BackupLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ + Path: "/opt/data/", + }, + }, + }) + require.NoError(t, err) + t.Run("mysql", func(t *testing.T) { agent := setup(t, db.Querier, models.MySQLServiceType, "test-mysql-backup-service") mockedJobsService.On("StartMySQLBackupJob", mock.Anything, mock.Anything, mock.Anything, @@ -103,25 +115,45 @@ func TestPerformBackup(t *testing.T) { for _, tc := range []struct { name string dbVersion string + locationID string + dataModel models.DataModel expectedError error }{ { name: "successful", dbVersion: "8.0.25", + locationID: s3Location.ID, + dataModel: models.PhysicalDataModel, expectedError: nil, }, { name: "fail", dbVersion: "", + locationID: s3Location.ID, + dataModel: models.PhysicalDataModel, expectedError: ErrXtrabackupNotInstalled, }, + { + name: "unsupported data model", + dbVersion: "8.0.25", + locationID: s3Location.ID, + dataModel: models.LogicalDataModel, + expectedError: ErrIncompatibleDataModel, + }, + { + name: "unsupported location type", + dbVersion: "8.0.25", + locationID: localLocation.ID, + dataModel: models.PhysicalDataModel, + expectedError: ErrIncompatibleLocationType, + }, } { t.Run(tc.name, func(t *testing.T) { mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, pointer.GetString(agent.ServiceID)). Return(tc.dbVersion, tc.expectedError).Once() artifactID, err := backupService.PerformBackup(ctx, PerformBackupParams{ ServiceID: pointer.GetString(agent.ServiceID), - LocationID: locationRes.ID, + LocationID: s3Location.ID, Name: "test_backup", DataModel: models.PhysicalDataModel, Mode: models.Snapshot, @@ -136,7 +168,7 @@ func TestPerformBackup(t *testing.T) { assert.NoError(t, err) artifact, err := models.FindArtifactByID(db.Querier, artifactID) require.NoError(t, err) - assert.Equal(t, locationRes.ID, artifact.LocationID) + assert.Equal(t, s3Location.ID, artifact.LocationID) assert.Equal(t, *agent.ServiceID, artifact.ServiceID) assert.EqualValues(t, models.MySQLServiceType, artifact.Vendor) }) @@ -151,7 +183,7 @@ func TestPerformBackup(t *testing.T) { Return("", nil).Once() artifactID, err := backupService.PerformBackup(ctx, PerformBackupParams{ ServiceID: pointer.GetString(agent.ServiceID), - LocationID: locationRes.ID, + LocationID: s3Location.ID, Name: "test_backup", DataModel: models.PhysicalDataModel, Mode: models.PITR, @@ -164,7 +196,7 @@ func TestPerformBackup(t *testing.T) { mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, "").Return("", nil).Once() artifactID, err := backupService.PerformBackup(ctx, PerformBackupParams{ ServiceID: "", - LocationID: locationRes.ID, + LocationID: s3Location.ID, Name: "test_backup", DataModel: models.PhysicalDataModel, Mode: models.PITR, @@ -178,7 +210,7 @@ func TestPerformBackup(t *testing.T) { Return("", nil).Once() artifactID, err := backupService.PerformBackup(ctx, PerformBackupParams{ ServiceID: pointer.GetString(agent.ServiceID), - LocationID: locationRes.ID, + LocationID: s3Location.ID, Name: "test_backup", DataModel: models.PhysicalDataModel, Mode: models.Incremental, @@ -188,7 +220,7 @@ func TestPerformBackup(t *testing.T) { }) }) - mock.AssertExpectationsForObjects(t, mockedJobsService, mockedAgentService, mockedCompatibilityService) + mock.AssertExpectationsForObjects(t, mockedJobsService, mockedCompatibilityService) } func TestRestoreBackup(t *testing.T) { @@ -203,9 +235,9 @@ func TestRestoreBackup(t *testing.T) { mockedJobsService := &mockJobsService{} mockedAgentService := &mockAgentService{} mockedCompatibilityService := &mockCompatibilityService{} - backupService := NewService(db, mockedJobsService, mockedAgentService, mockedCompatibilityService) + backupService := NewService(db, mockedJobsService, mockedAgentService, mockedCompatibilityService, nil) - locationRes, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ + s3Location, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ Name: "Test location", Description: "Test description", BackupLocationConfig: models.BackupLocationConfig{ @@ -220,13 +252,24 @@ func TestRestoreBackup(t *testing.T) { }) require.NoError(t, err) + localLocation, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ + Name: "Test local location", + Description: "Test local description", + BackupLocationConfig: models.BackupLocationConfig{ + FilesystemConfig: &models.FilesystemLocationConfig{ + Path: "/opt/data/", + }, + }, + }) + require.NoError(t, err) + t.Run("mysql", func(t *testing.T) { agent := setup(t, db.Querier, models.MySQLServiceType, "test-mysql-restore-service") artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ Name: "mysql-artifact-name", Vendor: string(models.MySQLServiceType), DBVersion: "8.0.25", - LocationID: locationRes.ID, + LocationID: s3Location.ID, ServiceID: *agent.ServiceID, DataModel: models.PhysicalDataModel, Mode: models.Snapshot, @@ -253,11 +296,12 @@ func TestRestoreBackup(t *testing.T) { t.Run(tc.name, func(t *testing.T) { mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, pointer.GetString(agent.ServiceID)). Return(tc.dbVersion, tc.expectedError).Once() + if tc.expectedError == nil { mockedJobsService.On("StartMySQLRestoreBackupJob", mock.Anything, pointer.GetString(agent.PMMAgentID), pointer.GetString(agent.ServiceID), mock.Anything, artifact.Name, mock.Anything).Return(nil).Once() } - restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID) + restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID, time.Unix(0, 0)) if tc.expectedError != nil { assert.ErrorIs(t, err, tc.expectedError) assert.Empty(t, restoreID) @@ -277,7 +321,8 @@ func TestRestoreBackup(t *testing.T) { mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, pointer.GetString(agent.ServiceID)). Return("8.0.25", nil).Once() - restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID) + + restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID, time.Unix(0, 0)) require.Errorf(t, err, "artifact %q status is not successful, status: \"pending\"", artifact.ID) assert.Empty(t, restoreID) }) @@ -285,39 +330,313 @@ func TestRestoreBackup(t *testing.T) { t.Run("mongo", func(t *testing.T) { agent := setup(t, db.Querier, models.MongoDBServiceType, "test-mongo-restore-service") - - artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ - Name: "mongo-artifact-name", - Vendor: string(models.MongoDBServiceType), - LocationID: locationRes.ID, - ServiceID: *agent.ServiceID, - DataModel: models.PhysicalDataModel, - Mode: models.Snapshot, - Status: models.PendingBackupStatus, - }) - require.NoError(t, err) - t.Run("incomplete backups won't restore", func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ + Name: "mongo-artifact-name-s3", + Vendor: string(models.MongoDBServiceType), + LocationID: s3Location.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.Snapshot, + Status: models.PendingBackupStatus, + }) + require.NoError(t, err) + mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, pointer.GetString(agent.ServiceID)). Return("", nil).Once() - restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID) + restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID, time.Unix(0, 0)) require.Errorf(t, err, "artifact %q status is not successful, status: \"pending\"", artifact.ID) assert.Empty(t, restoreID) }) - t.Run("physical backups is not supported", func(t *testing.T) { - mockedCompatibilityService.On("CheckSoftwareCompatibilityForService", ctx, pointer.GetString(agent.ServiceID)). - Return("", nil).Once() - - _, err = models.UpdateArtifact(db.Querier, artifact.ID, models.UpdateArtifactParams{ - Status: models.BackupStatusPointer(models.SuccessBackupStatus), + t.Run("PITR not supported for local storages", func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ + Name: "mongo-artifact-name-local", + Vendor: string(models.MongoDBServiceType), + LocationID: localLocation.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.Snapshot, + Status: models.PendingBackupStatus, }) - restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID) - require.ErrorIs(t, err, ErrIncompatibleService) + require.NoError(t, err) + + restoreID, err := backupService.RestoreBackup(ctx, pointer.GetString(agent.ServiceID), artifact.ID, time.Now()) + require.Errorf(t, err, "artifact %q status is not successful, status: \"pending\"", artifact.ID) assert.Empty(t, restoreID) }) }) mock.AssertExpectationsForObjects(t, mockedJobsService, mockedAgentService, mockedCompatibilityService) } + +func TestCheckArtifactModePreconditions(t *testing.T) { + ctx := context.Background() + sqlDB := testdb.Open(t, models.SkipFixtures, nil) + + t.Cleanup(func() { + require.NoError(t, sqlDB.Close()) + }) + + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) + mockedPitrTimerangeService := &mockPitrTimerangeService{} + backupService := NewService(db, nil, nil, nil, mockedPitrTimerangeService) + + locationRes, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{ + Name: "Test location", + Description: "Test description", + BackupLocationConfig: models.BackupLocationConfig{ + S3Config: &models.S3LocationConfig{ + Endpoint: "https://s3.us-west-2.amazonaws.com/", + AccessKey: "access_key", + SecretKey: "secret_key", + BucketName: "example_bucket", + BucketRegion: "us-east-2", + }, + }, + }) + require.NoError(t, err) + + t.Run("mysql", func(t *testing.T) { + agent := setup(t, db.Querier, models.MySQLServiceType, "test-mysql-restore-service") + + for _, tc := range []struct { + name string + pitrValue time.Time + artifactParams models.CreateArtifactParams + err error + }{ + { + name: "success", + pitrValue: time.Unix(0, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mysql-artifact-name-1", + Vendor: string(models.MySQLServiceType), + DBVersion: "8.0.25", + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.PhysicalDataModel, + Mode: models.Snapshot, + Status: models.SuccessBackupStatus, + }, + err: nil, + }, + { + name: "PITR not supported for MySQL", + pitrValue: time.Unix(0, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mysql-artifact-name-2", + Vendor: string(models.MySQLServiceType), + DBVersion: "8.0.25", + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.PhysicalDataModel, + Mode: models.PITR, + Status: models.SuccessBackupStatus, + }, + err: ErrIncompatibleService, + }, + { + name: "snapshot artifact is not compatible with non-empty pitr date", + pitrValue: time.Unix(1, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mysql-artifact-name-3", + Vendor: string(models.MySQLServiceType), + DBVersion: "8.0.25", + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.PhysicalDataModel, + Mode: models.Snapshot, + Status: models.SuccessBackupStatus, + }, + err: ErrIncompatibleArtifactMode, + }, + } { + t.Run(tc.name, func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, tc.artifactParams) + require.NoError(t, err) + + err = backupService.checkArtifactModePreconditions(ctx, artifact.ID, tc.pitrValue) + if tc.err == nil { + require.NoError(t, err) + } else { + assert.ErrorIs(t, err, tc.err) + } + }) + } + }) + + t.Run("mongo", func(t *testing.T) { + agent := setup(t, db.Querier, models.MongoDBServiceType, "test-mongodb-restore-service") + + rangeStart1 := uint32(1) + rangeEnd1 := rangeStart1 + (60 * 60 * 3) // plus 3 hours + + rangeStart2 := uint32(time.Now().Unix()) + rangeEnd2 := rangeStart2 + (60 * 60 * 3) // plus 3 hours + + timelineList := []Timeline{ + {Start: rangeStart1, End: rangeEnd1}, + {Start: rangeStart2, End: rangeEnd2}, + } + + for _, tc := range []struct { + name string + pitrValue time.Time + prepareMock bool + artifactParams models.CreateArtifactParams + err error + }{ + { + name: "success logical restore", + pitrValue: time.Unix(0, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-1", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.Snapshot, + Status: models.SuccessBackupStatus, + }, + err: nil, + }, + { + name: "physical restore is supported", + pitrValue: time.Unix(0, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-2", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.PhysicalDataModel, + Mode: models.Snapshot, + Status: models.SuccessBackupStatus, + }, + err: nil, + }, + { + name: "snapshot artifact is not compatible with non-empty pitr date", + pitrValue: time.Unix(1, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-3", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.Snapshot, + Status: models.SuccessBackupStatus, + }, + err: ErrIncompatibleArtifactMode, + }, + { + name: "timestamp not provided for pitr artifact", + pitrValue: time.Unix(0, 0), + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-4", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.PITR, + Status: models.SuccessBackupStatus, + }, + err: ErrIncompatibleArtifactMode, + }, + { + name: "pitr timestamp out of range", + pitrValue: time.Unix(int64(rangeStart2)-1, 0), + prepareMock: true, + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-5", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.PITR, + Status: models.SuccessBackupStatus, + }, + err: ErrTimestampOutOfRange, + }, + { + name: "success pitr timestamp inside the range", + pitrValue: time.Unix(int64(rangeStart2)+1, 0), + prepareMock: true, + artifactParams: models.CreateArtifactParams{ + Name: "mongo-artifact-name-6", + Vendor: string(models.MongoDBServiceType), + LocationID: locationRes.ID, + ServiceID: *agent.ServiceID, + DataModel: models.LogicalDataModel, + Mode: models.PITR, + Status: models.SuccessBackupStatus, + }, + err: nil, + }, + } { + t.Run(tc.name, func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, tc.artifactParams) + require.NoError(t, err) + + if tc.prepareMock { + mockedPitrTimerangeService.On("ListPITRTimeranges", ctx, artifact.Name, locationRes).Return(timelineList, nil).Once() + } + + err = backupService.checkArtifactModePreconditions(ctx, artifact.ID, tc.pitrValue) + if tc.err == nil { + require.NoError(t, err) + } else { + assert.ErrorIs(t, err, tc.err) + } + }) + } + }) + + mock.AssertExpectationsForObjects(t, mockedPitrTimerangeService) +} + +func TestInTimeSpan(t *testing.T) { + now := time.Now() + for _, tc := range []struct { + name string + start time.Time + end time.Time + value time.Time + inRange bool + }{ + { + name: "success start lt end", + start: now.Add(-1 * time.Hour), + end: now.Add(1 * time.Hour), + value: now, + inRange: true, + }, + { + name: "success start eq end", + start: now, + end: now, + value: now, + inRange: true, + }, + { + name: "fail start gt end", + start: now.Add(1 * time.Hour), + end: now.Add(-1 * time.Hour), + value: now, + inRange: false, + }, + { + name: "out of range", + start: now.Add(-1 * time.Hour), + end: now.Add(1 * time.Hour), + value: now.Add(1 * time.Hour).Add(1 * time.Second), + inRange: false, + }, + } { + t.Run(tc.name, func(t *testing.T) { + res := inTimeSpan(tc.start, tc.end, tc.value) + assert.Equal(t, tc.inRange, res) + }) + } +} diff --git a/managed/services/backup/compatibility_helpers.go b/managed/services/backup/compatibility_helpers.go index b70f653657..d4c95635b0 100644 --- a/managed/services/backup/compatibility_helpers.go +++ b/managed/services/backup/compatibility_helpers.go @@ -33,21 +33,6 @@ type compatibility struct { } var ( - // ErrIncompatibleService is returned when the service is incompatible for making a backup or restore. - ErrIncompatibleService = errors.New("incompatible service") - // ErrXtrabackupNotInstalled is returned if some xtrabackup component is missing. - ErrXtrabackupNotInstalled = errors.New("xtrabackup is not installed") - // ErrInvalidXtrabackup is returned if xtrabackup components have different version. - ErrInvalidXtrabackup = errors.New("invalid installation of the xtrabackup") - // ErrIncompatibleXtrabackup is returned if xtrabackup is not compatible with the MySQL. - ErrIncompatibleXtrabackup = errors.New("incompatible xtrabackup") - // ErrIncompatibleTargetMySQL is returned if target version of MySQL is not compatible for restoring selected artifact. - ErrIncompatibleTargetMySQL = errors.New("incompatible version of target mysql") - // ErrComparisonImpossible is returned when comparison of versions is impossible for some reasons. - ErrComparisonImpossible = errors.New("cannot compare software versions") - // ErrIncompatibleDataModel is returned if the specified data model (logical or physical) is not compatible with other parameters - ErrIncompatibleDataModel = errors.New("the specified backup model is not compatible with other parameters") - mysqlAndXtrabackupCompatibleVersions []compatibility // Starting from MySQL 8.0.22 if the Percona XtraBackup version is lower than the database version, // processing will be stopped and Percona XtraBackup will not be allowed to continue. diff --git a/managed/services/backup/compatibility_service.go b/managed/services/backup/compatibility_service.go index b9fe7c19d7..3d9b1ee9cc 100644 --- a/managed/services/backup/compatibility_service.go +++ b/managed/services/backup/compatibility_service.go @@ -42,7 +42,7 @@ func NewCompatibilityService(db *reform.DB, v versioner) *CompatibilityService { } } -// checkSoftwareCompatibilityForService contains compatibility checking logic. +// checkCompatibility contains compatibility checking logic. func (s *CompatibilityService) checkCompatibility(serviceModel *models.Service, agentModel *models.Agent) (string, error) { // Only MySQL compatibility checking implemented for now. if serviceModel.ServiceType != models.MySQLServiceType { diff --git a/managed/services/backup/deps.go b/managed/services/backup/deps.go index d26c9852ae..39371bfacc 100644 --- a/managed/services/backup/deps.go +++ b/managed/services/backup/deps.go @@ -21,13 +21,17 @@ import ( "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services/agents" + "github.com/percona/pmm/managed/services/minio" ) //go:generate ../../../bin/mockery -name=jobsService -case=snake -inpkg -testonly //go:generate ../../../bin/mockery -name=s3 -case=snake -inpkg -testonly //go:generate ../../../bin/mockery -name=agentService -case=snake -inpkg -testonly //go:generate ../../../bin/mockery -name=versioner -case=snake -inpkg -testonly +//go:generate ../../../bin/mockery -name=pitrLocationClient -case=snake -inpkg -testonly //go:generate ../../../bin/mockery -name=compatibilityService -case=snake -inpkg -testonly +//go:generate ../../../bin/mockery -name=pitrLocationClient -case=snake -inpkg -testonly +//go:generate ../../../bin/mockery -name=pitrTimerangeService -case=snake -inpkg -testonly // jobsService is a subset of methods of agents.JobsService used by this package. // We use it instead of real type for testing and to avoid dependency cycle. @@ -67,6 +71,7 @@ type jobsService interface { dbConfig *models.DBConfig, dataModel models.DataModel, locationConfig *models.BackupLocationConfig, + pitrTimestamp time.Time, ) error } @@ -89,10 +94,24 @@ type versioner interface { GetVersions(pmmAgentID string, softwares []agents.Software) ([]agents.Version, error) } -// We use it instead of real type for testing and to avoid dependency cycle type compatibilityService interface { // CheckSoftwareCompatibilityForService checks if all the necessary backup tools are installed, // and they are compatible with the db version. // Returns db version. CheckSoftwareCompatibilityForService(ctx context.Context, serviceID string) (string, error) } + +type pitrLocationClient interface { + // FileStat returns file info. It returns error if file is empty or not exists. + FileStat(ctx context.Context, endpoint, accessKey, secretKey, bucketName, name string) (minio.FileInfo, error) + + // List scans path with prefix and returns all files with given suffix. + // Both prefix and suffix can be omitted. + List(ctx context.Context, endpoint, accessKey, secretKey, bucketName, prefix, suffix string) ([]minio.FileInfo, error) +} + +// pitrTimerangeService provides methods that help us inspect PITR artifacts +type pitrTimerangeService interface { + // ListPITRTimeranges list the available PITR timeranges for the given artifact in the provided location + ListPITRTimeranges(ctx context.Context, artifactName string, location *models.BackupLocation) ([]Timeline, error) +} diff --git a/managed/services/backup/errors.go b/managed/services/backup/errors.go new file mode 100644 index 0000000000..d7647b4ab7 --- /dev/null +++ b/managed/services/backup/errors.go @@ -0,0 +1,45 @@ +// Copyright (C) 2017 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package backup + +import "github.com/pkg/errors" + +var ( + // ErrIncompatibleService is returned when the service is incompatible for making a backup or restore. + ErrIncompatibleService = errors.New("incompatible service") + // ErrXtrabackupNotInstalled is returned if some xtrabackup component is missing. + ErrXtrabackupNotInstalled = errors.New("xtrabackup is not installed") + // ErrInvalidXtrabackup is returned if xtrabackup components have different version. + ErrInvalidXtrabackup = errors.New("invalid installation of the xtrabackup") + // ErrIncompatibleXtrabackup is returned if xtrabackup is not compatible with the MySQL. + ErrIncompatibleXtrabackup = errors.New("incompatible xtrabackup") + // ErrIncompatibleTargetMySQL is returned if target version of MySQL is not compatible for restoring selected artifact. + ErrIncompatibleTargetMySQL = errors.New("incompatible version of target mysql") + // ErrComparisonImpossible is returned when comparison of versions is impossible for some reasons. + ErrComparisonImpossible = errors.New("cannot compare software versions") + // ErrIncompatibleDataModel is returned if the specified data model (logical or physical) is not compatible with other parameters. + ErrIncompatibleDataModel = errors.New("the specified backup model is not compatible with other parameters") + // ErrIncompatibleLocationType is returned if the specified location type (local or s3) is not compatible with other parameters. + ErrIncompatibleLocationType = errors.New("the specified location type is not compatible with other parameters") + // ErrIncompatibleArtifactMode is returned if artifact backup mode is incompatible with other parameters. + ErrIncompatibleArtifactMode = errors.New("artifact backup mode is not compatible with other parameters") + // ErrTimestampOutOfRange is returned if timestamp value is out of allowed range. + ErrTimestampOutOfRange = errors.New("timestamp value is out of range") + // ErrAnotherOperationInProgress is returned if there are other operations in progress that prevent running the requested one. + ErrAnotherOperationInProgress = errors.New("another operation in progress") + // ErrArtifactNotReady is returned when artifact not ready to be restored, i.e. not in success status. + ErrArtifactNotReady = errors.New("artifact not in success status") +) diff --git a/managed/services/backup/mock_jobs_service_test.go b/managed/services/backup/mock_jobs_service_test.go index 11b161b735..f9961b021d 100644 --- a/managed/services/backup/mock_jobs_service_test.go +++ b/managed/services/backup/mock_jobs_service_test.go @@ -29,13 +29,13 @@ func (_m *mockJobsService) StartMongoDBBackupJob(jobID string, pmmAgentID string return r0 } -// StartMongoDBRestoreBackupJob provides a mock function with given fields: jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig -func (_m *mockJobsService) StartMongoDBRestoreBackupJob(jobID string, pmmAgentID string, timeout time.Duration, name string, dbConfig *models.DBConfig, dataModel models.DataModel, locationConfig *models.BackupLocationConfig) error { - ret := _m.Called(jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig) +// StartMongoDBRestoreBackupJob provides a mock function with given fields: jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig, pitrTimestamp +func (_m *mockJobsService) StartMongoDBRestoreBackupJob(jobID string, pmmAgentID string, timeout time.Duration, name string, dbConfig *models.DBConfig, dataModel models.DataModel, locationConfig *models.BackupLocationConfig, pitrTimestamp time.Time) error { + ret := _m.Called(jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig, pitrTimestamp) var r0 error - if rf, ok := ret.Get(0).(func(string, string, time.Duration, string, *models.DBConfig, models.DataModel, *models.BackupLocationConfig) error); ok { - r0 = rf(jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig) + if rf, ok := ret.Get(0).(func(string, string, time.Duration, string, *models.DBConfig, models.DataModel, *models.BackupLocationConfig, time.Time) error); ok { + r0 = rf(jobID, pmmAgentID, timeout, name, dbConfig, dataModel, locationConfig, pitrTimestamp) } else { r0 = ret.Error(0) } diff --git a/managed/services/backup/mock_pitr_location_client_test.go b/managed/services/backup/mock_pitr_location_client_test.go new file mode 100644 index 0000000000..82a68a377a --- /dev/null +++ b/managed/services/backup/mock_pitr_location_client_test.go @@ -0,0 +1,60 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package backup + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + minio "github.com/percona/pmm/managed/services/minio" +) + +// mockPitrLocationClient is an autogenerated mock type for the pitrLocationClient type +type mockPitrLocationClient struct { + mock.Mock +} + +// FileStat provides a mock function with given fields: ctx, endpoint, accessKey, secretKey, bucketName, name +func (_m *mockPitrLocationClient) FileStat(ctx context.Context, endpoint string, accessKey string, secretKey string, bucketName string, name string) (minio.FileInfo, error) { + ret := _m.Called(ctx, endpoint, accessKey, secretKey, bucketName, name) + + var r0 minio.FileInfo + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string) minio.FileInfo); ok { + r0 = rf(ctx, endpoint, accessKey, secretKey, bucketName, name) + } else { + r0 = ret.Get(0).(minio.FileInfo) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, string) error); ok { + r1 = rf(ctx, endpoint, accessKey, secretKey, bucketName, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: ctx, endpoint, accessKey, secretKey, bucketName, prefix, suffix +func (_m *mockPitrLocationClient) List(ctx context.Context, endpoint string, accessKey string, secretKey string, bucketName string, prefix string, suffix string) ([]minio.FileInfo, error) { + ret := _m.Called(ctx, endpoint, accessKey, secretKey, bucketName, prefix, suffix) + + var r0 []minio.FileInfo + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string, string) []minio.FileInfo); ok { + r0 = rf(ctx, endpoint, accessKey, secretKey, bucketName, prefix, suffix) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]minio.FileInfo) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, string, string) error); ok { + r1 = rf(ctx, endpoint, accessKey, secretKey, bucketName, prefix, suffix) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/managed/services/backup/mock_pitr_timerange_service_test.go b/managed/services/backup/mock_pitr_timerange_service_test.go new file mode 100644 index 0000000000..d1558629d0 --- /dev/null +++ b/managed/services/backup/mock_pitr_timerange_service_test.go @@ -0,0 +1,39 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package backup + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + models "github.com/percona/pmm/managed/models" +) + +// mockPitrTimerangeService is an autogenerated mock type for the pitrTimerangeService type +type mockPitrTimerangeService struct { + mock.Mock +} + +// ListPITRTimeranges provides a mock function with given fields: ctx, artifactName, location +func (_m *mockPitrTimerangeService) ListPITRTimeranges(ctx context.Context, artifactName string, location *models.BackupLocation) ([]Timeline, error) { + ret := _m.Called(ctx, artifactName, location) + + var r0 []Timeline + if rf, ok := ret.Get(0).(func(context.Context, string, *models.BackupLocation) []Timeline); ok { + r0 = rf(ctx, artifactName, location) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Timeline) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, *models.BackupLocation) error); ok { + r1 = rf(ctx, artifactName, location) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/managed/services/backup/pitr_timerange_service.go b/managed/services/backup/pitr_timerange_service.go new file mode 100644 index 0000000000..b05f4c744d --- /dev/null +++ b/managed/services/backup/pitr_timerange_service.go @@ -0,0 +1,357 @@ +// Copyright (C) 2022 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package backup + +import ( + "context" + "path" + "sort" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "go.mongodb.org/mongo-driver/bson/primitive" + + "github.com/percona/pmm/managed/models" +) + +const ( + // pitrFSPrefix is the prefix (folder) for all PITR artifacts in the backup location. + pitrFSPrefix = "pbmPitr" +) + +var errUnsupportedLocation = errors.New("unsupported location config") + +// PITRTimerangeService helps perform file lookups in a backup locationClient location +type PITRTimerangeService struct { + l *logrus.Entry + locationClient pitrLocationClient +} + +// NewPITRTimerangeService creates new backup locationClient service. +func NewPITRTimerangeService(pitrLocationClient pitrLocationClient) *PITRTimerangeService { + return &PITRTimerangeService{ + l: logrus.WithField("component", "services/backup/pitr_storage"), + locationClient: pitrLocationClient, + } +} + +// oplogChunk is index metadata for the oplog chunks +type oplogChunk struct { + RS string `bson:"rs"` + FName string `bson:"fname"` + Compression compressionType `bson:"compression"` + StartTS primitive.Timestamp `bson:"start_ts"` + EndTS primitive.Timestamp `bson:"end_ts"` + size int64 `bson:"-"` +} + +// Timeline is an internal representation of a PITR Timeline +type Timeline struct { + ReplicaSet string `json:"replica_set"` + Start uint32 `json:"start"` + End uint32 `json:"end"` + Size int64 `json:"-"` +} + +type gap struct { + s, e uint32 +} + +type gaps []gap + +func (x gaps) Len() int { return len(x) } +func (x gaps) Less(i, j int) bool { + return x[i].s < x[j].s || (x[i].s == x[j].s && x[i].e < x[j].e) +} +func (x gaps) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +// compressionType is the type of compression used for PITR oplog +type compressionType string + +const ( + compressionTypeNone compressionType = "none" + compressionTypePGZIP compressionType = "pgzip" + compressionTypeSNAPPY compressionType = "snappy" + compressionTypeLZ4 compressionType = "lz4" + compressionTypeS2 compressionType = "s2" + compressionTypeZstandard compressionType = "zstd" +) + +// file return compression alg based on given file extension +func file(ext string) compressionType { + switch ext { + case "gz": + return compressionTypePGZIP + case "lz4": + return compressionTypeLZ4 + case "snappy": + return compressionTypeSNAPPY + case "s2": + return compressionTypeS2 + case "zst": + return compressionTypeZstandard + default: + return compressionTypeNone + } +} + +func (ss *PITRTimerangeService) getPITROplogs(ctx context.Context, location *models.BackupLocation, artifactName string) ([]*oplogChunk, error) { + if location.S3Config == nil { + return nil, errUnsupportedLocation + } + + var err error + var oplogChunks []*oplogChunk + + prefix := path.Join(artifactName, pitrFSPrefix) + pitrFiles, err := ss.locationClient.List(ctx, location.S3Config.Endpoint, location.S3Config.AccessKey, location.S3Config.SecretKey, location.S3Config.BucketName, prefix, "") + if err != nil { + return nil, errors.Wrap(err, "get list of pitr chunks") + } + if len(pitrFiles) == 0 { + return nil, nil + } + + for _, f := range pitrFiles { + if f.IsDeleteMarker { + ss.l.Debugf("skip pitr chunk %s/%s because of file has delete marker", prefix, f.Name) + continue + } + chunk := pitrMetaFromFileName(prefix, f.Name) + if chunk != nil { + chunk.size = f.Size + oplogChunks = append(oplogChunks, chunk) + } + } + + return oplogChunks, nil +} + +func (ss *PITRTimerangeService) ListPITRTimeranges(ctx context.Context, artifactName string, location *models.BackupLocation) ([]Timeline, error) { + var timelines [][]Timeline + + oplogs, err := ss.getPITROplogs(ctx, location, artifactName) + if err != nil { + return nil, errors.Wrap(err, "get slice") + } + if len(oplogs) == 0 { + return nil, nil + } + + t, err := gettimelines(oplogs), nil + if err != nil { + return nil, errors.Wrapf(err, "get PITR timeranges for backup '%s'", artifactName) + } + if len(t) != 0 { + timelines = append(timelines, t) + } + + return mergeTimelines(timelines...), nil +} + +// pitrMetaFromFileName parses given file name and returns PITRChunk metadata +// it returns nil if the file wasn't parse successfully (e.g. wrong format) +// current fromat is 20200715155939-0.20200715160029-1.oplog.snappy +// (https://github.com/percona/percona-backup-mongodb/wiki/PITR:-storage-layout) +// +// !!! should be agreed with pbm/pitr.chunkPath() +func pitrMetaFromFileName(prefix, f string) *oplogChunk { + ppath := strings.Split(f, "/") + if len(ppath) < 2 { + return nil + } + chnk := &oplogChunk{} + chnk.RS = ppath[0] + chnk.FName = path.Join(prefix, f) + + fname := ppath[len(ppath)-1] + fparts := strings.Split(fname, ".") + if len(fparts) < 3 || fparts[2] != "oplog" { + return nil + } + if len(fparts) == 4 { + chnk.Compression = file(fparts[3]) + } else { + chnk.Compression = compressionTypeNone + } + + start := pitrParseTS(fparts[0]) + if start == nil { + return nil + } + end := pitrParseTS(fparts[1]) + if end == nil { + return nil + } + + chnk.StartTS = *start + chnk.EndTS = *end + + return chnk +} + +func pitrParseTS(tstr string) *primitive.Timestamp { + tparts := strings.Split(tstr, "-") + t, err := time.Parse("20060102150405", tparts[0]) + if err != nil { + // just skip this file + return nil + } + ts := primitive.Timestamp{T: uint32(t.Unix())} + if len(tparts) > 1 { + ti, err := strconv.Atoi(tparts[1]) + if err != nil { + // just skip this file + return nil + } + ts.I = uint32(ti) + } + + return &ts +} + +func gettimelines(slices []*oplogChunk) []Timeline { + var tl Timeline + var timelines []Timeline + var prevEnd primitive.Timestamp + for _, s := range slices { + if prevEnd.T != 0 && primitive.CompareTimestamp(prevEnd, s.StartTS) == -1 { + timelines = append(timelines, tl) + tl = Timeline{} + } + if tl.Start == 0 { + tl.Start = s.StartTS.T + } + prevEnd = s.EndTS + tl.End = s.EndTS.T + tl.Size += s.size + tl.ReplicaSet = s.RS + } + + timelines = append(timelines, tl) + return timelines +} + +// mergeTimelines merges overlapping sets on timelines +// it presumes timelines are sorted and don't start from 0 +func mergeTimelines(timelines ...[]Timeline) []Timeline { + // fast paths + if len(timelines) == 0 { + return nil + } + if len(timelines) == 1 { + return timelines[0] + } + + // First, we define the available range. It equals to the beginning of the latest start of the first + // Timeline of any set and to the earliest end of the last Timeline of any set. Then define timelines' gaps + // merge overlapping and apply resulted gap on the available range. + // + // given timelines: + // 1 2 3 4 7 8 10 11 16 17 18 19 20 + // 3 4 5 6 7 8 10 11 12 15 16 17 + // 1 2 3 4 5 6 7 8 10 11 12 16 17 18 + // + // available range: + // 3 4 5 6 7 8 10 11 12 13 15 16 17 + // merged gaps: + // 5 6 12 13 15 18 19 20 + // result: + // 3 4 7 8 10 11 16 17 + // + + // limits of the available range + // `start` is the latest start the timelines range + // `end` - is the earliest end + var start, end uint32 + + // iterating through the timelines 1) define `start` and `end`, + // 2) define gaps and add them into slice. + var g gaps + for _, tln := range timelines { + if len(tln) == 0 { + continue + } + + if tln[0].Start > start { + start = tln[0].Start + } + + if end == 0 || tln[len(tln)-1].End < end { + end = tln[len(tln)-1].End + } + + if len(tln) == 1 { + continue + } + var ls uint32 + for i, t := range tln { + if i == 0 { + ls = t.End + continue + } + g = append(g, gap{ls, t.Start}) + ls = t.End + } + } + sort.Sort(g) + + // if no gaps, just return available range + if len(g) == 0 { + return []Timeline{{Start: start, End: end}} + } + + // merge overlapping gaps + var g2 gaps + var cend uint32 + for _, gp := range g { + if gp.e <= start { + continue + } + if gp.s >= end { + break + } + + if len(g2) != 0 { + cend = g2[len(g2)-1].e + } + + if gp.s > cend { + g2 = append(g2, gp) + continue + } + if gp.e > cend { + g2[len(g2)-1].e = gp.e + } + } + + // split available Timeline with gaps + var ret []Timeline + for _, g := range g2 { + if start < g.s { + ret = append(ret, Timeline{Start: start, End: g.s}) + } + start = g.e + } + if start < end { + ret = append(ret, Timeline{Start: start, End: end}) + } + + return ret +} diff --git a/managed/services/backup/pitr_timerange_service_test.go b/managed/services/backup/pitr_timerange_service_test.go new file mode 100644 index 0000000000..28ab7e1666 --- /dev/null +++ b/managed/services/backup/pitr_timerange_service_test.go @@ -0,0 +1,495 @@ +// Copyright (C) 2022 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package backup + +import ( + "context" + "fmt" + "path" + "strings" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "go.mongodb.org/mongo-driver/bson/primitive" + + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/services/minio" +) + +func TestPitrMetaFromFileName(t *testing.T) { + tests := []struct { + name string + filename string + expected *oplogChunk + }{ + { + name: "correctly formatted file name", + filename: "rs0/20220829/20220829115611-1.20220829120544-10.oplog.s2", + expected: &oplogChunk{ + RS: "rs0", + FName: "test_artifact_name/pbmPitr/rs0/20220829/20220829115611-1.20220829120544-10.oplog.s2", + Compression: compressionTypeS2, + StartTS: primitive.Timestamp{T: uint32(1661774171), I: 1}, + EndTS: primitive.Timestamp{T: uint32(1661774744), I: 10}, + }, + }, + { + name: "incomplete file name", + filename: "20220829115611-1.20220829120544-10.oplog.s2", + expected: nil, + }, + { + name: "without end timestamp", + filename: "rs0/20220829/20220829115611-1.oplog.s2", + expected: nil, + }, + { + name: "without specified compression", + filename: "rs0/20220829/20220829115611-1.20220829120544-10.oplog", + expected: &oplogChunk{ + RS: "rs0", + FName: "test_artifact_name/pbmPitr/rs0/20220829/20220829115611-1.20220829120544-10.oplog", + Compression: compressionTypeNone, + StartTS: primitive.Timestamp{T: uint32(1661774171), I: 1}, + EndTS: primitive.Timestamp{T: uint32(1661774744), I: 10}, + }, + }, + } + + prefix := path.Join("test_artifact_name", pitrFSPrefix) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + chunk := pitrMetaFromFileName(prefix, tt.filename) + assert.Equal(t, tt.expected, chunk) + }) + } +} + +func TestPitrParseTs(t *testing.T) { + tests := []struct { + name string + filename string + expected *primitive.Timestamp + }{ + { + name: "with time and index", + filename: "20220829115611-10", + expected: &primitive.Timestamp{T: uint32(1661774171), I: 10}, + }, + { + name: "time without index", + filename: "20220829120544", + expected: &primitive.Timestamp{T: uint32(1661774744), I: 0}, + }, + { + name: "with invalid timestamp", + filename: "2022", + expected: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := pitrParseTS(tt.filename) + assert.Equal(t, tt.expected, ts) + }) + } +} + +func TestListPITRTimelines(t *testing.T) { + ctx := context.Background() + location := &models.BackupLocation{ + S3Config: &models.S3LocationConfig{ + Endpoint: "https://s3.us-west-2.amazonaws.com", + AccessKey: "access_key", + SecretKey: "secret_key", + BucketName: "example_bucket", + BucketRegion: "us-east-1", + }, + } + + t.Run("successful", func(t *testing.T) { + mockedStorage := &mockPitrLocationClient{} + listedFiles := []minio.FileInfo{ + { + Name: "rs0/20220829/20220829115611-1.20220829120544-10.oplog.s2", + Size: 1024, + }, + } + + statFile := minio.FileInfo{ + Name: pitrFSPrefix + "rs0/20220829/20220829115611-1.20220829120544-10.oplog.s2", + Size: 1024, + } + mockedStorage.On("List", ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(listedFiles, nil) + mockedStorage.On("FileStat", ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(statFile, nil) + + ss := NewPITRTimerangeService(mockedStorage) + timelines, err := ss.getPITROplogs(ctx, location, "") + assert.NoError(t, err) + assert.Len(t, timelines, 1) + }) + + t.Run("fails on file list error", func(t *testing.T) { + mockedStorage := &mockPitrLocationClient{} + mockedStorage.On("List", ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("listing object error")) + + ss := NewPITRTimerangeService(mockedStorage) + timelines, err := ss.getPITROplogs(ctx, location, "") + assert.Error(t, err) + assert.Nil(t, timelines) + }) + + t.Run("skips artifacts with deletion markers", func(t *testing.T) { + mockedStorage := &mockPitrLocationClient{} + listedFiles := []minio.FileInfo{ + { + Name: "rs0/20220829/20220829115611-1.20220829120544-10.oplog.s2", + Size: 1024, + IsDeleteMarker: true, + }, + } + + mockedStorage.On("List", ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(listedFiles, nil) + + ss := NewPITRTimerangeService(mockedStorage) + timelines, err := ss.getPITROplogs(ctx, location, "") + assert.NoError(t, err) + assert.Len(t, timelines, 0) + }) +} + +func TestPITRMergeTimelines(t *testing.T) { + tests := []struct { + name string + tl [][]Timeline + expect []Timeline + }{ + { + name: "nothing", + tl: [][]Timeline{}, + expect: []Timeline{}, + }, + { + name: "empy set", + tl: [][]Timeline{ + {}, + }, + expect: []Timeline{}, + }, + { + name: "no match", + tl: [][]Timeline{ + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 20, End: 42}, + }, + { + {Start: 1, End: 3}, + {Start: 6, End: 14}, + {Start: 50, End: 55}, + }, + { + {Start: 7, End: 10}, + {Start: 12, End: 19}, + {Start: 20, End: 26}, + {Start: 27, End: 60}, + }, + }, + expect: []Timeline{}, + }, + { + name: "no match2", + tl: [][]Timeline{ + { + {Start: 1, End: 5}, + {Start: 8, End: 13}, + }, + { + {Start: 6, End: 7}, + }, + }, + expect: []Timeline{}, + }, + { + name: "no match3", + tl: [][]Timeline{ + { + {Start: 1, End: 5}, + {Start: 8, End: 13}, + }, + { + {Start: 5, End: 8}, + }, + }, + expect: []Timeline{}, + }, + { + name: "some empty", + tl: [][]Timeline{ + {}, + { + {Start: 4, End: 8}, + }, + }, + expect: []Timeline{{Start: 4, End: 8}}, + }, + { + name: "no gaps", + tl: [][]Timeline{ + { + {Start: 1, End: 5}, + }, + { + {Start: 4, End: 8}, + }, + }, + expect: []Timeline{{Start: 4, End: 5}}, + }, + { + name: "no gaps2", + tl: [][]Timeline{ + { + {Start: 4, End: 8}, + }, + { + {Start: 1, End: 5}, + }, + }, + expect: []Timeline{{Start: 4, End: 5}}, + }, + { + name: "no gaps3", + tl: [][]Timeline{ + { + {Start: 1, End: 8}, + }, + { + {Start: 1, End: 5}, + }, + }, + expect: []Timeline{{Start: 1, End: 5}}, + }, + { + name: "overlaps", + tl: [][]Timeline{ + { + {Start: 2, End: 6}, + {Start: 8, End: 12}, + {Start: 13, End: 15}, + }, + { + {Start: 1, End: 4}, + {Start: 9, End: 14}, + }, + { + {Start: 3, End: 7}, + {Start: 8, End: 11}, + {Start: 12, End: 14}, + }, + { + {Start: 2, End: 9}, + {Start: 10, End: 17}, + }, + { + {Start: 1, End: 5}, + {Start: 6, End: 14}, + {Start: 15, End: 19}, + }, + }, + expect: []Timeline{ + {Start: 3, End: 4}, + {Start: 10, End: 11}, + {Start: 13, End: 14}, + }, + }, + { + name: "all match", + tl: [][]Timeline{ + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 42}, + }, + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 42}, + }, + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 42}, + }, + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 42}, + }, + }, + expect: []Timeline{ + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 42}, + }, + }, + { + name: "partly overlap", + tl: [][]Timeline{ + { + {Start: 3, End: 8}, + {Start: 14, End: 19}, + {Start: 21, End: 42}, + }, + { + {Start: 1, End: 3}, + {Start: 4, End: 7}, + {Start: 19, End: 36}, + }, + { + {Start: 5, End: 8}, + {Start: 14, End: 19}, + {Start: 20, End: 42}, + }, + }, + expect: []Timeline{ + {Start: 5, End: 7}, + {Start: 21, End: 36}, + }, + }, + { + name: "partly overlap2", + tl: [][]Timeline{ + { + {Start: 1, End: 4}, + {Start: 7, End: 11}, + {Start: 16, End: 20}, + }, + { + {Start: 3, End: 12}, + {Start: 15, End: 17}, + }, + { + {Start: 1, End: 12}, + {Start: 16, End: 18}, + }, + }, + expect: []Timeline{ + {Start: 3, End: 4}, + {Start: 7, End: 11}, + {Start: 16, End: 17}, + }, + }, + { + name: "redundant chunks", + tl: [][]Timeline{ + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 40}, + {Start: 42, End: 100500}, + }, + { + {Start: 2, End: 7}, + {Start: 7, End: 8}, + {Start: 8, End: 10}, + {Start: 14, End: 20}, + {Start: 20, End: 30}, + }, + { + {Start: 1, End: 5}, + {Start: 13, End: 19}, + {Start: 20, End: 30}, + }, + }, + expect: []Timeline{ + {Start: 3, End: 5}, + {Start: 14, End: 19}, + {Start: 20, End: 30}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := mergeTimelines(test.tl...) + if len(test.expect) != len(got) { + t.Fatalf("wrong timelines, exepct <%d> %v, got <%d> %v", len(test.expect), printTTL(test.expect...), len(got), printTTL(got...)) + } + for i, gl := range got { + if test.expect[i] != gl { + t.Errorf("wrong timeline %d, exepct %v, got %v", i, printTTL(test.expect[i]), printTTL(gl)) + } + } + }) + } +} + +func BenchmarkMergeTimelines(b *testing.B) { + tl := [][]Timeline{ + { + {Start: 3, End: 8}, + {Start: 14, End: 19}, + {Start: 21, End: 42}, + }, + { + {Start: 1, End: 3}, + {Start: 4, End: 7}, + {Start: 19, End: 36}, + }, + { + {Start: 5, End: 8}, + {Start: 14, End: 19}, + {Start: 20, End: 42}, + }, + { + {Start: 3, End: 6}, + {Start: 14, End: 19}, + {Start: 19, End: 40}, + {Start: 42, End: 100500}, + }, + { + {Start: 2, End: 7}, + {Start: 7, End: 8}, + {Start: 8, End: 10}, + {Start: 14, End: 20}, + {Start: 20, End: 30}, + {Start: 31, End: 40}, + {Start: 41, End: 50}, + {Start: 51, End: 60}, + }, + { + {Start: 1, End: 5}, + {Start: 13, End: 19}, + {Start: 20, End: 30}, + }, + } + for i := 0; i < b.N; i++ { + mergeTimelines(tl...) + } +} + +func printTTL(tlns ...Timeline) string { + ret := make([]string, 0, len(tlns)) + for _, t := range tlns { + ret = append(ret, fmt.Sprintf("[%v - %v]", t.Start, t.End)) + } + + return strings.Join(ret, ", ") +} diff --git a/managed/services/management/backup/artifacts_service.go b/managed/services/management/backup/artifacts_service.go index 5d958ec155..af3112e82a 100644 --- a/managed/services/management/backup/artifacts_service.go +++ b/managed/services/management/backup/artifacts_service.go @@ -18,31 +18,36 @@ package backup import ( "context" + "time" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" "gopkg.in/reform.v1" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" ) // ArtifactsService represents artifacts API. type ArtifactsService struct { - l *logrus.Entry - db *reform.DB - removalSVC removalService + l *logrus.Entry + db *reform.DB + removalSVC removalService + pitrTimerangeSVC pitrTimerangeService - backupv1beta1.UnimplementedArtifactsServer + backuppb.UnimplementedArtifactsServer } // NewArtifactsService creates new artifacts API service. -func NewArtifactsService(db *reform.DB, removalSVC removalService) *ArtifactsService { +func NewArtifactsService(db *reform.DB, removalSVC removalService, storage pitrTimerangeService) *ArtifactsService { return &ArtifactsService{ - l: logrus.WithField("component", "management/backup/artifacts"), - db: db, - removalSVC: removalSVC, + l: logrus.WithField("component", "management/backup/artifacts"), + db: db, + removalSVC: removalSVC, + pitrTimerangeSVC: storage, } } @@ -57,7 +62,7 @@ func (s *ArtifactsService) Enabled() bool { } // ListArtifacts returns a list of all artifacts. -func (s *ArtifactsService) ListArtifacts(context.Context, *backupv1beta1.ListArtifactsRequest) (*backupv1beta1.ListArtifactsResponse, error) { +func (s *ArtifactsService) ListArtifacts(context.Context, *backuppb.ListArtifactsRequest) (*backuppb.ListArtifactsResponse, error) { q := s.db.Querier artifacts, err := models.FindArtifacts(q, models.ArtifactFilters{}) @@ -86,7 +91,7 @@ func (s *ArtifactsService) ListArtifacts(context.Context, *backupv1beta1.ListArt return nil, err } - artifactsResponse := make([]*backupv1beta1.Artifact, 0, len(artifacts)) + artifactsResponse := make([]*backuppb.Artifact, 0, len(artifacts)) for _, b := range artifacts { convertedArtifact, err := convertArtifact(b, services, locations) if err != nil { @@ -94,7 +99,7 @@ func (s *ArtifactsService) ListArtifacts(context.Context, *backupv1beta1.ListArt } artifactsResponse = append(artifactsResponse, convertedArtifact) } - return &backupv1beta1.ListArtifactsResponse{ + return &backuppb.ListArtifactsResponse{ Artifacts: artifactsResponse, }, nil } @@ -102,42 +107,83 @@ func (s *ArtifactsService) ListArtifacts(context.Context, *backupv1beta1.ListArt // DeleteArtifact deletes specified artifact. func (s *ArtifactsService) DeleteArtifact( ctx context.Context, - req *backupv1beta1.DeleteArtifactRequest, -) (*backupv1beta1.DeleteArtifactResponse, error) { + req *backuppb.DeleteArtifactRequest, +) (*backuppb.DeleteArtifactResponse, error) { if err := s.removalSVC.DeleteArtifact(ctx, req.ArtifactId, req.RemoveFiles); err != nil { return nil, err } - return &backupv1beta1.DeleteArtifactResponse{}, nil + return &backuppb.DeleteArtifactResponse{}, nil } -func convertDataModel(model models.DataModel) (backupv1beta1.DataModel, error) { +// ListPitrTimeranges lists available PITR timelines/time-ranges (for MongoDB) +func (s *ArtifactsService) ListPitrTimeranges( + ctx context.Context, + req *backuppb.ListPitrTimerangesRequest, +) (*backuppb.ListPitrTimerangesResponse, error) { + var artifact *models.Artifact + var err error + + artifact, err = models.FindArtifactByID(s.db.Querier, req.ArtifactId) + if err != nil { + if errors.Is(err, models.ErrNotFound) { + return nil, status.Errorf(codes.NotFound, "Artifact with ID %q not found.", req.ArtifactId) + } + return nil, err + } + + if artifact.Mode != models.PITR { + return nil, status.Errorf(codes.FailedPrecondition, "Artifact is not a PITR artifact") + } + + location, err := models.FindBackupLocationByID(s.db.Querier, artifact.LocationID) + if err != nil { + return nil, err + } + + timelines, err := s.pitrTimerangeSVC.ListPITRTimeranges(ctx, artifact.Name, location) + if err != nil { + return nil, err + } + result := make([]*backuppb.PitrTimerange, 0, len(timelines)) + for _, tl := range timelines { + result = append(result, &backuppb.PitrTimerange{ + StartTimestamp: timestamppb.New(time.Unix(int64(tl.Start), 0)), + EndTimestamp: timestamppb.New(time.Unix(int64(tl.End), 0)), + }) + } + return &backuppb.ListPitrTimerangesResponse{ + Timeranges: result, + }, nil +} + +func convertDataModel(model models.DataModel) (backuppb.DataModel, error) { switch model { case models.PhysicalDataModel: - return backupv1beta1.DataModel_PHYSICAL, nil + return backuppb.DataModel_PHYSICAL, nil case models.LogicalDataModel: - return backupv1beta1.DataModel_LOGICAL, nil + return backuppb.DataModel_LOGICAL, nil default: return 0, errors.Errorf("unknown data model: %s", model) } } -func convertBackupStatus(status models.BackupStatus) (backupv1beta1.BackupStatus, error) { +func convertBackupStatus(status models.BackupStatus) (backuppb.BackupStatus, error) { switch status { case models.PendingBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_PENDING, nil + return backuppb.BackupStatus_BACKUP_STATUS_PENDING, nil case models.InProgressBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_IN_PROGRESS, nil + return backuppb.BackupStatus_BACKUP_STATUS_IN_PROGRESS, nil case models.PausedBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_PAUSED, nil + return backuppb.BackupStatus_BACKUP_STATUS_PAUSED, nil case models.SuccessBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_SUCCESS, nil + return backuppb.BackupStatus_BACKUP_STATUS_SUCCESS, nil case models.ErrorBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_ERROR, nil + return backuppb.BackupStatus_BACKUP_STATUS_ERROR, nil case models.DeletingBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_DELETING, nil + return backuppb.BackupStatus_BACKUP_STATUS_DELETING, nil case models.FailedToDeleteBackupStatus: - return backupv1beta1.BackupStatus_BACKUP_STATUS_FAILED_TO_DELETE, nil + return backuppb.BackupStatus_BACKUP_STATUS_FAILED_TO_DELETE, nil default: return 0, errors.Errorf("invalid status '%s'", status) } @@ -147,7 +193,7 @@ func convertArtifact( a *models.Artifact, services map[string]*models.Service, locationModels map[string]*models.BackupLocation, -) (*backupv1beta1.Artifact, error) { +) (*backuppb.Artifact, error) { createdAt := timestamppb.New(a.CreatedAt) if err := createdAt.CheckValid(); err != nil { return nil, errors.Wrap(err, "failed to convert timestamp") @@ -179,7 +225,7 @@ func convertArtifact( return nil, errors.Wrapf(err, "artifact id '%s'", a.ID) } - return &backupv1beta1.Artifact{ + return &backuppb.Artifact{ ArtifactId: a.ID, Name: a.Name, Vendor: a.Vendor, @@ -196,5 +242,5 @@ func convertArtifact( // Check interfaces. var ( - _ backupv1beta1.ArtifactsServer = (*ArtifactsService)(nil) + _ backuppb.ArtifactsServer = (*ArtifactsService)(nil) ) diff --git a/managed/services/management/backup/artifacts_service_test.go b/managed/services/management/backup/artifacts_service_test.go new file mode 100644 index 0000000000..94f57e78b9 --- /dev/null +++ b/managed/services/management/backup/artifacts_service_test.go @@ -0,0 +1,127 @@ +// Copyright (C) 2022 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package backup + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/brianvoe/gofakeit/v6" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gopkg.in/reform.v1" + "gopkg.in/reform.v1/dialects/postgresql" + + backuppb "github.com/percona/pmm/api/managementpb/backup" + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/services/backup" + "github.com/percona/pmm/managed/utils/testdb" + "github.com/percona/pmm/managed/utils/tests" +) + +func TestListPitrTimelines(t *testing.T) { + ctx := context.Background() + sqlDB := testdb.Open(t, models.SkipFixtures, nil) + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) + + mockedPitrStorageSvc := &mockPitrTimerangeService{} + + timelines := []backup.Timeline{ + { + ReplicaSet: "rs0", + Start: uint32(time.Now().Unix()), + End: uint32(time.Now().Unix()), + }, + } + + mockedPitrStorageSvc.On("ListPITRTimeranges", ctx, mock.Anything, mock.Anything).Return(timelines, nil) + artifactsService := NewArtifactsService(db, nil, mockedPitrStorageSvc) + var locationID string + + params := models.CreateBackupLocationParams{ + Name: gofakeit.Name(), + Description: "", + } + params.S3Config = &models.S3LocationConfig{ + Endpoint: "https://awsS3.us-west-2.amazonaws.com/", + AccessKey: "access_key", + SecretKey: "secret_key", + BucketName: "example_bucket", + BucketRegion: "us-east-1", + } + loc, err := models.CreateBackupLocation(db.Querier, params) + require.NoError(t, err) + require.NotEmpty(t, loc.ID) + + locationID = loc.ID + + t.Run("successfully lists PITR time ranges", func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ + Name: "test_artifact", + Vendor: "test_vendor", + LocationID: locationID, + ServiceID: "test_service", + Mode: models.PITR, + DataModel: models.LogicalDataModel, + Status: models.PendingBackupStatus, + }) + assert.NoError(t, err) + assert.NotEmpty(t, artifact.ID) + + response, err := artifactsService.ListPitrTimeranges(ctx, &backuppb.ListPitrTimerangesRequest{ + ArtifactId: artifact.ID, + }) + require.NoError(t, err) + require.NotNil(t, response) + assert.Len(t, response.Timeranges, 1) + }) + + t.Run("fails for invalid artifact ID", func(t *testing.T) { + unknownID := "artifact_id/" + uuid.New().String() + response, err := artifactsService.ListPitrTimeranges(ctx, &backuppb.ListPitrTimerangesRequest{ + ArtifactId: unknownID, + }) + tests.AssertGRPCError(t, status.New(codes.NotFound, fmt.Sprintf("Artifact with ID %q not found.", unknownID)), err) + assert.Nil(t, response) + }) + + t.Run("fails for non-PITR artifact", func(t *testing.T) { + artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{ + Name: "test_non_pitr_artifact", + Vendor: "test_vendor", + LocationID: locationID, + ServiceID: "test_service", + Mode: models.Snapshot, + DataModel: models.LogicalDataModel, + Status: models.PendingBackupStatus, + }) + assert.NoError(t, err) + assert.NotEmpty(t, artifact.ID) + + response, err := artifactsService.ListPitrTimeranges(ctx, &backuppb.ListPitrTimerangesRequest{ + ArtifactId: artifact.ID, + }) + tests.AssertGRPCError(t, status.New(codes.FailedPrecondition, "Artifact is not a PITR artifact"), err) + assert.Nil(t, response) + }) + mock.AssertExpectationsForObjects(t, mockedPitrStorageSvc) +} diff --git a/managed/services/management/backup/backups_service.go b/managed/services/management/backup/backups_service.go index 855f96ba52..e32c963dc3 100644 --- a/managed/services/management/backup/backups_service.go +++ b/managed/services/management/backup/backups_service.go @@ -27,10 +27,11 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" "gopkg.in/reform.v1" "github.com/percona/pmm/api/inventorypb" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services" "github.com/percona/pmm/managed/services/agents" @@ -46,7 +47,7 @@ type BackupsService struct { scheduleService scheduleService l *logrus.Entry - backupv1beta1.UnimplementedBackupsServer + backuppb.UnimplementedBackupsServer } const ( @@ -70,41 +71,8 @@ func NewBackupsService( } } -func convertBackupError(restoreError error) error { - if restoreError == nil { - return nil - } - - var code backupv1beta1.ErrorCode - switch { - case errors.Is(restoreError, backup.ErrIncompatibleService): - return status.Error(codes.FailedPrecondition, restoreError.Error()) - case errors.Is(restoreError, backup.ErrXtrabackupNotInstalled): - code = backupv1beta1.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED - case errors.Is(restoreError, backup.ErrInvalidXtrabackup): - code = backupv1beta1.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP - case errors.Is(restoreError, backup.ErrIncompatibleXtrabackup): - code = backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP - - case errors.Is(restoreError, agents.ErrIncompatibleAgentVersion): - return status.Error(codes.FailedPrecondition, restoreError.Error()) - - default: - return restoreError - } - - st, err := status.New(codes.FailedPrecondition, restoreError.Error()).WithDetails(&backupv1beta1.Error{ - Code: code, - }) - if err != nil { - return fmt.Errorf("failed to construct status error: %w, restore error: %s", err, restoreError) - } - - return st.Err() -} - // StartBackup starts on-demand backup. -func (s *BackupsService) StartBackup(ctx context.Context, req *backupv1beta1.StartBackupRequest) (*backupv1beta1.StartBackupResponse, error) { +func (s *BackupsService) StartBackup(ctx context.Context, req *backuppb.StartBackupRequest) (*backuppb.StartBackupResponse, error) { if req.Retries > maxRetriesAttempts { return nil, status.Errorf(codes.InvalidArgument, "Exceeded max retries %d.", maxRetriesAttempts) } @@ -141,63 +109,43 @@ func (s *BackupsService) StartBackup(ctx context.Context, req *backupv1beta1.Sta return nil, convertBackupError(err) } - return &backupv1beta1.StartBackupResponse{ + return &backuppb.StartBackupResponse{ ArtifactId: artifactID, }, nil } -func convertRestoreBackupError(restoreError error) error { - if restoreError == nil { - return nil +// RestoreBackup starts restore backup job. +func (s *BackupsService) RestoreBackup( + ctx context.Context, + req *backuppb.RestoreBackupRequest, +) (*backuppb.RestoreBackupResponse, error) { + // Disable all related scheduled backups before restoring + tasks, err := models.FindScheduledTasks(s.db.Querier, models.ScheduledTasksFilter{ServiceID: req.ServiceId}) + if err != nil { + return nil, err } - var code backupv1beta1.ErrorCode - switch { - case errors.Is(restoreError, backup.ErrIncompatibleService): - return status.Error(codes.FailedPrecondition, restoreError.Error()) - case errors.Is(restoreError, backup.ErrXtrabackupNotInstalled): - code = backupv1beta1.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED - case errors.Is(restoreError, backup.ErrInvalidXtrabackup): - code = backupv1beta1.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP - case errors.Is(restoreError, backup.ErrIncompatibleXtrabackup): - code = backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP - case errors.Is(restoreError, backup.ErrIncompatibleTargetMySQL): - code = backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MYSQL - - case errors.Is(restoreError, agents.ErrIncompatibleAgentVersion): - return status.Error(codes.FailedPrecondition, restoreError.Error()) - - default: - return restoreError + for _, t := range tasks { + if _, err := s.ChangeScheduledBackup(ctx, &backuppb.ChangeScheduledBackupRequest{ + ScheduledBackupId: t.ID, + Enabled: &wrapperspb.BoolValue{Value: false}, + }); err != nil { + return nil, err + } } - st, err := status.New(codes.FailedPrecondition, restoreError.Error()).WithDetails(&backupv1beta1.Error{ - Code: code, - }) - if err != nil { - return fmt.Errorf("failed to construct status error: %w, restore error: %s", err, restoreError) - } - - return st.Err() -} - -// RestoreBackup starts restore backup job. -func (s *BackupsService) RestoreBackup( - ctx context.Context, - req *backupv1beta1.RestoreBackupRequest, -) (*backupv1beta1.RestoreBackupResponse, error) { - id, err := s.backupService.RestoreBackup(ctx, req.ServiceId, req.ArtifactId) + id, err := s.backupService.RestoreBackup(ctx, req.ServiceId, req.ArtifactId, req.PitrTimestamp.AsTime()) if err != nil { return nil, convertRestoreBackupError(err) } - return &backupv1beta1.RestoreBackupResponse{ + return &backuppb.RestoreBackupResponse{ RestoreId: id, }, nil } // ScheduleBackup add new backup task to scheduler. -func (s *BackupsService) ScheduleBackup(ctx context.Context, req *backupv1beta1.ScheduleBackupRequest) (*backupv1beta1.ScheduleBackupResponse, error) { +func (s *BackupsService) ScheduleBackup(ctx context.Context, req *backuppb.ScheduleBackupRequest) (*backuppb.ScheduleBackupResponse, error) { var id string if req.Retries > maxRetriesAttempts { @@ -281,11 +229,11 @@ func (s *BackupsService) ScheduleBackup(ctx context.Context, req *backupv1beta1. if errTx != nil { return nil, errTx } - return &backupv1beta1.ScheduleBackupResponse{ScheduledBackupId: id}, nil + return &backuppb.ScheduleBackupResponse{ScheduledBackupId: id}, nil } // ListScheduledBackups lists all tasks related to backup. -func (s *BackupsService) ListScheduledBackups(ctx context.Context, req *backupv1beta1.ListScheduledBackupsRequest) (*backupv1beta1.ListScheduledBackupsResponse, error) { +func (s *BackupsService) ListScheduledBackups(ctx context.Context, req *backuppb.ListScheduledBackupsRequest) (*backuppb.ListScheduledBackupsResponse, error) { tasks, err := models.FindScheduledTasks(s.db.Querier, models.ScheduledTasksFilter{ Types: []models.ScheduledTaskType{ models.ScheduledMySQLBackupTask, @@ -324,7 +272,7 @@ func (s *BackupsService) ListScheduledBackups(ctx context.Context, req *backupv1 return nil, err } - scheduledBackups := make([]*backupv1beta1.ScheduledBackup, 0, len(tasks)) + scheduledBackups := make([]*backuppb.ScheduledBackup, 0, len(tasks)) for _, task := range tasks { scheduledBackup, err := convertTaskToScheduledBackup(task, svcs, locations) if err != nil { @@ -334,13 +282,13 @@ func (s *BackupsService) ListScheduledBackups(ctx context.Context, req *backupv1 scheduledBackups = append(scheduledBackups, scheduledBackup) } - return &backupv1beta1.ListScheduledBackupsResponse{ + return &backuppb.ListScheduledBackupsResponse{ ScheduledBackups: scheduledBackups, }, nil } // ChangeScheduledBackup changes existing scheduled backup task. -func (s *BackupsService) ChangeScheduledBackup(ctx context.Context, req *backupv1beta1.ChangeScheduledBackupRequest) (*backupv1beta1.ChangeScheduledBackupResponse, error) { +func (s *BackupsService) ChangeScheduledBackup(ctx context.Context, req *backuppb.ChangeScheduledBackupRequest) (*backuppb.ChangeScheduledBackupResponse, error) { var disablePITR bool var serviceID string @@ -427,11 +375,11 @@ func (s *BackupsService) ChangeScheduledBackup(ctx context.Context, req *backupv } } - return &backupv1beta1.ChangeScheduledBackupResponse{}, nil + return &backuppb.ChangeScheduledBackupResponse{}, nil } // RemoveScheduledBackup stops and removes existing scheduled backup task. -func (s *BackupsService) RemoveScheduledBackup(ctx context.Context, req *backupv1beta1.RemoveScheduledBackupRequest) (*backupv1beta1.RemoveScheduledBackupResponse, error) { +func (s *BackupsService) RemoveScheduledBackup(ctx context.Context, req *backuppb.RemoveScheduledBackupRequest) (*backuppb.RemoveScheduledBackupResponse, error) { task, err := models.FindScheduledTaskByID(s.db.Querier, req.ScheduledBackupId) if err != nil { return nil, err @@ -477,11 +425,11 @@ func (s *BackupsService) RemoveScheduledBackup(ctx context.Context, req *backupv } } - return &backupv1beta1.RemoveScheduledBackupResponse{}, nil + return &backuppb.RemoveScheduledBackupResponse{}, nil } // GetLogs returns logs for artifact. -func (s *BackupsService) GetLogs(ctx context.Context, req *backupv1beta1.GetLogsRequest) (*backupv1beta1.GetLogsResponse, error) { +func (s *BackupsService) GetLogs(ctx context.Context, req *backuppb.GetLogsRequest) (*backuppb.GetLogsResponse, error) { jobs, err := models.FindJobs(s.db.Querier, models.JobsFilter{ ArtifactID: req.ArtifactId, Types: []models.JobType{ @@ -512,15 +460,15 @@ func (s *BackupsService) GetLogs(ctx context.Context, req *backupv1beta1.GetLogs return nil, err } - res := &backupv1beta1.GetLogsResponse{ - Logs: make([]*backupv1beta1.LogChunk, 0, len(jobLogs)), + res := &backuppb.GetLogsResponse{ + Logs: make([]*backuppb.LogChunk, 0, len(jobLogs)), } for _, log := range jobLogs { if log.LastChunk { res.End = true break } - res.Logs = append(res.Logs, &backupv1beta1.LogChunk{ + res.Logs = append(res.Logs, &backuppb.LogChunk{ ChunkId: uint32(log.ChunkID), Data: log.Data, }) @@ -532,8 +480,8 @@ func (s *BackupsService) GetLogs(ctx context.Context, req *backupv1beta1.GetLogs // ListArtifactCompatibleServices lists compatible service for restoring given artifact. func (s *BackupsService) ListArtifactCompatibleServices( ctx context.Context, - req *backupv1beta1.ListArtifactCompatibleServicesRequest, -) (*backupv1beta1.ListArtifactCompatibleServicesResponse, error) { + req *backuppb.ListArtifactCompatibleServicesRequest, +) (*backuppb.ListArtifactCompatibleServicesResponse, error) { compatibleServices, err := s.compatibilityService.FindArtifactCompatibleServices(ctx, req.ArtifactId) switch { case err == nil: @@ -543,7 +491,7 @@ func (s *BackupsService) ListArtifactCompatibleServices( return nil, err } - res := &backupv1beta1.ListArtifactCompatibleServicesResponse{} + res := &backuppb.ListArtifactCompatibleServicesResponse{} for _, service := range compatibleServices { apiService, err := services.ToAPIService(service) if err != nil { @@ -571,8 +519,8 @@ func (s *BackupsService) ListArtifactCompatibleServices( func convertTaskToScheduledBackup(task *models.ScheduledTask, services map[string]*models.Service, locationModels map[string]*models.BackupLocation, -) (*backupv1beta1.ScheduledBackup, error) { - scheduledBackup := &backupv1beta1.ScheduledBackup{ +) (*backuppb.ScheduledBackup, error) { + scheduledBackup := &backuppb.ScheduledBackup{ ScheduledBackupId: task.ID, CronExpression: task.CronExpression, Enabled: !task.Disabled, @@ -627,46 +575,123 @@ func convertTaskToScheduledBackup(task *models.ScheduledTask, return scheduledBackup, nil } -func convertBackupModeToModel(mode backupv1beta1.BackupMode) (models.BackupMode, error) { +func convertBackupModeToModel(mode backuppb.BackupMode) (models.BackupMode, error) { switch mode { - case backupv1beta1.BackupMode_SNAPSHOT: + case backuppb.BackupMode_SNAPSHOT: return models.Snapshot, nil - case backupv1beta1.BackupMode_INCREMENTAL: + case backuppb.BackupMode_INCREMENTAL: return models.Incremental, nil - case backupv1beta1.BackupMode_PITR: + case backuppb.BackupMode_PITR: return models.PITR, nil - case backupv1beta1.BackupMode_BACKUP_MODE_INVALID: + case backuppb.BackupMode_BACKUP_MODE_INVALID: return "", status.Errorf(codes.InvalidArgument, "invalid backup mode: %s", mode.String()) default: return "", status.Errorf(codes.InvalidArgument, "Unknown backup mode: %s", mode.String()) } } -func convertModelToBackupMode(mode models.BackupMode) (backupv1beta1.BackupMode, error) { +func convertModelToBackupMode(mode models.BackupMode) (backuppb.BackupMode, error) { switch mode { case models.Snapshot: - return backupv1beta1.BackupMode_SNAPSHOT, nil + return backuppb.BackupMode_SNAPSHOT, nil case models.Incremental: - return backupv1beta1.BackupMode_INCREMENTAL, nil + return backuppb.BackupMode_INCREMENTAL, nil case models.PITR: - return backupv1beta1.BackupMode_PITR, nil + return backuppb.BackupMode_PITR, nil default: return 0, errors.Errorf("unknown backup mode: %s", mode) } } -func convertModelToBackupModel(dataModel backupv1beta1.DataModel) (models.DataModel, error) { +func convertModelToBackupModel(dataModel backuppb.DataModel) (models.DataModel, error) { switch dataModel { - case backupv1beta1.DataModel_LOGICAL: + case backuppb.DataModel_LOGICAL: return models.LogicalDataModel, nil - case backupv1beta1.DataModel_PHYSICAL: + case backuppb.DataModel_PHYSICAL: return models.PhysicalDataModel, nil default: return "", errors.Errorf("unknown backup mode: %s", dataModel) } } +func convertBackupError(restoreError error) error { + if restoreError == nil { + return nil + } + + var code backuppb.ErrorCode + switch { + case errors.Is(restoreError, backup.ErrIncompatibleService): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + case errors.Is(restoreError, backup.ErrXtrabackupNotInstalled): + code = backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED + case errors.Is(restoreError, backup.ErrInvalidXtrabackup): + code = backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP + case errors.Is(restoreError, backup.ErrIncompatibleXtrabackup): + code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP + + case errors.Is(restoreError, agents.ErrIncompatibleAgentVersion): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + + default: + return restoreError + } + + st, err := status.New(codes.FailedPrecondition, restoreError.Error()).WithDetails(&backuppb.Error{ + Code: code, + }) + if err != nil { + return fmt.Errorf("failed to construct status error: %w, restore error: %s", err, restoreError) + } + + return st.Err() +} + +func convertRestoreBackupError(restoreError error) error { + if restoreError == nil { + return nil + } + + var code backuppb.ErrorCode + switch { + case errors.Is(restoreError, backup.ErrIncompatibleService): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + case errors.Is(restoreError, backup.ErrXtrabackupNotInstalled): + code = backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED + case errors.Is(restoreError, backup.ErrInvalidXtrabackup): + code = backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP + case errors.Is(restoreError, backup.ErrIncompatibleXtrabackup): + code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP + case errors.Is(restoreError, backup.ErrIncompatibleTargetMySQL): + code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MYSQL + case errors.Is(restoreError, backup.ErrTimestampOutOfRange): + return status.Error(codes.OutOfRange, restoreError.Error()) + case errors.Is(restoreError, backup.ErrIncompatibleArtifactMode): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + case errors.Is(restoreError, agents.ErrIncompatibleAgentVersion): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + case errors.Is(restoreError, models.ErrNotFound): + return status.Error(codes.NotFound, restoreError.Error()) + case errors.Is(restoreError, backup.ErrAnotherOperationInProgress): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + case errors.Is(restoreError, backup.ErrArtifactNotReady): + return status.Error(codes.FailedPrecondition, restoreError.Error()) + + default: + return restoreError + } + + st, err := status.New(codes.FailedPrecondition, restoreError.Error()).WithDetails(&backuppb.Error{ + Code: code, + }) + if err != nil { + return fmt.Errorf("failed to construct status error: %w, restore error: %s", err, restoreError) + } + + return st.Err() +} + // Check interfaces. var ( - _ backupv1beta1.BackupsServer = (*BackupsService)(nil) + _ backuppb.BackupsServer = (*BackupsService)(nil) ) diff --git a/managed/services/management/backup/backups_service_test.go b/managed/services/management/backup/backups_service_test.go index 02be92f065..d2c037a203 100644 --- a/managed/services/management/backup/backups_service_test.go +++ b/managed/services/management/backup/backups_service_test.go @@ -33,7 +33,7 @@ import ( "gopkg.in/reform.v1" "gopkg.in/reform.v1/dialects/postgresql" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services/backup" "github.com/percona/pmm/managed/services/scheduler" @@ -87,22 +87,22 @@ func TestStartBackup(t *testing.T) { for _, tc := range []struct { testName string backupError error - code backupv1beta1.ErrorCode + code backuppb.ErrorCode }{ { testName: "xtrabackup not installed", backupError: backup.ErrXtrabackupNotInstalled, - code: backupv1beta1.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED, + code: backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED, }, { testName: "invalid xtrabackup", backupError: backup.ErrInvalidXtrabackup, - code: backupv1beta1.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP, + code: backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP, }, { testName: "incompatible xtrabackup", backupError: backup.ErrIncompatibleXtrabackup, - code: backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP, + code: backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP, }, } { t.Run(tc.testName, func(t *testing.T) { @@ -110,7 +110,7 @@ func TestStartBackup(t *testing.T) { backupService.On("PerformBackup", mock.Anything, mock.Anything). Return("", backupError).Once() ctx := context.Background() - resp, err := backupSvc.StartBackup(ctx, &backupv1beta1.StartBackupRequest{ + resp, err := backupSvc.StartBackup(ctx, &backuppb.StartBackupRequest{ ServiceId: *agent.ServiceID, LocationId: "locationID", Name: "name", @@ -124,7 +124,7 @@ func TestStartBackup(t *testing.T) { assert.Equal(t, codes.FailedPrecondition, st.Code()) assert.Equal(t, backupError.Error(), st.Message()) require.Len(t, st.Details(), 1) - detailedError, ok := st.Details()[0].(*backupv1beta1.Error) + detailedError, ok := st.Details()[0].(*backuppb.Error) require.True(t, ok) assert.Equal(t, tc.code, detailedError.Code) }) @@ -156,14 +156,14 @@ func TestStartBackup(t *testing.T) { backupService := &mockBackupService{} backupSvc := NewBackupsService(db, backupService, nil, nil) backupService.On("PerformBackup", mock.Anything, mock.Anything).Return("", nil) - _, err := backupSvc.StartBackup(ctx, &backupv1beta1.StartBackupRequest{ + _, err := backupSvc.StartBackup(ctx, &backuppb.StartBackupRequest{ ServiceId: *agent.ServiceID, LocationId: locationRes.ID, Name: "name", Description: "description", RetryInterval: nil, Retries: 0, - DataModel: backupv1beta1.DataModel_PHYSICAL, + DataModel: backuppb.DataModel_PHYSICAL, }) require.NoError(t, err) }) @@ -171,41 +171,43 @@ func TestStartBackup(t *testing.T) { } func TestRestoreBackupErrors(t *testing.T) { + sqlDB := testdb.Open(t, models.SkipFixtures, nil) + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) backupService := &mockBackupService{} - backupSvc := NewBackupsService(nil, backupService, nil, nil) + backupSvc := NewBackupsService(db, backupService, nil, nil) for _, tc := range []struct { testName string backupError error - code backupv1beta1.ErrorCode + code backuppb.ErrorCode }{ { testName: "xtrabackup not installed", backupError: backup.ErrXtrabackupNotInstalled, - code: backupv1beta1.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED, + code: backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED, }, { testName: "invalid xtrabackup", backupError: backup.ErrInvalidXtrabackup, - code: backupv1beta1.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP, + code: backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP, }, { testName: "incompatible xtrabackup", backupError: backup.ErrIncompatibleXtrabackup, - code: backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP, + code: backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP, }, { testName: "target MySQL is not compatible", backupError: backup.ErrIncompatibleTargetMySQL, - code: backupv1beta1.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MYSQL, + code: backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MYSQL, }, } { t.Run(tc.testName, func(t *testing.T) { backupError := fmt.Errorf("error: %w", tc.backupError) - backupService.On("RestoreBackup", mock.Anything, "serviceID1", "artifactID1"). + backupService.On("RestoreBackup", mock.Anything, "serviceID1", "artifactID1", mock.Anything). Return("", backupError).Once() ctx := context.Background() - resp, err := backupSvc.RestoreBackup(ctx, &backupv1beta1.RestoreBackupRequest{ + resp, err := backupSvc.RestoreBackup(ctx, &backuppb.RestoreBackupRequest{ ServiceId: "serviceID1", ArtifactId: "artifactID1", }) @@ -215,7 +217,7 @@ func TestRestoreBackupErrors(t *testing.T) { assert.Equal(t, codes.FailedPrecondition, st.Code()) assert.Equal(t, backupError.Error(), st.Message()) require.Len(t, st.Details(), 1) - detailedError, ok := st.Details()[0].(*backupv1beta1.Error) + detailedError, ok := st.Details()[0].(*backuppb.Error) require.True(t, ok) assert.Equal(t, tc.code, detailedError.Code) }) @@ -252,7 +254,7 @@ func TestScheduledBackups(t *testing.T) { agent := setup(t, db.Querier, models.MySQLServiceType, t.Name()) t.Run("schedule/change", func(t *testing.T) { - req := &backupv1beta1.ScheduleBackupRequest{ + req := &backuppb.ScheduleBackupRequest{ ServiceId: pointer.GetString(agent.ServiceID), LocationId: locationRes.ID, CronExpression: "1 * * * *", @@ -260,7 +262,7 @@ func TestScheduledBackups(t *testing.T) { Name: t.Name(), Description: t.Name(), Enabled: true, - Mode: backupv1beta1.BackupMode_SNAPSHOT, + Mode: backuppb.BackupMode_SNAPSHOT, Retries: maxRetriesAttempts - 1, RetryInterval: durationpb.New(maxRetryInterval), } @@ -281,7 +283,7 @@ func TestScheduledBackups(t *testing.T) { assert.Equal(t, req.Retries, data.Retries) assert.Equal(t, req.RetryInterval.AsDuration(), data.RetryInterval) - changeReq := &backupv1beta1.ChangeScheduledBackupRequest{ + changeReq := &backuppb.ChangeScheduledBackupRequest{ ScheduledBackupId: task.ID, Enabled: wrapperspb.Bool(false), CronExpression: wrapperspb.String("2 * * * *"), @@ -306,7 +308,7 @@ func TestScheduledBackups(t *testing.T) { }) t.Run("list", func(t *testing.T) { - res, err := backupSvc.ListScheduledBackups(ctx, &backupv1beta1.ListScheduledBackupsRequest{}) + res, err := backupSvc.ListScheduledBackups(ctx, &backuppb.ListScheduledBackupsRequest{}) assert.NoError(t, err) assert.Len(t, res.ScheduledBackups, 1) @@ -333,7 +335,7 @@ func TestScheduledBackups(t *testing.T) { }) require.NoError(t, err) - _, err = backupSvc.RemoveScheduledBackup(ctx, &backupv1beta1.RemoveScheduledBackupRequest{ + _, err = backupSvc.RemoveScheduledBackup(ctx, &backuppb.RemoveScheduledBackupRequest{ ScheduledBackupId: task.ID, }) assert.NoError(t, err) @@ -360,15 +362,15 @@ func TestScheduledBackups(t *testing.T) { backupSvc := NewBackupsService(db, nil, nil, schedulerService) schedulerService.On("Add", mock.Anything, mock.Anything).Return("", nil) - _, err := backupSvc.ScheduleBackup(ctx, &backupv1beta1.ScheduleBackupRequest{ + _, err := backupSvc.ScheduleBackup(ctx, &backuppb.ScheduleBackupRequest{ ServiceId: *agent.ServiceID, LocationId: locationRes.ID, Name: "name", Description: "description", RetryInterval: durationpb.New(maxRetryInterval), Retries: maxRetriesAttempts, - DataModel: backupv1beta1.DataModel_PHYSICAL, - Mode: backupv1beta1.BackupMode_PITR, + DataModel: backuppb.DataModel_PHYSICAL, + Mode: backuppb.BackupMode_PITR, }) require.Error(t, err) tests.AssertGRPCErrorRE(t, codes.InvalidArgument, "PITR is only supported for logical backups", err) @@ -379,15 +381,15 @@ func TestScheduledBackups(t *testing.T) { schedulerService := &mockScheduleService{} backupSvc := NewBackupsService(db, nil, nil, schedulerService) schedulerService.On("Add", mock.Anything, mock.Anything).Return(&models.ScheduledTask{}, nil) - _, err := backupSvc.ScheduleBackup(ctx, &backupv1beta1.ScheduleBackupRequest{ + _, err := backupSvc.ScheduleBackup(ctx, &backuppb.ScheduleBackupRequest{ ServiceId: *agent.ServiceID, LocationId: locationRes.ID, Name: "name", Description: "description", RetryInterval: durationpb.New(maxRetryInterval), Retries: maxRetriesAttempts, - DataModel: backupv1beta1.DataModel_PHYSICAL, - Mode: backupv1beta1.BackupMode_SNAPSHOT, + DataModel: backuppb.DataModel_PHYSICAL, + Mode: backuppb.BackupMode_SNAPSHOT, }) require.NoError(t, err) }) @@ -453,7 +455,7 @@ func TestGetLogs(t *testing.T) { }, } for _, tc := range testCases { - logs, err := backupSvc.GetLogs(ctx, &backupv1beta1.GetLogsRequest{ + logs, err := backupSvc.GetLogs(ctx, &backuppb.GetLogsRequest{ ArtifactId: "artifact", Offset: tc.offset, Limit: tc.limit, diff --git a/managed/services/management/backup/deps.go b/managed/services/management/backup/deps.go index d917077217..4b43efd318 100644 --- a/managed/services/management/backup/deps.go +++ b/managed/services/management/backup/deps.go @@ -17,6 +17,7 @@ package backup import ( "context" + "time" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services/backup" @@ -27,6 +28,7 @@ import ( //go:generate ../../../../bin/mockery -name=backupService -case=snake -inpkg -testonly //go:generate ../../../../bin/mockery -name=scheduleService -case=snake -inpkg -testonly //go:generate ../../../../bin/mockery -name=removalService -case=snake -inpkg -testonly +//go:generate ../../../../bin/mockery -name=pitrTimerangeService -case=snake -inpkg -testonly type awsS3 interface { GetBucketLocation(ctx context.Context, host string, accessKey, secretKey, name string) (string, error) @@ -36,7 +38,7 @@ type awsS3 interface { type backupService interface { PerformBackup(ctx context.Context, params backup.PerformBackupParams) (string, error) - RestoreBackup(ctx context.Context, serviceID, artifactID string) (string, error) + RestoreBackup(ctx context.Context, serviceID, artifactID string, pitrTimestamp time.Time) (string, error) SwitchMongoPITR(ctx context.Context, serviceID string, enabled bool) error } @@ -56,3 +58,9 @@ type scheduleService interface { type removalService interface { DeleteArtifact(ctx context.Context, artifactID string, removeFiles bool) error } + +// pitrTimerangeService provides methods that help us inspect PITR artifacts +type pitrTimerangeService interface { + // ListPITRTimeranges returns the available PITR timeranges for the given artifact in the provided location + ListPITRTimeranges(ctx context.Context, artifactName string, location *models.BackupLocation) ([]backup.Timeline, error) +} diff --git a/managed/services/management/backup/locations_service.go b/managed/services/management/backup/locations_service.go index 8808c6e361..fbe8e7ad77 100644 --- a/managed/services/management/backup/locations_service.go +++ b/managed/services/management/backup/locations_service.go @@ -25,7 +25,7 @@ import ( "google.golang.org/grpc/status" "gopkg.in/reform.v1" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" ) @@ -35,7 +35,7 @@ type LocationsService struct { s3 awsS3 l *logrus.Entry - backupv1beta1.UnimplementedLocationsServer + backuppb.UnimplementedLocationsServer } // NewLocationsService creates new backup locations API service. @@ -58,12 +58,12 @@ func (s *LocationsService) Enabled() bool { } // ListLocations returns list of all available backup locations. -func (s *LocationsService) ListLocations(ctx context.Context, req *backupv1beta1.ListLocationsRequest) (*backupv1beta1.ListLocationsResponse, error) { +func (s *LocationsService) ListLocations(ctx context.Context, req *backuppb.ListLocationsRequest) (*backuppb.ListLocationsResponse, error) { locations, err := models.FindBackupLocations(s.db.Querier) if err != nil { return nil, err } - res := make([]*backupv1beta1.Location, len(locations)) + res := make([]*backuppb.Location, len(locations)) for i, location := range locations { loc, err := convertLocation(location) if err != nil { @@ -71,13 +71,13 @@ func (s *LocationsService) ListLocations(ctx context.Context, req *backupv1beta1 } res[i] = loc } - return &backupv1beta1.ListLocationsResponse{ + return &backuppb.ListLocationsResponse{ Locations: res, }, nil } // AddLocation adds new backup location. -func (s *LocationsService) AddLocation(ctx context.Context, req *backupv1beta1.AddLocationRequest) (*backupv1beta1.AddLocationResponse, error) { +func (s *LocationsService) AddLocation(ctx context.Context, req *backuppb.AddLocationRequest) (*backuppb.AddLocationResponse, error) { params := models.CreateBackupLocationParams{ Name: req.Name, Description: req.Description, @@ -92,9 +92,9 @@ func (s *LocationsService) AddLocation(ctx context.Context, req *backupv1beta1.A } } - if req.PmmClientConfig != nil { - params.PMMClientConfig = &models.PMMClientLocationConfig{ - Path: req.PmmClientConfig.Path, + if req.FilesystemConfig != nil { + params.FilesystemConfig = &models.FilesystemLocationConfig{ + Path: req.FilesystemConfig.Path, } } @@ -127,13 +127,13 @@ func (s *LocationsService) AddLocation(ctx context.Context, req *backupv1beta1.A return nil, err } - return &backupv1beta1.AddLocationResponse{ + return &backuppb.AddLocationResponse{ LocationId: locationModel.ID, }, nil } // ChangeLocation changes existing backup location. -func (s *LocationsService) ChangeLocation(ctx context.Context, req *backupv1beta1.ChangeLocationRequest) (*backupv1beta1.ChangeLocationResponse, error) { +func (s *LocationsService) ChangeLocation(ctx context.Context, req *backuppb.ChangeLocationRequest) (*backuppb.ChangeLocationResponse, error) { params := models.ChangeBackupLocationParams{ Name: req.Name, Description: req.Description, @@ -148,9 +148,9 @@ func (s *LocationsService) ChangeLocation(ctx context.Context, req *backupv1beta } } - if req.PmmClientConfig != nil { - params.PMMClientConfig = &models.PMMClientLocationConfig{ - Path: req.PmmClientConfig.Path, + if req.FilesystemConfig != nil { + params.FilesystemConfig = &models.FilesystemLocationConfig{ + Path: req.FilesystemConfig.Path, } } if err := params.Validate(models.BackupLocationValidationParams{ @@ -180,14 +180,14 @@ func (s *LocationsService) ChangeLocation(ctx context.Context, req *backupv1beta return nil, err } - return &backupv1beta1.ChangeLocationResponse{}, nil + return &backuppb.ChangeLocationResponse{}, nil } // TestLocationConfig tests backup location and credentials. func (s *LocationsService) TestLocationConfig( ctx context.Context, - req *backupv1beta1.TestLocationConfigRequest, -) (*backupv1beta1.TestLocationConfigResponse, error) { + req *backuppb.TestLocationConfigRequest, +) (*backuppb.TestLocationConfigResponse, error) { var locationConfig models.BackupLocationConfig if req.S3Config != nil { @@ -199,9 +199,9 @@ func (s *LocationsService) TestLocationConfig( } } - if req.PmmClientConfig != nil { - locationConfig.PMMClientConfig = &models.PMMClientLocationConfig{ - Path: req.PmmClientConfig.Path, + if req.FilesystemConfig != nil { + locationConfig.FilesystemConfig = &models.FilesystemLocationConfig{ + Path: req.FilesystemConfig.Path, } } @@ -218,11 +218,11 @@ func (s *LocationsService) TestLocationConfig( } } - return &backupv1beta1.TestLocationConfigResponse{}, nil + return &backuppb.TestLocationConfigResponse{}, nil } // RemoveLocation removes backup location. -func (s *LocationsService) RemoveLocation(ctx context.Context, req *backupv1beta1.RemoveLocationRequest) (*backupv1beta1.RemoveLocationResponse, error) { +func (s *LocationsService) RemoveLocation(ctx context.Context, req *backuppb.RemoveLocationRequest) (*backuppb.RemoveLocationResponse, error) { mode := models.RemoveRestrict if req.Force { mode = models.RemoveCascade @@ -235,27 +235,27 @@ func (s *LocationsService) RemoveLocation(ctx context.Context, req *backupv1beta return nil, err } - return &backupv1beta1.RemoveLocationResponse{}, nil + return &backuppb.RemoveLocationResponse{}, nil } -func convertLocation(locationModel *models.BackupLocation) (*backupv1beta1.Location, error) { - loc := &backupv1beta1.Location{ +func convertLocation(locationModel *models.BackupLocation) (*backuppb.Location, error) { + loc := &backuppb.Location{ LocationId: locationModel.ID, Name: locationModel.Name, Description: locationModel.Description, } switch locationModel.Type { - case models.PMMClientBackupLocationType: - config := locationModel.PMMClientConfig - loc.Config = &backupv1beta1.Location_PmmClientConfig{ - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + case models.FilesystemBackupLocationType: + config := locationModel.FilesystemConfig + loc.Config = &backuppb.Location_FilesystemConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: config.Path, }, } case models.S3BackupLocationType: config := locationModel.S3Config - loc.Config = &backupv1beta1.Location_S3Config{ - S3Config: &backupv1beta1.S3LocationConfig{ + loc.Config = &backuppb.Location_S3Config{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: config.Endpoint, AccessKey: config.AccessKey, SecretKey: config.SecretKey, @@ -299,5 +299,5 @@ func (s *LocationsService) checkBucket(ctx context.Context, c *models.S3Location // Check interfaces. var ( - _ backupv1beta1.LocationsServer = (*LocationsService)(nil) + _ backuppb.LocationsServer = (*LocationsService)(nil) ) diff --git a/managed/services/management/backup/locations_service_test.go b/managed/services/management/backup/locations_service_test.go index f51622c539..3da986e337 100644 --- a/managed/services/management/backup/locations_service_test.go +++ b/managed/services/management/backup/locations_service_test.go @@ -29,7 +29,7 @@ import ( "gopkg.in/reform.v1" "gopkg.in/reform.v1/dialects/postgresql" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/utils/testdb" "github.com/percona/pmm/managed/utils/tests" @@ -45,9 +45,9 @@ func TestCreateBackupLocation(t *testing.T) { mock.Anything).Return("us-east-2", nil) svc := NewLocationsService(db, mockedS3) t.Run("add server config", func(t *testing.T) { - loc, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + loc, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, }) @@ -57,9 +57,9 @@ func TestCreateBackupLocation(t *testing.T) { }) t.Run("add client config", func(t *testing.T) { - loc, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + loc, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, }) @@ -69,9 +69,9 @@ func TestCreateBackupLocation(t *testing.T) { }) t.Run("add awsS3", func(t *testing.T) { - loc, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + loc, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - S3Config: &backupv1beta1.S3LocationConfig{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "access_key", SecretKey: "secret_key", @@ -84,12 +84,12 @@ func TestCreateBackupLocation(t *testing.T) { }) t.Run("multiple configs", func(t *testing.T) { - _, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + _, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, - S3Config: &backupv1beta1.S3LocationConfig{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "access_key", SecretKey: "secret_key", @@ -110,17 +110,17 @@ func TestListBackupLocations(t *testing.T) { mock.Anything).Return("us-east-2", nil) svc := NewLocationsService(db, mockedS3) - req1 := &backupv1beta1.AddLocationRequest{ + req1 := &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, } res1, err := svc.AddLocation(ctx, req1) require.Nil(t, err) - req2 := &backupv1beta1.AddLocationRequest{ + req2 := &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - S3Config: &backupv1beta1.S3LocationConfig{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "access_key", SecretKey: "secret_key", @@ -131,10 +131,10 @@ func TestListBackupLocations(t *testing.T) { require.Nil(t, err) t.Run("list", func(t *testing.T) { - res, err := svc.ListLocations(ctx, &backupv1beta1.ListLocationsRequest{}) + res, err := svc.ListLocations(ctx, &backuppb.ListLocationsRequest{}) require.Nil(t, err) - checkLocation := func(id string, req *backupv1beta1.AddLocationRequest) func() bool { + checkLocation := func(id string, req *backuppb.AddLocationRequest) func() bool { return func() bool { for _, loc := range res.Locations { if loc.LocationId == id { @@ -142,7 +142,7 @@ func TestListBackupLocations(t *testing.T) { return false } if req.S3Config != nil { - cfg := loc.Config.(*backupv1beta1.Location_S3Config) + cfg := loc.Config.(*backuppb.Location_S3Config) if req.S3Config.Endpoint != cfg.S3Config.Endpoint || req.S3Config.AccessKey != cfg.S3Config.AccessKey || req.S3Config.SecretKey != cfg.S3Config.SecretKey || @@ -151,9 +151,9 @@ func TestListBackupLocations(t *testing.T) { } } - if req.PmmClientConfig != nil { - cfg := loc.Config.(*backupv1beta1.Location_PmmClientConfig) - if req.PmmClientConfig.Path != cfg.PmmClientConfig.Path { + if req.FilesystemConfig != nil { + cfg := loc.Config.(*backuppb.Location_FilesystemConfig) + if req.FilesystemConfig.Path != cfg.FilesystemConfig.Path { return false } } @@ -181,20 +181,20 @@ func TestChangeBackupLocation(t *testing.T) { mock.Anything).Return("us-east-2", nil) svc := NewLocationsService(db, mockedS3) t.Run("update existing config", func(t *testing.T) { - loc, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + loc, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, }) require.NoError(t, err) require.NotEmpty(t, loc.LocationId) - updateReq := &backupv1beta1.ChangeLocationRequest{ + updateReq := &backuppb.ChangeLocationRequest{ LocationId: loc.LocationId, Name: gofakeit.Name(), Description: gofakeit.Quote(), - S3Config: &backupv1beta1.S3LocationConfig{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://example.com", AccessKey: "access_key", SecretKey: "secret_key", @@ -208,7 +208,7 @@ func TestChangeBackupLocation(t *testing.T) { require.NoError(t, err) assert.Equal(t, updateReq.Name, updatedLocation.Name) assert.Equal(t, updateReq.Description, updatedLocation.Description) - assert.Nil(t, updatedLocation.PMMClientConfig) + assert.Nil(t, updatedLocation.FilesystemConfig) require.NotNil(t, updatedLocation.S3Config) assert.Equal(t, updateReq.S3Config.Endpoint, updatedLocation.S3Config.Endpoint) assert.Equal(t, updateReq.S3Config.AccessKey, updatedLocation.S3Config.AccessKey) @@ -217,9 +217,9 @@ func TestChangeBackupLocation(t *testing.T) { }) t.Run("update only name", func(t *testing.T) { - addReq := &backupv1beta1.AddLocationRequest{ + addReq := &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, } @@ -227,7 +227,7 @@ func TestChangeBackupLocation(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, loc.LocationId) - updateReq := &backupv1beta1.ChangeLocationRequest{ + updateReq := &backuppb.ChangeLocationRequest{ LocationId: loc.LocationId, Name: gofakeit.Name(), } @@ -237,32 +237,32 @@ func TestChangeBackupLocation(t *testing.T) { updatedLocation, err := models.FindBackupLocationByID(db.Querier, loc.LocationId) require.NoError(t, err) assert.Equal(t, updateReq.Name, updatedLocation.Name) - require.NotNil(t, updatedLocation.PMMClientConfig) - assert.Equal(t, addReq.PmmClientConfig.Path, updatedLocation.PMMClientConfig.Path) + require.NotNil(t, updatedLocation.FilesystemConfig) + assert.Equal(t, addReq.FilesystemConfig.Path, updatedLocation.FilesystemConfig.Path) }) t.Run("update to existing name", func(t *testing.T) { name := gofakeit.Name() - _, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + _, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: name, - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, }) require.NoError(t, err) - loc2, err := svc.AddLocation(ctx, &backupv1beta1.AddLocationRequest{ + loc2, err := svc.AddLocation(ctx, &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, }) require.NoError(t, err) - updateReq := &backupv1beta1.ChangeLocationRequest{ + updateReq := &backuppb.ChangeLocationRequest{ LocationId: loc2.LocationId, Name: name, - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, } @@ -278,9 +278,9 @@ func TestRemoveBackupLocation(t *testing.T) { mockedS3 := &mockAwsS3{} svc := NewLocationsService(db, mockedS3) - req := &backupv1beta1.AddLocationRequest{ + req := &backuppb.AddLocationRequest{ Name: gofakeit.Name(), - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "/tmp", }, } @@ -293,7 +293,7 @@ func TestRemoveBackupLocation(t *testing.T) { res3, err := svc.AddLocation(ctx, req) require.NoError(t, err) - foundLocation := func(id string, locations []*backupv1beta1.Location) bool { + foundLocation := func(id string, locations []*backuppb.Location) bool { for _, loc := range locations { if loc.LocationId == id { return true @@ -302,17 +302,17 @@ func TestRemoveBackupLocation(t *testing.T) { return false } - _, err = svc.RemoveLocation(ctx, &backupv1beta1.RemoveLocationRequest{ + _, err = svc.RemoveLocation(ctx, &backuppb.RemoveLocationRequest{ LocationId: res1.LocationId, }) assert.NoError(t, err) - _, err = svc.RemoveLocation(ctx, &backupv1beta1.RemoveLocationRequest{ + _, err = svc.RemoveLocation(ctx, &backuppb.RemoveLocationRequest{ LocationId: res3.LocationId, }) assert.NoError(t, err) - res, err := svc.ListLocations(ctx, &backupv1beta1.ListLocationsRequest{}) + res, err := svc.ListLocations(ctx, &backuppb.ListLocationsRequest{}) require.NoError(t, err) assert.False(t, foundLocation(res1.LocationId, res.Locations)) @@ -320,7 +320,7 @@ func TestRemoveBackupLocation(t *testing.T) { assert.True(t, foundLocation(res2.LocationId, res.Locations)) // Try to remove non-existing location - _, err = svc.RemoveLocation(ctx, &backupv1beta1.RemoveLocationRequest{ + _, err = svc.RemoveLocation(ctx, &backuppb.RemoveLocationRequest{ LocationId: "non-existing", }) assert.EqualError(t, err, `rpc error: code = NotFound desc = Backup location with ID "non-existing" not found.`) @@ -339,13 +339,13 @@ func TestVerifyBackupLocationValidation(t *testing.T) { tableTests := []struct { name string - req *backupv1beta1.TestLocationConfigRequest + req *backuppb.TestLocationConfigRequest errorMsg string }{ { name: "client config - missing path", - req: &backupv1beta1.TestLocationConfigRequest{ - PmmClientConfig: &backupv1beta1.PMMClientLocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + FilesystemConfig: &backuppb.FilesystemLocationConfig{ Path: "", }, }, @@ -353,13 +353,13 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - missing config", - req: &backupv1beta1.TestLocationConfigRequest{}, + req: &backuppb.TestLocationConfigRequest{}, errorMsg: "rpc error: code = InvalidArgument desc = Missing location config.", }, { name: "awsS3 config - missing endpoint", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "", AccessKey: "access_key", SecretKey: "secret_key", @@ -370,8 +370,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - missing access key", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "", SecretKey: "secret_key", @@ -382,8 +382,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - missing secret key", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "secret_key", SecretKey: "", @@ -394,8 +394,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - missing bucket name", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/", AccessKey: "secret_key", SecretKey: "example_key", @@ -406,8 +406,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - invalid endpoint", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "#invalidendpoint", AccessKey: "secret_key", SecretKey: "example_key", @@ -418,8 +418,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - invalid endpoint, path is not allowed", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "https://awsS3.us-west-2.amazonaws.com/path", AccessKey: "secret_key", SecretKey: "example_key", @@ -430,8 +430,8 @@ func TestVerifyBackupLocationValidation(t *testing.T) { }, { name: "awsS3 config - invalid scheme", - req: &backupv1beta1.TestLocationConfigRequest{ - S3Config: &backupv1beta1.S3LocationConfig{ + req: &backuppb.TestLocationConfigRequest{ + S3Config: &backuppb.S3LocationConfig{ Endpoint: "tcp://awsS3.us-west-2.amazonaws.com", AccessKey: "secret_key", SecretKey: "example_key", diff --git a/managed/services/management/backup/mock_backup_service_test.go b/managed/services/management/backup/mock_backup_service_test.go index efa518e749..a7df318ba1 100644 --- a/managed/services/management/backup/mock_backup_service_test.go +++ b/managed/services/management/backup/mock_backup_service_test.go @@ -4,6 +4,7 @@ package backup import ( context "context" + time "time" mock "github.com/stretchr/testify/mock" @@ -36,20 +37,20 @@ func (_m *mockBackupService) PerformBackup(ctx context.Context, params backup.Pe return r0, r1 } -// RestoreBackup provides a mock function with given fields: ctx, serviceID, artifactID -func (_m *mockBackupService) RestoreBackup(ctx context.Context, serviceID string, artifactID string) (string, error) { - ret := _m.Called(ctx, serviceID, artifactID) +// RestoreBackup provides a mock function with given fields: ctx, serviceID, artifactID, pitrTimestamp +func (_m *mockBackupService) RestoreBackup(ctx context.Context, serviceID string, artifactID string, pitrTimestamp time.Time) (string, error) { + ret := _m.Called(ctx, serviceID, artifactID, pitrTimestamp) var r0 string - if rf, ok := ret.Get(0).(func(context.Context, string, string) string); ok { - r0 = rf(ctx, serviceID, artifactID) + if rf, ok := ret.Get(0).(func(context.Context, string, string, time.Time) string); ok { + r0 = rf(ctx, serviceID, artifactID, pitrTimestamp) } else { r0 = ret.Get(0).(string) } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = rf(ctx, serviceID, artifactID) + if rf, ok := ret.Get(1).(func(context.Context, string, string, time.Time) error); ok { + r1 = rf(ctx, serviceID, artifactID, pitrTimestamp) } else { r1 = ret.Error(1) } diff --git a/managed/services/management/backup/mock_pitr_timerange_service_test.go b/managed/services/management/backup/mock_pitr_timerange_service_test.go new file mode 100644 index 0000000000..43f7faa583 --- /dev/null +++ b/managed/services/management/backup/mock_pitr_timerange_service_test.go @@ -0,0 +1,40 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package backup + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + models "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/services/backup" +) + +// mockPitrTimerangeService is an autogenerated mock type for the pitrTimerangeService type +type mockPitrTimerangeService struct { + mock.Mock +} + +// ListPITRTimeranges provides a mock function with given fields: ctx, artifactName, location +func (_m *mockPitrTimerangeService) ListPITRTimeranges(ctx context.Context, artifactName string, location *models.BackupLocation) ([]backup.Timeline, error) { + ret := _m.Called(ctx, artifactName, location) + + var r0 []backup.Timeline + if rf, ok := ret.Get(0).(func(context.Context, string, *models.BackupLocation) []backup.Timeline); ok { + r0 = rf(ctx, artifactName, location) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]backup.Timeline) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, *models.BackupLocation) error); ok { + r1 = rf(ctx, artifactName, location) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/managed/services/management/backup/restore_history_service.go b/managed/services/management/backup/restore_history_service.go index 64d9ed616e..75d3a93c97 100644 --- a/managed/services/management/backup/restore_history_service.go +++ b/managed/services/management/backup/restore_history_service.go @@ -24,7 +24,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "gopkg.in/reform.v1" - backupv1beta1 "github.com/percona/pmm/api/managementpb/backup" + backuppb "github.com/percona/pmm/api/managementpb/backup" "github.com/percona/pmm/managed/models" ) @@ -33,7 +33,7 @@ type RestoreHistoryService struct { l *logrus.Entry db *reform.DB - backupv1beta1.UnimplementedRestoreHistoryServer + backuppb.UnimplementedRestoreHistoryServer } // NewRestoreHistoryService creates new restore history API service. @@ -57,8 +57,8 @@ func (s *RestoreHistoryService) Enabled() bool { // ListRestoreHistory returns a list of restore history. func (s *RestoreHistoryService) ListRestoreHistory( context.Context, - *backupv1beta1.ListRestoreHistoryRequest, -) (*backupv1beta1.ListRestoreHistoryResponse, error) { + *backuppb.ListRestoreHistoryRequest, +) (*backuppb.ListRestoreHistoryResponse, error) { var items []*models.RestoreHistoryItem var services map[string]*models.Service var artifacts map[string]*models.Artifact @@ -104,7 +104,7 @@ func (s *RestoreHistoryService) ListRestoreHistory( return nil, err } - artifactsResponse := make([]*backupv1beta1.RestoreHistoryItem, 0, len(artifacts)) + artifactsResponse := make([]*backuppb.RestoreHistoryItem, 0, len(artifacts)) for _, i := range items { convertedArtifact, err := convertRestoreHistoryItem(i, services, artifacts, locationModels) if err != nil { @@ -113,20 +113,20 @@ func (s *RestoreHistoryService) ListRestoreHistory( artifactsResponse = append(artifactsResponse, convertedArtifact) } - return &backupv1beta1.ListRestoreHistoryResponse{ + return &backuppb.ListRestoreHistoryResponse{ Items: artifactsResponse, }, nil } -func convertRestoreStatus(status models.RestoreStatus) (*backupv1beta1.RestoreStatus, error) { - var s backupv1beta1.RestoreStatus +func convertRestoreStatus(status models.RestoreStatus) (*backuppb.RestoreStatus, error) { + var s backuppb.RestoreStatus switch status { case models.InProgressRestoreStatus: - s = backupv1beta1.RestoreStatus_RESTORE_STATUS_IN_PROGRESS + s = backuppb.RestoreStatus_RESTORE_STATUS_IN_PROGRESS case models.SuccessRestoreStatus: - s = backupv1beta1.RestoreStatus_RESTORE_STATUS_SUCCESS + s = backuppb.RestoreStatus_RESTORE_STATUS_SUCCESS case models.ErrorRestoreStatus: - s = backupv1beta1.RestoreStatus_RESTORE_STATUS_ERROR + s = backuppb.RestoreStatus_RESTORE_STATUS_ERROR default: return nil, errors.Errorf("invalid status '%s'", status) } @@ -140,7 +140,7 @@ func convertRestoreHistoryItem( services map[string]*models.Service, artifacts map[string]*models.Artifact, locations map[string]*models.BackupLocation, -) (*backupv1beta1.RestoreHistoryItem, error) { +) (*backuppb.RestoreHistoryItem, error) { startedAt := timestamppb.New(i.StartedAt) if err := startedAt.CheckValid(); err != nil { return nil, errors.Wrap(err, "failed to convert startedAt timestamp") @@ -183,7 +183,7 @@ func convertRestoreHistoryItem( return nil, errors.Wrapf(err, "restore history item id '%s'", i.ID) } - return &backupv1beta1.RestoreHistoryItem{ + return &backuppb.RestoreHistoryItem{ RestoreId: i.ID, ArtifactId: i.ArtifactID, Name: artifact.Name, @@ -201,5 +201,5 @@ func convertRestoreHistoryItem( // Check interfaces. var ( - _ backupv1beta1.RestoreHistoryServer = (*RestoreHistoryService)(nil) + _ backuppb.RestoreHistoryServer = (*RestoreHistoryService)(nil) ) diff --git a/managed/services/minio/client.go b/managed/services/minio/client.go new file mode 100644 index 0000000000..a508132c4a --- /dev/null +++ b/managed/services/minio/client.go @@ -0,0 +1,211 @@ +// Copyright (C) 2017 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package minio provides implementation for Minio operations. +package minio + +import ( + "context" + "strings" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + + "github.com/percona/pmm/managed/models" +) + +// Client is a wrapper around minio.Client. +type Client struct { + l *logrus.Entry +} + +// New creates a new minio client. +func New() *Client { + return &Client{ + l: logrus.WithField("component", "minio-client"), + } +} + +// FileInfo contains information about a single file in the bucket. +type FileInfo struct { + // Name is the absolute object name (with path included) + Name string + // Size is the size of the object + Size int64 + // IsDeleteMarker specifies if the object is marked for deletion + IsDeleteMarker bool +} + +// BucketExists return true if bucket can be accessed with provided credentials and exists. +func (c *Client) BucketExists(ctx context.Context, endpoint, accessKey, secretKey, bucketName string) (bool, error) { + mc, err := createMinioClient(endpoint, accessKey, secretKey) + if err != nil { + return false, err + } + return mc.BucketExists(ctx, bucketName) +} + +// GetBucketLocation retrieves bucket location by specified bucket name. +func (c *Client) GetBucketLocation(ctx context.Context, endpoint, accessKey, secretKey, bucketName string) (string, error) { + mc, err := createMinioClient(endpoint, accessKey, secretKey) + if err != nil { + return "", err + } + return mc.GetBucketLocation(ctx, bucketName) +} + +// RemoveRecursive removes objects recursively from storage with given prefix. +func (c *Client) RemoveRecursive(ctx context.Context, endpoint, accessKey, secretKey, bucketName, prefix string) (rerr error) { + mc, err := createMinioClient(endpoint, accessKey, secretKey) + if err != nil { + return err + } + + objectsCh := make(chan minio.ObjectInfo) + var g errgroup.Group + g.Go(func() error { + defer close(objectsCh) + + options := minio.ListObjectsOptions{ //nolint:exhaustruct + Prefix: prefix, + Recursive: true, + } + for object := range mc.ListObjects(ctx, bucketName, options) { + if object.Err != nil { + return errors.WithStack(object.Err) + } + + objectsCh <- object + } + + return nil + }) + + defer func() { + err := g.Wait() + if err == nil { + return + } + + if rerr != nil { + rerr = errors.Wrapf(rerr, "listing objects error: %s", err.Error()) + } else { + rerr = errors.WithStack(err) + } + }() + + var errorsEncountered bool + for rErr := range mc.RemoveObjects(ctx, bucketName, objectsCh, minio.RemoveObjectsOptions{}) { //nolint:exhaustruct + errorsEncountered = true + c.l.WithError(rErr.Err).Debugf("failed to remove object %q", rErr.ObjectName) + } + + if errorsEncountered { + return errors.Errorf("errors encountered while removing objects from bucket %q", bucketName) + } + + return nil +} + +// List is a wrapper over the minio API to list all objects in the bucket. +// It scans path with prefix and returns all files with given suffix. +// Both prefix and suffix can be omitted. +func (c *Client) List(ctx context.Context, endpoint, accessKey, secretKey, bucketName, prefix, suffix string) ([]FileInfo, error) { + var files []FileInfo + if prefix != "" && !strings.HasSuffix(prefix, "/") { + prefix += "/" + } + mc, err := createMinioClient(endpoint, accessKey, secretKey) + if err != nil { + return nil, err + } + + options := minio.ListObjectsOptions{ + Prefix: prefix, + Recursive: true, + } + + for object := range mc.ListObjects(ctx, bucketName, options) { + if object.Err != nil { + return nil, errors.WithStack(object.Err) + } + filename := object.Key + filename = strings.TrimPrefix(filename, options.Prefix) + if len(filename) == 0 { + continue + } + if filename[0] == '/' { + filename = filename[1:] + } + + if strings.HasSuffix(filename, suffix) { + files = append(files, FileInfo{ + Name: filename, + Size: object.Size, + IsDeleteMarker: object.IsDeleteMarker, + }) + } + } + + return files, nil +} + +// FileStat returns file info. It returns error if file is empty or not exists. +func (c *Client) FileStat(ctx context.Context, endpoint, accessKey, secretKey, bucketName, name string) (FileInfo, error) { + var file FileInfo + mc, err := createMinioClient(endpoint, accessKey, secretKey) + if err != nil { + return file, err + } + + stat, err := mc.StatObject(ctx, bucketName, name, minio.StatObjectOptions{}) //nolint:exhaustruct + if err != nil { + return file, err + } + + if stat.IsDeleteMarker { + return file, errors.New("file has delete marker") + } + + file.Name = name + file.Size = stat.Size + file.IsDeleteMarker = stat.IsDeleteMarker + + if file.Size == 0 { + return file, errors.New("file is empty") + } + + return file, nil +} + +func createMinioClient(endpoint, accessKey, secretKey string) (*minio.Client, error) { + url, err := models.ParseEndpoint(endpoint) + if err != nil { + return nil, err + } + + secure := true + if url.Scheme == "http" { + secure = false + } + + return minio.New(url.Host, &minio.Options{ + Secure: secure, + Creds: credentials.NewStaticV4(accessKey, secretKey, ""), + }) +} diff --git a/managed/services/minio/service.go b/managed/services/minio/service.go deleted file mode 100644 index 05bd772133..0000000000 --- a/managed/services/minio/service.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2017 Percona LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -// Package minio provides implementation for Minio operations. -package minio - -import ( - "context" - - "github.com/minio/minio-go/v7" - "github.com/minio/minio-go/v7/pkg/credentials" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "golang.org/x/sync/errgroup" - - "github.com/percona/pmm/managed/models" -) - -// Service is wrapper around minio client. -type Service struct { - l *logrus.Entry -} - -// New creates new minio service. -func New() *Service { - return &Service{ - l: logrus.WithField("component", "minio-client"), - } -} - -// BucketExists return true if bucket can be accessed with provided credentials and exists. -func (s *Service) BucketExists(ctx context.Context, endpoint, accessKey, secretKey, name string) (bool, error) { - minioClient, err := newClient(endpoint, accessKey, secretKey) - if err != nil { - return false, err - } - return minioClient.BucketExists(ctx, name) -} - -// GetBucketLocation retrieves bucket location by specified bucket name. -func (s *Service) GetBucketLocation(ctx context.Context, endpoint, accessKey, secretKey, name string) (string, error) { - minioClient, err := newClient(endpoint, accessKey, secretKey) - if err != nil { - return "", err - } - return minioClient.GetBucketLocation(ctx, name) -} - -// RemoveRecursive removes objects recursively from storage with given prefix. -func (s *Service) RemoveRecursive(ctx context.Context, endpoint, accessKey, secretKey, bucketName, prefix string) (rerr error) { - minioClient, err := newClient(endpoint, accessKey, secretKey) - if err != nil { - return err - } - - objectsCh := make(chan minio.ObjectInfo) - var g errgroup.Group - g.Go(func() error { - defer close(objectsCh) - - options := minio.ListObjectsOptions{ - Prefix: prefix, - Recursive: true, - } - for object := range minioClient.ListObjects(ctx, bucketName, options) { - if object.Err != nil { - return errors.WithStack(object.Err) - } - - objectsCh <- object - } - - return nil - }) - - defer func() { - err := g.Wait() - if err == nil { - return - } - - if rerr != nil { - rerr = errors.Wrapf(rerr, "listing objects error: %s", err.Error()) - } else { - rerr = errors.WithStack(err) - } - }() - - var errorsEncountered bool - for rErr := range minioClient.RemoveObjects(ctx, bucketName, objectsCh, minio.RemoveObjectsOptions{}) { - errorsEncountered = true - s.l.WithError(rErr.Err).Debugf("failed to remove object %q", rErr.ObjectName) - } - - if errorsEncountered { - return errors.Errorf("errors encountered while removing objects from bucket %q", bucketName) - } - - return nil -} - -func newClient(endpoint, accessKey, secretKey string) (*minio.Client, error) { - url, err := models.ParseEndpoint(endpoint) - if err != nil { - return nil, err - } - - secure := true - if url.Scheme == "http" { - secure = false - } - - return minio.New(url.Host, &minio.Options{ - Secure: secure, - Creds: credentials.NewStaticV4(accessKey, secretKey, ""), - }) -}