/
data_akamai_cloudlets_application_load_balancer.go
380 lines (357 loc) · 13.8 KB
/
data_akamai_cloudlets_application_load_balancer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
package cloudlets
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/v6/pkg/cloudlets"
"github.com/akamai/terraform-provider-akamai/v4/pkg/akamai"
"github.com/akamai/terraform-provider-akamai/v4/pkg/common/tf"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func dataSourceCloudletsApplicationLoadBalancer() *schema.Resource {
return &schema.Resource{
ReadContext: dataApplicationLoadBalancerRead,
Schema: map[string]*schema.Schema{
"origin_id": {
Type: schema.TypeString,
Required: true,
Description: "The conditional origin’s unique identifier",
},
"version": {
Type: schema.TypeInt,
Optional: true,
Description: "The load balancer configuration version",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "The load balancer configuration description",
},
"type": {
Type: schema.TypeString,
Computed: true,
Description: "The type of conditional origin",
},
"balancing_type": {
Type: schema.TypeString,
Computed: true,
Description: "The type of load balancing being performed. Options include WEIGHTED and PERFORMANCE",
},
"created_by": {
Type: schema.TypeString,
Computed: true,
Description: "The value which is set by the server at the time of creation and never subsequently changes",
},
"created_date": {
Type: schema.TypeString,
Computed: true,
Description: "The created date which is only set by the server the first time the load balancer version is created. All subsequent responses will contain the same value.",
},
"deleted": {
Type: schema.TypeBool,
Computed: true,
Description: "Describes if load balancer version has been deleted",
},
"immutable": {
Type: schema.TypeBool,
Computed: true,
Description: "Denotes whether you can edit the load balancing version. The default setting for this member is false. It automatically becomes true when the load balancing version is activated for the first time.",
},
"last_modified_by": {
Type: schema.TypeString,
Computed: true,
Description: "The last modification of load balancer configuration which is set by the server",
},
"last_modified_date": {
Type: schema.TypeString,
Computed: true,
Description: "Describes when load balancer configuration has been modified for the last time",
},
"warnings": {
Type: schema.TypeString,
Computed: true,
Description: "Describes warnings during activation of load balancer configuration",
},
"data_centers": {
Type: schema.TypeSet,
Computed: true,
Description: "The object containing information on conditional origins being used as data centers for an Application Load Balancer implementation. Only Conditional Origins with an originType of CUSTOMER or NETSTORAGE can be used as data centers in an application load balancer configuration.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"city": {
Type: schema.TypeString,
Computed: true,
Description: "The city in which the data center is located.",
},
"cloud_server_host_header_override": {
Type: schema.TypeBool,
Computed: true,
Description: "Describes if cloud server host header is overridden",
},
"cloud_service": {
Type: schema.TypeBool,
Computed: true,
Description: "Describes if this datacenter is a cloud service",
},
"continent": {
Type: schema.TypeString,
Computed: true,
Description: "The continent on which the data center is located",
},
"country": {
Type: schema.TypeString,
Computed: true,
Description: "The country in which the data center is located",
},
"hostname": {
Type: schema.TypeString,
Computed: true,
Description: "This should match the 'hostname' value defined for this datacenter in Property Manager",
},
"latitude": {
Type: schema.TypeFloat,
Computed: true,
Description: "The latitude value for the data center. This member supports six decimal places of precision.",
},
"liveness_hosts": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Description: "An array of strings that represent the origin servers used to poll the data centers in an application load balancer configuration. These servers support basic HTTP polling.",
},
"longitude": {
Type: schema.TypeFloat,
Computed: true,
Description: "The longitude value for the data center. This member supports six decimal places of precision.",
},
"origin_id": {
Type: schema.TypeString,
Computed: true,
Description: "The id of an origin that represents the data center. The conditional origin, which is defined in the Property Manager API, must have an originType of either CUSTOMER or NET_STORAGE",
},
"percent": {
Type: schema.TypeFloat,
Computed: true,
Description: "The percent of traffic that is sent to the data center. The total for all data centers must equal 100%.",
},
"state_or_province": {
Type: schema.TypeString,
Computed: true,
Description: "The state, province, or region where the data center is located",
},
},
},
},
"liveness_settings": {
Type: schema.TypeSet,
Computed: true,
Description: "The liveness settings are used to determine the health of each load balanced data center defined in the data center list",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"host_header": {
Type: schema.TypeString,
Computed: true,
Description: "The Host header for the liveness HTTP request",
},
"additional_headers": {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Description: "Maps additional case-insensitive HTTP header names included to the liveness testing requests",
},
"interval": {
Type: schema.TypeInt,
Computed: true,
Description: "Describes how often the liveness test will be performed. Optional defaults to 60 seconds, minimum is 10 seconds.",
},
"path": {
Type: schema.TypeString,
Computed: true,
Description: "The path to the test object used for liveness testing. The function of the test object is to help determine whether the data center is functioning.",
},
"peer_certificate_verification": {
Type: schema.TypeBool,
Computed: true,
Description: "Describes whether or not to validate the origin certificate for an HTTPS request",
},
"port": {
Type: schema.TypeInt,
Computed: true,
Description: "The port for the test object. The default port is 80, which is standard for HTTP. Enter 443 if you are using HTTPS.",
},
"protocol": {
Type: schema.TypeString,
Computed: true,
Description: "The protocol or scheme for the database, either HTTP or HTTPS.",
},
"request_string": {
Type: schema.TypeString,
Computed: true,
Description: "The request which will be used for TCP(S) tests",
},
"response_string": {
Type: schema.TypeString,
Computed: true,
Description: "The response which will be used for TCP(S) tests",
},
"status_3xx_failure": {
Type: schema.TypeBool,
Computed: true,
Description: "Set to true to mark the liveness test as failed when the request returns a 3xx (redirection) status code.",
},
"status_4xx_failure": {
Type: schema.TypeBool,
Computed: true,
Description: "Set to true to mark the liveness test as failed when the request returns a 4xx (client error) status code.",
},
"status_5xx_failure": {
Type: schema.TypeBool,
Computed: true,
Description: "Set to true to mark the liveness test as failed when the request returns a 5xx (server error) status code.",
},
"timeout": {
Type: schema.TypeFloat,
Computed: true,
Description: "The number of seconds the system waits before failing the liveness test. The default is 25 seconds.",
},
},
},
},
},
}
}
func dataApplicationLoadBalancerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
meta := akamai.Meta(m)
client := inst.Client(meta)
log := meta.Log("Cloudlets", "dataApplicationLoadBalancerRead")
log.Debug("Reading Load Balancer")
originID, err := tf.GetStringValue("origin_id", d)
if err != nil {
return diag.FromErr(err)
}
origin, err := client.GetOrigin(ctx, cloudlets.GetOriginRequest{OriginID: originID})
if err != nil {
return diag.FromErr(err)
}
var version int64
if v, err := tf.GetIntValue("version", d); err != nil {
if !errors.Is(err, tf.ErrNotFound) {
return diag.FromErr(err)
}
version, err = getLatestVersionOfApplicationLoadBalancer(ctx, originID, client)
if err != nil {
return diag.FromErr(err)
}
} else {
version = int64(v)
}
getLoadBalancerVersionRequest := cloudlets.GetLoadBalancerVersionRequest{
OriginID: originID,
Version: version,
ShouldValidate: true,
}
loadBalancerVersion, err := client.GetLoadBalancerVersion(ctx, getLoadBalancerVersionRequest)
if err != nil {
return diag.FromErr(err)
}
if loadBalancerVersion.Deleted {
return diag.Errorf("specified load balancer version is deleted: %d", version)
}
fields, err := getSchemaLoadBalancer(loadBalancerVersion, origin)
if err != nil {
return diag.FromErr(err)
}
err = tf.SetAttrs(d, fields)
if err != nil {
return diag.FromErr(err)
}
d.SetId(fmt.Sprintf("%s:%d", originID, version))
return nil
}
func getSchemaLoadBalancer(loadBalancerVersion *cloudlets.LoadBalancerVersion, origin *cloudlets.Origin) (map[string]interface{}, error) {
warnings, err := json.MarshalIndent(loadBalancerVersion.Warnings, "", " ")
if err != nil {
return nil, fmt.Errorf("cannot marshal json %s", err)
}
return map[string]interface{}{
"origin_id": loadBalancerVersion.OriginID,
"version": loadBalancerVersion.Version,
"description": loadBalancerVersion.Description,
"type": origin.Type,
"balancing_type": loadBalancerVersion.BalancingType,
"created_by": loadBalancerVersion.CreatedBy,
"created_date": loadBalancerVersion.CreatedDate,
"deleted": loadBalancerVersion.Deleted,
"immutable": loadBalancerVersion.Immutable,
"last_modified_by": loadBalancerVersion.LastModifiedBy,
"last_modified_date": loadBalancerVersion.LastModifiedDate,
"warnings": string(warnings),
"data_centers": getSchemaDataCenters(loadBalancerVersion.DataCenters),
"liveness_settings": getSchemaLivenessSettings(loadBalancerVersion.LivenessSettings),
}, nil
}
func getSchemaDataCenters(centers []cloudlets.DataCenter) []map[string]interface{} {
var dataCenters []map[string]interface{}
for _, c := range centers {
dataCenter := map[string]interface{}{
"city": c.City,
"cloud_server_host_header_override": c.CloudServerHostHeaderOverride,
"cloud_service": c.CloudService,
"continent": c.Continent,
"country": c.Country,
"hostname": c.Hostname,
"latitude": c.Latitude,
"liveness_hosts": c.LivenessHosts,
"longitude": c.Longitude,
"origin_id": c.OriginID,
"percent": c.Percent,
"state_or_province": c.StateOrProvince,
}
dataCenters = append(dataCenters, dataCenter)
}
return dataCenters
}
func getSchemaLivenessSettings(settings *cloudlets.LivenessSettings) []map[string]interface{} {
if settings != nil {
return []map[string]interface{}{
{
"host_header": settings.HostHeader,
"additional_headers": settings.AdditionalHeaders,
"interval": settings.Interval,
"path": settings.Path,
"peer_certificate_verification": settings.PeerCertificateVerification,
"port": settings.Port,
"protocol": settings.Protocol,
"request_string": settings.RequestString,
"response_string": settings.ResponseString,
"status_3xx_failure": settings.Status3xxFailure,
"status_4xx_failure": settings.Status4xxFailure,
"status_5xx_failure": settings.Status5xxFailure,
"timeout": settings.Timeout,
},
}
}
return nil
}
var errNoVersionForOrigin = errors.New("no load balancer version found for origin")
func getLatestVersionOfApplicationLoadBalancer(ctx context.Context, originID string, client cloudlets.Cloudlets) (int64, error) {
listLoadBalancerVersionsRequest := cloudlets.ListLoadBalancerVersionsRequest{
OriginID: originID,
}
versions, err := client.ListLoadBalancerVersions(ctx, listLoadBalancerVersionsRequest)
if err != nil {
return 0, err
}
if len(versions) == 0 {
return 0, fmt.Errorf("%w: %s", errNoVersionForOrigin, originID)
}
var theLatestVersion int64
for _, version := range versions {
if version.Version > theLatestVersion {
theLatestVersion = version.Version
}
}
return theLatestVersion, nil
}