From 4797ac281a8f3b17356a34a1343496990e5dd1e8 Mon Sep 17 00:00:00 2001 From: sanne Date: Tue, 21 Dec 2021 15:28:59 +0100 Subject: [PATCH] osbuild-service-maintenance: Rework GCP credentials mapping Because of the way the gcp secrets are stored for the workers, and how the mapping from vault to openshift works (unable to map a multiple key secret into a single json file), there's a bit of juggling required to get the gcp credentials in the right format. --- cmd/osbuild-service-maintenance/config.go | 68 +++++++++++++++++++---- cmd/osbuild-service-maintenance/gcp.go | 4 +- cmd/osbuild-service-maintenance/main.go | 21 ++++++- templates/composer.yml | 50 +++++++++++++++++ 4 files changed, 127 insertions(+), 16 deletions(-) diff --git a/cmd/osbuild-service-maintenance/config.go b/cmd/osbuild-service-maintenance/config.go index 668f17979..5caedf916 100644 --- a/cmd/osbuild-service-maintenance/config.go +++ b/cmd/osbuild-service-maintenance/config.go @@ -8,17 +8,29 @@ import ( // Do not write this config to logs or stdout, it contains secrets! type Config struct { - DryRun string `env:"DRY_RUN"` - MaxConcurrentRequests string `env:"MAX_CONCURRENT_REQUESTS"` - PGHost string `env:"PGHOST"` - PGPort string `env:"PGPORT"` - PGDatabase string `env:"PGDATABASE"` - PGUser string `env:"PGUSER"` - PGPassword string `env:"PGPASSWORD"` - PGSSLMode string `env:"PGSSLMODE"` - GoogleApplicationCreds string `env:"GOOGLE_APPLICATION_CREDENTIALS"` - AWSAccessKeyID string `env:"AWS_ACCESS_KEY_ID"` - AWSSecretAccessKey string `env:"AWS_SECRET_ACCESS_KEY"` + DryRun string `env:"DRY_RUN"` + MaxConcurrentRequests string `env:"MAX_CONCURRENT_REQUESTS"` + PGHost string `env:"PGHOST"` + PGPort string `env:"PGPORT"` + PGDatabase string `env:"PGDATABASE"` + PGUser string `env:"PGUSER"` + PGPassword string `env:"PGPASSWORD"` + PGSSLMode string `env:"PGSSLMODE"` + AWSAccessKeyID string `env:"AWS_ACCESS_KEY_ID"` + AWSSecretAccessKey string `env:"AWS_SECRET_ACCESS_KEY"` +} + +type GCPCredentialsConfig struct { + AuthProviderX509CertUrl string `json:"auth_provider_x509_cert_url" env:"GCP_AUTH_PROVIDER_X509_CERT_URL"` + AuthUri string `json:"auth_uril" env:"GCP_AUTH_URI"` + ClientEmail string `json:"client_email" env:"GCP_CLIENT_EMAIL"` + ClientId string `json:"client_id" env:"GCP_CLIENT_ID"` + ClientX509CertUrl string `json:"client_x509_cert_url" env:"GCP_CLIENT_X509_CERT_URL"` + PrivateKey string `json:"private_key" env:"GCP_PRIVATE_KEY"` + PrivateKeyId string `json:"private_key_id" env:"GCP_PRIVATE_KEY_ID"` + ProjectId string `json:"project_id" env:"GCP_PROJECT_ID"` + TokenUri string `json:"token_uri" env:"GCP_TOKEN_URI"` + Type string `json:"type" env:"GCP_TYPE"` } // *string means the value is not required @@ -53,3 +65,37 @@ func LoadConfigFromEnv(intf interface{}) error { } return nil } + +func (gc *GCPCredentialsConfig) valid() bool { + if gc.AuthProviderX509CertUrl == "" { + return false + } + if gc.AuthUri == "" { + return false + } + if gc.ClientEmail == "" { + return false + } + if gc.ClientId == "" { + return false + } + if gc.ClientX509CertUrl == "" { + return false + } + if gc.PrivateKey == "" { + return false + } + if gc.PrivateKeyId == "" { + return false + } + if gc.ProjectId == "" { + return false + } + if gc.TokenUri == "" { + return false + } + if gc.Type == "" { + return false + } + return true +} diff --git a/cmd/osbuild-service-maintenance/gcp.go b/cmd/osbuild-service-maintenance/gcp.go index f658da83d..3cf4fac70 100644 --- a/cmd/osbuild-service-maintenance/gcp.go +++ b/cmd/osbuild-service-maintenance/gcp.go @@ -13,8 +13,8 @@ import ( "github.com/osbuild/osbuild-composer/internal/cloud/gcp" ) -func GCPCleanup(maxConcurrentRequests int, dryRun bool, cutoff time.Time) error { - g, err := gcp.New(nil) +func GCPCleanup(creds []byte, maxConcurrentRequests int, dryRun bool, cutoff time.Time) error { + g, err := gcp.New(creds) if err != nil { return err } diff --git a/cmd/osbuild-service-maintenance/main.go b/cmd/osbuild-service-maintenance/main.go index 0cfb2f3be..1e375c9a9 100644 --- a/cmd/osbuild-service-maintenance/main.go +++ b/cmd/osbuild-service-maintenance/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "strconv" "sync" @@ -66,11 +67,25 @@ func main() { go func() { defer wg.Done() logrus.Info("Cleaning up GCP") - if conf.GoogleApplicationCreds == "" { - logrus.Error("GCP credentials not specified") + var gcpConf GCPCredentialsConfig + err := LoadConfigFromEnv(&gcpConf) + if err != nil { + logrus.Error("Unable to load GCP config from environment") return } - err = GCPCleanup(maxCReqs, dryRun, cutoff) + + if !gcpConf.valid() { + logrus.Error("GCP credentials invalid, fields missing") + return + } + + creds, err := json.Marshal(&gcpConf) + if err != nil { + logrus.Errorf("Unable to marshal gcp conf: %v", err) + return + } + + err = GCPCleanup(creds, maxCReqs, dryRun, cutoff) if err != nil { logrus.Errorf("GCP Cleanup failed: %v", err) } diff --git a/templates/composer.yml b/templates/composer.yml index 718936af8..c0de96b98 100644 --- a/templates/composer.yml +++ b/templates/composer.yml @@ -275,6 +275,56 @@ objects: key: db.password - name: PGSSLMODE value: "${PGSSLMODE}" + - name: GCP_AUTH_PROVIDER_X509_CERT_URL + valueFrom: + secretKeyRef: + name: gcp-service-account + key: auth_provider_x509_cert_url + - name: GCP_AUTH_URI + valueFrom: + secretKeyRef: + name: gcp-service-account + key: auth_uri + - name: GCP_CLIENT_EMAIL + valueFrom: + secretKeyRef: + name: gcp-service-account + key: client_email + - name: GCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: gcp-service-account + key: client_id + - name: GCP_CLIENT_X509_CERT_URL + valueFrom: + secretKeyRef: + name: gcp-service-account + key: client_x509_cert_url + - name: GCP_PRIVATE_KEY + valueFrom: + secretKeyRef: + name: gcp-service-account + key: private_key + - name: GCP_PRIVATE_KEY_ID + valueFrom: + secretKeyRef: + name: gcp-service-account + key: private_key_id + - name: GCP_PROJECT_ID + valueFrom: + secretKeyRef: + name: gcp-service-account + key: project_id + - name: GCP_TOKEN_URI + valueFrom: + secretKeyRef: + name: gcp-service-account + key: token_uri + - name: GCP_TYPE + valueFrom: + secretKeyRef: + name: gcp-service-account + key: type - name: DRY_RUN value: "${MAINTENANCE_DRY_RUN}" - name: MAX_CONCURRENT_REQUESTS