fix template-set credentials

update tests with mocked session
This commit is contained in:
Megan Marsh 2018-10-19 15:01:46 -07:00
parent 9573013d3a
commit 0924a316b7
12 changed files with 809 additions and 26 deletions

View File

@ -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()))
}

View File

@ -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 {

View File

@ -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.")
}

View File

@ -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)

212
vendor/github.com/aws/aws-sdk-go/awstesting/assert.go generated vendored Normal file
View File

@ -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)
}

24
vendor/github.com/aws/aws-sdk-go/awstesting/client.go generated vendored Normal file
View File

@ -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)
}

View File

@ -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-----
`)
)

View File

@ -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
}

121
vendor/github.com/aws/aws-sdk-go/awstesting/util.go generated vendored Normal file
View File

@ -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)
}
}

View File

@ -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
}

109
vendor/github.com/aws/aws-sdk-go/private/util/util.go generated vendored Normal file
View File

@ -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()
}

24
vendor/vendor.json vendored
View File

@ -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",