Skip to content

Commit ec04254

Browse files
authored
perform exhaustive region discovery (#9)
* perform exhaustive region discovery * add error msg for region detection
1 parent 8fea12d commit ec04254

File tree

4 files changed

+130
-18
lines changed

4 files changed

+130
-18
lines changed

THIRD_PARTY_LICENSES

+37-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Copyright 2014-2015 Stripe, Inc.
66
Copyright © 2015 Steve Francia <[email protected]>
77
** go-yaml/yaml; version v2.2.2 -- https://github.com/go-yaml/yaml
88
Copyright 2011-2016 Canonical Ltd.
9+
** go-ini/ini; version v1.57.0 -- https://github.com/go-ini/ini
10+
911

1012
Licensed under the Apache License, Version 2.0 (the "License");
1113
you may not use this file except in compliance with the License.
@@ -228,6 +230,8 @@ limitations under the License.
228230
Copyright © 2015 Steve Francia <[email protected]>
229231
* For go-yaml/yaml see also this required NOTICE:
230232
Copyright 2011-2016 Canonical Ltd.
233+
* For go-ini/ini see also this required NOTICE:
234+
Copyright 2016
231235

232236
Licensed under the Apache License, Version 2.0 (the "License");
233237
you may not use this file except in compliance with the License.
@@ -747,4 +751,36 @@ Exhibit B - “Incompatible With Secondary Licenses” Notice
747751

748752
This Source Code Form is “Incompatible
749753
With Secondary Licenses”, as defined by
750-
the Mozilla Public License, v. 2.0.
754+
the Mozilla Public License, v. 2.0.
755+
756+
------
757+
758+
** github.com/mitchellh/go-homedir; version v1.1.0 --
759+
https://github.com/mitchellh/go-homedir
760+
Copyright (c) 2013 Mitchell Hashimoto
761+
** github.com/mitchellh/mapstructure; version v1.1.2 --
762+
https://github.com/mitchellh/mapstructure
763+
Copyright (c) 2013 Mitchell Hashimoto
764+
765+
The MIT License (MIT)
766+
767+
Copyright (c) 2013 Mitchell Hashimoto
768+
769+
Permission is hereby granted, free of charge, to any person obtaining a copy
770+
of this software and associated documentation files (the "Software"), to deal
771+
in the Software without restriction, including without limitation the rights
772+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
773+
copies of the Software, and to permit persons to whom the Software is
774+
furnished to do so, subject to the following conditions:
775+
776+
The above copyright notice and this permission notice shall be included in
777+
all copies or substantial portions of the Software.
778+
779+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
780+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
781+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
782+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
783+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
784+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
785+
THE SOFTWARE.
786+

cmd/main.go

+78-10
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ import (
2424
"github.com/aws/amazon-ec2-instance-selector/pkg/selector"
2525
"github.com/aws/amazon-ec2-instance-selector/pkg/selector/outputs"
2626
"github.com/aws/aws-sdk-go/aws/session"
27+
homedir "github.com/mitchellh/go-homedir"
2728
"github.com/spf13/cobra"
29+
"gopkg.in/ini.v1"
2830
)
2931

3032
const (
31-
binName = "ec2-instance-selector"
33+
binName = "ec2-instance-selector"
34+
awsRegionEnvVar = "AWS_REGION"
35+
defaultRegionEnvVar = "AWS_DEFAULT_REGION"
36+
defaultProfile = "default"
37+
awsConfigFile = "~/.aws/config"
38+
3239
// cfnJSON is an output type
3340
cfnJSON = "cfn-json"
3441
// cfnYAML is an output type
@@ -157,14 +164,12 @@ Full docs can be found at github.com/aws/amazon-` + binName
157164
os.Exit(0)
158165
}
159166

160-
sessOpts := session.Options{}
161-
162-
if flags[region] != nil {
163-
sessOpts.Config.Region = cli.StringMe(flags[region])
164-
}
165-
if flags[profile] != nil {
166-
sessOpts.Profile = *cli.StringMe(flags[profile])
167+
sess, err := getRegionAndProfileAWSSession(cli.StringMe(flags[region]), cli.StringMe(flags[profile]))
168+
if err != nil {
169+
fmt.Println(err)
170+
os.Exit(1)
167171
}
172+
flags[region] = sess.Config.Region
168173

169174
if flags[availabilityZone] != nil {
170175
log.Printf("You are using a deprecated flag --%s which will be removed in future versions, switch to --%s to avoid issues.\n", availabilityZone, availabilityZones)
@@ -175,8 +180,6 @@ Full docs can be found at github.com/aws/amazon-` + binName
175180
}
176181
}
177182

178-
sess := session.Must(session.NewSessionWithOptions(sessOpts))
179-
180183
instanceSelector := selector.New(sess)
181184

182185
filters := selector.Filters{
@@ -265,3 +268,68 @@ func getOutputFn(outputFlag *string, currentFn selector.InstanceTypesOutputFn) s
265268
}
266269
return outputFn
267270
}
271+
272+
func getRegionAndProfileAWSSession(regionName *string, profileName *string) (*session.Session, error) {
273+
sessOpts := session.Options{}
274+
if regionName != nil {
275+
sessOpts.Config.Region = regionName
276+
}
277+
278+
if profileName != nil {
279+
sessOpts.Profile = *profileName
280+
if sessOpts.Config.Region == nil {
281+
if profileRegion, err := getProfileRegion(*profileName); err != nil {
282+
log.Println(err)
283+
} else {
284+
sessOpts.Config.Region = &profileRegion
285+
}
286+
}
287+
}
288+
289+
sess := session.Must(session.NewSessionWithOptions(sessOpts))
290+
if sess.Config.Region != nil && *sess.Config.Region != "" {
291+
return sess, nil
292+
}
293+
if defaultProfileRegion, err := getProfileRegion(defaultProfile); err == nil {
294+
sess.Config.Region = &defaultProfileRegion
295+
return sess, nil
296+
}
297+
298+
if defaultRegion, ok := os.LookupEnv(defaultRegionEnvVar); ok && defaultRegion != "" {
299+
sess.Config.Region = &defaultRegion
300+
return sess, nil
301+
}
302+
303+
errorMsg := "Unable to find a region in the usual places: \n"
304+
errorMsg = errorMsg + "\t - --region flag\n"
305+
errorMsg = errorMsg + fmt.Sprintf("\t - %s environment variable\n", awsRegionEnvVar)
306+
if profileName != nil {
307+
errorMsg = errorMsg + fmt.Sprintf("\t - profile region in %s\n", awsConfigFile)
308+
}
309+
errorMsg = errorMsg + fmt.Sprintf("\t - default profile region in %s\n", awsConfigFile)
310+
errorMsg = errorMsg + fmt.Sprintf("\t - %s environment variable\n", defaultRegionEnvVar)
311+
return sess, fmt.Errorf(errorMsg)
312+
}
313+
314+
func getProfileRegion(profileName string) (string, error) {
315+
if profileName != defaultProfile {
316+
profileName = fmt.Sprintf("profile %s", profileName)
317+
}
318+
awsConfigPath, err := homedir.Expand(awsConfigFile)
319+
if err != nil {
320+
return "", fmt.Errorf("Warning: unable to find home directory to parse aws config file")
321+
}
322+
awsConfigIni, err := ini.Load(awsConfigPath)
323+
if err != nil {
324+
return "", fmt.Errorf("Warning: unable to load aws config file for profile at path: %s", awsConfigPath)
325+
}
326+
section, err := awsConfigIni.GetSection(profileName)
327+
if err != nil {
328+
return "", fmt.Errorf("Warning: there is no configuration for the specified aws profile %s at %s", profileName, awsConfigPath)
329+
}
330+
regionConfig, err := section.GetKey("region")
331+
if err != nil || regionConfig.String() == "" {
332+
return "", fmt.Errorf("Warning: there is no region configured for the specified aws profile %s at %s", profileName, awsConfigPath)
333+
}
334+
return regionConfig.String(), nil
335+
}

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ require (
66
github.com/aws/aws-sdk-go v1.31.12
77
github.com/ghodss/yaml v1.0.0
88
github.com/hashicorp/hcl v1.0.0
9+
github.com/mitchellh/go-homedir v1.1.0
10+
github.com/smartystreets/goconvey v1.6.4 // indirect
911
github.com/spf13/cobra v0.0.7
1012
github.com/spf13/pflag v1.0.3
13+
gopkg.in/ini.v1 v1.57.0
1114
)

go.sum

+12-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
44
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
55
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
66
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
7-
github.com/aws/aws-sdk-go v1.29.33 h1:WP85+WHalTFQR2wYp5xR2sjiVAZXew2bBQXGU1QJBXI=
8-
github.com/aws/aws-sdk-go v1.29.33/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
9-
github.com/aws/aws-sdk-go v1.30.26 h1:wP0N6DBb/3EyHTtWNz4jzgGVi1l290zoFGfu4HFGeM0=
107
github.com/aws/aws-sdk-go v1.31.12 h1:SxRRGyhlCagI0DYkhOg+FgdXGXzRTE3vEX/gsgFaiKQ=
118
github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
129
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -44,6 +41,8 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
4441
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
4542
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
4643
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
44+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
45+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
4746
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
4847
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
4948
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@@ -52,11 +51,11 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
5251
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
5352
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
5453
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
55-
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
56-
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
5754
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
5855
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
5956
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
57+
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
58+
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
6059
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
6160
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
6261
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -94,6 +93,10 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
9493
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
9594
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
9695
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
96+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
97+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
98+
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
99+
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
97100
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
98101
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
99102
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
@@ -108,8 +111,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
108111
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
109112
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
110113
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
111-
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
112-
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
114+
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
113115
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
114116
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
115117
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
@@ -147,6 +149,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
147149
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
148150
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
149151
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
152+
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
150153
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
151154
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
152155
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -156,6 +159,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
156159
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
157160
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
158161
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
162+
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
163+
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
159164
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
160165
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
161166
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 commit comments

Comments
 (0)