84 lines
2.3 KiB
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
|
|
}
|