Merge pull request #1277 from prattmic/gcs_cleanup

Document GCS permission requirements
This commit is contained in:
Alexander Neumann 2017-09-24 20:49:02 +02:00
commit 5ace41471e
3 changed files with 39 additions and 14 deletions

View file

@ -405,11 +405,22 @@ established.
Google Cloud Storage
~~~~~~~~~~~~~~~~~~~~
Restic supports Google Cloud Storage as a backend. In order for this to work
you first need create a "service account" and download the JSON key file for
it. In addition, you need the Google Project ID that you can see in the Google
Restic supports Google Cloud Storage as a backend.
Restic connects to Google Cloud Storage via a `service account`_.
For normal restic operation, the service account must have the
``storage.objects.{create,delete,get,list}`` permissions for the bucket. These
are included in the "Storage Object Admin" role. For ``restic init``, the
service account must also have the ``storage.buckets.get`` and
``storage.buckets.create`` (if the bucket does not exist) permissions. These
are included in the "Storage Admin" role.
`Create a service account key`_ and download the JSON credentials file.
In addition, you need the Google Project ID that you can see in the Google
Cloud Platform console at the "Storage/Settings" menu. Export the path to the
JSON credentials file and the project ID as follows:
JSON key file and the project ID as follows:
.. code-block:: console
@ -432,6 +443,9 @@ The number of concurrent connections to the GCS service can be set with the
`-o gs.connections=10`. By default, at most five parallel connections are
established.
.. _service account: https://cloud.google.com/storage/docs/authentication#service_accounts
.. _Create a service account key: https://cloud.google.com/storage/docs/authentication#generating-a-private-key
Password prompt on Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -8,8 +8,8 @@ import (
"github.com/restic/restic/internal/options"
)
// Config contains all configuration necessary to connect to an gcs compatible
// server.
// Config contains all configuration necessary to connect to a Google Cloud
// Storage bucket.
type Config struct {
ProjectID string
JSONKeyPath string

View file

@ -1,3 +1,4 @@
// Package gs provides a restic backend for Google Cloud Storage.
package gs
import (
@ -20,7 +21,13 @@ import (
storage "google.golang.org/api/storage/v1"
)
// Backend stores data on an gs endpoint.
// Backend stores data in a GCS bucket.
//
// The service account used to access the bucket must have these permissions:
// * storage.objects.create
// * storage.objects.delete
// * storage.objects.get
// * storage.objects.list
type Backend struct {
service *storage.Service
projectID string
@ -31,7 +38,7 @@ type Backend struct {
backend.Layout
}
// make sure that *Backend implements backend.Backend
// Ensure that *Backend implements restic.Backend.
var _ restic.Backend = &Backend{}
func getStorageService(jsonKeyPath string) (*storage.Service, error) {
@ -87,21 +94,25 @@ func open(cfg Config) (*Backend, error) {
return be, nil
}
// Open opens the gs backend at bucket and region.
// Open opens the gs backend at the specified bucket.
func Open(cfg Config) (restic.Backend, error) {
return open(cfg)
}
// Create opens the S3 backend at bucket and region and creates the bucket if
// it does not exist yet.
// Create opens the gs backend at the specified bucket and creates the bucket
// if it does not exist yet.
//
// In addition to the permissions required by Backend, Create requires these
// permissions:
// * storage.buckets.get
// * storage.buckets.create (if the bucket doesn't exist)
func Create(cfg Config) (restic.Backend, error) {
be, err := open(cfg)
if err != nil {
return nil, errors.Wrap(err, "open")
}
// Create bucket if not exists
// Create bucket if it doesn't exist.
if _, err := be.service.Buckets.Get(be.bucketName).Do(); err != nil {
bucket := &storage.Bucket{
Name: be.bucketName,
@ -371,5 +382,5 @@ func (be *Backend) Delete(ctx context.Context) error {
return be.Remove(ctx, restic.Handle{Type: restic.ConfigFile})
}
// Close does nothing
// Close does nothing.
func (be *Backend) Close() error { return nil }