diff --git a/cmd/influxd/launcher/backup_restore_test.go b/cmd/influxd/launcher/backup_restore_test.go index 4ce07f2b76..7c3c65ac1f 100644 --- a/cmd/influxd/launcher/backup_restore_test.go +++ b/cmd/influxd/launcher/backup_restore_test.go @@ -29,6 +29,7 @@ func TestBackupRestore_Full(t *testing.T) { o.Testing = false o.LogLevel = zap.InfoLevel }) + originalAuth := *l1.Auth l1.WritePointsOrFail(t, "m,k=v1 f=100i 946684800000000000\nm,k=v2 f=200i 946684800000000001") l1.BackupOrFail(t, ctx, backup.Params{Path: backupDir}) @@ -46,7 +47,7 @@ func TestBackupRestore_Full(t *testing.T) { // Shut down the server. l1.ShutdownOrFail(t, ctx) - // Boot up a second server, using the same auth token as the previous. + // Boot up a second server, using a new auth token l2 := launcher.NewTestLauncher() l2.RunOrFail(t, ctx, func(o *launcher.InfluxdOpts) { o.StoreType = "bolt" @@ -60,7 +61,6 @@ func TestBackupRestore_Full(t *testing.T) { Password: "PASSWORD", Org: "ORG", Bucket: "BUCKET", - Token: l1.Auth.Token, } onboardRes := l2.OnBoardOrFail(t, &onboardReq) l2.Org = onboardRes.Org @@ -79,6 +79,10 @@ func TestBackupRestore_Full(t *testing.T) { // Perform a full restore from the previous backups. l2.RestoreOrFail(t, ctx, restore.Params{Path: backupDir, Full: true}) + // A full restore also restores the original token + l2.Auth = &originalAuth + l2.ResetHTTPCLient() + // Check that orgs and buckets were reset to match the original server's metadata. _, err = l2.OrgService(t).FindOrganizationByID(ctx, l2.Org.ID) require.Equal(t, errors.ENotFound, errors.ErrorCode(err)) diff --git a/cmd/influxd/launcher/launcher_helpers.go b/cmd/influxd/launcher/launcher_helpers.go index 23d79bc85b..20fbff3821 100644 --- a/cmd/influxd/launcher/launcher_helpers.go +++ b/cmd/influxd/launcher/launcher_helpers.go @@ -495,12 +495,18 @@ func (tl *TestLauncher) RestoreService(tb testing.TB) *clirestore.Client { client := tl.APIClient(tb) return &clirestore.Client{ CLI: clients.CLI{}, - RestoreApi: client.RestoreApi, - OrganizationsApi: client.OrganizationsApi, HealthApi: client.HealthApi, + RestoreApi: client.RestoreApi, + BucketsApi: client.BucketsApi, + OrganizationsApi: client.OrganizationsApi, + ApiConfig: client, } } +func (tl *TestLauncher) ResetHTTPCLient() { + tl.httpClient = nil +} + func (tl *TestLauncher) HTTPClient(tb testing.TB) *httpc.Client { tb.Helper() diff --git a/go.mod b/go.mod index 2d1398ae83..12f0ce13d2 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,6 @@ require ( github.com/influxdata/cron v0.0.0-20201006132531-4bb0a200dcbe github.com/influxdata/flux v0.133.0 github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69 - github.com/influxdata/influx-cli/v2 v2.1.1-0.20211006152725-857e2b356cc0 github.com/influxdata/influxql v1.1.1-0.20211004132434-7e7d61973256 github.com/influxdata/pkg-config v0.2.9-0.20210928145121-f721f9766b86 github.com/jmoiron/sqlx v1.3.4 @@ -165,6 +164,7 @@ require ( github.com/hashicorp/vault/sdk v0.1.8 // indirect github.com/huandu/xstrings v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/influxdata/influx-cli/v2 v2.1.1-0.20211007122339-c4a5a13c8ee3 github.com/influxdata/influxdb-client-go/v2 v2.3.1-0.20210518120617-5d1fff431040 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/influxdata/tdigest v0.0.2-0.20210216194612-fc98d27c9e8b // indirect @@ -220,13 +220,4 @@ require ( gopkg.in/square/go-jose.v2 v2.3.1 // indirect ) -// Arrow has been taking too long to merge our PR that addresses some checkptr fixes. -// We are using our own fork, which specifically applies the change in -// https://github.com/apache/arrow/pull/8112, on top of the commit of Arrow that flux uses. -// -// The next time Flux updates its Arrow dependency, we will see checkptr test failures, -// if that version does not include PR 8112. In that event, someone (perhaps Mark R again) -// will need to apply the change in 8112 on top of the newer version of Arrow. -replace github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db => github.com/influxdata/arrow/go/arrow v0.0.0-20200917142114-986e413c1705 - replace github.com/nats-io/nats-streaming-server v0.11.2 => github.com/influxdata/nats-streaming-server v0.11.3-0.20201112040610-c277f7560803 diff --git a/go.sum b/go.sum index 6f3999ee2f..cdd3250db3 100644 --- a/go.sum +++ b/go.sum @@ -430,8 +430,8 @@ github.com/influxdata/flux v0.133.0 h1:U1zYP5qXjh6esGOMc4d8efkTgqNORDc9KRWc6NIZs github.com/influxdata/flux v0.133.0/go.mod h1:RzogdNsdZoyDAw53BwLrhqyrVI7eT0IKEWW2UjAvTiw= github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69 h1:WQsmW0fXO4ZE/lFGIE84G6rIV5SJN3P3sjIXAP1a8eU= github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69/go.mod h1:pwymjR6SrP3gD3pRj9RJwdl1j5s3doEEV8gS4X9qSzA= -github.com/influxdata/influx-cli/v2 v2.1.1-0.20211006152725-857e2b356cc0 h1:2tFXbj1A3pRpuccDUEro4ZZYVAmAJgFha60Oz4+kSCE= -github.com/influxdata/influx-cli/v2 v2.1.1-0.20211006152725-857e2b356cc0/go.mod h1:piIN/dAOSRqdZZc2sHO7CORuWUQ0UXdNrjugF3cEr8k= +github.com/influxdata/influx-cli/v2 v2.1.1-0.20211007122339-c4a5a13c8ee3 h1:DJFtOP/Gji5K6iut794K1pTKPd9SqM9J+Cb7vXgsnq0= +github.com/influxdata/influx-cli/v2 v2.1.1-0.20211007122339-c4a5a13c8ee3/go.mod h1:piIN/dAOSRqdZZc2sHO7CORuWUQ0UXdNrjugF3cEr8k= github.com/influxdata/influxdb-client-go/v2 v2.3.1-0.20210518120617-5d1fff431040 h1:MBLCfcSsUyFPDJp6T7EoHp/Ph3Jkrm4EuUKLD2rUWHg= github.com/influxdata/influxdb-client-go/v2 v2.3.1-0.20210518120617-5d1fff431040/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxql v1.1.1-0.20211004132434-7e7d61973256 h1:8io3jjCJ0j9NFvq3/m/rMrDiEILpsfOqWDPItUt/078= diff --git a/http/restore_service.go b/http/restore_service.go index a4a2ad6957..34562526a1 100644 --- a/http/restore_service.go +++ b/http/restore_service.go @@ -2,7 +2,9 @@ package http import ( "compress/gzip" + "context" "encoding/json" + "fmt" "io" "io/ioutil" "net/http" @@ -11,6 +13,8 @@ import ( "github.com/influxdata/httprouter" "github.com/influxdata/influxdb/v2" + "github.com/influxdata/influxdb/v2/authorizer" + context2 "github.com/influxdata/influxdb/v2/context" "github.com/influxdata/influxdb/v2/kit/platform/errors" "github.com/influxdata/influxdb/v2/kit/tracing" kithttp "github.com/influxdata/influxdb/v2/kit/transport/http" @@ -26,6 +30,7 @@ type RestoreBackend struct { RestoreService influxdb.RestoreService SqlBackupRestoreService influxdb.SqlBackupRestoreService BucketService influxdb.BucketService + AuthorizationService influxdb.AuthorizationService } // NewRestoreBackend returns a new instance of RestoreBackend. @@ -37,6 +42,7 @@ func NewRestoreBackend(b *APIBackend) *RestoreBackend { RestoreService: b.RestoreService, SqlBackupRestoreService: b.SqlBackupRestoreService, BucketService: b.BucketService, + AuthorizationService: b.AuthorizationService, } } @@ -50,6 +56,7 @@ type RestoreHandler struct { RestoreService influxdb.RestoreService SqlBackupRestoreService influxdb.SqlBackupRestoreService BucketService influxdb.BucketService + AuthorizationService influxdb.AuthorizationService } const ( @@ -72,6 +79,7 @@ func NewRestoreHandler(b *RestoreBackend) *RestoreHandler { RestoreService: b.RestoreService, SqlBackupRestoreService: b.SqlBackupRestoreService, BucketService: b.BucketService, + AuthorizationService: b.AuthorizationService, api: kithttp.NewAPI(kithttp.WithLog(b.Logger)), } @@ -85,6 +93,30 @@ func NewRestoreHandler(b *RestoreBackend) *RestoreHandler { return h } +func (h *RestoreHandler) getOperatorToken(ctx context.Context) (influxdb.Authorization, error) { + // Get the token post-restore + auths, _, err := h.AuthorizationService.FindAuthorizations(ctx, influxdb.AuthorizationFilter{}) + if err != nil { + return influxdb.Authorization{}, err + } + + var operToken *influxdb.Authorization + for _, a := range auths { + authCtx := context.Background() + authCtx = context2.SetAuthorizer(authCtx, a) + if authorizer.IsAllowedAll(authCtx, influxdb.OperPermissions()) == nil { + operToken = a + break + } + } + + if operToken == nil { + return influxdb.Authorization{}, fmt.Errorf("invalid backup without an operator token, consider editing the BoltDB in the backup with 'influxd recovery'") + } + + return *operToken, nil +} + func (h *RestoreHandler) handleRestoreKVStore(w http.ResponseWriter, r *http.Request) { span, r := tracing.ExtractFromHTTPRequest(r, "RestoreHandler.handleRestoreKVStore") defer span.Finish() @@ -110,6 +142,19 @@ func (h *RestoreHandler) handleRestoreKVStore(w http.ResponseWriter, r *http.Req h.HandleHTTPError(ctx, err, w) return } + + // Get the token post-restore + operatorToken, err := h.getOperatorToken(ctx) + if err != nil { + h.HandleHTTPError(ctx, err, w) + return + } + + // Return the new token to the caller so it can continue the restore + response := make(map[string]string) + response["token"] = operatorToken.Token + + h.api.Respond(w, r, http.StatusOK, response) } func (h *RestoreHandler) handleRestoreSqlStore(w http.ResponseWriter, r *http.Request) { diff --git a/scripts/fetch-swagger.sh b/scripts/fetch-swagger.sh index 6adea585c7..7c1dd0df97 100755 --- a/scripts/fetch-swagger.sh +++ b/scripts/fetch-swagger.sh @@ -10,7 +10,7 @@ declare -r ROOT_DIR=$(dirname ${SCRIPT_DIR}) declare -r STATIC_DIR="$ROOT_DIR/static" # Pins the swagger that will be downloaded to a specific commit -declare -r OPENAPI_SHA=b1c4e11654e5755f83c197e271c713147d784b8e +declare -r OPENAPI_SHA=d6f9073685dfb58e36f20c2ed351cf872ad31a86 # Don't do a shallow clone since the commit we want might be several commits # back; but do only clone the main branch.