Skip to content

Commit e35a7f0

Browse files
Cloud stack: Allow read operations from either slug or ID (#884)
* Cloud stack: Allow read operations from either slug or ID Currently, the logic is in the importer but that doesn't work for Crossplane that doesn't use import but instead seems to custom build a state This will be functionally the same but the slug is now usable at all points in the process, instead of being translated in the importer * Remove `SetID` * Oops * Fixed it for real now. Tests pass
1 parent 1668229 commit e35a7f0

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

internal/resources/cloud/resource_cloud_stack.go

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,8 @@ func ResourceStack() *schema.Resource {
3636
UpdateContext: UpdateStack,
3737
DeleteContext: DeleteStack,
3838
ReadContext: ReadStack,
39-
40-
// Import either by ID or slug
4139
Importer: &schema.ResourceImporter{
42-
StateContext: func(c context.Context, rd *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
43-
_, err := strconv.ParseInt(rd.Id(), 10, 64)
44-
if err != nil {
45-
// If the ID is not a number, then it may be a slug
46-
client := meta.(*common.Client).GrafanaCloudAPI
47-
stack, err := client.StackBySlug(rd.Id())
48-
if err != nil {
49-
return nil, fmt.Errorf("failed to find stack by ID or slug '%s': %w", rd.Id(), err)
50-
}
51-
rd.SetId(strconv.FormatInt(stack.ID, 10))
52-
}
53-
return []*schema.ResourceData{rd}, nil
54-
},
40+
StateContext: schema.ImportStatePassthroughContext,
5541
},
5642

5743
Schema: map[string]*schema.Schema{
@@ -308,8 +294,7 @@ func UpdateStack(ctx context.Context, d *schema.ResourceData, meta interface{})
308294

309295
func DeleteStack(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
310296
client := meta.(*common.Client).GrafanaCloudAPI
311-
slug := d.Get("slug").(string)
312-
if err := client.DeleteStack(slug); err != nil {
297+
if err := client.DeleteStack(d.Id()); err != nil {
313298
return diag.FromErr(err)
314299
}
315300

@@ -318,14 +303,8 @@ func DeleteStack(ctx context.Context, d *schema.ResourceData, meta interface{})
318303

319304
func ReadStack(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
320305
client := meta.(*common.Client).GrafanaCloudAPI
306+
stack, err := getStackFromIDOrSlug(client, d.Id())
321307

322-
idStr := d.Id()
323-
id, err := strconv.ParseInt(idStr, 10, 64)
324-
if err != nil {
325-
return diag.Errorf("Invalid id: %#v", idStr)
326-
}
327-
328-
stack, err := client.StackByID(id)
329308
if err != nil {
330309
if strings.HasPrefix(err.Error(), "status: 404") {
331310
log.Printf("[WARN] removing stack %s from state because it no longer exists in grafana", d.Get("name").(string))
@@ -341,7 +320,7 @@ func ReadStack(ctx context.Context, d *schema.ResourceData, meta interface{}) di
341320
return nil
342321
}
343322

344-
if err := FlattenStack(d, stack); err != nil {
323+
if err := FlattenStack(d, *stack); err != nil {
345324
return diag.FromErr(err)
346325
}
347326
// Always set the wait attribute to true after creation
@@ -353,7 +332,6 @@ func ReadStack(ctx context.Context, d *schema.ResourceData, meta interface{}) di
353332

354333
func FlattenStack(d *schema.ResourceData, stack gapi.Stack) error {
355334
id := strconv.FormatInt(stack.ID, 10)
356-
357335
d.SetId(id)
358336
d.Set("name", stack.Name)
359337
d.Set("slug", stack.Slug)
@@ -404,6 +382,25 @@ func FlattenStack(d *schema.ResourceData, stack gapi.Stack) error {
404382
return nil
405383
}
406384

385+
func getStackFromIDOrSlug(client *gapi.Client, id string) (*gapi.Stack, error) {
386+
numericalID, err := strconv.ParseInt(id, 10, 64)
387+
if err != nil {
388+
// If the ID is not a number, then it may be a slug
389+
stack, err := client.StackBySlug(id)
390+
if err != nil {
391+
return nil, fmt.Errorf("failed to find stack by ID or slug '%s': %w", id, err)
392+
}
393+
return &stack, nil
394+
}
395+
396+
stack, err := client.StackByID(numericalID)
397+
if err != nil {
398+
return nil, err
399+
}
400+
401+
return &stack, nil
402+
}
403+
407404
// Append path to baseurl
408405
func appendPath(baseURL, path string) (string, error) {
409406
bu, err := url.Parse(baseURL)

internal/resources/cloud/resource_cloud_stack_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cloud_test
33
import (
44
"fmt"
55
"strings"
6+
"time"
67

78
"strconv"
89
"testing"
@@ -53,6 +54,7 @@ func TestResourceStack_Basic(t *testing.T) {
5354
// Terraform should detect that it's gone and recreate it (status should be active at all times)
5455
PreConfig: func() {
5556
testAccDeleteExistingStacks(t, prefix)
57+
time.Sleep(10 * time.Second)
5658
},
5759
Config: testAccStackConfigBasic(resourceName, resourceName),
5860
Check: resource.ComposeTestCheckFunc(
@@ -74,6 +76,7 @@ func TestResourceStack_Basic(t *testing.T) {
7476
resource.TestCheckResourceAttr("grafana_cloud_stack.test", "status", "active"),
7577
),
7678
},
79+
// Test import from ID
7780
{
7881
ResourceName: "grafana_cloud_stack.test",
7982
ImportState: true,

0 commit comments

Comments
 (0)