]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / session / shared_config.go
1 package session
2
3 import (
4 "fmt"
5
6 "github.com/aws/aws-sdk-go/aws/awserr"
7 "github.com/aws/aws-sdk-go/aws/credentials"
8
9 "github.com/aws/aws-sdk-go/internal/ini"
10 )
11
12 const (
13 // Static Credentials group
14 accessKeyIDKey = `aws_access_key_id` // group required
15 secretAccessKey = `aws_secret_access_key` // group required
16 sessionTokenKey = `aws_session_token` // optional
17
18 // Assume Role Credentials group
19 roleArnKey = `role_arn` // group required
20 sourceProfileKey = `source_profile` // group required (or credential_source)
21 credentialSourceKey = `credential_source` // group required (or source_profile)
22 externalIDKey = `external_id` // optional
23 mfaSerialKey = `mfa_serial` // optional
24 roleSessionNameKey = `role_session_name` // optional
25
26 // Additional Config fields
27 regionKey = `region`
28
29 // endpoint discovery group
30 enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
31 // External Credential Process
32 credentialProcessKey = `credential_process`
33
34 // DefaultSharedConfigProfile is the default profile to be used when
35 // loading configuration from the config files if another profile name
36 // is not provided.
37 DefaultSharedConfigProfile = `default`
38 )
39
40 type assumeRoleConfig struct {
41 RoleARN string
42 SourceProfile string
43 CredentialSource string
44 ExternalID string
45 MFASerial string
46 RoleSessionName string
47 }
48
49 // sharedConfig represents the configuration fields of the SDK config files.
50 type sharedConfig struct {
51 // Credentials values from the config file. Both aws_access_key_id
52 // and aws_secret_access_key must be provided together in the same file
53 // to be considered valid. The values will be ignored if not a complete group.
54 // aws_session_token is an optional field that can be provided if both of the
55 // other two fields are also provided.
56 //
57 // aws_access_key_id
58 // aws_secret_access_key
59 // aws_session_token
60 Creds credentials.Value
61
62 AssumeRole assumeRoleConfig
63 AssumeRoleSource *sharedConfig
64
65 // An external process to request credentials
66 CredentialProcess string
67
68 // Region is the region the SDK should use for looking up AWS service endpoints
69 // and signing requests.
70 //
71 // region
72 Region string
73
74 // EnableEndpointDiscovery can be enabled in the shared config by setting
75 // endpoint_discovery_enabled to true
76 //
77 // endpoint_discovery_enabled = true
78 EnableEndpointDiscovery *bool
79 }
80
81 type sharedConfigFile struct {
82 Filename string
83 IniData ini.Sections
84 }
85
86 // loadSharedConfig retrieves the configuration from the list of files
87 // using the profile provided. The order the files are listed will determine
88 // precedence. Values in subsequent files will overwrite values defined in
89 // earlier files.
90 //
91 // For example, given two files A and B. Both define credentials. If the order
92 // of the files are A then B, B's credential values will be used instead of A's.
93 //
94 // See sharedConfig.setFromFile for information how the config files
95 // will be loaded.
96 func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
97 if len(profile) == 0 {
98 profile = DefaultSharedConfigProfile
99 }
100
101 files, err := loadSharedConfigIniFiles(filenames)
102 if err != nil {
103 return sharedConfig{}, err
104 }
105
106 cfg := sharedConfig{}
107 if err = cfg.setFromIniFiles(profile, files); err != nil {
108 return sharedConfig{}, err
109 }
110
111 if len(cfg.AssumeRole.SourceProfile) > 0 {
112 if err := cfg.setAssumeRoleSource(profile, files); err != nil {
113 return sharedConfig{}, err
114 }
115 }
116
117 return cfg, nil
118 }
119
120 func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
121 files := make([]sharedConfigFile, 0, len(filenames))
122
123 for _, filename := range filenames {
124 sections, err := ini.OpenFile(filename)
125 if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile {
126 // Skip files which can't be opened and read for whatever reason
127 continue
128 } else if err != nil {
129 return nil, SharedConfigLoadError{Filename: filename, Err: err}
130 }
131
132 files = append(files, sharedConfigFile{
133 Filename: filename, IniData: sections,
134 })
135 }
136
137 return files, nil
138 }
139
140 func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
141 var assumeRoleSrc sharedConfig
142
143 if len(cfg.AssumeRole.CredentialSource) > 0 {
144 // setAssumeRoleSource is only called when source_profile is found.
145 // If both source_profile and credential_source are set, then
146 // ErrSharedConfigSourceCollision will be returned
147 return ErrSharedConfigSourceCollision
148 }
149
150 // Multiple level assume role chains are not support
151 if cfg.AssumeRole.SourceProfile == origProfile {
152 assumeRoleSrc = *cfg
153 assumeRoleSrc.AssumeRole = assumeRoleConfig{}
154 } else {
155 err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files)
156 if err != nil {
157 return err
158 }
159 }
160
161 if len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
162 return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
163 }
164
165 cfg.AssumeRoleSource = &assumeRoleSrc
166
167 return nil
168 }
169
170 func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
171 // Trim files from the list that don't exist.
172 for _, f := range files {
173 if err := cfg.setFromIniFile(profile, f); err != nil {
174 if _, ok := err.(SharedConfigProfileNotExistsError); ok {
175 // Ignore proviles missings
176 continue
177 }
178 return err
179 }
180 }
181
182 return nil
183 }
184
185 // setFromFile loads the configuration from the file using
186 // the profile provided. A sharedConfig pointer type value is used so that
187 // multiple config file loadings can be chained.
188 //
189 // Only loads complete logically grouped values, and will not set fields in cfg
190 // for incomplete grouped values in the config. Such as credentials. For example
191 // if a config file only includes aws_access_key_id but no aws_secret_access_key
192 // the aws_access_key_id will be ignored.
193 func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
194 section, ok := file.IniData.GetSection(profile)
195 if !ok {
196 // Fallback to to alternate profile name: profile <name>
197 section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
198 if !ok {
199 return SharedConfigProfileNotExistsError{Profile: profile, Err: nil}
200 }
201 }
202
203 // Shared Credentials
204 akid := section.String(accessKeyIDKey)
205 secret := section.String(secretAccessKey)
206 if len(akid) > 0 && len(secret) > 0 {
207 cfg.Creds = credentials.Value{
208 AccessKeyID: akid,
209 SecretAccessKey: secret,
210 SessionToken: section.String(sessionTokenKey),
211 ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
212 }
213 }
214
215 // Assume Role
216 roleArn := section.String(roleArnKey)
217 srcProfile := section.String(sourceProfileKey)
218 credentialSource := section.String(credentialSourceKey)
219 hasSource := len(srcProfile) > 0 || len(credentialSource) > 0
220 if len(roleArn) > 0 && hasSource {
221 cfg.AssumeRole = assumeRoleConfig{
222 RoleARN: roleArn,
223 SourceProfile: srcProfile,
224 CredentialSource: credentialSource,
225 ExternalID: section.String(externalIDKey),
226 MFASerial: section.String(mfaSerialKey),
227 RoleSessionName: section.String(roleSessionNameKey),
228 }
229 }
230
231 // `credential_process`
232 if credProc := section.String(credentialProcessKey); len(credProc) > 0 {
233 cfg.CredentialProcess = credProc
234 }
235
236 // Region
237 if v := section.String(regionKey); len(v) > 0 {
238 cfg.Region = v
239 }
240
241 // Endpoint discovery
242 if section.Has(enableEndpointDiscoveryKey) {
243 v := section.Bool(enableEndpointDiscoveryKey)
244 cfg.EnableEndpointDiscovery = &v
245 }
246
247 return nil
248 }
249
250 // SharedConfigLoadError is an error for the shared config file failed to load.
251 type SharedConfigLoadError struct {
252 Filename string
253 Err error
254 }
255
256 // Code is the short id of the error.
257 func (e SharedConfigLoadError) Code() string {
258 return "SharedConfigLoadError"
259 }
260
261 // Message is the description of the error
262 func (e SharedConfigLoadError) Message() string {
263 return fmt.Sprintf("failed to load config file, %s", e.Filename)
264 }
265
266 // OrigErr is the underlying error that caused the failure.
267 func (e SharedConfigLoadError) OrigErr() error {
268 return e.Err
269 }
270
271 // Error satisfies the error interface.
272 func (e SharedConfigLoadError) Error() string {
273 return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
274 }
275
276 // SharedConfigProfileNotExistsError is an error for the shared config when
277 // the profile was not find in the config file.
278 type SharedConfigProfileNotExistsError struct {
279 Profile string
280 Err error
281 }
282
283 // Code is the short id of the error.
284 func (e SharedConfigProfileNotExistsError) Code() string {
285 return "SharedConfigProfileNotExistsError"
286 }
287
288 // Message is the description of the error
289 func (e SharedConfigProfileNotExistsError) Message() string {
290 return fmt.Sprintf("failed to get profile, %s", e.Profile)
291 }
292
293 // OrigErr is the underlying error that caused the failure.
294 func (e SharedConfigProfileNotExistsError) OrigErr() error {
295 return e.Err
296 }
297
298 // Error satisfies the error interface.
299 func (e SharedConfigProfileNotExistsError) Error() string {
300 return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
301 }
302
303 // SharedConfigAssumeRoleError is an error for the shared config when the
304 // profile contains assume role information, but that information is invalid
305 // or not complete.
306 type SharedConfigAssumeRoleError struct {
307 RoleARN string
308 }
309
310 // Code is the short id of the error.
311 func (e SharedConfigAssumeRoleError) Code() string {
312 return "SharedConfigAssumeRoleError"
313 }
314
315 // Message is the description of the error
316 func (e SharedConfigAssumeRoleError) Message() string {
317 return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
318 e.RoleARN)
319 }
320
321 // OrigErr is the underlying error that caused the failure.
322 func (e SharedConfigAssumeRoleError) OrigErr() error {
323 return nil
324 }
325
326 // Error satisfies the error interface.
327 func (e SharedConfigAssumeRoleError) Error() string {
328 return awserr.SprintError(e.Code(), e.Message(), "", nil)
329 }