mirror of
https://github.com/foomo/posh-providers.git
synced 2025-10-16 12:35:41 +00:00
123 lines
2.9 KiB
Go
123 lines
2.9 KiB
Go
package gcloud
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"path"
|
|
"regexp"
|
|
|
|
"github.com/foomo/posh/pkg/env"
|
|
"github.com/foomo/posh/pkg/shell"
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/foomo/posh/pkg/cache"
|
|
"github.com/foomo/posh/pkg/log"
|
|
"github.com/foomo/posh/pkg/util/files"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type (
|
|
GCloud struct {
|
|
l log.Logger
|
|
cfg *Config
|
|
cache cache.Namespace
|
|
configKey string
|
|
accountFileNameRegex *regexp.Regexp
|
|
}
|
|
Option func(*GCloud)
|
|
)
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Options
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func WithConfig(v *Config) Option {
|
|
return func(o *GCloud) {
|
|
o.cfg = v
|
|
}
|
|
}
|
|
|
|
func WithConfigKey(v string) Option {
|
|
return func(o *GCloud) {
|
|
o.configKey = v
|
|
}
|
|
}
|
|
|
|
func WithAccountFileNameRegex(v *regexp.Regexp) Option {
|
|
return func(o *GCloud) {
|
|
o.accountFileNameRegex = v
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Constructor
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func New(l log.Logger, cache cache.Cache, opts ...Option) (*GCloud, error) {
|
|
inst := &GCloud{
|
|
l: l,
|
|
cache: cache.Get("gcloud"),
|
|
configKey: "gcloud",
|
|
accountFileNameRegex: regexp.MustCompile(`(\w+)@(\w+)-(\w+)\.json`),
|
|
}
|
|
for _, opt := range opts {
|
|
if opt != nil {
|
|
opt(inst)
|
|
}
|
|
}
|
|
|
|
if inst.cfg == nil && inst.configKey != "" {
|
|
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// ensure config path
|
|
if err := files.MkdirAll(inst.cfg.ConfigPath); err != nil {
|
|
return nil, errors.Wrapf(err, "failed to create directory %q", inst.cfg.ConfigPath)
|
|
}
|
|
|
|
if err := os.Setenv("CLOUDSDK_CONFIG", env.Path(inst.cfg.ConfigPath)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return inst, nil
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Public methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (p *GCloud) Config() *Config {
|
|
return p.cfg
|
|
}
|
|
|
|
func (p *GCloud) ServiceAccountKeysPath() string {
|
|
return path.Join(p.cfg.ConfigPath, "service_account_keys")
|
|
}
|
|
|
|
// ActiveAccount returns the active account email
|
|
func (p *GCloud) ActiveAccount(ctx context.Context, l log.Logger) (string, error) {
|
|
out, err := shell.New(ctx, l, "gcloud", "auth", "list", "--format", "json").Quiet().Output()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var list []struct {
|
|
Account string `json:"account"`
|
|
Status string `json:"status"`
|
|
}
|
|
if err := json.Unmarshal(out, &list); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for _, item := range list {
|
|
if item.Status == "ACTIVE" {
|
|
return item.Account, nil
|
|
}
|
|
}
|
|
|
|
return "", errors.New("no active account")
|
|
}
|