]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
Initial transfer of provider code
[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 unkonwn 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 := range p.p.Regions {
210 rs[id] = Region{
211 id: id,
212 p: p.p,
213 }
214 }
215
216 return rs
217 }
218
219 // Services returns a map of Service indexed by their ID. This is useful for
220 // enumerating over the services in a partition.
221 func (p Partition) Services() map[string]Service {
222 ss := map[string]Service{}
223 for id := range p.p.Services {
224 ss[id] = Service{
225 id: id,
226 p: p.p,
227 }
228 }
229
230 return ss
231 }
232
233 // A Region provides information about a region, and ability to resolve an
234 // endpoint from the context of a region, given a service.
235 type Region struct {
236 id, desc string
237 p *partition
238 }
239
240 // ID returns the region's identifier.
241 func (r Region) ID() string { return r.id }
242
243 // ResolveEndpoint resolves an endpoint from the context of the region given
244 // a service. See Partition.EndpointFor for usage and errors that can be returned.
245 func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
246 return r.p.EndpointFor(service, r.id, opts...)
247 }
248
249 // Services returns a list of all services that are known to be in this region.
250 func (r Region) Services() map[string]Service {
251 ss := map[string]Service{}
252 for id, s := range r.p.Services {
253 if _, ok := s.Endpoints[r.id]; ok {
254 ss[id] = Service{
255 id: id,
256 p: r.p,
257 }
258 }
259 }
260
261 return ss
262 }
263
264 // A Service provides information about a service, and ability to resolve an
265 // endpoint from the context of a service, given a region.
266 type Service struct {
267 id string
268 p *partition
269 }
270
271 // ID returns the identifier for the service.
272 func (s Service) ID() string { return s.id }
273
274 // ResolveEndpoint resolves an endpoint from the context of a service given
275 // a region. See Partition.EndpointFor for usage and errors that can be returned.
276 func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
277 return s.p.EndpointFor(s.id, region, opts...)
278 }
279
280 // Regions returns a map of Regions that the service is present in.
281 //
282 // A region is the AWS region the service exists in. Whereas a Endpoint is
283 // an URL that can be resolved to a instance of a service.
284 func (s Service) Regions() map[string]Region {
285 rs := map[string]Region{}
286 for id := range s.p.Services[s.id].Endpoints {
287 if _, ok := s.p.Regions[id]; ok {
288 rs[id] = Region{
289 id: id,
290 p: s.p,
291 }
292 }
293 }
294
295 return rs
296 }
297
298 // Endpoints returns a map of Endpoints indexed by their ID for all known
299 // endpoints for a service.
300 //
301 // A region is the AWS region the service exists in. Whereas a Endpoint is
302 // an URL that can be resolved to a instance of a service.
303 func (s Service) Endpoints() map[string]Endpoint {
304 es := map[string]Endpoint{}
305 for id := range s.p.Services[s.id].Endpoints {
306 es[id] = Endpoint{
307 id: id,
308 serviceID: s.id,
309 p: s.p,
310 }
311 }
312
313 return es
314 }
315
316 // A Endpoint provides information about endpoints, and provides the ability
317 // to resolve that endpoint for the service, and the region the endpoint
318 // represents.
319 type Endpoint struct {
320 id string
321 serviceID string
322 p *partition
323 }
324
325 // ID returns the identifier for an endpoint.
326 func (e Endpoint) ID() string { return e.id }
327
328 // ServiceID returns the identifier the endpoint belongs to.
329 func (e Endpoint) ServiceID() string { return e.serviceID }
330
331 // ResolveEndpoint resolves an endpoint from the context of a service and
332 // region the endpoint represents. See Partition.EndpointFor for usage and
333 // errors that can be returned.
334 func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
335 return e.p.EndpointFor(e.serviceID, e.id, opts...)
336 }
337
338 // A ResolvedEndpoint is an endpoint that has been resolved based on a partition
339 // service, and region.
340 type ResolvedEndpoint struct {
341 // The endpoint URL
342 URL string
343
344 // The region that should be used for signing requests.
345 SigningRegion string
346
347 // The service name that should be used for signing requests.
348 SigningName string
349
350 // The signing method that should be used for signing requests.
351 SigningMethod string
352 }
353
354 // So that the Error interface type can be included as an anonymous field
355 // in the requestError struct and not conflict with the error.Error() method.
356 type awsError awserr.Error
357
358 // A EndpointNotFoundError is returned when in StrictMatching mode, and the
359 // endpoint for the service and region cannot be found in any of the partitions.
360 type EndpointNotFoundError struct {
361 awsError
362 Partition string
363 Service string
364 Region string
365 }
366
367 // A UnknownServiceError is returned when the service does not resolve to an
368 // endpoint. Includes a list of all known services for the partition. Returned
369 // when a partition does not support the service.
370 type UnknownServiceError struct {
371 awsError
372 Partition string
373 Service string
374 Known []string
375 }
376
377 // NewUnknownServiceError builds and returns UnknownServiceError.
378 func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
379 return UnknownServiceError{
380 awsError: awserr.New("UnknownServiceError",
381 "could not resolve endpoint for unknown service", nil),
382 Partition: p,
383 Service: s,
384 Known: known,
385 }
386 }
387
388 // String returns the string representation of the error.
389 func (e UnknownServiceError) Error() string {
390 extra := fmt.Sprintf("partition: %q, service: %q",
391 e.Partition, e.Service)
392 if len(e.Known) > 0 {
393 extra += fmt.Sprintf(", known: %v", e.Known)
394 }
395 return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
396 }
397
398 // String returns the string representation of the error.
399 func (e UnknownServiceError) String() string {
400 return e.Error()
401 }
402
403 // A UnknownEndpointError is returned when in StrictMatching mode and the
404 // service is valid, but the region does not resolve to an endpoint. Includes
405 // a list of all known endpoints for the service.
406 type UnknownEndpointError struct {
407 awsError
408 Partition string
409 Service string
410 Region string
411 Known []string
412 }
413
414 // NewUnknownEndpointError builds and returns UnknownEndpointError.
415 func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
416 return UnknownEndpointError{
417 awsError: awserr.New("UnknownEndpointError",
418 "could not resolve endpoint", nil),
419 Partition: p,
420 Service: s,
421 Region: r,
422 Known: known,
423 }
424 }
425
426 // String returns the string representation of the error.
427 func (e UnknownEndpointError) Error() string {
428 extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
429 e.Partition, e.Service, e.Region)
430 if len(e.Known) > 0 {
431 extra += fmt.Sprintf(", known: %v", e.Known)
432 }
433 return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
434 }
435
436 // String returns the string representation of the error.
437 func (e UnknownEndpointError) String() string {
438 return e.Error()
439 }