From 340009009dab9dcd020b7d5b0ca1dfb40cb0a935 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 23 Oct 2018 09:58:27 -0700 Subject: [PATCH 1/3] Revert "Revert "Merge pull request #6892 from hashicorp/fix_6890"" This reverts commit 0cd3f36d50becb03fcb8fbfbe0d3061be0271856. --- builder/amazon/common/access_config.go | 10 +- builder/amazon/common/ami_config.go | 7 +- builder/amazon/common/ami_config_test.go | 30 ++- builder/amazon/common/regions.go | 11 - .../aws/aws-sdk-go/awstesting/assert.go | 212 ++++++++++++++++++ .../aws/aws-sdk-go/awstesting/client.go | 24 ++ .../aws-sdk-go/awstesting/custom_ca_bundle.go | 199 ++++++++++++++++ .../aws/aws-sdk-go/awstesting/mock/mock.go | 74 ++++++ .../aws/aws-sdk-go/awstesting/util.go | 121 ++++++++++ .../aws/aws-sdk-go/private/util/sort_keys.go | 14 ++ .../aws/aws-sdk-go/private/util/util.go | 109 +++++++++ vendor/vendor.json | 24 ++ 12 files changed, 809 insertions(+), 26 deletions(-) create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/assert.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/client.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/util.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/util/util.go diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index cb97ff91e..5c05f4280 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/packer/template/interpolate" ) @@ -38,7 +39,6 @@ func (c *AccessConfig) Session() (*session.Session, error) { } config := aws.NewConfig().WithCredentialsChainVerboseErrors(true) - staticCreds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token) if _, err := staticCreds.Get(); err != credentials.ErrStaticCredentialsEmpty { config.WithCredentials(staticCreds) @@ -148,8 +148,12 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { } if c.RawRegion != "" && !c.SkipValidation { - ec2conn := getValidationSession() - err := ValidateRegion(c.RawRegion, ec2conn) + sess, err := c.Session() + if err != nil { + errs = append(errs, err) + } + ec2conn := ec2.New(sess) + err = ValidateRegion(c.RawRegion, ec2conn) if err != nil { errs = append(errs, fmt.Errorf("error validating region: %s", err.Error())) } diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index 4c8c7567b..ffaab2245 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/hashicorp/packer/template/interpolate" ) @@ -57,7 +58,11 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context } } - ec2conn := getValidationSession() + sess, err := accessConfig.Session() + if err != nil { + errs = append(errs, err) + } + ec2conn := ec2.New(sess) errs = c.prepareRegions(ec2conn, accessConfig, errs) if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume { diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index 9afad469c..3265703e2 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/awstesting/mock" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" ) @@ -19,18 +20,20 @@ func testAMIConfig() *AMIConfig { func getFakeAccessConfig(region string) *AccessConfig { return &AccessConfig{ RawRegion: region, + session: mock.Session, } } func TestAMIConfigPrepare_name(t *testing.T) { c := testAMIConfig() + accessConf := getFakeAccessConfig("wherever") c.AMISkipRegionValidation = true - if err := c.Prepare(nil, nil); err != nil { + if err := c.Prepare(accessConf, nil); err != nil { t.Fatalf("shouldn't have err: %s", err) } c.AMIName = "" - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("should have error") } } @@ -141,7 +144,8 @@ func TestAMIConfigPrepare_regions(t *testing.T) { } c.AMISkipRegionValidation = true - if err := c.Prepare(nil, nil); err == nil { + accessConf := getFakeAccessConfig("wherever") + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } c.AMISkipRegionValidation = false @@ -159,7 +163,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { } // allow rawregion to exist in ami_regions list. - accessConf := getFakeAccessConfig("us-east-1") + accessConf = getFakeAccessConfig("us-east-1") c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} c.AMIRegionKMSKeyIDs = nil if errs = c.prepareRegions(mockConn, accessConf, errs); len(errs) > 0 { @@ -173,13 +177,15 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { c.AMIUsers = []string{"testAccountID"} c.AMIEncryptBootVolume = true + accessConf := getFakeAccessConfig("wherever") + c.AMIKmsKeyId = "" - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("shouldn't be able to share ami with encrypted boot volume") } c.AMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c" - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("shouldn't be able to share ami with encrypted boot volume") } } @@ -187,8 +193,10 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { func TestAMINameValidation(t *testing.T) { c := testAMIConfig() + accessConf := getFakeAccessConfig("wherever") + c.AMIName = "aa" - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with less than 3 characters") } @@ -197,22 +205,22 @@ func TestAMINameValidation(t *testing.T) { longAmiName += "a" } c.AMIName = longAmiName - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with great than 128 characters") } c.AMIName = "+aaa" - if err := c.Prepare(nil, nil); err == nil { + if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with invalid characters") } c.AMIName = "fooBAR1()[] ./-'@_" - if err := c.Prepare(nil, nil); err != nil { + if err := c.Prepare(accessConf, nil); err != nil { t.Fatal("should be able to use all of the allowed AMI characters") } c.AMIName = `xyz-base-2017-04-05-1934` - if err := c.Prepare(nil, nil); err != nil { + if err := c.Prepare(accessConf, nil); err != nil { t.Fatalf("expected `xyz-base-2017-04-05-1934` to pass validation.") } diff --git a/builder/amazon/common/regions.go b/builder/amazon/common/regions.go index eb8bba19b..6eee8c54a 100644 --- a/builder/amazon/common/regions.go +++ b/builder/amazon/common/regions.go @@ -2,20 +2,9 @@ package common import ( "fmt" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" ) -func getValidationSession() *ec2.EC2 { - sess := session.Must(session.NewSessionWithOptions(session.Options{ - SharedConfigState: session.SharedConfigEnable, - })) - - ec2conn := ec2.New(sess) - return ec2conn -} - func listEC2Regions(ec2conn ec2iface.EC2API) ([]string, error) { var regions []string resultRegions, err := ec2conn.DescribeRegions(nil) diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go b/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go new file mode 100644 index 000000000..510066fc5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go @@ -0,0 +1,212 @@ +package awstesting + +import ( + "encoding/json" + "encoding/xml" + "fmt" + "net/url" + "reflect" + "regexp" + "sort" + "strings" + "testing" +) + +// Match is a testing helper to test for testing error by comparing expected +// with a regular expression. +func Match(t *testing.T, regex, expected string) { + if !regexp.MustCompile(regex).Match([]byte(expected)) { + t.Errorf("%q\n\tdoes not match /%s/", expected, regex) + } +} + +// AssertURL verifies the expected URL is matches the actual. +func AssertURL(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { + expectURL, err := url.Parse(expect) + if err != nil { + t.Errorf(errMsg("unable to parse expected URL", err, msgAndArgs)) + return false + } + actualURL, err := url.Parse(actual) + if err != nil { + t.Errorf(errMsg("unable to parse actual URL", err, msgAndArgs)) + return false + } + + equal(t, expectURL.Host, actualURL.Host, msgAndArgs...) + equal(t, expectURL.Scheme, actualURL.Scheme, msgAndArgs...) + equal(t, expectURL.Path, actualURL.Path, msgAndArgs...) + + return AssertQuery(t, expectURL.Query().Encode(), actualURL.Query().Encode(), msgAndArgs...) +} + +var queryMapKey = regexp.MustCompile("(.*?)\\.[0-9]+\\.key") + +// AssertQuery verifies the expect HTTP query string matches the actual. +func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { + expectQ, err := url.ParseQuery(expect) + if err != nil { + t.Errorf(errMsg("unable to parse expected Query", err, msgAndArgs)) + return false + } + actualQ, err := url.ParseQuery(actual) + if err != nil { + t.Errorf(errMsg("unable to parse actual Query", err, msgAndArgs)) + return false + } + + // Make sure the keys are the same + if !equal(t, queryValueKeys(expectQ), queryValueKeys(actualQ), msgAndArgs...) { + return false + } + + keys := map[string][]string{} + for key, v := range expectQ { + if queryMapKey.Match([]byte(key)) { + submatch := queryMapKey.FindStringSubmatch(key) + keys[submatch[1]] = append(keys[submatch[1]], v...) + } + } + + for k, v := range keys { + // clear all keys that have prefix + for key := range expectQ { + if strings.HasPrefix(key, k) { + delete(expectQ, key) + } + } + + sort.Strings(v) + for i, value := range v { + expectQ[fmt.Sprintf("%s.%d.key", k, i+1)] = []string{value} + } + } + + for k, expectQVals := range expectQ { + sort.Strings(expectQVals) + actualQVals := actualQ[k] + sort.Strings(actualQVals) + if !equal(t, expectQVals, actualQVals, msgAndArgs...) { + return false + } + } + + return true +} + +// AssertJSON verifies that the expect json string matches the actual. +func AssertJSON(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { + expectVal := map[string]interface{}{} + if err := json.Unmarshal([]byte(expect), &expectVal); err != nil { + t.Errorf(errMsg("unable to parse expected JSON", err, msgAndArgs...)) + return false + } + + actualVal := map[string]interface{}{} + if err := json.Unmarshal([]byte(actual), &actualVal); err != nil { + t.Errorf(errMsg("unable to parse actual JSON", err, msgAndArgs...)) + return false + } + + return equal(t, expectVal, actualVal, msgAndArgs...) +} + +// AssertXML verifies that the expect xml string matches the actual. +func AssertXML(t *testing.T, expect, actual string, container interface{}, msgAndArgs ...interface{}) bool { + expectVal := container + if err := xml.Unmarshal([]byte(expect), &expectVal); err != nil { + t.Errorf(errMsg("unable to parse expected XML", err, msgAndArgs...)) + } + + actualVal := container + if err := xml.Unmarshal([]byte(actual), &actualVal); err != nil { + t.Errorf(errMsg("unable to parse actual XML", err, msgAndArgs...)) + } + return equal(t, expectVal, actualVal, msgAndArgs...) +} + +// DidPanic returns if the function paniced and returns true if the function paniced. +func DidPanic(fn func()) (bool, interface{}) { + var paniced bool + var msg interface{} + func() { + defer func() { + if msg = recover(); msg != nil { + paniced = true + } + }() + fn() + }() + + return paniced, msg +} + +// objectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +// +// Based on github.com/stretchr/testify/assert.ObjectsAreEqual +// Copied locally to prevent non-test build dependencies on testify +func objectsAreEqual(expected, actual interface{}) bool { + if expected == nil || actual == nil { + return expected == actual + } + + return reflect.DeepEqual(expected, actual) +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +// +// Based on github.com/stretchr/testify/assert.Equal +// Copied locally to prevent non-test build dependencies on testify +func equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if !objectsAreEqual(expected, actual) { + t.Errorf("%s\n%s", messageFromMsgAndArgs(msgAndArgs), + SprintExpectActual(expected, actual)) + return false + } + + return true +} + +func errMsg(baseMsg string, err error, msgAndArgs ...interface{}) string { + message := messageFromMsgAndArgs(msgAndArgs) + if message != "" { + message += ", " + } + return fmt.Sprintf("%s%s, %v", message, baseMsg, err) +} + +// Based on github.com/stretchr/testify/assert.messageFromMsgAndArgs +// Copied locally to prevent non-test build dependencies on testify +func messageFromMsgAndArgs(msgAndArgs []interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +func queryValueKeys(v url.Values) []string { + keys := make([]string, 0, len(v)) + for k := range v { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +// SprintExpectActual returns a string for test failure cases when the actual +// value is not the same as the expected. +func SprintExpectActual(expect, actual interface{}) string { + return fmt.Sprintf("expect: %+v\nactual: %+v\n", expect, actual) +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/client.go b/vendor/github.com/aws/aws-sdk-go/awstesting/client.go new file mode 100644 index 000000000..539639d8b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/client.go @@ -0,0 +1,24 @@ +package awstesting + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/defaults" +) + +// NewClient creates and initializes a generic service client for testing. +func NewClient(cfgs ...*aws.Config) *client.Client { + info := metadata.ClientInfo{ + Endpoint: "http://endpoint", + SigningName: "", + } + def := defaults.Get() + def.Config.MergeIn(cfgs...) + + if v := aws.StringValue(def.Config.Endpoint); len(v) > 0 { + info.Endpoint = v + } + + return client.New(*def.Config, info, def.Handlers) +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go b/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go new file mode 100644 index 000000000..13edc7bcf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go @@ -0,0 +1,199 @@ +package awstesting + +import ( + "io/ioutil" + "net" + "net/http" + "os" + "strings" + "time" +) + +func availableLocalAddr(ip string) (string, error) { + l, err := net.Listen("tcp", ip+":0") + if err != nil { + return "", err + } + defer l.Close() + + return l.Addr().String(), nil +} + +// CreateTLSServer will create the TLS server on an open port using the +// certificate and key. The address will be returned that the server is running on. +func CreateTLSServer(cert, key string, mux *http.ServeMux) (string, error) { + addr, err := availableLocalAddr("127.0.0.1") + if err != nil { + return "", err + } + + if mux == nil { + mux = http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {}) + } + + go func() { + if err := http.ListenAndServeTLS(addr, cert, key, mux); err != nil { + panic(err) + } + }() + + for i := 0; i < 60; i++ { + if _, err := http.Get("https://" + addr); err != nil && !strings.Contains(err.Error(), "connection refused") { + break + } + + time.Sleep(1 * time.Second) + } + + return "https://" + addr, nil +} + +// CreateTLSBundleFiles returns the temporary filenames for the certificate +// key, and CA PEM content. These files should be deleted when no longer +// needed. CleanupTLSBundleFiles can be used for this cleanup. +func CreateTLSBundleFiles() (cert, key, ca string, err error) { + cert, err = createTmpFile(TLSBundleCert) + if err != nil { + return "", "", "", err + } + + key, err = createTmpFile(TLSBundleKey) + if err != nil { + return "", "", "", err + } + + ca, err = createTmpFile(TLSBundleCA) + if err != nil { + return "", "", "", err + } + + return cert, key, ca, nil +} + +// CleanupTLSBundleFiles takes variadic list of files to be deleted. +func CleanupTLSBundleFiles(files ...string) error { + for _, file := range files { + if err := os.Remove(file); err != nil { + return err + } + } + + return nil +} + +func createTmpFile(b []byte) (string, error) { + bundleFile, err := ioutil.TempFile(os.TempDir(), "aws-sdk-go-session-test") + if err != nil { + return "", err + } + + _, err = bundleFile.Write(b) + if err != nil { + return "", err + } + + defer bundleFile.Close() + return bundleFile.Name(), nil +} + +/* Cert generation steps +# Create the CA key +openssl genrsa -des3 -out ca.key 1024 + +# Create the CA Cert +openssl req -new -sha256 -x509 -days 3650 \ + -subj "/C=GO/ST=Gopher/O=Testing ROOT CA" \ + -key ca.key -out ca.crt + +# Create config +cat > csr_details.txt <<-EOF + +[req] +default_bits = 1024 +prompt = no +default_md = sha256 +req_extensions = SAN +distinguished_name = dn + +[ dn ] +C=GO +ST=Gopher +O=Testing Certificate +OU=Testing IP + +[SAN] +subjectAltName = IP:127.0.0.1 +EOF + +# Create certificate signing request +openssl req -new -sha256 -nodes -newkey rsa:1024 \ + -config <( cat csr_details.txt ) \ + -keyout ia.key -out ia.csr + +# Create a signed certificate +openssl x509 -req -days 3650 \ + -CAcreateserial \ + -extfile <( cat csr_details.txt ) \ + -extensions SAN \ + -CA ca.crt -CAkey ca.key -in ia.csr -out ia.crt + +# Verify +openssl req -noout -text -in ia.csr +openssl x509 -noout -text -in ia.crt +*/ +var ( + // TLSBundleCA ca.crt + TLSBundleCA = []byte(`-----BEGIN CERTIFICATE----- +MIICiTCCAfKgAwIBAgIJAJ5X1olt05XjMA0GCSqGSIb3DQEBCwUAMDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QTAeFw0xNzAzMDkwMDAyMDZaFw0yNzAzMDcwMDAyMDZaMDgxCzAJBgNVBAYTAkdP +MQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBDQTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw/8DN+t9XQR60jx42rsQ2WE2Dx85rb3n +GQxnKZZLNddsT8rDyxJNP18aFalbRbFlyln5fxWxZIblu9Xkm/HRhOpbSimSqo1y +uDx21NVZ1YsOvXpHby71jx3gPrrhSc/t/zikhi++6D/C6m1CiIGuiJ0GBiJxtrub +UBMXT0QtI2ECAwEAAaOBmjCBlzAdBgNVHQ4EFgQU8XG3X/YHBA6T04kdEkq6+4GV +YykwaAYDVR0jBGEwX4AU8XG3X/YHBA6T04kdEkq6+4GVYymhPKQ6MDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QYIJAJ5X1olt05XjMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAeILv +z49+uxmPcfOZzonuOloRcpdvyjiXblYxbzz6ch8GsE7Q886FTZbvwbgLhzdwSVgG +G8WHkodDUsymVepdqAamS3f8PdCUk8xIk9mop8LgaB9Ns0/TssxDvMr3sOD2Grb3 +xyWymTWMcj6uCiEBKtnUp4rPiefcvCRYZ17/hLE= +-----END CERTIFICATE----- +`) + + // TLSBundleCert ai.crt + TLSBundleCert = []byte(`-----BEGIN CERTIFICATE----- +MIICGjCCAYOgAwIBAgIJAIIu+NOoxxM0MA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QTAeFw0xNzAzMDkwMDAzMTRaFw0yNzAzMDcwMDAzMTRaMFExCzAJBgNVBAYTAkdP +MQ8wDQYDVQQIDAZHb3BoZXIxHDAaBgNVBAoME1Rlc3RpbmcgQ2VydGlmaWNhdGUx +EzARBgNVBAsMClRlc3RpbmcgSVAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB +AN1hWHeioo/nASvbrjwCQzXCiWiEzGkw353NxsAB54/NqDL3LXNATtiSJu8kJBrm +Ah12IFLtWLGXjGjjYlHbQWnOR6awveeXnQZukJyRWh7m/Qlt9Ho0CgZE1U+832ac +5GWVldNxW1Lz4I+W9/ehzqe8I80RS6eLEKfUFXGiW+9RAgMBAAGjEzARMA8GA1Ud +EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEFBQADgYEAdF4WQHfVdPCbgv9sxgJjcR1H +Hgw9rZ47gO1IiIhzglnLXQ6QuemRiHeYFg4kjcYBk1DJguxzDTGnUwhUXOibAB+S +zssmrkdYYvn9aUhjc3XK3tjAoDpsPpeBeTBamuUKDHoH/dNRXxerZ8vu6uPR3Pgs +5v/KCV6IAEcvNyOXMPo= +-----END CERTIFICATE----- +`) + + // TLSBundleKey ai.key + TLSBundleKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDdYVh3oqKP5wEr2648AkM1wolohMxpMN+dzcbAAeePzagy9y1z +QE7YkibvJCQa5gIddiBS7Vixl4xo42JR20FpzkemsL3nl50GbpCckVoe5v0JbfR6 +NAoGRNVPvN9mnORllZXTcVtS8+CPlvf3oc6nvCPNEUunixCn1BVxolvvUQIDAQAB +AoGBAMISrcirddGrlLZLLrKC1ULS2T0cdkqdQtwHYn4+7S5+/z42vMx1iumHLsSk +rVY7X41OWkX4trFxhvEIrc/O48bo2zw78P7flTxHy14uxXnllU8cLThE29SlUU7j +AVBNxJZMsXMlS/DowwD4CjFe+x4Pu9wZcReF2Z9ntzMpySABAkEA+iWoJCPE2JpS +y78q3HYYgpNY3gF3JqQ0SI/zTNkb3YyEIUffEYq0Y9pK13HjKtdsSuX4osTIhQkS ++UgRp6tCAQJBAOKPYTfQ2FX8ijgUpHZRuEAVaxASAS0UATiLgzXxLvOh/VC2at5x +wjOX6sD65pPz/0D8Qj52Cq6Q1TQ+377SDVECQAIy0od+yPweXxvrUjUd1JlRMjbB +TIrKZqs8mKbUQapw0bh5KTy+O1elU4MRPS3jNtBxtP25PQnuSnxmZcFTgAECQFzg +DiiFcsn9FuRagfkHExMiNJuH5feGxeFaP9WzI144v9GAllrOI6Bm3JNzx2ZLlg4b +20Qju8lIEj6yr6JYFaECQHM1VSojGRKpOl9Ox/R4yYSA9RV5Gyn00/aJNxVYyPD5 +i3acL2joQm2kLD/LO8paJ4+iQdRXCOMMIpjxSNjGQjQ= +-----END RSA PRIVATE KEY----- +`) +) diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go b/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go new file mode 100644 index 000000000..e16021ed3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go @@ -0,0 +1,74 @@ +package mock + +import ( + "crypto/rsa" + "math/big" + "net/http" + "net/http/httptest" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/session" +) + +// Session is a mock session which is used to hit the mock server +var Session = func() *session.Session { + // server is the mock server that simply writes a 200 status back to the client + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + + return session.Must(session.NewSession(&aws.Config{ + DisableSSL: aws.Bool(true), + Endpoint: aws.String(server.URL), + })) +}() + +// NewMockClient creates and initializes a client that will connect to the +// mock server +func NewMockClient(cfgs ...*aws.Config) *client.Client { + c := Session.ClientConfig("Mock", cfgs...) + + svc := client.New( + *c.Config, + metadata.ClientInfo{ + ServiceName: "Mock", + SigningRegion: c.SigningRegion, + Endpoint: c.Endpoint, + APIVersion: "2015-12-08", + JSONVersion: "1.1", + TargetPrefix: "MockServer", + }, + c.Handlers, + ) + + return svc +} + +// RSAPrivateKey is used for testing functionality that requires some +// sort of private key. Taken from crypto/rsa/rsa_test.go +// +// Credit to golang 1.11 +var RSAPrivateKey = &rsa.PrivateKey{ + PublicKey: rsa.PublicKey{ + N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"), + E: 3, + }, + D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"), + Primes: []*big.Int{ + fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"), + fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"), + }, +} + +// Taken from crypto/rsa/rsa_test.go +// +// Credit to golang 1.11 +func fromBase10(base10 string) *big.Int { + i, ok := new(big.Int).SetString(base10, 10) + if !ok { + panic("bad number: " + base10) + } + return i +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/util.go b/vendor/github.com/aws/aws-sdk-go/awstesting/util.go new file mode 100644 index 000000000..3c146a23d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/util.go @@ -0,0 +1,121 @@ +package awstesting + +import ( + "io" + "os" + "strings" + "time" + + "github.com/aws/aws-sdk-go/private/util" +) + +// ZeroReader is a io.Reader which will always write zeros to the byte slice provided. +type ZeroReader struct{} + +// Read fills the provided byte slice with zeros returning the number of bytes written. +func (r *ZeroReader) Read(b []byte) (int, error) { + for i := 0; i < len(b); i++ { + b[i] = 0 + } + return len(b), nil +} + +// ReadCloser is a io.ReadCloser for unit testing. +// Designed to test for leaks and whether a handle has +// been closed +type ReadCloser struct { + Size int + Closed bool + set bool + FillData func(bool, []byte, int, int) +} + +// Read will call FillData and fill it with whatever data needed. +// Decrements the size until zero, then return io.EOF. +func (r *ReadCloser) Read(b []byte) (int, error) { + if r.Closed { + return 0, io.EOF + } + + delta := len(b) + if delta > r.Size { + delta = r.Size + } + r.Size -= delta + + for i := 0; i < delta; i++ { + b[i] = 'a' + } + + if r.FillData != nil { + r.FillData(r.set, b, r.Size, delta) + } + r.set = true + + if r.Size > 0 { + return delta, nil + } + return delta, io.EOF +} + +// Close sets Closed to true and returns no error +func (r *ReadCloser) Close() error { + r.Closed = true + return nil +} + +// SortedKeys returns a sorted slice of keys of a map. +func SortedKeys(m map[string]interface{}) []string { + return util.SortedKeys(m) +} + +// A FakeContext provides a simple stub implementation of a Context +type FakeContext struct { + Error error + DoneCh chan struct{} +} + +// Deadline always will return not set +func (c *FakeContext) Deadline() (deadline time.Time, ok bool) { + return time.Time{}, false +} + +// Done returns a read channel for listening to the Done event +func (c *FakeContext) Done() <-chan struct{} { + return c.DoneCh +} + +// Err returns the error, is nil if not set. +func (c *FakeContext) Err() error { + return c.Error +} + +// Value ignores the Value and always returns nil +func (c *FakeContext) Value(key interface{}) interface{} { + return nil +} + +// StashEnv stashes the current environment variables and returns an array of +// all environment values as key=val strings. +func StashEnv() []string { + env := os.Environ() + os.Clearenv() + + return env +} + +// PopEnv takes the list of the environment values and injects them into the +// process's environment variable data. Clears any existing environment values +// that may already exist. +func PopEnv(env []string) { + os.Clearenv() + + for _, e := range env { + p := strings.SplitN(e, "=", 2) + k, v := p[0], "" + if len(p) > 1 { + v = p[1] + } + os.Setenv(k, v) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go b/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go new file mode 100644 index 000000000..48000565c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go @@ -0,0 +1,14 @@ +package util + +import "sort" + +// SortedKeys returns a sorted slice of keys of a map. +func SortedKeys(m map[string]interface{}) []string { + i, sorted := 0, make([]string, len(m)) + for k := range m { + sorted[i] = k + i++ + } + sort.Strings(sorted) + return sorted +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/util/util.go b/vendor/github.com/aws/aws-sdk-go/private/util/util.go new file mode 100644 index 000000000..5f2dab25e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/util/util.go @@ -0,0 +1,109 @@ +package util + +import ( + "bytes" + "encoding/xml" + "fmt" + "go/format" + "io" + "reflect" + "regexp" + "strings" + + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// GoFmt returns the Go formated string of the input. +// +// Panics if the format fails. +func GoFmt(buf string) string { + formatted, err := format.Source([]byte(buf)) + if err != nil { + panic(fmt.Errorf("%s\nOriginal code:\n%s", err.Error(), buf)) + } + return string(formatted) +} + +var reTrim = regexp.MustCompile(`\s{2,}`) + +// Trim removes all leading and trailing white space. +// +// All consecutive spaces will be reduced to a single space. +func Trim(s string) string { + return strings.TrimSpace(reTrim.ReplaceAllString(s, " ")) +} + +// Capitalize capitalizes the first character of the string. +func Capitalize(s string) string { + if len(s) == 1 { + return strings.ToUpper(s) + } + return strings.ToUpper(s[0:1]) + s[1:] +} + +// SortXML sorts the reader's XML elements +func SortXML(r io.Reader) string { + var buf bytes.Buffer + d := xml.NewDecoder(r) + root, _ := xmlutil.XMLToStruct(d, nil) + e := xml.NewEncoder(&buf) + xmlutil.StructToXML(e, root, true) + return buf.String() +} + +// PrettyPrint generates a human readable representation of the value v. +// All values of v are recursively found and pretty printed also. +func PrettyPrint(v interface{}) string { + value := reflect.ValueOf(v) + switch value.Kind() { + case reflect.Struct: + str := fullName(value.Type()) + "{\n" + for i := 0; i < value.NumField(); i++ { + l := string(value.Type().Field(i).Name[0]) + if strings.ToUpper(l) == l { + str += value.Type().Field(i).Name + ": " + str += PrettyPrint(value.Field(i).Interface()) + str += ",\n" + } + } + str += "}" + return str + case reflect.Map: + str := "map[" + fullName(value.Type().Key()) + "]" + fullName(value.Type().Elem()) + "{\n" + for _, k := range value.MapKeys() { + str += "\"" + k.String() + "\": " + str += PrettyPrint(value.MapIndex(k).Interface()) + str += ",\n" + } + str += "}" + return str + case reflect.Ptr: + if e := value.Elem(); e.IsValid() { + return "&" + PrettyPrint(e.Interface()) + } + return "nil" + case reflect.Slice: + str := "[]" + fullName(value.Type().Elem()) + "{\n" + for i := 0; i < value.Len(); i++ { + str += PrettyPrint(value.Index(i).Interface()) + str += ",\n" + } + str += "}" + return str + default: + return fmt.Sprintf("%#v", v) + } +} + +func pkgName(t reflect.Type) string { + pkg := t.PkgPath() + c := strings.Split(pkg, "/") + return c[len(c)-1] +} + +func fullName(t reflect.Type) string { + if pkg := pkgName(t); pkg != "" { + return pkg + "." + t.Name() + } + return t.Name() +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 9a2135b5f..710ca896a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -433,6 +433,22 @@ "version": "v1.15.54", "versionExact": "v1.15.54" }, + { + "checksumSHA1": "MxSiiCoPpY1mCRjyEFClUu3e14w=", + "path": "github.com/aws/aws-sdk-go/awstesting", + "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", + "revisionTime": "2018-10-12T21:50:02Z", + "version": "v1.15.54", + "versionExact": "v1.15.54" + }, + { + "checksumSHA1": "Til1RNskoxuni9LNTwJWzm1GKrU=", + "path": "github.com/aws/aws-sdk-go/awstesting/mock", + "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", + "revisionTime": "2018-10-12T21:50:02Z", + "version": "v1.15.54", + "versionExact": "v1.15.54" + }, { "checksumSHA1": "QvKGojx+wCHTDfXQ1aoOYzH3Y88=", "path": "github.com/aws/aws-sdk-go/internal/s3err", @@ -570,6 +586,14 @@ "version": "v1.15.54", "versionExact": "v1.15.54" }, + { + "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", + "path": "github.com/aws/aws-sdk-go/private/util", + "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", + "revisionTime": "2018-10-12T21:50:02Z", + "version": "v1.15.54", + "versionExact": "v1.15.54" + }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "comment": "v1.7.1", From fe044d8ff7976168475b10ae0fd9568e6104f496 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 23 Oct 2018 13:12:22 -0700 Subject: [PATCH 2/3] fix tests --- builder/amazon/common/ami_config.go | 12 +- builder/amazon/common/ami_config_test.go | 4 +- .../aws/aws-sdk-go/awstesting/assert.go | 212 ------------------ .../aws/aws-sdk-go/awstesting/client.go | 24 -- .../aws-sdk-go/awstesting/custom_ca_bundle.go | 199 ---------------- .../aws/aws-sdk-go/awstesting/mock/mock.go | 74 ------ .../aws/aws-sdk-go/awstesting/util.go | 121 ---------- .../aws/aws-sdk-go/private/util/sort_keys.go | 14 -- .../aws/aws-sdk-go/private/util/util.go | 109 --------- vendor/vendor.json | 24 -- 10 files changed, 10 insertions(+), 783 deletions(-) delete mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/assert.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/util.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/util/util.go diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index ffaab2245..ceb7dbe57 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -58,11 +58,15 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context } } - sess, err := accessConfig.Session() - if err != nil { - errs = append(errs, err) + var ec2conn *ec2.EC2 + if !c.AMISkipRegionValidation { + sess, err := accessConfig.Session() + if err != nil { + errs = append(errs, err) + } + ec2conn = ec2.New(sess) } - ec2conn := ec2.New(sess) + errs = c.prepareRegions(ec2conn, accessConfig, errs) if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume { diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index 3265703e2..4aee3204c 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/awstesting/mock" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" ) @@ -20,7 +19,6 @@ func testAMIConfig() *AMIConfig { func getFakeAccessConfig(region string) *AccessConfig { return &AccessConfig{ RawRegion: region, - session: mock.Session, } } @@ -174,6 +172,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { c := testAMIConfig() + c.AMISkipRegionValidation = true c.AMIUsers = []string{"testAccountID"} c.AMIEncryptBootVolume = true @@ -192,6 +191,7 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { func TestAMINameValidation(t *testing.T) { c := testAMIConfig() + c.AMISkipRegionValidation = true accessConf := getFakeAccessConfig("wherever") diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go b/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go deleted file mode 100644 index 510066fc5..000000000 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go +++ /dev/null @@ -1,212 +0,0 @@ -package awstesting - -import ( - "encoding/json" - "encoding/xml" - "fmt" - "net/url" - "reflect" - "regexp" - "sort" - "strings" - "testing" -) - -// Match is a testing helper to test for testing error by comparing expected -// with a regular expression. -func Match(t *testing.T, regex, expected string) { - if !regexp.MustCompile(regex).Match([]byte(expected)) { - t.Errorf("%q\n\tdoes not match /%s/", expected, regex) - } -} - -// AssertURL verifies the expected URL is matches the actual. -func AssertURL(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { - expectURL, err := url.Parse(expect) - if err != nil { - t.Errorf(errMsg("unable to parse expected URL", err, msgAndArgs)) - return false - } - actualURL, err := url.Parse(actual) - if err != nil { - t.Errorf(errMsg("unable to parse actual URL", err, msgAndArgs)) - return false - } - - equal(t, expectURL.Host, actualURL.Host, msgAndArgs...) - equal(t, expectURL.Scheme, actualURL.Scheme, msgAndArgs...) - equal(t, expectURL.Path, actualURL.Path, msgAndArgs...) - - return AssertQuery(t, expectURL.Query().Encode(), actualURL.Query().Encode(), msgAndArgs...) -} - -var queryMapKey = regexp.MustCompile("(.*?)\\.[0-9]+\\.key") - -// AssertQuery verifies the expect HTTP query string matches the actual. -func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { - expectQ, err := url.ParseQuery(expect) - if err != nil { - t.Errorf(errMsg("unable to parse expected Query", err, msgAndArgs)) - return false - } - actualQ, err := url.ParseQuery(actual) - if err != nil { - t.Errorf(errMsg("unable to parse actual Query", err, msgAndArgs)) - return false - } - - // Make sure the keys are the same - if !equal(t, queryValueKeys(expectQ), queryValueKeys(actualQ), msgAndArgs...) { - return false - } - - keys := map[string][]string{} - for key, v := range expectQ { - if queryMapKey.Match([]byte(key)) { - submatch := queryMapKey.FindStringSubmatch(key) - keys[submatch[1]] = append(keys[submatch[1]], v...) - } - } - - for k, v := range keys { - // clear all keys that have prefix - for key := range expectQ { - if strings.HasPrefix(key, k) { - delete(expectQ, key) - } - } - - sort.Strings(v) - for i, value := range v { - expectQ[fmt.Sprintf("%s.%d.key", k, i+1)] = []string{value} - } - } - - for k, expectQVals := range expectQ { - sort.Strings(expectQVals) - actualQVals := actualQ[k] - sort.Strings(actualQVals) - if !equal(t, expectQVals, actualQVals, msgAndArgs...) { - return false - } - } - - return true -} - -// AssertJSON verifies that the expect json string matches the actual. -func AssertJSON(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { - expectVal := map[string]interface{}{} - if err := json.Unmarshal([]byte(expect), &expectVal); err != nil { - t.Errorf(errMsg("unable to parse expected JSON", err, msgAndArgs...)) - return false - } - - actualVal := map[string]interface{}{} - if err := json.Unmarshal([]byte(actual), &actualVal); err != nil { - t.Errorf(errMsg("unable to parse actual JSON", err, msgAndArgs...)) - return false - } - - return equal(t, expectVal, actualVal, msgAndArgs...) -} - -// AssertXML verifies that the expect xml string matches the actual. -func AssertXML(t *testing.T, expect, actual string, container interface{}, msgAndArgs ...interface{}) bool { - expectVal := container - if err := xml.Unmarshal([]byte(expect), &expectVal); err != nil { - t.Errorf(errMsg("unable to parse expected XML", err, msgAndArgs...)) - } - - actualVal := container - if err := xml.Unmarshal([]byte(actual), &actualVal); err != nil { - t.Errorf(errMsg("unable to parse actual XML", err, msgAndArgs...)) - } - return equal(t, expectVal, actualVal, msgAndArgs...) -} - -// DidPanic returns if the function paniced and returns true if the function paniced. -func DidPanic(fn func()) (bool, interface{}) { - var paniced bool - var msg interface{} - func() { - defer func() { - if msg = recover(); msg != nil { - paniced = true - } - }() - fn() - }() - - return paniced, msg -} - -// objectsAreEqual determines if two objects are considered equal. -// -// This function does no assertion of any kind. -// -// Based on github.com/stretchr/testify/assert.ObjectsAreEqual -// Copied locally to prevent non-test build dependencies on testify -func objectsAreEqual(expected, actual interface{}) bool { - if expected == nil || actual == nil { - return expected == actual - } - - return reflect.DeepEqual(expected, actual) -} - -// Equal asserts that two objects are equal. -// -// assert.Equal(t, 123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Based on github.com/stretchr/testify/assert.Equal -// Copied locally to prevent non-test build dependencies on testify -func equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if !objectsAreEqual(expected, actual) { - t.Errorf("%s\n%s", messageFromMsgAndArgs(msgAndArgs), - SprintExpectActual(expected, actual)) - return false - } - - return true -} - -func errMsg(baseMsg string, err error, msgAndArgs ...interface{}) string { - message := messageFromMsgAndArgs(msgAndArgs) - if message != "" { - message += ", " - } - return fmt.Sprintf("%s%s, %v", message, baseMsg, err) -} - -// Based on github.com/stretchr/testify/assert.messageFromMsgAndArgs -// Copied locally to prevent non-test build dependencies on testify -func messageFromMsgAndArgs(msgAndArgs []interface{}) string { - if len(msgAndArgs) == 0 || msgAndArgs == nil { - return "" - } - if len(msgAndArgs) == 1 { - return msgAndArgs[0].(string) - } - if len(msgAndArgs) > 1 { - return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) - } - return "" -} - -func queryValueKeys(v url.Values) []string { - keys := make([]string, 0, len(v)) - for k := range v { - keys = append(keys, k) - } - sort.Strings(keys) - return keys -} - -// SprintExpectActual returns a string for test failure cases when the actual -// value is not the same as the expected. -func SprintExpectActual(expect, actual interface{}) string { - return fmt.Sprintf("expect: %+v\nactual: %+v\n", expect, actual) -} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/client.go b/vendor/github.com/aws/aws-sdk-go/awstesting/client.go deleted file mode 100644 index 539639d8b..000000000 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/client.go +++ /dev/null @@ -1,24 +0,0 @@ -package awstesting - -import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/aws/client/metadata" - "github.com/aws/aws-sdk-go/aws/defaults" -) - -// NewClient creates and initializes a generic service client for testing. -func NewClient(cfgs ...*aws.Config) *client.Client { - info := metadata.ClientInfo{ - Endpoint: "http://endpoint", - SigningName: "", - } - def := defaults.Get() - def.Config.MergeIn(cfgs...) - - if v := aws.StringValue(def.Config.Endpoint); len(v) > 0 { - info.Endpoint = v - } - - return client.New(*def.Config, info, def.Handlers) -} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go b/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go deleted file mode 100644 index 13edc7bcf..000000000 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/custom_ca_bundle.go +++ /dev/null @@ -1,199 +0,0 @@ -package awstesting - -import ( - "io/ioutil" - "net" - "net/http" - "os" - "strings" - "time" -) - -func availableLocalAddr(ip string) (string, error) { - l, err := net.Listen("tcp", ip+":0") - if err != nil { - return "", err - } - defer l.Close() - - return l.Addr().String(), nil -} - -// CreateTLSServer will create the TLS server on an open port using the -// certificate and key. The address will be returned that the server is running on. -func CreateTLSServer(cert, key string, mux *http.ServeMux) (string, error) { - addr, err := availableLocalAddr("127.0.0.1") - if err != nil { - return "", err - } - - if mux == nil { - mux = http.NewServeMux() - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {}) - } - - go func() { - if err := http.ListenAndServeTLS(addr, cert, key, mux); err != nil { - panic(err) - } - }() - - for i := 0; i < 60; i++ { - if _, err := http.Get("https://" + addr); err != nil && !strings.Contains(err.Error(), "connection refused") { - break - } - - time.Sleep(1 * time.Second) - } - - return "https://" + addr, nil -} - -// CreateTLSBundleFiles returns the temporary filenames for the certificate -// key, and CA PEM content. These files should be deleted when no longer -// needed. CleanupTLSBundleFiles can be used for this cleanup. -func CreateTLSBundleFiles() (cert, key, ca string, err error) { - cert, err = createTmpFile(TLSBundleCert) - if err != nil { - return "", "", "", err - } - - key, err = createTmpFile(TLSBundleKey) - if err != nil { - return "", "", "", err - } - - ca, err = createTmpFile(TLSBundleCA) - if err != nil { - return "", "", "", err - } - - return cert, key, ca, nil -} - -// CleanupTLSBundleFiles takes variadic list of files to be deleted. -func CleanupTLSBundleFiles(files ...string) error { - for _, file := range files { - if err := os.Remove(file); err != nil { - return err - } - } - - return nil -} - -func createTmpFile(b []byte) (string, error) { - bundleFile, err := ioutil.TempFile(os.TempDir(), "aws-sdk-go-session-test") - if err != nil { - return "", err - } - - _, err = bundleFile.Write(b) - if err != nil { - return "", err - } - - defer bundleFile.Close() - return bundleFile.Name(), nil -} - -/* Cert generation steps -# Create the CA key -openssl genrsa -des3 -out ca.key 1024 - -# Create the CA Cert -openssl req -new -sha256 -x509 -days 3650 \ - -subj "/C=GO/ST=Gopher/O=Testing ROOT CA" \ - -key ca.key -out ca.crt - -# Create config -cat > csr_details.txt <<-EOF - -[req] -default_bits = 1024 -prompt = no -default_md = sha256 -req_extensions = SAN -distinguished_name = dn - -[ dn ] -C=GO -ST=Gopher -O=Testing Certificate -OU=Testing IP - -[SAN] -subjectAltName = IP:127.0.0.1 -EOF - -# Create certificate signing request -openssl req -new -sha256 -nodes -newkey rsa:1024 \ - -config <( cat csr_details.txt ) \ - -keyout ia.key -out ia.csr - -# Create a signed certificate -openssl x509 -req -days 3650 \ - -CAcreateserial \ - -extfile <( cat csr_details.txt ) \ - -extensions SAN \ - -CA ca.crt -CAkey ca.key -in ia.csr -out ia.crt - -# Verify -openssl req -noout -text -in ia.csr -openssl x509 -noout -text -in ia.crt -*/ -var ( - // TLSBundleCA ca.crt - TLSBundleCA = []byte(`-----BEGIN CERTIFICATE----- -MIICiTCCAfKgAwIBAgIJAJ5X1olt05XjMA0GCSqGSIb3DQEBCwUAMDgxCzAJBgNV -BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD -QTAeFw0xNzAzMDkwMDAyMDZaFw0yNzAzMDcwMDAyMDZaMDgxCzAJBgNVBAYTAkdP -MQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBDQTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw/8DN+t9XQR60jx42rsQ2WE2Dx85rb3n -GQxnKZZLNddsT8rDyxJNP18aFalbRbFlyln5fxWxZIblu9Xkm/HRhOpbSimSqo1y -uDx21NVZ1YsOvXpHby71jx3gPrrhSc/t/zikhi++6D/C6m1CiIGuiJ0GBiJxtrub -UBMXT0QtI2ECAwEAAaOBmjCBlzAdBgNVHQ4EFgQU8XG3X/YHBA6T04kdEkq6+4GV -YykwaAYDVR0jBGEwX4AU8XG3X/YHBA6T04kdEkq6+4GVYymhPKQ6MDgxCzAJBgNV -BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD -QYIJAJ5X1olt05XjMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAeILv -z49+uxmPcfOZzonuOloRcpdvyjiXblYxbzz6ch8GsE7Q886FTZbvwbgLhzdwSVgG -G8WHkodDUsymVepdqAamS3f8PdCUk8xIk9mop8LgaB9Ns0/TssxDvMr3sOD2Grb3 -xyWymTWMcj6uCiEBKtnUp4rPiefcvCRYZ17/hLE= ------END CERTIFICATE----- -`) - - // TLSBundleCert ai.crt - TLSBundleCert = []byte(`-----BEGIN CERTIFICATE----- -MIICGjCCAYOgAwIBAgIJAIIu+NOoxxM0MA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNV -BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD -QTAeFw0xNzAzMDkwMDAzMTRaFw0yNzAzMDcwMDAzMTRaMFExCzAJBgNVBAYTAkdP -MQ8wDQYDVQQIDAZHb3BoZXIxHDAaBgNVBAoME1Rlc3RpbmcgQ2VydGlmaWNhdGUx -EzARBgNVBAsMClRlc3RpbmcgSVAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB -AN1hWHeioo/nASvbrjwCQzXCiWiEzGkw353NxsAB54/NqDL3LXNATtiSJu8kJBrm -Ah12IFLtWLGXjGjjYlHbQWnOR6awveeXnQZukJyRWh7m/Qlt9Ho0CgZE1U+832ac -5GWVldNxW1Lz4I+W9/ehzqe8I80RS6eLEKfUFXGiW+9RAgMBAAGjEzARMA8GA1Ud -EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEFBQADgYEAdF4WQHfVdPCbgv9sxgJjcR1H -Hgw9rZ47gO1IiIhzglnLXQ6QuemRiHeYFg4kjcYBk1DJguxzDTGnUwhUXOibAB+S -zssmrkdYYvn9aUhjc3XK3tjAoDpsPpeBeTBamuUKDHoH/dNRXxerZ8vu6uPR3Pgs -5v/KCV6IAEcvNyOXMPo= ------END CERTIFICATE----- -`) - - // TLSBundleKey ai.key - TLSBundleKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQDdYVh3oqKP5wEr2648AkM1wolohMxpMN+dzcbAAeePzagy9y1z -QE7YkibvJCQa5gIddiBS7Vixl4xo42JR20FpzkemsL3nl50GbpCckVoe5v0JbfR6 -NAoGRNVPvN9mnORllZXTcVtS8+CPlvf3oc6nvCPNEUunixCn1BVxolvvUQIDAQAB -AoGBAMISrcirddGrlLZLLrKC1ULS2T0cdkqdQtwHYn4+7S5+/z42vMx1iumHLsSk -rVY7X41OWkX4trFxhvEIrc/O48bo2zw78P7flTxHy14uxXnllU8cLThE29SlUU7j -AVBNxJZMsXMlS/DowwD4CjFe+x4Pu9wZcReF2Z9ntzMpySABAkEA+iWoJCPE2JpS -y78q3HYYgpNY3gF3JqQ0SI/zTNkb3YyEIUffEYq0Y9pK13HjKtdsSuX4osTIhQkS -+UgRp6tCAQJBAOKPYTfQ2FX8ijgUpHZRuEAVaxASAS0UATiLgzXxLvOh/VC2at5x -wjOX6sD65pPz/0D8Qj52Cq6Q1TQ+377SDVECQAIy0od+yPweXxvrUjUd1JlRMjbB -TIrKZqs8mKbUQapw0bh5KTy+O1elU4MRPS3jNtBxtP25PQnuSnxmZcFTgAECQFzg -DiiFcsn9FuRagfkHExMiNJuH5feGxeFaP9WzI144v9GAllrOI6Bm3JNzx2ZLlg4b -20Qju8lIEj6yr6JYFaECQHM1VSojGRKpOl9Ox/R4yYSA9RV5Gyn00/aJNxVYyPD5 -i3acL2joQm2kLD/LO8paJ4+iQdRXCOMMIpjxSNjGQjQ= ------END RSA PRIVATE KEY----- -`) -) diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go b/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go deleted file mode 100644 index e16021ed3..000000000 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/mock/mock.go +++ /dev/null @@ -1,74 +0,0 @@ -package mock - -import ( - "crypto/rsa" - "math/big" - "net/http" - "net/http/httptest" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/aws/client/metadata" - "github.com/aws/aws-sdk-go/aws/session" -) - -// Session is a mock session which is used to hit the mock server -var Session = func() *session.Session { - // server is the mock server that simply writes a 200 status back to the client - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - })) - - return session.Must(session.NewSession(&aws.Config{ - DisableSSL: aws.Bool(true), - Endpoint: aws.String(server.URL), - })) -}() - -// NewMockClient creates and initializes a client that will connect to the -// mock server -func NewMockClient(cfgs ...*aws.Config) *client.Client { - c := Session.ClientConfig("Mock", cfgs...) - - svc := client.New( - *c.Config, - metadata.ClientInfo{ - ServiceName: "Mock", - SigningRegion: c.SigningRegion, - Endpoint: c.Endpoint, - APIVersion: "2015-12-08", - JSONVersion: "1.1", - TargetPrefix: "MockServer", - }, - c.Handlers, - ) - - return svc -} - -// RSAPrivateKey is used for testing functionality that requires some -// sort of private key. Taken from crypto/rsa/rsa_test.go -// -// Credit to golang 1.11 -var RSAPrivateKey = &rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ - N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"), - E: 3, - }, - D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"), - Primes: []*big.Int{ - fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"), - fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"), - }, -} - -// Taken from crypto/rsa/rsa_test.go -// -// Credit to golang 1.11 -func fromBase10(base10 string) *big.Int { - i, ok := new(big.Int).SetString(base10, 10) - if !ok { - panic("bad number: " + base10) - } - return i -} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/util.go b/vendor/github.com/aws/aws-sdk-go/awstesting/util.go deleted file mode 100644 index 3c146a23d..000000000 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/util.go +++ /dev/null @@ -1,121 +0,0 @@ -package awstesting - -import ( - "io" - "os" - "strings" - "time" - - "github.com/aws/aws-sdk-go/private/util" -) - -// ZeroReader is a io.Reader which will always write zeros to the byte slice provided. -type ZeroReader struct{} - -// Read fills the provided byte slice with zeros returning the number of bytes written. -func (r *ZeroReader) Read(b []byte) (int, error) { - for i := 0; i < len(b); i++ { - b[i] = 0 - } - return len(b), nil -} - -// ReadCloser is a io.ReadCloser for unit testing. -// Designed to test for leaks and whether a handle has -// been closed -type ReadCloser struct { - Size int - Closed bool - set bool - FillData func(bool, []byte, int, int) -} - -// Read will call FillData and fill it with whatever data needed. -// Decrements the size until zero, then return io.EOF. -func (r *ReadCloser) Read(b []byte) (int, error) { - if r.Closed { - return 0, io.EOF - } - - delta := len(b) - if delta > r.Size { - delta = r.Size - } - r.Size -= delta - - for i := 0; i < delta; i++ { - b[i] = 'a' - } - - if r.FillData != nil { - r.FillData(r.set, b, r.Size, delta) - } - r.set = true - - if r.Size > 0 { - return delta, nil - } - return delta, io.EOF -} - -// Close sets Closed to true and returns no error -func (r *ReadCloser) Close() error { - r.Closed = true - return nil -} - -// SortedKeys returns a sorted slice of keys of a map. -func SortedKeys(m map[string]interface{}) []string { - return util.SortedKeys(m) -} - -// A FakeContext provides a simple stub implementation of a Context -type FakeContext struct { - Error error - DoneCh chan struct{} -} - -// Deadline always will return not set -func (c *FakeContext) Deadline() (deadline time.Time, ok bool) { - return time.Time{}, false -} - -// Done returns a read channel for listening to the Done event -func (c *FakeContext) Done() <-chan struct{} { - return c.DoneCh -} - -// Err returns the error, is nil if not set. -func (c *FakeContext) Err() error { - return c.Error -} - -// Value ignores the Value and always returns nil -func (c *FakeContext) Value(key interface{}) interface{} { - return nil -} - -// StashEnv stashes the current environment variables and returns an array of -// all environment values as key=val strings. -func StashEnv() []string { - env := os.Environ() - os.Clearenv() - - return env -} - -// PopEnv takes the list of the environment values and injects them into the -// process's environment variable data. Clears any existing environment values -// that may already exist. -func PopEnv(env []string) { - os.Clearenv() - - for _, e := range env { - p := strings.SplitN(e, "=", 2) - k, v := p[0], "" - if len(p) > 1 { - v = p[1] - } - os.Setenv(k, v) - } -} diff --git a/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go b/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go deleted file mode 100644 index 48000565c..000000000 --- a/vendor/github.com/aws/aws-sdk-go/private/util/sort_keys.go +++ /dev/null @@ -1,14 +0,0 @@ -package util - -import "sort" - -// SortedKeys returns a sorted slice of keys of a map. -func SortedKeys(m map[string]interface{}) []string { - i, sorted := 0, make([]string, len(m)) - for k := range m { - sorted[i] = k - i++ - } - sort.Strings(sorted) - return sorted -} diff --git a/vendor/github.com/aws/aws-sdk-go/private/util/util.go b/vendor/github.com/aws/aws-sdk-go/private/util/util.go deleted file mode 100644 index 5f2dab25e..000000000 --- a/vendor/github.com/aws/aws-sdk-go/private/util/util.go +++ /dev/null @@ -1,109 +0,0 @@ -package util - -import ( - "bytes" - "encoding/xml" - "fmt" - "go/format" - "io" - "reflect" - "regexp" - "strings" - - "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" -) - -// GoFmt returns the Go formated string of the input. -// -// Panics if the format fails. -func GoFmt(buf string) string { - formatted, err := format.Source([]byte(buf)) - if err != nil { - panic(fmt.Errorf("%s\nOriginal code:\n%s", err.Error(), buf)) - } - return string(formatted) -} - -var reTrim = regexp.MustCompile(`\s{2,}`) - -// Trim removes all leading and trailing white space. -// -// All consecutive spaces will be reduced to a single space. -func Trim(s string) string { - return strings.TrimSpace(reTrim.ReplaceAllString(s, " ")) -} - -// Capitalize capitalizes the first character of the string. -func Capitalize(s string) string { - if len(s) == 1 { - return strings.ToUpper(s) - } - return strings.ToUpper(s[0:1]) + s[1:] -} - -// SortXML sorts the reader's XML elements -func SortXML(r io.Reader) string { - var buf bytes.Buffer - d := xml.NewDecoder(r) - root, _ := xmlutil.XMLToStruct(d, nil) - e := xml.NewEncoder(&buf) - xmlutil.StructToXML(e, root, true) - return buf.String() -} - -// PrettyPrint generates a human readable representation of the value v. -// All values of v are recursively found and pretty printed also. -func PrettyPrint(v interface{}) string { - value := reflect.ValueOf(v) - switch value.Kind() { - case reflect.Struct: - str := fullName(value.Type()) + "{\n" - for i := 0; i < value.NumField(); i++ { - l := string(value.Type().Field(i).Name[0]) - if strings.ToUpper(l) == l { - str += value.Type().Field(i).Name + ": " - str += PrettyPrint(value.Field(i).Interface()) - str += ",\n" - } - } - str += "}" - return str - case reflect.Map: - str := "map[" + fullName(value.Type().Key()) + "]" + fullName(value.Type().Elem()) + "{\n" - for _, k := range value.MapKeys() { - str += "\"" + k.String() + "\": " - str += PrettyPrint(value.MapIndex(k).Interface()) - str += ",\n" - } - str += "}" - return str - case reflect.Ptr: - if e := value.Elem(); e.IsValid() { - return "&" + PrettyPrint(e.Interface()) - } - return "nil" - case reflect.Slice: - str := "[]" + fullName(value.Type().Elem()) + "{\n" - for i := 0; i < value.Len(); i++ { - str += PrettyPrint(value.Index(i).Interface()) - str += ",\n" - } - str += "}" - return str - default: - return fmt.Sprintf("%#v", v) - } -} - -func pkgName(t reflect.Type) string { - pkg := t.PkgPath() - c := strings.Split(pkg, "/") - return c[len(c)-1] -} - -func fullName(t reflect.Type) string { - if pkg := pkgName(t); pkg != "" { - return pkg + "." + t.Name() - } - return t.Name() -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 710ca896a..9a2135b5f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -433,22 +433,6 @@ "version": "v1.15.54", "versionExact": "v1.15.54" }, - { - "checksumSHA1": "MxSiiCoPpY1mCRjyEFClUu3e14w=", - "path": "github.com/aws/aws-sdk-go/awstesting", - "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", - "revisionTime": "2018-10-12T21:50:02Z", - "version": "v1.15.54", - "versionExact": "v1.15.54" - }, - { - "checksumSHA1": "Til1RNskoxuni9LNTwJWzm1GKrU=", - "path": "github.com/aws/aws-sdk-go/awstesting/mock", - "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", - "revisionTime": "2018-10-12T21:50:02Z", - "version": "v1.15.54", - "versionExact": "v1.15.54" - }, { "checksumSHA1": "QvKGojx+wCHTDfXQ1aoOYzH3Y88=", "path": "github.com/aws/aws-sdk-go/internal/s3err", @@ -586,14 +570,6 @@ "version": "v1.15.54", "versionExact": "v1.15.54" }, - { - "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", - "path": "github.com/aws/aws-sdk-go/private/util", - "revision": "bf8067ceb6e7f51e150c218972dccfeeed892b85", - "revisionTime": "2018-10-12T21:50:02Z", - "version": "v1.15.54", - "versionExact": "v1.15.54" - }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "comment": "v1.7.1", From ed793a8fb8d51703f3d5a09301bd8565f67ba9de Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 24 Oct 2018 11:26:53 +0200 Subject: [PATCH 3/3] make ValidateRegion a member of *AccessConfig and make it variadic --- builder/amazon/common/access_config.go | 21 ++++++++---- builder/amazon/common/access_config_test.go | 15 +++++---- builder/amazon/common/ami_config.go | 31 ++++++------------ builder/amazon/common/ami_config_test.go | 36 ++++++++++----------- builder/amazon/common/regions.go | 29 +++++++++++++---- 5 files changed, 75 insertions(+), 57 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 5c05f4280..66b595300 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -12,6 +12,7 @@ import ( "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/packer/template/interpolate" ) @@ -29,6 +30,8 @@ type AccessConfig struct { SkipMetadataApiCheck bool `mapstructure:"skip_metadata_api_check"` Token string `mapstructure:"token"` session *session.Session + + getEC2Connection func() ec2iface.EC2API } // Config returns a valid aws.Config object for access to AWS services, or @@ -148,12 +151,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { } if c.RawRegion != "" && !c.SkipValidation { - sess, err := c.Session() - if err != nil { - errs = append(errs, err) - } - ec2conn := ec2.New(sess) - err = ValidateRegion(c.RawRegion, ec2conn) + err := c.ValidateRegion(c.RawRegion) if err != nil { errs = append(errs, fmt.Errorf("error validating region: %s", err.Error())) } @@ -161,3 +159,14 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { return errs } + +func (c *AccessConfig) NewEC2Connection() (ec2iface.EC2API, error) { + if c.getEC2Connection != nil { + return c.getEC2Connection(), nil + } + sess, err := c.Session() + if err != nil { + return nil, err + } + return ec2.New(sess), nil +} diff --git a/builder/amazon/common/access_config_test.go b/builder/amazon/common/access_config_test.go index c94d78bff..489bf08df 100644 --- a/builder/amazon/common/access_config_test.go +++ b/builder/amazon/common/access_config_test.go @@ -5,31 +5,34 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ec2/ec2iface" ) func testAccessConfig() *AccessConfig { - return &AccessConfig{} + return &AccessConfig{ + getEC2Connection: func() ec2iface.EC2API { + return &mockEC2Client{} + }, + } } func TestAccessConfigPrepare_Region(t *testing.T) { c := testAccessConfig() - mockConn := &mockEC2Client{} - c.RawRegion = "us-east-12" - err := ValidateRegion(c.RawRegion, mockConn) + err := c.ValidateRegion(c.RawRegion) if err == nil { t.Fatalf("should have region validation err: %s", c.RawRegion) } c.RawRegion = "us-east-1" - err = ValidateRegion(c.RawRegion, mockConn) + err = c.ValidateRegion(c.RawRegion) if err != nil { t.Fatalf("shouldn't have region validation err: %s", c.RawRegion) } c.RawRegion = "custom" - err = ValidateRegion(c.RawRegion, mockConn) + err = c.ValidateRegion(c.RawRegion) if err == nil { t.Fatalf("should have region validation err: %s", c.RawRegion) } diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index ceb7dbe57..5fbac557a 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -4,8 +4,6 @@ import ( "fmt" "log" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/hashicorp/packer/template/interpolate" ) @@ -58,16 +56,7 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context } } - var ec2conn *ec2.EC2 - if !c.AMISkipRegionValidation { - sess, err := accessConfig.Session() - if err != nil { - errs = append(errs, err) - } - ec2conn = ec2.New(sess) - } - - errs = c.prepareRegions(ec2conn, accessConfig, errs) + errs = append(errs, c.prepareRegions(accessConfig)...) if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume { errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume")) @@ -105,8 +94,16 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context return nil } -func (c *AMIConfig) prepareRegions(ec2conn ec2iface.EC2API, accessConfig *AccessConfig, errs []error) []error { +func (c *AMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { if len(c.AMIRegions) > 0 { + if !c.AMISkipRegionValidation { + // Verify the regions are real + err := accessConfig.ValidateRegion(c.AMIRegions...) + if err != nil { + errs = append(errs, fmt.Errorf("error validating regions: %v", err)) + } + } + regionSet := make(map[string]struct{}) regions := make([]string, 0, len(c.AMIRegions)) @@ -119,14 +116,6 @@ func (c *AMIConfig) prepareRegions(ec2conn ec2iface.EC2API, accessConfig *Access // Mark that we saw the region regionSet[region] = struct{}{} - if !c.AMISkipRegionValidation { - // Verify the region is real - err := ValidateRegion(region, ec2conn) - if err != nil { - errs = append(errs, fmt.Errorf("error validating region: %s", err.Error())) - } - } - // Make sure that if we have region_kms_key_ids defined, // the regions in ami_regions are also in region_kms_key_ids if len(c.AMIRegionKMSKeyIDs) > 0 { diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index 4aee3204c..7623d6adb 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -17,14 +17,14 @@ func testAMIConfig() *AMIConfig { } func getFakeAccessConfig(region string) *AccessConfig { - return &AccessConfig{ - RawRegion: region, - } + c := testAccessConfig() + c.RawRegion = region + return c } func TestAMIConfigPrepare_name(t *testing.T) { c := testAMIConfig() - accessConf := getFakeAccessConfig("wherever") + accessConf := testAccessConfig() c.AMISkipRegionValidation = true if err := c.Prepare(accessConf, nil); err != nil { t.Fatalf("shouldn't have err: %s", err) @@ -57,8 +57,9 @@ func TestAMIConfigPrepare_regions(t *testing.T) { var errs []error var err error + accessConf := testAccessConfig() mockConn := &mockEC2Client{} - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatalf("shouldn't have err: %#v", errs) } @@ -67,18 +68,18 @@ func TestAMIConfigPrepare_regions(t *testing.T) { if err != nil { t.Fatalf("shouldn't have err: %s", err.Error()) } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatalf("shouldn't have err: %#v", errs) } c.AMIRegions = []string{"foo"} - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) == 0 { + if errs = c.prepareRegions(accessConf); len(errs) == 0 { t.Fatal("should have error") } errs = errs[:0] c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-1"} - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatalf("bad: %s", errs[0]) } @@ -89,7 +90,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { c.AMIRegions = []string{"custom"} c.AMISkipRegionValidation = true - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("shouldn't have error") } c.AMISkipRegionValidation = false @@ -100,7 +101,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "456-789-0123", } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal(fmt.Sprintf("shouldn't have error: %s", errs[0])) } @@ -110,7 +111,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "", } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have passed; we are able to use default KMS key if not sharing") } @@ -121,7 +122,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "", } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have an error b/c can't use default KMS key if sharing") } @@ -131,7 +132,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "456-789-0123", } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have error b/c theres a region in the key map that isn't in ami_regions") } @@ -142,7 +143,6 @@ func TestAMIConfigPrepare_regions(t *testing.T) { } c.AMISkipRegionValidation = true - accessConf := getFakeAccessConfig("wherever") if err := c.Prepare(accessConf, nil); err == nil { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } @@ -156,7 +156,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-east-1": "123-456-7890", "us-west-1": "", } - if errs = c.prepareRegions(mockConn, nil, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } @@ -164,7 +164,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { accessConf = getFakeAccessConfig("us-east-1") c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} c.AMIRegionKMSKeyIDs = nil - if errs = c.prepareRegions(mockConn, accessConf, errs); len(errs) > 0 { + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should allow user to have the raw region in ami_regions") } @@ -176,7 +176,7 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { c.AMIUsers = []string{"testAccountID"} c.AMIEncryptBootVolume = true - accessConf := getFakeAccessConfig("wherever") + accessConf := testAccessConfig() c.AMIKmsKeyId = "" if err := c.Prepare(accessConf, nil); err == nil { @@ -193,7 +193,7 @@ func TestAMINameValidation(t *testing.T) { c := testAMIConfig() c.AMISkipRegionValidation = true - accessConf := getFakeAccessConfig("wherever") + accessConf := testAccessConfig() c.AMIName = "aa" if err := c.Prepare(accessConf, nil); err == nil { diff --git a/builder/amazon/common/regions.go b/builder/amazon/common/regions.go index 6eee8c54a..3bdda86da 100644 --- a/builder/amazon/common/regions.go +++ b/builder/amazon/common/regions.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/aws/aws-sdk-go/service/ec2/ec2iface" ) @@ -20,17 +21,33 @@ func listEC2Regions(ec2conn ec2iface.EC2API) ([]string, error) { // ValidateRegion returns true if the supplied region is a valid AWS // region and false if it's not. -func ValidateRegion(region string, ec2conn ec2iface.EC2API) error { - regions, err := listEC2Regions(ec2conn) +func (c *AccessConfig) ValidateRegion(regions ...string) error { + ec2conn, err := c.NewEC2Connection() if err != nil { return err } - for _, valid := range regions { - if region == valid { - return nil + validRegions, err := listEC2Regions(ec2conn) + if err != nil { + return err + } + + var invalidRegions []string + for _, region := range regions { + found := false + for _, validRegion := range validRegions { + if region == validRegion { + found = true + break + } + } + if !found { + invalidRegions = append(invalidRegions, region) } } - return fmt.Errorf("Invalid region: %s", region) + if len(invalidRegions) > 0 { + return fmt.Errorf("Invalid region(s): %v", invalidRegions) + } + return nil }