Merge pull request #2849 from classmarkets/gcs-access-token

gs: support authentication with access token
This commit is contained in:
MichaelEischer 2020-09-30 17:42:56 +02:00 committed by GitHub
commit fd02407863
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 7 deletions

View file

@ -0,0 +1,7 @@
Enhancement: Authenticate to Google Cloud Storage with access token
When using the GCS backend, it is now possible to authenticate with OAuth2
access tokens instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN
environment variable.
https://github.com/restic/restic/pull/2849

View file

@ -458,6 +458,18 @@ which means if you're running in Google Container Engine or are otherwise
located on an instance with default service accounts then these should work out of
the box.
Alternatively, you can specify an existing access token directly:
.. code-block:: console
$ export GOOGLE_ACCESS_TOKEN=ya29.a0AfH6SMC78...
If ``GOOGLE_ACCESS_TOKEN`` is set all other authentication mechanisms are
disabled. The access token must have at least the
``https://www.googleapis.com/auth/devstorage.read_write`` scope. Keep in mind
that access tokens are short-lived (usually one hour), so they are not suitable
if creating a backup takes longer than that, for instance.
Once authenticated, you can use the ``gs:`` backend type to create a new
repository in the bucket ``foo`` at the root path:

View file

@ -47,15 +47,25 @@ func getStorageService(rt http.RoundTripper) (*storage.Service, error) {
Transport: rt,
}
// create a now context with the HTTP client stored at the oauth2.HTTPClient key
// create a new context with the HTTP client stored at the oauth2.HTTPClient key
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, httpClient)
// use this context
client, err := google.DefaultClient(ctx, storage.DevstorageReadWriteScope)
if err != nil {
return nil, err
var ts oauth2.TokenSource
if token := os.Getenv("GOOGLE_ACCESS_TOKEN"); token != "" {
ts = oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: token,
TokenType: "Bearer",
})
} else {
var err error
ts, err = google.DefaultTokenSource(ctx, storage.DevstorageReadWriteScope)
if err != nil {
return nil, err
}
}
client := oauth2.NewClient(ctx, ts)
service, err := storage.New(client)
if err != nil {
return nil, err

View file

@ -87,7 +87,6 @@ func TestBackendGS(t *testing.T) {
}()
vars := []string{
"GOOGLE_APPLICATION_CREDENTIALS",
"RESTIC_TEST_GS_PROJECT_ID",
"RESTIC_TEST_GS_REPOSITORY",
}
@ -98,6 +97,10 @@ func TestBackendGS(t *testing.T) {
return
}
}
if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")+os.Getenv("GOOGLE_ACCESS_TOKEN") == "" {
t.Skipf("environment variable GOOGLE_APPLICATION_CREDENTIALS not set, nor GOOGLE_ACCESS_TOKEN")
return
}
t.Logf("run tests")
newGSTestSuite(t).RunTests(t)
@ -105,7 +108,6 @@ func TestBackendGS(t *testing.T) {
func BenchmarkBackendGS(t *testing.B) {
vars := []string{
"GOOGLE_APPLICATION_CREDENTIALS",
"RESTIC_TEST_GS_PROJECT_ID",
"RESTIC_TEST_GS_REPOSITORY",
}
@ -116,6 +118,10 @@ func BenchmarkBackendGS(t *testing.B) {
return
}
}
if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")+os.Getenv("GOOGLE_ACCESS_TOKEN") == "" {
t.Skipf("environment variable GOOGLE_APPLICATION_CREDENTIALS not set, nor GOOGLE_ACCESS_TOKEN")
return
}
t.Logf("run tests")
newGSTestSuite(t).RunBenchmarks(t)