diff --git a/commands/check.go b/commands/check.go index 646ffba..5a37f16 100644 --- a/commands/check.go +++ b/commands/check.go @@ -49,6 +49,12 @@ func (c *Check) Execute() error { return fmt.Errorf("invalid payload: %s", err) } + if req.Source.GcpTokenSource != nil { + if !req.Source.AuthenticateToGCP(*req.Source.GcpTokenSource) { + return fmt.Errorf("cannot authenticate with GCP") + } + } + if req.Source.AwsAccessKeyId != "" && req.Source.AwsSecretAccessKey != "" && req.Source.AwsRegion != "" { if !req.Source.AuthenticateToECR() { return fmt.Errorf("cannot authenticate with ECR") diff --git a/commands/in.go b/commands/in.go index cbffa4e..e91b6ac 100644 --- a/commands/in.go +++ b/commands/in.go @@ -65,6 +65,12 @@ func (i *In) Execute() error { dest := i.args[1] + if req.Source.GcpTokenSource != nil { + if !req.Source.AuthenticateToGCP(*req.Source.GcpTokenSource) { + return fmt.Errorf("cannot authenticate with GCP") + } + } + if req.Source.AwsAccessKeyId != "" && req.Source.AwsSecretAccessKey != "" && req.Source.AwsRegion != "" { if !req.Source.AuthenticateToECR() { return fmt.Errorf("cannot authenticate with ECR") diff --git a/commands/out.go b/commands/out.go index 03a8fa1..d3d837f 100644 --- a/commands/out.go +++ b/commands/out.go @@ -62,6 +62,12 @@ func (o *Out) Execute() error { src := o.args[1] + if req.Source.GcpTokenSource != nil { + if !req.Source.AuthenticateToGCP(*req.Source.GcpTokenSource) { + return fmt.Errorf("cannot authenticate with GCP") + } + } + if req.Source.AwsAccessKeyId != "" && req.Source.AwsSecretAccessKey != "" && req.Source.AwsRegion != "" { if !req.Source.AuthenticateToECR() { return fmt.Errorf("cannot authenticate with ECR") diff --git a/go.mod b/go.mod index 67baa5a..b8a6a0a 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/spf13/viper v1.7.0 // indirect github.com/vbauerster/mpb v3.4.0+incompatible golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect gopkg.in/ini.v1 v1.56.0 // indirect ) diff --git a/go.sum b/go.sum index 60567db..e87fc89 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,7 @@ cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -541,6 +542,7 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -668,6 +670,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/types.go b/types.go index 9f77514..1e5199e 100644 --- a/types.go +++ b/types.go @@ -24,6 +24,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/remote/transport" "github.com/sirupsen/logrus" + "golang.org/x/oauth2/google" ) type CheckRequest struct { @@ -95,6 +96,8 @@ type Source struct { DomainCerts []string `json:"ca_certs,omitempty"` Debug bool `json:"debug,omitempty"` + + GcpTokenSource *string `json:"gcp_token_source,omitempty"` } func (source Source) Mirror() (Source, bool, error) { @@ -277,6 +280,23 @@ func (source *Source) Metadata() []MetadataField { } } +func (source *Source) AuthenticateToGCP(tokenSource string) bool { + logrus.Warnln("GCP integration is experimental and untested") + logrus.Info("Using GCP service account credentials to authenticate to GCP") + + oauthToken := google.ComputeTokenSource(tokenSource) + token, err := oauthToken.Token() + + if err != nil || token == nil { + logrus.Errorf("Failed to get access token for GCP: %s", err) + return false + } + + source.Username = "oauth2accesstoken" + source.Password = token.AccessToken + return true +} + func (source *Source) AuthenticateToECR() bool { logrus.Warnln("ECR integration is experimental and untested")