-
Notifications
You must be signed in to change notification settings - Fork 21
/
data_source_autoscaling_group.go
323 lines (307 loc) · 14.8 KB
/
data_source_autoscaling_group.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
package ionoscloud
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
autoscaling "github.com/ionos-cloud/sdk-go-vm-autoscaling"
"github.com/ionos-cloud/terraform-provider-ionoscloud/v6/services"
autoscalingService "github.com/ionos-cloud/terraform-provider-ionoscloud/v6/services/autoscaling"
)
func dataSourceAutoscalingGroup() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceAutoscalingGroupRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Description: "UUID of the Autoscaling Group.",
Optional: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.IsUUID),
},
"name": {
Type: schema.TypeString,
Description: "User-defined name for the Autoscaling Group.",
Optional: true,
},
"max_replica_count": {
Type: schema.TypeInt,
Description: "Maximum replica count value for `targetReplicaCount`. Will be enforced for both automatic and manual changes.",
Computed: true,
},
"min_replica_count": {
Type: schema.TypeInt,
Description: "Minimum replica count value for `targetReplicaCount`. Will be enforced for both automatic and manual changes.",
Computed: true,
},
"target_replica_count": {
Type: schema.TypeInt,
Description: "The target number of VMs in this Group. Depending on the scaling policy, this number will be adjusted automatically. VMs will be created or destroyed automatically in order to adjust the actual number of VMs to this number. If targetReplicaCount is given in the request body then it must be >= minReplicaCount and <= maxReplicaCount.",
Computed: true,
},
"policy": {
Type: schema.TypeList,
Description: "Specifies the behavior of this Autoscaling Group. A policy consists of Triggers and Actions, whereby an Action is some kind of automated behavior, and a Trigger is defined by the circumstances under which the Action is triggered. Currently, two separate Actions, namely Scaling In and Out are supported, triggered through Thresholds defined on a given Metric.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"metric": {
Computed: true,
Type: schema.TypeString,
Description: "The Metric that should trigger the scaling actions. Metric values are checked at fixed intervals.",
},
"range": {
Computed: true,
Type: schema.TypeString,
Description: "Defines the time range, for which the samples will be aggregated. Default is 120s.",
},
"scale_in_action": {
Computed: true,
Type: schema.TypeList,
Description: "Specifies the action to take when the `scaleInThreshold` is exceeded. Hereby, scaling in is always about removing VMs that are currently associated with this autoscaling group. Default termination policy is OLDEST_SERVER_FIRST.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"amount": {
Computed: true,
Type: schema.TypeInt,
Description: "When 'amountType=ABSOLUTE' specifies the absolute number of VMs that are removed. The value must be between 1 to 10. 'amountType=PERCENTAGE' specifies the percentage value that is applied to the current number of replicas of the VM Auto Scaling Group. The value must be between 1 to 200. At least one VM is always removed. Note that for 'SCALE_IN' operations, volumes are not deleted after the server is deleted.",
},
"amount_type": {
Computed: true,
Type: schema.TypeString,
Description: "The type for the given amount. Possible values are: [ABSOLUTE, PERCENTAGE].",
},
"termination_policy_type": {
Computed: true,
Type: schema.TypeString,
Description: "The type of the termination policy for the autoscaling group so that a specific pattern is followed for Scaling-In instances. Default termination policy is OLDEST_SERVER_FIRST.",
},
"cooldown_period": {
Computed: true,
Type: schema.TypeString,
Description: "Minimum time to pass after this Scaling action has started, until the next Scaling action will be started. Additionally, if a Scaling action is currently in progress, no second Scaling action will be started for the same autoscaling group. Instead, the Metric will be re-evaluated after the current Scaling action is completed (either successfully or with failures). This is validated with a minimum value of 2 minutes and a maximum of 24 hours currently. Default value is 5 minutes if not given.",
},
"delete_volumes": {
Computed: true,
Type: schema.TypeBool,
Description: "If set to 'true', when deleting an replica during scale in, any attached volume will also be deleted. When set to 'false', all volumes remain in the datacenter and must be deleted manually. Note that every scale-out creates new volumes. When they are not deleted, they will eventually use all of your contracts resource limits. At this point, scaling out would not be possible anymore.",
},
},
},
},
"scale_in_threshold": {
Computed: true,
Type: schema.TypeInt,
Description: "The lower threshold for the value of the `metric`. Will be used with `less than` (<) operator. Exceeding this will start a Scale-In action as specified by the `scaleInAction` property. The value must have a higher minimum delta to the `scaleOutThreshold` depending on the `metric` to avoid competitive actions at the same time.",
},
"scale_out_action": {
Computed: true,
Type: schema.TypeList,
Description: "Specifies the action to take when the `scaleOutThreshold` is exceeded. Hereby, scaling out is always about adding new VMs to this autoscaling group.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"amount": {
Computed: true,
Type: schema.TypeInt,
Description: "When 'amountType=ABSOLUTE' specifies the absolute number of VMs that are added. The value must be between 1 to 10. 'amountType=PERCENTAGE' specifies the percentage value that is applied to the current number of replicas of the VM Auto Scaling Group. The value must be between 1 to 200. At least one VM is always added. Note that for 'SCALE_IN' operations, volumes are not deleted after the server is deleted.",
},
"amount_type": {
Computed: true,
Type: schema.TypeString,
Description: "The type for the given amount. Possible values are: [ABSOLUTE, PERCENTAGE].",
},
"cooldown_period": {
Computed: true,
Type: schema.TypeString,
Description: "Minimum time to pass after this Scaling action has started, until the next Scaling action will be started. Additionally, if a Scaling action is currently in progress, no second Scaling action will be started for the same autoscaling group. Instead, the Metric will be re-evaluated after the current Scaling action is completed (either successfully or with failures). This is validated with a minimum value of 2 minutes and a maximum of 24 hours currently. Default value is 5 minutes if not given.",
},
},
},
},
"scale_out_threshold": {
Computed: true,
Type: schema.TypeInt,
Description: "The upper threshold for the value of the `metric`. Will be used with `greater than` (>) operator. Exceeding this will start a Scale-Out action as specified by the `scaleOutAction` property. The value must have a lower minimum delta to the `scaleInThreshold` depending on the `metric` to avoid competitive actions at the same time.",
},
"unit": {
Computed: true,
Type: schema.TypeString,
Description: "Units of the applied Metric. Possible values are: PER_HOUR, PER_MINUTE, PER_SECOND, TOTAL.",
},
},
},
},
"replica_configuration": {
Type: schema.TypeList,
Description: "VMs for this Autoscaling Group will be created in this Virtual Datacenter. Please note, that it has to have the same `location` as the `template`.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"availability_zone": {
Computed: true,
Type: schema.TypeString,
Description: "The zone where the VMs are created using this configuration.",
},
"cores": {
Computed: true,
Type: schema.TypeInt,
Description: "The total number of cores for the VMs.",
},
"cpu_family": {
Computed: true,
Type: schema.TypeString,
Description: "The zone where the VMs are created using this configuration.",
},
"nic": {
Type: schema.TypeSet,
Description: "List of NICs associated with this Replica.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"lan": {
Computed: true,
Type: schema.TypeInt,
Description: "Lan ID for this replica Nic.",
},
"name": {
Computed: true,
Type: schema.TypeString,
Description: "Name for this replica NIC.",
},
"dhcp": {
Computed: true,
Type: schema.TypeBool,
Description: "Dhcp flag for this replica Nic. This is an optional attribute with default value of 'true' if not given in the request payload or given as null.",
},
}},
},
"ram": {
Computed: true,
Type: schema.TypeInt,
Description: "The amount of memory for the VMs in MB, e.g. 2048. Size must be specified in multiples of 256 MB with a minimum of 256 MB; however, if you set ramHotPlug to TRUE then you must use a minimum of 1024 MB. If you set the RAM size more than 240GB, then ramHotPlug will be set to FALSE and can not be set to TRUE unless RAM size not set to less than 240GB.",
},
"volume": {
Type: schema.TypeSet,
Description: "List of volumes associated with this Replica. Only a single volume is currently supported.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"image": {
Computed: true,
Type: schema.TypeString,
Description: "The image installed on the volume. Only the UUID of the image is presently supported.",
},
"image_alias": {
Computed: true,
Type: schema.TypeString,
Description: "The image installed on the volume. Must be an 'imageAlias' as specified via the images API.",
},
"name": {
Computed: true,
Type: schema.TypeString,
Description: "Name for this replica volume.",
},
"size": {
Computed: true,
Type: schema.TypeInt,
Description: "User-defined size for this replica volume in GB.",
},
"ssh_keys": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
"type": {
Computed: true,
Type: schema.TypeString,
Description: "Storage Type for this replica volume. Possible values: SSD, HDD, SSD_STANDARD or SSD_PREMIUM",
},
"boot_order": {
Computed: true,
Type: schema.TypeString,
Description: `Determines whether the volume will be used as a boot volume: NONE - the volume will not be used as boot volume, PRIMARY - the volume will be used as boot volume, AUTO - will delegate the decision to the provisioning engine to decide whether to use the volume as boot volume.`,
},
"bus": {
Computed: true,
Type: schema.TypeString,
Description: `The bus type of the volume. Default setting is 'VIRTIO'. The bus type 'IDE' is also supported.`,
},
"backup_unit_id": {
Computed: true,
Type: schema.TypeString,
Description: "The uuid of the Backup Unit that user has access to.",
},
}},
},
},
},
},
"datacenter_id": {
Type: schema.TypeString,
Description: "Unique identifier for the resource",
Computed: true,
},
"location": {
Type: schema.TypeString,
Description: "Location of the data center.",
Computed: true,
},
},
Timeouts: &resourceDefaultTimeouts,
}
}
func dataSourceAutoscalingGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(services.SdkBundle).AutoscalingClient
id, idOk := d.GetOk("id")
name, nameOk := d.GetOk("name")
if idOk && nameOk {
return diag.FromErr(fmt.Errorf("id and name cannot be both specified at the same time"))
}
if !idOk && !nameOk {
return diag.FromErr(fmt.Errorf("please provide either the group id or name"))
}
var group autoscaling.Group
var err error
if idOk {
group, _, err = client.GetGroup(ctx, id.(string), 2)
if err != nil {
return diag.FromErr(fmt.Errorf("an error occurred while fetching group with ID %s: %w", id.(string), err))
}
} else {
groups, _, err := client.ListGroups(ctx)
if err != nil {
return diag.FromErr(fmt.Errorf("an error occurred while getting groups: %w", err))
}
var results []autoscaling.Group
if groups.Items != nil {
for _, g := range *groups.Items {
// TODO: this will not be necessary once the swagger is fixed and list returns the full properties
if g.Id == nil {
return diag.FromErr(fmt.Errorf("expected a valid ID for the Autoscaling Group, but received 'nil' instead"))
}
tmpGroup, _, err := client.GetGroup(ctx, *g.Id, 2)
if err != nil {
return diag.FromErr(fmt.Errorf("an error occurred while fetching group %s: %w", *g.Id, err))
}
if tmpGroup.Properties != nil && tmpGroup.Properties.Name != nil && strings.EqualFold(*tmpGroup.Properties.Name, name.(string)) {
results = append(results, tmpGroup)
break
}
}
}
if results == nil || len(results) == 0 {
return diag.FromErr(fmt.Errorf("no group found with the specified criteria: name = %s", name.(string)))
} else {
group = results[0]
}
}
if group.Id == nil {
return diag.FromErr(fmt.Errorf("expected a valid ID for the Autoscaling Group, but received 'nil' instead"))
}
d.SetId(*group.Id)
if err := autoscalingService.SetAutoscalingGroupData(d, group.Properties); err != nil {
return diag.FromErr(err)
}
return nil
}