mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 01:52:37 +08:00
133 lines
4.1 KiB
Go
133 lines
4.1 KiB
Go
package containers
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
|
|
"dagger.io/dagger"
|
|
)
|
|
|
|
const GoogleCloudImage = "google/cloud-sdk:alpine"
|
|
|
|
// GCPAuthenticator injects authentication information into the provided container.
|
|
type GCPAuthenticator interface {
|
|
Authenticate(*dagger.Client, *dagger.Container) (*dagger.Container, error)
|
|
}
|
|
|
|
// GCPServiceAccount satisfies GCPAuthenticator and injects the provided ServiceAccount into the filesystem and adds a 'gcloud auth activate-service-account'
|
|
type GCPServiceAccount struct {
|
|
DaggerFile *dagger.File
|
|
JSONFile string
|
|
}
|
|
|
|
func (a *GCPServiceAccount) Authenticate(d *dagger.Client, c *dagger.Container) (*dagger.Container, error) {
|
|
if a.DaggerFile == nil && a.JSONFile == "" {
|
|
return nil, fmt.Errorf("GCPServiceAccount authentication missed JSONFile AND DaggerFile")
|
|
}
|
|
var container *dagger.Container
|
|
|
|
if a.JSONFile != "" {
|
|
container = c.WithMountedFile(
|
|
"/opt/service_account.json",
|
|
d.Host().Directory(filepath.Dir(a.JSONFile)).File(filepath.Base(a.JSONFile)),
|
|
)
|
|
}
|
|
|
|
if a.DaggerFile != nil {
|
|
container = c.WithMountedFile("/opt/service_account.json", a.DaggerFile)
|
|
}
|
|
|
|
return container.WithExec([]string{"gcloud", "auth", "activate-service-account", "--key-file", "/opt/service_account.json"}), nil
|
|
}
|
|
|
|
func NewGCPServiceAccount(filepath string) *GCPServiceAccount {
|
|
return &GCPServiceAccount{
|
|
JSONFile: filepath,
|
|
}
|
|
}
|
|
|
|
func NewGCPServiceAccountWithFile(file *dagger.File) *GCPServiceAccount {
|
|
return &GCPServiceAccount{
|
|
DaggerFile: file,
|
|
}
|
|
}
|
|
|
|
// InheritedServiceAccount uses `gcloud` command in the current shell to get the GCS credentials.
|
|
// This type should really only be used when running locally.
|
|
type GCPInheritedAuth struct{}
|
|
|
|
func (a *GCPInheritedAuth) Authenticate(d *dagger.Client, c *dagger.Container) (*dagger.Container, error) {
|
|
if val, ok := os.LookupEnv("GOOGLE_APPLICATION_CREDENTIALS"); ok {
|
|
return c.WithMountedDirectory("/auth/credentials.json", d.Host().Directory(val)).WithEnvVariable("GOOGLE_APPLICATION_CREDENTIALS", "/auth/credentials.json"), nil
|
|
}
|
|
|
|
cfg, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return c.WithMountedDirectory("/root/.config/gcloud", d.Host().Directory(filepath.Join(cfg, ".config", "gcloud"))), nil
|
|
}
|
|
|
|
func GCSUploadDirectory(d *dagger.Client, image string, auth GCPAuthenticator, dir *dagger.Directory, dst string) (*dagger.Container, error) {
|
|
container := d.Container().From(image).
|
|
WithMountedDirectory("/src", dir)
|
|
|
|
var err error
|
|
container, err = auth.Authenticate(d, container)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
secret := d.SetSecret("gcs-destination", dst)
|
|
container = container.WithSecretVariable("GCS_DESTINATION", secret)
|
|
|
|
return container.WithExec([]string{"/bin/sh", "-c", "gcloud storage cp -r /src/* ${GCS_DESTINATION}"}), nil
|
|
}
|
|
|
|
func GCSDownloadFile(d *dagger.Client, image string, auth GCPAuthenticator, url string) (*dagger.File, error) {
|
|
var (
|
|
container = d.Container().From(image)
|
|
err error
|
|
r = rand.Int()
|
|
)
|
|
|
|
container, err = auth.Authenticate(d, container)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
secret := d.SetSecret("gcs-download-url", url)
|
|
file := container.
|
|
WithEnvVariable("RAND", strconv.Itoa(r)).
|
|
WithSecretVariable("GCS_DOWNLOAD_URL", secret).
|
|
WithExec([]string{"/bin/sh", "-c", "gcloud storage cp ${GCS_DOWNLOAD_URL} /src/file"}).
|
|
File("/src/file")
|
|
|
|
return file, nil
|
|
}
|
|
|
|
func GCSAuth(d *dagger.Client, opts *GCPOpts) GCPAuthenticator {
|
|
var auth GCPAuthenticator = &GCPInheritedAuth{}
|
|
// The order of operations:
|
|
// 1. Try to use base64 key.
|
|
// 2. Try to use gcp-service-account-key (path to a file).
|
|
// 3. Try mounting $XDG_CONFIG_HOME/gcloud
|
|
if key := opts.ServiceAccountKeyBase64; key != "" {
|
|
secret := d.SetSecret("gcp-sa-key-base64", key)
|
|
// Write key to a file in an alpine container...
|
|
file := d.Container().From("alpine").
|
|
WithSecretVariable("GCP_SERVICE_ACCOUNT_KEY_BASE64", secret).
|
|
WithExec([]string{"/bin/sh", "-c", "echo $GCP_SERVICE_ACCOUNT_KEY_BASE64 | base64 -d > /key.json"}).
|
|
File("/key.json")
|
|
|
|
auth = NewGCPServiceAccountWithFile(file)
|
|
} else if key := opts.ServiceAccountKey; key != "" {
|
|
auth = NewGCPServiceAccount(key)
|
|
}
|
|
|
|
return auth
|
|
}
|