You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-07-17 01:42:37 +02:00
feat: blob kms support (#1056)
* feat: blob kms support Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
committed by
GitHub
parent
00cba17696
commit
4541fd9f20
9
go.sum
9
go.sum
@ -4,6 +4,7 @@ cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7h
|
||||
cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw=
|
||||
cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.11.0/go.mod h1:hA7rlmtavV03FGxzWXAPBUnZeZBhWN/QYQAuMtxc9Bk=
|
||||
contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
|
||||
@ -14,13 +15,16 @@ github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9a
|
||||
github.com/Azure/azure-pipeline-go v0.1.9 h1:u7JFb9fFTE6Y/j8ae2VK33ePrRqJqoCM/IWkQdAZ+rg=
|
||||
github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
||||
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible h1:i+ROfG3CsZUPoVAnhK06T3R6PmBzKB9ds+lHBpN7Mzo=
|
||||
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-service-bus-go v0.4.1/go.mod h1:d9ho9e/06euiTwGpKxmlbpPhFUsfCsq6a4tZ68r51qI=
|
||||
github.com/Azure/azure-storage-blob-go v0.6.0 h1:SEATKb3LIHcaSIX+E6/K4kJpwfuozFEsmt5rS56N6CE=
|
||||
github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y=
|
||||
github.com/Azure/go-autorest v11.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v11.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA=
|
||||
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc=
|
||||
github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190418212003-6ac0b49e7197/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=
|
||||
@ -48,13 +52,16 @@ github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw=
|
||||
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
|
||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ=
|
||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
@ -105,6 +112,7 @@ github.com/goreleaser/nfpm v0.12.0 h1:2eyO5y6SlnokPZIJN98ewVN45ch0j70WenFE9qWyJp
|
||||
github.com/goreleaser/nfpm v0.12.0/go.mod h1:F2yzin6cBAL9gb+mSiReuXdsfTrOQwDMsuSpULof+y4=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
@ -191,6 +199,7 @@ gocloud.dev v0.15.0/go.mod h1:ShXCyJaGrJu9y/7a6+DSCyBb9MFGZ1P5wwPa0Wu6w34=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd h1:sMHc2rZHuzQmrbVoSpt9HgerkXPyIeCSO6k0zUMGfFk=
|
||||
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -9,11 +9,6 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/semerrgroup"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
|
||||
// Import the blob packages we want to be able to open.
|
||||
_ "gocloud.dev/blob/azureblob"
|
||||
_ "gocloud.dev/blob/gcsblob"
|
||||
_ "gocloud.dev/blob/s3blob"
|
||||
)
|
||||
|
||||
// Pipe for Artifactory
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
@ -219,7 +220,7 @@ func TestPipe_Publish(t *testing.T) {
|
||||
setEnv(tt.env)
|
||||
defer unsetEnv(tt.env)
|
||||
if err := p.Publish(tt.args.ctx); (err != nil) != tt.wantErr {
|
||||
if err.Error() != tt.wantErrString {
|
||||
if !strings.HasPrefix(err.Error(), tt.wantErrString) {
|
||||
t.Errorf("Pipe.Publish() error = %v, wantErr %v", err, tt.wantErrString)
|
||||
}
|
||||
}
|
||||
|
@ -10,23 +10,30 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/semerrgroup"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
gocdk "gocloud.dev/blob"
|
||||
"github.com/pkg/errors"
|
||||
"gocloud.dev/blob"
|
||||
"gocloud.dev/secrets"
|
||||
|
||||
// Import the blob packages we want to be able to open.
|
||||
_ "gocloud.dev/blob/azureblob"
|
||||
_ "gocloud.dev/blob/gcsblob"
|
||||
_ "gocloud.dev/blob/s3blob"
|
||||
|
||||
// import the secrets packages we want to be able to open:
|
||||
_ "gocloud.dev/secrets/awskms"
|
||||
_ "gocloud.dev/secrets/azurekeyvault"
|
||||
_ "gocloud.dev/secrets/gcpkms"
|
||||
)
|
||||
|
||||
// OpenBucket is the interface that wraps the BucketConnect and UploadBucket method
|
||||
type OpenBucket interface {
|
||||
Connect(ctx *context.Context, bucketURL string) (*gocdk.Bucket, error)
|
||||
Connect(ctx *context.Context, bucketURL string) (*blob.Bucket, error)
|
||||
Upload(ctx *context.Context, conf config.Blob, folder string) error
|
||||
}
|
||||
|
||||
// Bucket is object which holds connection for Go Bucker Provider
|
||||
type Bucket struct {
|
||||
BucketConn *gocdk.Bucket
|
||||
BucketConn *blob.Bucket
|
||||
}
|
||||
|
||||
// returns openbucket connection for list of providers
|
||||
@ -35,12 +42,12 @@ func newOpenBucket() OpenBucket {
|
||||
}
|
||||
|
||||
// Connect makes connection with provider
|
||||
func (b Bucket) Connect(ctx *context.Context, bucketURL string) (*gocdk.Bucket, error) {
|
||||
bucketConnection, err := gocdk.OpenBucket(ctx, bucketURL)
|
||||
func (b Bucket) Connect(ctx *context.Context, bucketURL string) (*blob.Bucket, error) {
|
||||
conn, err := blob.OpenBucket(ctx, bucketURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bucketConnection, nil
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Upload takes connection initilized from newOpenBucket to upload goreleaser artifacts
|
||||
@ -49,11 +56,11 @@ func (b Bucket) Upload(ctx *context.Context, conf config.Blob, folder string) er
|
||||
var bucketURL = fmt.Sprintf("%s://%s", conf.Provider, conf.Bucket)
|
||||
|
||||
// Get the openbucket connection for specific provider
|
||||
openbucketConn, err := b.Connect(ctx, bucketURL)
|
||||
conn, err := b.Connect(ctx, bucketURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer openbucketConn.Close()
|
||||
defer conn.Close()
|
||||
|
||||
var filter = artifact.Or(
|
||||
artifact.ByType(artifact.UploadableArchive),
|
||||
@ -70,49 +77,48 @@ func (b Bucket) Upload(ctx *context.Context, conf config.Blob, folder string) er
|
||||
for _, artifact := range ctx.Artifacts.Filter(filter).List() {
|
||||
artifact := artifact
|
||||
g.Go(func() error {
|
||||
// Prepare artifact for upload.
|
||||
data, err := ioutil.ReadFile(artifact.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"provider": bucketURL,
|
||||
"artifact": artifact.Name,
|
||||
}).Info("uploading")
|
||||
|
||||
w, err := openbucketConn.NewWriter(ctx, filepath.Join(folder, artifact.Path), nil)
|
||||
w, err := conn.NewWriter(ctx, filepath.Join(folder, artifact.Path), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to obtain writer: %s", err)
|
||||
return errors.Wrap(err, "failed to obtain writer")
|
||||
}
|
||||
data, err := getData(ctx, conf, artifact.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(data)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errorContains(err, "NoSuchBucket", "ContainerNotFound", "notFound"):
|
||||
return fmt.Errorf("(%v) provided bucket does not exist", bucketURL)
|
||||
return errors.Wrapf(err, "provided bucket does not exist: %s", bucketURL)
|
||||
case errorContains(err, "NoCredentialProviders"):
|
||||
return fmt.Errorf("check credentials and access to bucket %s", bucketURL)
|
||||
return errors.Wrapf(err, "check credentials and access to bucket: %s", bucketURL)
|
||||
default:
|
||||
return fmt.Errorf("failed to write to bucket : %s", err)
|
||||
return errors.Wrapf(err, "failed to write to bucket")
|
||||
}
|
||||
}
|
||||
if err = w.Close(); err != nil {
|
||||
switch {
|
||||
case errorContains(err, "InvalidAccessKeyId"):
|
||||
return fmt.Errorf("aws access key id you provided does not exist in our records")
|
||||
return errors.Wrap(err, "aws access key id you provided does not exist in our records")
|
||||
case errorContains(err, "AuthenticationFailed"):
|
||||
return fmt.Errorf("azure storage key you provided is not valid")
|
||||
return errors.Wrap(err, "azure storage key you provided is not valid")
|
||||
case errorContains(err, "invalid_grant"):
|
||||
return fmt.Errorf("google app credentials you provided is not valid")
|
||||
return errors.Wrap(err, "google app credentials you provided is not valid")
|
||||
case errorContains(err, "no such host"):
|
||||
return fmt.Errorf("azure storage account you provided is not valid")
|
||||
return errors.Wrap(err, "azure storage account you provided is not valid")
|
||||
case errorContains(err, "NoSuchBucket", "ContainerNotFound", "notFound"):
|
||||
return fmt.Errorf("(%v) provided bucket does not exist", bucketURL)
|
||||
return errors.Wrapf(err, "provided bucket does not exist: %s", bucketURL)
|
||||
case errorContains(err, "NoCredentialProviders"):
|
||||
return fmt.Errorf("check credentials and access to bucket %s", bucketURL)
|
||||
return errors.Wrapf(err, "check credentials and access to bucket %s", bucketURL)
|
||||
case errorContains(err, "ServiceCode=ResourceNotFound"):
|
||||
return fmt.Errorf("missing azure storage key for provided bucket %s", bucketURL)
|
||||
return errors.Wrapf(err, "missing azure storage key for provided bucket %s", bucketURL)
|
||||
default:
|
||||
return fmt.Errorf("failed to close Bucket writer: %s", err)
|
||||
return errors.Wrap(err, "failed to close Bucket writer")
|
||||
}
|
||||
}
|
||||
return err
|
||||
@ -120,3 +126,23 @@ func (b Bucket) Upload(ctx *context.Context, conf config.Blob, folder string) er
|
||||
}
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func getData(ctx *context.Context, conf config.Blob, path string) ([]byte, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return data, errors.Wrapf(err, "failed to open file %s", path)
|
||||
}
|
||||
if conf.KMSKey == "" {
|
||||
return data, nil
|
||||
}
|
||||
keeper, err := secrets.OpenKeeper(ctx, conf.KMSKey)
|
||||
if err != nil {
|
||||
return data, errors.Wrapf(err, "failed to open kms %s", conf.KMSKey)
|
||||
}
|
||||
defer keeper.Close()
|
||||
data, err = keeper.Encrypt(ctx, data)
|
||||
if err != nil {
|
||||
return data, errors.Wrap(err, "failed to encrypt with kms")
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
|
@ -302,20 +302,21 @@ type Before struct {
|
||||
|
||||
// S3 contains s3 config
|
||||
type S3 struct {
|
||||
Region string
|
||||
Bucket string
|
||||
Folder string
|
||||
Profile string
|
||||
Endpoint string // used for minio for example
|
||||
ACL string
|
||||
Region string `yaml:",omitempty"`
|
||||
Bucket string `yaml:",omitempty"`
|
||||
Folder string `yaml:",omitempty"`
|
||||
Profile string `yaml:",omitempty"`
|
||||
Endpoint string `yaml:",omitempty"` // used for minio for example
|
||||
ACL string `yaml:",omitempty"`
|
||||
IDs []string `yaml:"ids,omitempty"`
|
||||
}
|
||||
|
||||
// Blob contains config for GO CDK blob
|
||||
type Blob struct {
|
||||
Bucket string
|
||||
Provider string
|
||||
Folder string
|
||||
Bucket string `yaml:",omitempty"`
|
||||
Provider string `yaml:",omitempty"`
|
||||
Folder string `yaml:",omitempty"`
|
||||
KMSKey string `yaml:",omitempty"`
|
||||
IDs []string `yaml:"ids,omitempty"`
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user