diff --git a/internal/resources/grafana/common_check_exists_test.go b/internal/resources/grafana/common_check_exists_test.go index e4488b745..9c80b95e3 100644 --- a/internal/resources/grafana/common_check_exists_test.go +++ b/internal/resources/grafana/common_check_exists_test.go @@ -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" @@ -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( @@ -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) } diff --git a/internal/resources/grafana/resource_folder.go b/internal/resources/grafana/resource_folder.go index 09bd67989..974ee7bd0 100644 --- a/internal/resources/grafana/resource_folder.go +++ b/internal/resources/grafana/resource_folder.go @@ -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" @@ -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) } @@ -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