keel/extension/credentialshelper/gcr/gcr.go

84 lines
2.3 KiB
Go

package gcr
import (
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"cloud.google.com/go/storage"
"github.com/keel-hq/keel/extension/credentialshelper"
"github.com/keel-hq/keel/types"
"golang.org/x/oauth2/google"
)
func init() {
credentialshelper.RegisterCredentialsHelper("gcr", New())
}
type CredentialsHelper struct {
enabled bool
}
func New() *CredentialsHelper {
return &CredentialsHelper{
enabled: true,
}
}
func (h *CredentialsHelper) IsEnabled() bool {
return h.enabled
}
func (h *CredentialsHelper) GetCredentials(image *types.TrackedImage) (*types.Credentials, error) {
if !h.enabled {
return nil, errors.New("not initialised")
}
if !strings.HasPrefix(image.Image.Registry(), "gcr.io") && !strings.Contains(image.Image.Registry(), "pkg.dev") {
return nil, credentialshelper.ErrUnsupportedRegistry
}
if credentials, err := readCredentialsFromFile(); err == nil {
return credentials, nil
}
return getWorkloadIdentityTokenCredentials()
}
func readCredentialsFromFile() (*types.Credentials, error) {
credentialsFile, ok := os.LookupEnv("GOOGLE_APPLICATION_CREDENTIALS")
if !ok {
return nil, errors.New("GOOGLE_APPLICATION_CREDENTIALS environment variable not set")
}
credentials, err := ioutil.ReadFile(credentialsFile)
if err != nil {
return nil, fmt.Errorf("failed to read credentials file: %w", err)
}
return &types.Credentials{
Username: "_json_key",
Password: string(credentials),
}, nil
}
func getWorkloadIdentityTokenCredentials() (*types.Credentials, error) {
ctx := context.Background()
tokenSource, err := google.DefaultTokenSource(ctx, storage.ScopeReadOnly)
if err != nil {
return nil, fmt.Errorf("failed to get default token source: %w", err)
}
token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("failed to get token: %w", err)
}
return &types.Credentials{
Username: "_token",
Password: token.AccessToken,
}, nil
}