blob: 40c9dd9e339d7615f449be98b58ff375010240ba [file] [log] [blame]
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bootstrap
import (
"context"
"fmt"
"cloud.google.com/go/storage"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
)
type AuthOption int
const (
AuthNone AuthOption = iota
AuthAppDefault
NumAuthOptions
)
var authOptString = [NumAuthOptions]string{
"none",
"app-default",
}
func (a *AuthOption) String() string {
return authOptString[*a]
}
func (a *AuthOption) Set(input string) error {
for i := range authOptString {
if authOptString[i] == input {
*a = AuthOption(i)
return nil
}
}
return fmt.Errorf("unrecognized authentication option: %s", input)
}
func NewStorageWriter(bucket, version string, auth AuthOption, force bool) (*storage.Writer, error) {
ctx := context.Background()
var opts []option.ClientOption
switch auth {
case AuthAppDefault:
creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadWrite)
if err != nil {
return nil, err
}
opts = append(opts, option.WithCredentials(creds))
case AuthNone:
return nil, fmt.Errorf("authentication required for upload")
default:
return nil, fmt.Errorf("unknown authentication method")
}
client, err := storage.NewClient(ctx, opts...)
if err != nil {
return nil, err
}
o := client.Bucket(bucket).Object(VersionArchiveName(version))
if _, err := o.Attrs(ctx); err != nil && err != storage.ErrObjectNotExist {
return nil, fmt.Errorf("checking if object exists: %w", err)
} else if err == nil && !force {
return nil, fmt.Errorf("assets object already exists for version %s", version)
}
return o.NewWriter(ctx), nil
}
func NewStorageReader(bucket, version string, auth AuthOption) (*storage.Reader, error) {
ctx := context.Background()
opts := []option.ClientOption{option.WithScopes(storage.ScopeReadOnly)}
switch auth {
case AuthAppDefault:
creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
if err != nil {
return nil, err
}
opts = append(opts, option.WithCredentials(creds))
case AuthNone:
opts = append(opts, option.WithoutAuthentication())
default:
return nil, fmt.Errorf("unknown authentication method")
}
client, err := storage.NewClient(ctx, opts...)
if err != nil {
return nil, err
}
return client.Bucket(bucket).Object(VersionArchiveName(version)).NewReader(ctx)
}