]>
Commit | Line | Data |
---|---|---|
1 | // Package defaults is a collection of helpers to retrieve the SDK's default | |
2 | // configuration and handlers. | |
3 | // | |
4 | // Generally this package shouldn't be used directly, but session.Session | |
5 | // instead. This package is useful when you need to reset the defaults | |
6 | // of a session or service client to the SDK defaults before setting | |
7 | // additional parameters. | |
8 | package defaults | |
9 | ||
10 | import ( | |
11 | "fmt" | |
12 | "net/http" | |
13 | "net/url" | |
14 | "os" | |
15 | "time" | |
16 | ||
17 | "github.com/aws/aws-sdk-go/aws" | |
18 | "github.com/aws/aws-sdk-go/aws/awserr" | |
19 | "github.com/aws/aws-sdk-go/aws/corehandlers" | |
20 | "github.com/aws/aws-sdk-go/aws/credentials" | |
21 | "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" | |
22 | "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" | |
23 | "github.com/aws/aws-sdk-go/aws/ec2metadata" | |
24 | "github.com/aws/aws-sdk-go/aws/endpoints" | |
25 | "github.com/aws/aws-sdk-go/aws/request" | |
26 | ) | |
27 | ||
28 | // A Defaults provides a collection of default values for SDK clients. | |
29 | type Defaults struct { | |
30 | Config *aws.Config | |
31 | Handlers request.Handlers | |
32 | } | |
33 | ||
34 | // Get returns the SDK's default values with Config and handlers pre-configured. | |
35 | func Get() Defaults { | |
36 | cfg := Config() | |
37 | handlers := Handlers() | |
38 | cfg.Credentials = CredChain(cfg, handlers) | |
39 | ||
40 | return Defaults{ | |
41 | Config: cfg, | |
42 | Handlers: handlers, | |
43 | } | |
44 | } | |
45 | ||
46 | // Config returns the default configuration without credentials. | |
47 | // To retrieve a config with credentials also included use | |
48 | // `defaults.Get().Config` instead. | |
49 | // | |
50 | // Generally you shouldn't need to use this method directly, but | |
51 | // is available if you need to reset the configuration of an | |
52 | // existing service client or session. | |
53 | func Config() *aws.Config { | |
54 | return aws.NewConfig(). | |
55 | WithCredentials(credentials.AnonymousCredentials). | |
56 | WithRegion(os.Getenv("AWS_REGION")). | |
57 | WithHTTPClient(http.DefaultClient). | |
58 | WithMaxRetries(aws.UseServiceDefaultRetries). | |
59 | WithLogger(aws.NewDefaultLogger()). | |
60 | WithLogLevel(aws.LogOff). | |
61 | WithEndpointResolver(endpoints.DefaultResolver()) | |
62 | } | |
63 | ||
64 | // Handlers returns the default request handlers. | |
65 | // | |
66 | // Generally you shouldn't need to use this method directly, but | |
67 | // is available if you need to reset the request handlers of an | |
68 | // existing service client or session. | |
69 | func Handlers() request.Handlers { | |
70 | var handlers request.Handlers | |
71 | ||
72 | handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) | |
73 | handlers.Validate.AfterEachFn = request.HandlerListStopOnError | |
74 | handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) | |
75 | handlers.Build.AfterEachFn = request.HandlerListStopOnError | |
76 | handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) | |
77 | handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) | |
78 | handlers.Send.PushBackNamed(corehandlers.SendHandler) | |
79 | handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) | |
80 | handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) | |
81 | ||
82 | return handlers | |
83 | } | |
84 | ||
85 | // CredChain returns the default credential chain. | |
86 | // | |
87 | // Generally you shouldn't need to use this method directly, but | |
88 | // is available if you need to reset the credentials of an | |
89 | // existing service client or session's Config. | |
90 | func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { | |
91 | return credentials.NewCredentials(&credentials.ChainProvider{ | |
92 | VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), | |
93 | Providers: []credentials.Provider{ | |
94 | &credentials.EnvProvider{}, | |
95 | &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, | |
96 | RemoteCredProvider(*cfg, handlers), | |
97 | }, | |
98 | }) | |
99 | } | |
100 | ||
101 | const ( | |
102 | httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" | |
103 | ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | |
104 | ) | |
105 | ||
106 | // RemoteCredProvider returns a credentials provider for the default remote | |
107 | // endpoints such as EC2 or ECS Roles. | |
108 | func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { | |
109 | if u := os.Getenv(httpProviderEnvVar); len(u) > 0 { | |
110 | return localHTTPCredProvider(cfg, handlers, u) | |
111 | } | |
112 | ||
113 | if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 { | |
114 | u := fmt.Sprintf("http://169.254.170.2%s", uri) | |
115 | return httpCredProvider(cfg, handlers, u) | |
116 | } | |
117 | ||
118 | return ec2RoleProvider(cfg, handlers) | |
119 | } | |
120 | ||
121 | func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { | |
122 | var errMsg string | |
123 | ||
124 | parsed, err := url.Parse(u) | |
125 | if err != nil { | |
126 | errMsg = fmt.Sprintf("invalid URL, %v", err) | |
127 | } else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") { | |
128 | errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host) | |
129 | } | |
130 | ||
131 | if len(errMsg) > 0 { | |
132 | if cfg.Logger != nil { | |
133 | cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err) | |
134 | } | |
135 | return credentials.ErrorProvider{ | |
136 | Err: awserr.New("CredentialsEndpointError", errMsg, err), | |
137 | ProviderName: endpointcreds.ProviderName, | |
138 | } | |
139 | } | |
140 | ||
141 | return httpCredProvider(cfg, handlers, u) | |
142 | } | |
143 | ||
144 | func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { | |
145 | return endpointcreds.NewProviderClient(cfg, handlers, u, | |
146 | func(p *endpointcreds.Provider) { | |
147 | p.ExpiryWindow = 5 * time.Minute | |
148 | }, | |
149 | ) | |
150 | } | |
151 | ||
152 | func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { | |
153 | resolver := cfg.EndpointResolver | |
154 | if resolver == nil { | |
155 | resolver = endpoints.DefaultResolver() | |
156 | } | |
157 | ||
158 | e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "") | |
159 | return &ec2rolecreds.EC2RoleProvider{ | |
160 | Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion), | |
161 | ExpiryWindow: 5 * time.Minute, | |
162 | } | |
163 | } |