• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Scalr / terraform-provider-scalr / 13264987980

11 Feb 2025 02:17PM UTC coverage: 70.922% (+0.03%) from 70.894%
13264987980

Pull #395

github

denkl
SCALRCORE-32832 API > Environments > Cleanup EOL policy-groups relationship
Pull Request #395: SCALRCORE-32832 API > Environments > Cleanup EOL policy-groups relati…

2 of 3 new or added lines in 1 file covered. (66.67%)

24 existing lines in 1 file now uncovered.

7334 of 10341 relevant lines covered (70.92%)

167.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.65
/internal/provider/resource_scalr_environment.go
1
package provider
2

3
import (
4
        "context"
5
        "errors"
6
        "log"
7

8
        "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
9

10
        "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11
        "github.com/scalr/go-scalr"
12
)
13

14
func resourceScalrEnvironment() *schema.Resource {
96✔
15
        return &schema.Resource{
96✔
16
                Description:   "Manage the state of environments in Scalr. Creates, updates and destroys.",
96✔
17
                CreateContext: resourceScalrEnvironmentCreate,
96✔
18
                ReadContext:   resourceScalrEnvironmentRead,
96✔
19
                DeleteContext: resourceScalrEnvironmentDelete,
96✔
20
                UpdateContext: resourceScalrEnvironmentUpdate,
96✔
21
                Importer: &schema.ResourceImporter{
96✔
22
                        StateContext: schema.ImportStatePassthroughContext,
96✔
23
                },
96✔
24

96✔
25
                Schema: map[string]*schema.Schema{
96✔
26
                        "name": {
96✔
27
                                Description: "Name of the environment.",
96✔
28
                                Type:        schema.TypeString,
96✔
29
                                Required:    true,
96✔
30
                        },
96✔
31
                        "cost_estimation_enabled": {
96✔
32
                                Description: "Set (true/false) to enable/disable cost estimation for the environment.",
96✔
33
                                Type:        schema.TypeBool,
96✔
34
                                Computed:    true,
96✔
35
                                Optional:    true,
96✔
36
                                Deprecated:  "Managing cost estimation is deprecated. Use Infracost integration instead.",
96✔
37
                        },
96✔
38
                        "status": {
96✔
39
                                Description: "The status of the environment.",
96✔
40
                                Type:        schema.TypeString,
96✔
41
                                Computed:    true,
96✔
42
                        },
96✔
43
                        "created_by": {
96✔
44
                                Description: "Details of the user that created the environment.",
96✔
45
                                Type:        schema.TypeList,
96✔
46
                                Computed:    true,
96✔
47
                                Elem: &schema.Resource{
96✔
48
                                        Schema: map[string]*schema.Schema{
96✔
49
                                                "username": {
96✔
50
                                                        Description: "Username of creator.",
96✔
51
                                                        Type:        schema.TypeString,
96✔
52
                                                        Computed:    true,
96✔
53
                                                },
96✔
54
                                                "email": {
96✔
55
                                                        Description: "Email address of creator.",
96✔
56
                                                        Type:        schema.TypeString,
96✔
57
                                                        Computed:    true,
96✔
58
                                                },
96✔
59
                                                "full_name": {
96✔
60
                                                        Description: "Full name of creator.",
96✔
61
                                                        Type:        schema.TypeString,
96✔
62
                                                        Computed:    true,
96✔
63
                                                },
96✔
64
                                        },
96✔
65
                                },
96✔
66
                        },
96✔
67
                        "account_id": {
96✔
68
                                Description: "ID of the environment account, in the format `acc-<RANDOM STRING>`.",
96✔
69
                                Type:        schema.TypeString,
96✔
70
                                Optional:    true,
96✔
71
                                Computed:    true,
96✔
72
                                DefaultFunc: scalrAccountIDDefaultFunc,
96✔
73
                                ForceNew:    true,
96✔
74
                        },
96✔
75
                        "default_provider_configurations": {
96✔
76
                                Description: "List of IDs of provider configurations, used in the environment workspaces by default.",
96✔
77
                                Type:        schema.TypeSet,
96✔
78
                                Optional:    true,
96✔
79
                                Elem:        &schema.Schema{Type: schema.TypeString},
96✔
80
                                Computed:    true,
96✔
81
                        },
96✔
82
                        "tag_ids": {
96✔
83
                                Description: "List of tag IDs associated with the environment.",
96✔
84
                                Type:        schema.TypeSet,
96✔
85
                                Optional:    true,
96✔
86
                                Computed:    true,
96✔
87
                                Elem:        &schema.Schema{Type: schema.TypeString},
96✔
88
                        },
96✔
89
                        "remote_backend": {
96✔
90
                                Description: "If Scalr exports the remote backend configuration and state storage for your infrastructure management. Disabling this feature will also prevent the ability to perform state locking, which ensures that concurrent operations do not conflict. Additionally, it will disable the capability to initiate CLI-driven runs through Scalr.",
96✔
91
                                Type:        schema.TypeBool,
96✔
92
                                Optional:    true,
96✔
93
                                Computed:    true,
96✔
94
                                ForceNew:    true,
96✔
95
                        },
96✔
96
                },
96✔
97
        }
96✔
98
}
96✔
99

100
func resourceScalrEnvironmentCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
46✔
101
        scalrClient := meta.(*scalr.Client)
46✔
102

46✔
103
        name := d.Get("name").(string)
46✔
104
        accountID := d.Get("account_id").(string)
46✔
105

46✔
106
        options := scalr.EnvironmentCreateOptions{
46✔
107
                Name:    ptr(name),
46✔
108
                Account: &scalr.Account{ID: accountID},
46✔
109
        }
46✔
110
        if costEstimationEnabled, ok := d.GetOkExists("cost_estimation_enabled"); ok { //nolint:staticcheck
51✔
111
                options.CostEstimationEnabled = ptr(costEstimationEnabled.(bool))
5✔
112
        }
5✔
113
        if remoteBackend, ok := d.GetOkExists("remote_backend"); ok { //nolint:staticcheck
48✔
114
                options.RemoteBackend = ptr(remoteBackend.(bool))
2✔
115
        }
2✔
116

117
        if defaultProviderConfigurationsI, ok := d.GetOk("default_provider_configurations"); ok {
47✔
118
                defaultProviderConfigurations := defaultProviderConfigurationsI.(*schema.Set).List()
1✔
119
                pcfgValues := make([]*scalr.ProviderConfiguration, 0)
1✔
120
                for _, pcfg := range defaultProviderConfigurations {
2✔
121
                        pcfgValues = append(pcfgValues, &scalr.ProviderConfiguration{ID: pcfg.(string)})
1✔
122
                }
1✔
123
                options.DefaultProviderConfigurations = pcfgValues
1✔
124

125
        }
126
        if tagIDs, ok := d.GetOk("tag_ids"); ok {
49✔
127
                tagIDsList := tagIDs.(*schema.Set).List()
3✔
128
                tags := make([]*scalr.Tag, len(tagIDsList))
3✔
129
                for i, id := range tagIDsList {
8✔
130
                        tags[i] = &scalr.Tag{ID: id.(string)}
5✔
131
                }
5✔
132
                options.Tags = tags
3✔
133
        }
134

135
        log.Printf("[DEBUG] Create Environment %s for account: %s", name, accountID)
46✔
136
        environment, err := scalrClient.Environments.Create(ctx, options)
46✔
137
        if err != nil {
46✔
UNCOV
138
                return diag.Errorf(
×
UNCOV
139
                        "Error creating Environment %s for account %s: %v", name, accountID, err)
×
UNCOV
140
        }
×
141
        d.SetId(environment.ID)
46✔
142
        return resourceScalrEnvironmentRead(ctx, d, meta)
46✔
143
}
144

145
func resourceScalrEnvironmentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
144✔
146
        scalrClient := meta.(*scalr.Client)
144✔
147

144✔
148
        environmentID := d.Id()
144✔
149

144✔
150
        log.Printf("[DEBUG] Read configuration of environment: %s", environmentID)
144✔
151
        environment, err := scalrClient.Environments.Read(ctx, environmentID)
144✔
152
        if err != nil {
144✔
UNCOV
153
                if errors.Is(err, scalr.ErrResourceNotFound) {
×
UNCOV
154
                        // If the resource isn't available, the function should set the ID
×
UNCOV
155
                        // to an empty string so Terraform "destroys" the resource in state.
×
UNCOV
156
                        d.SetId("")
×
UNCOV
157
                        return nil
×
UNCOV
158
                }
×
159
                return diag.Errorf("Error reading environment %s: %v", environmentID, err)
×
160
        }
161

162
        // Update the configuration.
163
        _ = d.Set("name", environment.Name)
144✔
164
        _ = d.Set("account_id", environment.Account.ID)
144✔
165
        _ = d.Set("cost_estimation_enabled", environment.CostEstimationEnabled)
144✔
166
        _ = d.Set("remote_backend", environment.RemoteBackend)
144✔
167
        _ = d.Set("status", environment.Status)
144✔
168

144✔
169
        defaultProviderConfigurations := make([]string, 0)
144✔
170
        for _, providerConfiguration := range environment.DefaultProviderConfigurations {
152✔
171
                defaultProviderConfigurations = append(defaultProviderConfigurations, providerConfiguration.ID)
8✔
172
        }
8✔
173
        _ = d.Set("default_provider_configurations", defaultProviderConfigurations)
144✔
174

144✔
175
        var createdBy []interface{}
144✔
176
        if environment.CreatedBy != nil {
288✔
177
                createdBy = append(createdBy, map[string]interface{}{
144✔
178
                        "username":  environment.CreatedBy.Username,
144✔
179
                        "email":     environment.CreatedBy.Email,
144✔
180
                        "full_name": environment.CreatedBy.FullName,
144✔
181
                })
144✔
182
        }
144✔
183
        _ = d.Set("created_by", createdBy)
144✔
184

144✔
185
        var tagIDs []string
144✔
186
        if len(environment.Tags) != 0 {
150✔
187
                for _, tag := range environment.Tags {
16✔
188
                        tagIDs = append(tagIDs, tag.ID)
10✔
189
                }
10✔
190
        }
191
        _ = d.Set("tag_ids", tagIDs)
144✔
192

144✔
193
        return nil
144✔
194
}
195

196
func resourceScalrEnvironmentUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
2✔
197
        scalrClient := meta.(*scalr.Client)
2✔
198

2✔
199
        var err error
2✔
200

2✔
201
        // Create a new options struct.
2✔
202
        options := scalr.EnvironmentUpdateOptions{
2✔
203
                Name: ptr(d.Get("name").(string)),
2✔
204
        }
2✔
205
        if costEstimationEnabled, ok := d.GetOkExists("cost_estimation_enabled"); ok { //nolint:staticcheck
4✔
206
                options.CostEstimationEnabled = ptr(costEstimationEnabled.(bool))
2✔
207
        }
2✔
208

209
        if defaultProviderConfigurationsI, ok := d.GetOk("default_provider_configurations"); ok {
3✔
210
                defaultProviderConfigurations := defaultProviderConfigurationsI.(*schema.Set).List()
1✔
211
                pcfgValues := make([]*scalr.ProviderConfiguration, 0)
1✔
212
                for _, pcfg := range defaultProviderConfigurations {
2✔
213
                        pcfgValues = append(pcfgValues, &scalr.ProviderConfiguration{ID: pcfg.(string)})
1✔
214
                }
1✔
215
                options.DefaultProviderConfigurations = pcfgValues
1✔
216
        } else {
1✔
217
                options.DefaultProviderConfigurations = make([]*scalr.ProviderConfiguration, 0)
1✔
218
        }
1✔
219

220
        log.Printf("[DEBUG] Update environment: %s", d.Id())
2✔
221
        _, err = scalrClient.Environments.Update(ctx, d.Id(), options)
2✔
222
        if err != nil {
2✔
UNCOV
223
                return diag.Errorf("Error updating environment %s: %v", d.Id(), err)
×
UNCOV
224
        }
×
225

226
        if d.HasChange("tag_ids") {
2✔
NEW
227
                oldTags, newTags := d.GetChange("tag_ids")
×
UNCOV
228
                oldSet := oldTags.(*schema.Set)
×
UNCOV
229
                newSet := newTags.(*schema.Set)
×
UNCOV
230
                tagsToAdd := InterfaceArrToTagRelationArr(newSet.Difference(oldSet).List())
×
UNCOV
231
                tagsToDelete := InterfaceArrToTagRelationArr(oldSet.Difference(newSet).List())
×
UNCOV
232

×
UNCOV
233
                if len(tagsToAdd) > 0 {
×
UNCOV
234
                        err := scalrClient.EnvironmentTags.Add(ctx, d.Id(), tagsToAdd)
×
UNCOV
235
                        if err != nil {
×
UNCOV
236
                                return diag.Errorf(
×
237
                                        "Error adding tags to environment %s: %v", d.Id(), err)
×
238
                        }
×
239
                }
240

241
                if len(tagsToDelete) > 0 {
×
242
                        err := scalrClient.EnvironmentTags.Delete(ctx, d.Id(), tagsToDelete)
×
243
                        if err != nil {
×
244
                                return diag.Errorf(
×
245
                                        "Error deleting tags from environment %s: %v", d.Id(), err)
×
246
                        }
×
247
                }
248
        }
249

250
        return resourceScalrEnvironmentRead(ctx, d, meta)
2✔
251
}
252

253
func resourceScalrEnvironmentDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
47✔
254
        scalrClient := meta.(*scalr.Client)
47✔
255
        environmentID := d.Id()
47✔
256

47✔
257
        log.Printf("[DEBUG] Delete environment %s", environmentID)
47✔
258
        err := scalrClient.Environments.Delete(ctx, d.Id())
47✔
259
        if err != nil {
47✔
260
                if errors.Is(err, scalr.ErrResourceNotFound) {
×
UNCOV
261
                        return nil
×
UNCOV
262
                }
×
UNCOV
263
                return diag.Errorf(
×
UNCOV
264
                        "Error deleting environment %s: %v", environmentID, err)
×
265
        }
266

267
        return nil
47✔
268
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc