]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / endpoints / endpoints.go
1 package endpoints
2
3 import (
4 "fmt"
5 "regexp"
6
7 "github.com/aws/aws-sdk-go/aws/awserr"
8 )
9
10 // Options provide the configuration needed to direct how the
11 // endpoints will be resolved.
12 type Options struct {
13 // DisableSSL forces the endpoint to be resolved as HTTP.
14 // instead of HTTPS if the service supports it.
15 DisableSSL bool
16
17 // Sets the resolver to resolve the endpoint as a dualstack endpoint
18 // for the service. If dualstack support for a service is not known and
19 // StrictMatching is not enabled a dualstack endpoint for the service will
20 // be returned. This endpoint may not be valid. If StrictMatching is
21 // enabled only services that are known to support dualstack will return
22 // dualstack endpoints.
23 UseDualStack bool
24
25 // Enables strict matching of services and regions resolved endpoints.
26 // If the partition doesn't enumerate the exact service and region an
27 // error will be returned. This option will prevent returning endpoints
28 // that look valid, but may not resolve to any real endpoint.
29 StrictMatching bool
30
31 // Enables resolving a service endpoint based on the region provided if the
32 // service does not exist. The service endpoint ID will be used as the service
33 // domain name prefix. By default the endpoint resolver requires the service
34 // to be known when resolving endpoints.
35 //
36 // If resolving an endpoint on the partition list the provided region will
37 // be used to determine which partition's domain name pattern to the service
38 // endpoint ID with. If both the service and region are unknown and resolving
39 // the endpoint on partition list an UnknownEndpointError error will be returned.
40 //
41 // If resolving and endpoint on a partition specific resolver that partition's
42 // domain name pattern will be used with the service endpoint ID. If both
43 // region and service do not exist when resolving an endpoint on a specific
44 // partition the partition's domain pattern will be used to combine the
45 // endpoint and region together.
46 //
47 // This option is ignored if StrictMatching is enabled.
48 ResolveUnknownService bool
49 }
50
51 // Set combines all of the option functions together.
52 func (o *Options) Set(optFns ...func(*Options)) {
53 for _, fn := range optFns {
54 fn(o)
55 }
56 }
57
58 // DisableSSLOption sets the DisableSSL options. Can be used as a functional
59 // option when resolving endpoints.
60 func DisableSSLOption(o *Options) {
61 o.DisableSSL = true
62 }
63
64 // UseDualStackOption sets the UseDualStack option. Can be used as a functional
65 // option when resolving endpoints.
66 func UseDualStackOption(o *Options) {
67 o.UseDualStack = true
68 }
69
70 // StrictMatchingOption sets the StrictMatching option. Can be used as a functional
71 // option when resolving endpoints.
72 func StrictMatchingOption(o *Options) {
73 o.StrictMatching = true
74 }
75
76 // ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
77 // as a functional option when resolving endpoints.
78 func ResolveUnknownServiceOption(o *Options) {
79 o.ResolveUnknownService = true
80 }
81
82 // A Resolver provides the interface for functionality to resolve endpoints.
83 // The build in Partition and DefaultResolver return value satisfy this interface.
84 type Resolver interface {
85 EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
86 }
87
88 // ResolverFunc is a helper utility that wraps a function so it satisfies the
89 // Resolver interface. This is useful when you want to add additional endpoint
90 // resolving logic, or stub out specific endpoints with custom values.
91 type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
92
93 // EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
94 func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
95 return fn(service, region, opts...)
96 }
97
98 var schemeRE = regexp.MustCompile("^([^:]+)://")
99
100 // AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
101 // scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
102 //
103 // If disableSSL is set, it will only set the URL's scheme if the URL does not
104 // contain a scheme.
105 func AddScheme(endpoint string, disableSSL bool) string {
106 if !schemeRE.MatchString(endpoint) {
107 scheme := "https"
108 if disableSSL {
109 scheme = "http"
110 }
111 endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
112 }
113
114 return endpoint
115 }
116
117 // EnumPartitions a provides a way to retrieve the underlying partitions that
118 // make up the SDK's default Resolver, or any resolver decoded from a model
119 // file.
120 //
121 // Use this interface with DefaultResolver and DecodeModels to get the list of
122 // Partitions.
123 type EnumPartitions interface {
124 Partitions() []Partition
125 }
126
127 // RegionsForService returns a map of regions for the partition and service.
128 // If either the partition or service does not exist false will be returned
129 // as the second parameter.
130 //
131 // This example shows how to get the regions for DynamoDB in the AWS partition.
132 // rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
133 //
134 // This is equivalent to using the partition directly.
135 // rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
136 func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
137 for _, p := range ps {
138 if p.ID() != partitionID {
139 continue
140 }
141 if _, ok := p.p.Services[serviceID]; !ok {
142 break
143 }
144
145 s := Service{
146 id: serviceID,
147 p: p.p,
148 }
149 return s.Regions(), true
150 }
151
152 return map[string]Region{}, false
153 }
154
155 // PartitionForRegion returns the first partition which includes the region
156 // passed in. This includes both known regions and regions which match
157 // a pattern supported by the partition which may include regions that are
158 // not explicitly known by the partition. Use the Regions method of the
159 // returned Partition if explicit support is needed.
160 func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
161 for _, p := range ps {
162 if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
163 return p, true
164 }
165 }
166
167 return Partition{}, false
168 }
169
170 // A Partition provides the ability to enumerate the partition's regions
171 // and services.
172 type Partition struct {
173 id string
174 p *partition
175 }
176
177 // ID returns the identifier of the partition.
178 func (p Partition) ID() string { return p.id }
179
180 // EndpointFor attempts to resolve the endpoint based on service and region.
181 // See Options for information on configuring how the endpoint is resolved.
182 //
183 // If the service cannot be found in the metadata the UnknownServiceError
184 // error will be returned. This validation will occur regardless if
185 // StrictMatching is enabled. To enable resolving unknown services set the
186 // "ResolveUnknownService" option to true. When StrictMatching is disabled
187 // this option allows the partition resolver to resolve a endpoint based on
188 // the service endpoint ID provided.
189 //
190 // When resolving endpoints you can choose to enable StrictMatching. This will
191 // require the provided service and region to be known by the partition.
192 // If the endpoint cannot be strictly resolved an error will be returned. This
193 // mode is useful to ensure the endpoint resolved is valid. Without
194 // StrictMatching enabled the endpoint returned my look valid but may not work.
195 // StrictMatching requires the SDK to be updated if you want to take advantage
196 // of new regions and services expansions.
197 //
198 // Errors that can be returned.
199 // * UnknownServiceError
200 // * UnknownEndpointError
201 func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
202 return p.p.EndpointFor(service, region, opts...)
203 }
204
205 // Regions returns a map of Regions indexed by their ID. This is useful for
206 // enumerating over the regions in a partition.
207 func (p Partition) Regions() map[string]Region {
208 rs := map[string]Region{}
209 for id, r := range p.p.Regions {
210 rs[id] = Region{
211 id: id,
212 desc: r.Description,
213 p: p.p,
214 }
215 }
216
217 return rs
218 }
219
220 // Services returns a map of Service indexed by their ID. This is useful for
221 // enumerating over the services in a partition.
222 func (p Partition) Services() map[string]Service {
223 ss := map[string]Service{}
224 for id := range p.p.Services {
225 ss[id] = Service{
226 id: id,
227 p: p.p,
228 }
229 }
230
231 return ss
232 }
233
234 // A Region provides information about a region, and ability to resolve an
235 // endpoint from the context of a region, given a service.
236 type Region struct {
237 id, desc string
238 p *partition
239 }
240
241 // ID returns the region's identifier.
242 func (r Region) ID() string { return r.id }
243
244 // Description returns the region's description. The region description
245 // is free text, it can be empty, and it may change between SDK releases.
246 func (r Region) Description() string { return r.desc }
247
248 // ResolveEndpoint resolves an endpoint from the context of the region given
249 // a service. See Partition.EndpointFor for usage and errors that can be returned.
250 func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
251 return r.p.EndpointFor(service, r.id, opts...)
252 }
253
254 // Services returns a list of all services that are known to be in this region.
255 func (r Region) Services() map[string]Service {
256 ss := map[string]Service{}
257 for id, s := range r.p.Services {
258 if _, ok := s.Endpoints[r.id]; ok {
259 ss[id] = Service{
260 id: id,
261 p: r.p,
262 }
263 }
264 }
265
266 return ss
267 }
268
269 // A Service provides information about a service, and ability to resolve an
270 // endpoint from the context of a service, given a region.
271 type Service struct {
272 id string
273 p *partition
274 }
275
276 // ID returns the identifier for the service.
277 func (s Service) ID() string { return s.id }
278
279 // ResolveEndpoint resolves an endpoint from the context of a service given
280 // a region. See Partition.EndpointFor for usage and errors that can be returned.
281 func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
282 return s.p.EndpointFor(s.id, region, opts...)
283 }
284
285 // Regions returns a map of Regions that the service is present in.
286 //
287 // A region is the AWS region the service exists in. Whereas a Endpoint is
288 // an URL that can be resolved to a instance of a service.
289 func (s Service) Regions() map[string]Region {
290 rs := map[string]Region{}
291 for id := range s.p.Services[s.id].Endpoints {
292 if r, ok := s.p.Regions[id]; ok {
293 rs[id] = Region{
294 id: id,
295 desc: r.Description,
296 p: s.p,
297 }
298 }
299 }
300
301 return rs
302 }
303
304 // Endpoints returns a map of Endpoints indexed by their ID for all known
305 // endpoints for a service.
306 //
307 // A region is the AWS region the service exists in. Whereas a Endpoint is
308 // an URL that can be resolved to a instance of a service.
309 func (s Service) Endpoints() map[string]Endpoint {
310 es := map[string]Endpoint{}
311 for id := range s.p.Services[s.id].Endpoints {
312 es[id] = Endpoint{
313 id: id,
314 serviceID: s.id,
315 p: s.p,
316 }
317 }
318
319 return es
320 }
321
322 // A Endpoint provides information about endpoints, and provides the ability
323 // to resolve that endpoint for the service, and the region the endpoint
324 // represents.
325 type Endpoint struct {
326 id string
327 serviceID string
328 p *partition
329 }
330
331 // ID returns the identifier for an endpoint.
332 func (e Endpoint) ID() string { return e.id }
333
334 // ServiceID returns the identifier the endpoint belongs to.
335 func (e Endpoint) ServiceID() string { return e.serviceID }
336
337 // ResolveEndpoint resolves an endpoint from the context of a service and
338 // region the endpoint represents. See Partition.EndpointFor for usage and
339 // errors that can be returned.
340 func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
341 return e.p.EndpointFor(e.serviceID, e.id, opts...)
342 }
343
344 // A ResolvedEndpoint is an endpoint that has been resolved based on a partition
345 // service, and region.
346 type ResolvedEndpoint struct {
347 // The endpoint URL
348 URL string
349
350 // The region that should be used for signing requests.
351 SigningRegion string
352
353 // The service name that should be used for signing requests.
354 SigningName string
355
356 // States that the signing name for this endpoint was derived from metadata
357 // passed in, but was not explicitly modeled.
358 SigningNameDerived bool
359
360 // The signing method that should be used for signing requests.
361 SigningMethod string
362 }
363
364 // So that the Error interface type can be included as an anonymous field
365 // in the requestError struct and not conflict with the error.Error() method.
366 type awsError awserr.Error
367
368 // A EndpointNotFoundError is returned when in StrictMatching mode, and the
369 // endpoint for the service and region cannot be found in any of the partitions.
370 type EndpointNotFoundError struct {
371 awsError
372 Partition string
373 Service string
374 Region string
375 }
376
377 // A UnknownServiceError is returned when the service does not resolve to an
378 // endpoint. Includes a list of all known services for the partition. Returned
379 // when a partition does not support the service.
380 type UnknownServiceError struct {
381 awsError
382 Partition string
383 Service string
384 Known []string
385 }
386
387 // NewUnknownServiceError builds and returns UnknownServiceError.
388 func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
389 return UnknownServiceError{
390 awsError: awserr.New("UnknownServiceError",
391 "could not resolve endpoint for unknown service", nil),
392 Partition: p,
393 Service: s,
394 Known: known,
395 }
396 }
397
398 // String returns the string representation of the error.
399 func (e UnknownServiceError) Error() string {
400 extra := fmt.Sprintf("partition: %q, service: %q",
401 e.Partition, e.Service)
402 if len(e.Known) > 0 {
403 extra += fmt.Sprintf(", known: %v", e.Known)
404 }
405 return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
406 }
407
408 // String returns the string representation of the error.
409 func (e UnknownServiceError) String() string {
410 return e.Error()
411 }
412
413 // A UnknownEndpointError is returned when in StrictMatching mode and the
414 // service is valid, but the region does not resolve to an endpoint. Includes
415 // a list of all known endpoints for the service.
416 type UnknownEndpointError struct {
417 awsError
418 Partition string
419 Service string
420 Region string
421 Known []string
422 }
423
424 // NewUnknownEndpointError builds and returns UnknownEndpointError.
425 func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
426 return UnknownEndpointError{
427 awsError: awserr.New("UnknownEndpointError",
428 "could not resolve endpoint", nil),
429 Partition: p,
430 Service: s,
431 Region: r,
432 Known: known,
433 }
434 }
435
436 // String returns the string representation of the error.
437 func (e UnknownEndpointError) Error() string {
438 extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
439 e.Partition, e.Service, e.Region)
440 if len(e.Known) > 0 {
441 extra += fmt.Sprintf(", known: %v", e.Known)
442 }
443 return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
444 }
445
446 // String returns the string representation of the error.
447 func (e UnknownEndpointError) String() string {
448 return e.Error()
449 }