Skip to content

Commit

Permalink
Folder: Clean up API calls (#1123)
Browse files Browse the repository at this point in the history
- Use ID instead of UID in helper. This should match the actual TF ID
- Use the new client for dashboard search
- Do not list folders, use get by ID instead. The API has been fixed
  • Loading branch information
julienduchesne authored Nov 7, 2023
1 parent a8b847f commit c284510
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 33 deletions.
13 changes: 10 additions & 3 deletions internal/resources/grafana/common_check_exists_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
gapi "github.com/grafana/grafana-api-golang-client"
goapi "github.com/grafana/grafana-openapi-client-go/client"
"github.com/grafana/grafana-openapi-client-go/client/annotations"
"github.com/grafana/grafana-openapi-client-go/client/folders"
"github.com/grafana/grafana-openapi-client-go/client/teams"
"github.com/grafana/grafana-openapi-client-go/models"
"github.com/grafana/terraform-provider-grafana/internal/common"
Expand All @@ -31,9 +32,15 @@ var (
},
)
folderCheckExists = newCheckExistsHelper(
func(f *models.Folder) string { return f.UID },
func(f *models.Folder) string { return strconv.FormatInt(f.ID, 10) },
func(client *goapi.GrafanaHTTPAPI, id string) (*models.Folder, error) {
return grafana.GetFolderByIDorUID(client.Folders, id)
idInt, _ := strconv.ParseInt(id, 10, 64)
params := folders.NewGetFolderByIDParams().WithFolderID(idInt)
folder, err := client.Folders.GetFolderByID(params, nil)
if err != nil {
return nil, err
}
return folder.GetPayload(), nil
},
)
teamCheckExists = newCheckExistsHelper(
Expand Down Expand Up @@ -110,7 +117,7 @@ func (h *checkExistsHelper[T]) destroyed(v *T, org *gapi.Org) resource.TestCheck
id := h.getIDFunc(v)
_, err := h.getResourceFunc(client, id)
if err == nil {
return fmt.Errorf("resource %s still exists in org %d", id, orgID)
return fmt.Errorf("%T %s still exists in org %d", v, id, orgID)
} else if !common.IsNotFoundError(err) {
return fmt.Errorf("error checking if resource %s exists in org %d: %s", id, orgID, err)
}
Expand Down
51 changes: 21 additions & 30 deletions internal/resources/grafana/resource_folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package grafana
import (
"context"
"encoding/json"
"net/url"
"strconv"

gapi "github.com/grafana/grafana-api-golang-client"
goapi "github.com/grafana/grafana-openapi-client-go/client/folders"
"github.com/grafana/grafana-openapi-client-go/client/search"
"github.com/grafana/grafana-openapi-client-go/models"

"github.com/grafana/terraform-provider-grafana/internal/common"
Expand Down Expand Up @@ -127,37 +126,34 @@ func ReadFolder(ctx context.Context, d *schema.ResourceData, meta interface{}) d
}

func DeleteFolder(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
deleteParams := []url.Values{}
client, _, idStr := OAPIClientFromExistingOrgResource(meta, d.Id())
deleteParams := goapi.NewDeleteFolderParams().WithFolderUID(d.Get("uid").(string))
if d.Get("prevent_destroy_if_not_empty").(bool) {
// Search for dashboards and fail if any are found
GAPIClient, _, idStr := ClientFromExistingOrgResource(meta, d.Id())
dashboards, err := GAPIClient.FolderDashboardSearch(url.Values{
"type": []string{"dash-db"},
"folderIds": []string{idStr},
})
folderID, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
return diag.Errorf("failed to parse folder ID: %s", err)
}
searchType := "dash-db"
searchParams := search.NewSearchParams().WithFolderIds([]int64{folderID}).WithType(&searchType)
searchResp, err := client.Search.Search(searchParams, nil)
if err != nil {
return diag.Errorf("failed to search for dashboards in folder: %s", err)
}
if len(dashboards) > 0 {
if len(searchResp.GetPayload()) > 0 {
var dashboardNames []string
for _, dashboard := range dashboards {
for _, dashboard := range searchResp.GetPayload() {
dashboardNames = append(dashboardNames, dashboard.Title)
}
return diag.Errorf("folder %s is not empty and prevent_destroy_if_not_empty is set. It contains the following dashboards: %v", d.Get("uid").(string), dashboardNames)
}
} else {
// If we're not preventing destroys, then we can force delete folders that have alert rules
deleteParams = append(deleteParams, gapi.ForceDeleteFolderRules())
}

var force bool
if len(deleteParams) > 0 {
force, _ = strconv.ParseBool(deleteParams[0].Get("forceDeleteRules"))
force := true
deleteParams.WithForceDeleteRules(&force)
}

client, _, _ := OAPIClientFromExistingOrgResource(meta, d.Id())
params := goapi.NewDeleteFolderParams().WithForceDeleteRules(&force).WithFolderUID(d.Get("uid").(string))
if _, err := client.Folders.DeleteFolder(params, nil); err != nil {
if _, err := client.Folders.DeleteFolder(deleteParams, nil); err != nil {
return diag.Errorf("failed to delete folder: %s", err)
}

Expand Down Expand Up @@ -202,22 +198,17 @@ func GetFolderByIDorUID(client goapi.ClientService, id string) (*models.Folder,
// If the ID is a number, find the folder UID
// Getting the folder by ID is broken in some versions, but getting by UID works in all versions
// We need to use two API calls in the numerical ID case, because the "list" call doesn't have all the info
uid := id
if numericalID, err := strconv.ParseInt(id, 10, 64); err == nil {
resp, err := client.GetFolders(goapi.NewGetFoldersParams(), nil)
if err != nil {
params := goapi.NewGetFolderByIDParams().WithFolderID(numericalID)
resp, err := client.GetFolderByID(params, nil)
if err != nil && !common.IsNotFoundError(err) {
return nil, err
}
folders := resp.GetPayload()
for _, folder := range folders {
if folder.ID == numericalID {
uid = folder.UID
break
}
} else if err == nil {
return resp.GetPayload(), nil
}
}

params := goapi.NewGetFolderByUIDParams().WithFolderUID(uid)
params := goapi.NewGetFolderByUIDParams().WithFolderUID(id)
resp, err := client.GetFolderByUID(params, nil)
if err != nil {
return nil, err
Expand Down

0 comments on commit c284510

Please sign in to comment.