]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / endpoints / decode.go
1 package endpoints
2
3 import (
4 "encoding/json"
5 "fmt"
6 "io"
7
8 "github.com/aws/aws-sdk-go/aws/awserr"
9 )
10
11 type modelDefinition map[string]json.RawMessage
12
13 // A DecodeModelOptions are the options for how the endpoints model definition
14 // are decoded.
15 type DecodeModelOptions struct {
16 SkipCustomizations bool
17 }
18
19 // Set combines all of the option functions together.
20 func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
21 for _, fn := range optFns {
22 fn(d)
23 }
24 }
25
26 // DecodeModel unmarshals a Regions and Endpoint model definition file into
27 // a endpoint Resolver. If the file format is not supported, or an error occurs
28 // when unmarshaling the model an error will be returned.
29 //
30 // Casting the return value of this func to a EnumPartitions will
31 // allow you to get a list of the partitions in the order the endpoints
32 // will be resolved in.
33 //
34 // resolver, err := endpoints.DecodeModel(reader)
35 //
36 // partitions := resolver.(endpoints.EnumPartitions).Partitions()
37 // for _, p := range partitions {
38 // // ... inspect partitions
39 // }
40 func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
41 var opts DecodeModelOptions
42 opts.Set(optFns...)
43
44 // Get the version of the partition file to determine what
45 // unmarshaling model to use.
46 modelDef := modelDefinition{}
47 if err := json.NewDecoder(r).Decode(&modelDef); err != nil {
48 return nil, newDecodeModelError("failed to decode endpoints model", err)
49 }
50
51 var version string
52 if b, ok := modelDef["version"]; ok {
53 version = string(b)
54 } else {
55 return nil, newDecodeModelError("endpoints version not found in model", nil)
56 }
57
58 if version == "3" {
59 return decodeV3Endpoints(modelDef, opts)
60 }
61
62 return nil, newDecodeModelError(
63 fmt.Sprintf("endpoints version %s, not supported", version), nil)
64 }
65
66 func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) {
67 b, ok := modelDef["partitions"]
68 if !ok {
69 return nil, newDecodeModelError("endpoints model missing partitions", nil)
70 }
71
72 ps := partitions{}
73 if err := json.Unmarshal(b, &ps); err != nil {
74 return nil, newDecodeModelError("failed to decode endpoints model", err)
75 }
76
77 if opts.SkipCustomizations {
78 return ps, nil
79 }
80
81 // Customization
82 for i := 0; i < len(ps); i++ {
83 p := &ps[i]
84 custAddEC2Metadata(p)
85 custAddS3DualStack(p)
86 custRmIotDataService(p)
87 custFixAppAutoscalingChina(p)
88 custFixAppAutoscalingUsGov(p)
89 }
90
91 return ps, nil
92 }
93
94 func custAddS3DualStack(p *partition) {
95 if p.ID != "aws" {
96 return
97 }
98
99 custAddDualstack(p, "s3")
100 custAddDualstack(p, "s3-control")
101 }
102
103 func custAddDualstack(p *partition, svcName string) {
104 s, ok := p.Services[svcName]
105 if !ok {
106 return
107 }
108
109 s.Defaults.HasDualStack = boxedTrue
110 s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}"
111
112 p.Services[svcName] = s
113 }
114
115 func custAddEC2Metadata(p *partition) {
116 p.Services["ec2metadata"] = service{
117 IsRegionalized: boxedFalse,
118 PartitionEndpoint: "aws-global",
119 Endpoints: endpoints{
120 "aws-global": endpoint{
121 Hostname: "169.254.169.254/latest",
122 Protocols: []string{"http"},
123 },
124 },
125 }
126 }
127
128 func custRmIotDataService(p *partition) {
129 delete(p.Services, "data.iot")
130 }
131
132 func custFixAppAutoscalingChina(p *partition) {
133 if p.ID != "aws-cn" {
134 return
135 }
136
137 const serviceName = "application-autoscaling"
138 s, ok := p.Services[serviceName]
139 if !ok {
140 return
141 }
142
143 const expectHostname = `autoscaling.{region}.amazonaws.com`
144 if e, a := s.Defaults.Hostname, expectHostname; e != a {
145 fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a)
146 return
147 }
148
149 s.Defaults.Hostname = expectHostname + ".cn"
150 p.Services[serviceName] = s
151 }
152
153 func custFixAppAutoscalingUsGov(p *partition) {
154 if p.ID != "aws-us-gov" {
155 return
156 }
157
158 const serviceName = "application-autoscaling"
159 s, ok := p.Services[serviceName]
160 if !ok {
161 return
162 }
163
164 if a := s.Defaults.CredentialScope.Service; a != "" {
165 fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty credential scope service, got %s\n", a)
166 return
167 }
168
169 if a := s.Defaults.Hostname; a != "" {
170 fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty hostname, got %s\n", a)
171 return
172 }
173
174 s.Defaults.CredentialScope.Service = "application-autoscaling"
175 s.Defaults.Hostname = "autoscaling.{region}.amazonaws.com"
176
177 p.Services[serviceName] = s
178 }
179
180 type decodeModelError struct {
181 awsError
182 }
183
184 func newDecodeModelError(msg string, err error) decodeModelError {
185 return decodeModelError{
186 awsError: awserr.New("DecodeEndpointsModelError", msg, err),
187 }
188 }