Skip to content

Cloud: Better errors #1329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions internal/resources/cloud/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cloud

import (
"github.com/grafana/grafana-com-public-clients/go/gcom"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
)

func clientRequestID() string {
uuid, err := uuid.GenerateUUID()
if err != nil {
return ""
}
return "tf-" + uuid
}

func apiError(err error) diag.Diagnostics {
if err == nil {
return nil
}
detail := err.Error()
if err, ok := err.(*gcom.GenericOpenAPIError); ok {
detail += "\n" + string(err.Body())
}
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Error,
Summary: err.Error(),
Detail: detail,
},
}
}
2 changes: 1 addition & 1 deletion internal/resources/cloud/data_source_cloud_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func DataSourceOrganizationRead(ctx context.Context, d *schema.ResourceData, met
}
org, err := client.GetCloudOrg(id)
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

id = strconv.FormatInt(org.ID, 10)
Expand Down
2 changes: 1 addition & 1 deletion internal/resources/cloud/data_source_cloud_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func DataSourceStackRead(ctx context.Context, d *schema.ResourceData, meta inter
req := client.InstancesAPI.GetInstance(ctx, slug)
stack, _, err := req.Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

if err := FlattenStack(d, stack); err != nil {
Expand Down
11 changes: 0 additions & 11 deletions internal/resources/cloud/request_id.go

This file was deleted.

6 changes: 3 additions & 3 deletions internal/resources/cloud/resource_cloud_access_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func CreateCloudAccessPolicy(ctx context.Context, d *schema.ResourceData, meta i
Realms: expandCloudAccessPolicyRealm(d.Get("realm").(*schema.Set).List()),
})
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

d.SetId(fmt.Sprintf("%s/%s", region, result.ID))
Expand All @@ -158,7 +158,7 @@ func UpdateCloudAccessPolicy(ctx context.Context, d *schema.ResourceData, meta i
Realms: expandCloudAccessPolicyRealm(d.Get("realm").(*schema.Set).List()),
})
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

return ReadCloudAccessPolicy(ctx, d, meta)
Expand Down Expand Up @@ -188,7 +188,7 @@ func ReadCloudAccessPolicy(ctx context.Context, d *schema.ResourceData, meta int
func DeleteCloudAccessPolicy(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*common.Client).GrafanaCloudAPI
region, id, _ := strings.Cut(d.Id(), "/")
return diag.FromErr(client.DeleteCloudAccessPolicy(region, id))
return apiError(client.DeleteCloudAccessPolicy(region, id))
}

func validateCloudAccessPolicyScope(v interface{}, path cty.Path) diag.Diagnostics {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func CreateCloudAccessPolicyToken(ctx context.Context, d *schema.ResourceData, m

result, err := client.CreateCloudAccessPolicyToken(region, tokenInput)
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

d.SetId(fmt.Sprintf("%s/%s", region, result.ID))
Expand All @@ -130,7 +130,7 @@ func UpdateCloudAccessPolicyToken(ctx context.Context, d *schema.ResourceData, m
DisplayName: displayName,
})
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

return ReadCloudAccessPolicyToken(ctx, d, meta)
Expand Down Expand Up @@ -165,5 +165,5 @@ func DeleteCloudAccessPolicyToken(ctx context.Context, d *schema.ResourceData, m
client := meta.(*common.Client).GrafanaCloudAPI
region, id, _ := strings.Cut(d.Id(), "/")

return diag.FromErr(client.DeleteCloudAccessPolicyToken(region, id))
return apiError(client.DeleteCloudAccessPolicyToken(region, id))
}
6 changes: 3 additions & 3 deletions internal/resources/cloud/resource_cloud_api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func ResourceAPIKeyCreate(ctx context.Context, d *schema.ResourceData, meta inte
XRequestId(clientRequestID()).
Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

d.Set("key", *resp.Token)
Expand All @@ -90,7 +90,7 @@ func ResourceAPIKeyRead(ctx context.Context, d *schema.ResourceData, meta interf

resp, _, err := c.OrgsAPI.GetApiKey(ctx, name, org).Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

d.Set("name", resp.Name)
Expand All @@ -105,5 +105,5 @@ func ResourceAPIKeyDelete(ctx context.Context, d *schema.ResourceData, meta inte

_, err := c.OrgsAPI.DelApiKey(ctx, d.Get("name").(string), d.Get("cloud_org_slug").(string)).XRequestId(clientRequestID()).Execute()
d.SetId("")
return diag.FromErr(err)
return apiError(err)
}
4 changes: 2 additions & 2 deletions internal/resources/cloud/resource_cloud_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func ResourcePluginInstallationCreate(ctx context.Context, d *schema.ResourceDat
PostInstancePluginsRequest(req).
XRequestId(clientRequestID()).Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

d.SetId(stackSlug + "_" + pluginSlug)
Expand Down Expand Up @@ -94,5 +94,5 @@ func ResourcePluginInstallationDelete(ctx context.Context, d *schema.ResourceDat
stackSlug, pluginSlug := splitID[0], splitID[1]

_, _, err := client.InstancesAPI.DeleteInstancePlugin(ctx, stackSlug, pluginSlug).XRequestId(clientRequestID()).Execute()
return diag.FromErr(err)
return apiError(err)
}
8 changes: 4 additions & 4 deletions internal/resources/cloud/resource_cloud_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func CreateStack(ctx context.Context, d *schema.ResourceData, meta interface{})
// It may also mean that the stack was recently deleted and is still in the process of being deleted
// In that case, we want to retry
time.Sleep(10 * time.Second) // Do not retry too fast, default is 500ms
return retry.RetryableError(fmt.Errorf("a stack with the name '%s' already exists: %w", stack.Name, err))
return retry.RetryableError(err)
case err != nil:
// If we had an error that isn't a a conflict error (already exists), try to read the stack
// Sometimes, the stack is created but the API returns an error (e.g. 504)
Expand All @@ -289,7 +289,7 @@ func CreateStack(ctx context.Context, d *schema.ResourceData, meta interface{})
return nil
})
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

if diag := ReadStack(ctx, d, meta); diag != nil {
Expand Down Expand Up @@ -318,7 +318,7 @@ func UpdateStack(ctx context.Context, d *schema.ResourceData, meta interface{})
req := client.InstancesAPI.PostInstance(ctx, d.Id()).PostInstanceRequest(stack).XRequestId(clientRequestID())
_, _, err := req.Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}
}

Expand All @@ -333,7 +333,7 @@ func DeleteStack(ctx context.Context, d *schema.ResourceData, meta interface{})
client := meta.(*common.Client).GrafanaCloudAPIOpenAPI
req := client.InstancesAPI.DeleteInstance(ctx, d.Id()).XRequestId(clientRequestID())
_, _, err := req.Execute()
return diag.FromErr(err)
return apiError(err)
}

func ReadStack(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
Expand Down
2 changes: 1 addition & 1 deletion internal/resources/cloud/resource_cloud_stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestResourceStack_Basic(t *testing.T) {
{
Config: testAccStackConfigBasic(resourceName, resourceName, stackDescription) +
testAccStackConfigBasicWithCustomResourceName(resourceName, resourceName, "eu", "test2", stackDescription), // new stack with same name/slug
ExpectError: regexp.MustCompile(fmt.Sprintf(".*a stack with the name '%s' already exists.*", resourceName)),
ExpectError: regexp.MustCompile(".*That URL has already been taken.*"),
},
// Test that the stack is correctly recreated if it's tainted and reapplied
// This is a special case because stack deletion is asynchronous
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func ResourceInstallationCreate(ctx context.Context, d *schema.ResourceData, met
req := cloudClient.InstancesAPI.GetInstance(ctx, d.Get("stack_id").(string))
stack, _, err := req.Execute()
if err != nil {
return diag.FromErr(err)
return apiError(err)
}

// TODO: Get this URL programatically
Expand Down