diff --git a/docs/en/resources/tools/looker/looker-make-dashboard.md b/docs/en/resources/tools/looker/looker-make-dashboard.md index 048d42bef0..f8112bcd5d 100644 --- a/docs/en/resources/tools/looker/looker-make-dashboard.md +++ b/docs/en/resources/tools/looker/looker-make-dashboard.md @@ -18,9 +18,11 @@ It's compatible with the following sources: - [looker](../../sources/looker.md) -`looker-make-dashboard` takes one parameter: +`looker-make-dashboard` takes three parameters: 1. the `title` +2. the `description` +3. an optional `folder` id. If not provided, the user's default folder will be used. ## Example diff --git a/docs/en/resources/tools/looker/looker-make-look.md b/docs/en/resources/tools/looker/looker-make-look.md index 148f245532..9c69898437 100644 --- a/docs/en/resources/tools/looker/looker-make-look.md +++ b/docs/en/resources/tools/looker/looker-make-look.md @@ -18,7 +18,7 @@ It's compatible with the following sources: - [looker](../../sources/looker.md) -`looker-make-look` takes eleven parameters: +`looker-make-look` takes twelve parameters: 1. the `model` 2. the `explore` @@ -31,6 +31,7 @@ It's compatible with the following sources: 9. an optional `vis_config` 10. the `title` 11. an optional `description` +12. an optional `folder` id. If not provided, the user's default folder will be used. ## Example diff --git a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go index 2930d6e993..ea64b8b148 100644 --- a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go +++ b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go @@ -76,6 +76,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) params = append(params, titleParameter) descParameter := parameters.NewStringParameterWithDefault("description", "", "The description of the Dashboard") params = append(params, descParameter) + folderParameter := parameters.NewStringParameterWithDefault("folder", "", "The folder id where the Dashboard will be created. Leave blank to use the user's personal folder") + params = append(params, folderParameter) annotations := cfg.Annotations if annotations == nil { @@ -130,21 +132,26 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) } + + paramsMap := params.AsMap() + title := paramsMap["title"].(string) + description := paramsMap["description"].(string) + folder := paramsMap["folder"].(string) + mrespFields := "id,personal_folder_id" mresp, err := sdk.Me(mrespFields, source.LookerApiSettings()) if err != nil { return nil, fmt.Errorf("error making me request: %s", err) } - paramsMap := params.AsMap() - title := paramsMap["title"].(string) - description := paramsMap["description"].(string) - - if mresp.PersonalFolderId == nil || *mresp.PersonalFolderId == "" { - return nil, fmt.Errorf("user does not have a personal folder. cannot continue") + if folder == "" { + if mresp.PersonalFolderId == nil || *mresp.PersonalFolderId == "" { + return nil, fmt.Errorf("user does not have a personal folder. A folder must be specified") + } + folder = *mresp.PersonalFolderId } - dashs, err := sdk.FolderDashboards(*mresp.PersonalFolderId, "title", source.LookerApiSettings()) + dashs, err := sdk.FolderDashboards(folder, "title", source.LookerApiSettings()) if err != nil { return nil, fmt.Errorf("error getting existing dashboards in folder: %s", err) } @@ -155,13 +162,13 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } if slices.Contains(dashTitles, title) { lt, _ := json.Marshal(dashTitles) - return nil, fmt.Errorf("title %s already used in user's folder. Currently used titles are %v. Make the call again with a unique title", title, string(lt)) + return nil, fmt.Errorf("title %s already used in folder. Currently used titles are %v. Make the call again with a unique title", title, string(lt)) } wd := v4.WriteDashboard{ Title: &title, Description: &description, - FolderId: mresp.PersonalFolderId, + FolderId: &folder, } resp, err := sdk.CreateDashboard(wd, source.LookerApiSettings()) if err != nil { diff --git a/internal/tools/looker/lookermakelook/lookermakelook.go b/internal/tools/looker/lookermakelook/lookermakelook.go index 7244c5d6fe..f3a09805e2 100644 --- a/internal/tools/looker/lookermakelook/lookermakelook.go +++ b/internal/tools/looker/lookermakelook/lookermakelook.go @@ -76,6 +76,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) params = append(params, titleParameter) descParameter := parameters.NewStringParameterWithDefault("description", "", "The description of the Look") params = append(params, descParameter) + folderParameter := parameters.NewStringParameterWithDefault("folder", "", "The folder id where the Look will be created. Leave blank to use the user's personal folder") + params = append(params, folderParameter) vizParameter := parameters.NewMapParameterWithDefault("vis_config", map[string]any{}, "The visualization config for the query", @@ -140,17 +142,26 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) } + paramsMap := params.AsMap() + title := paramsMap["title"].(string) + description := paramsMap["description"].(string) + folder := paramsMap["folder"].(string) + visConfig := paramsMap["vis_config"].(map[string]any) + mrespFields := "id,personal_folder_id" mresp, err := sdk.Me(mrespFields, source.LookerApiSettings()) if err != nil { return nil, fmt.Errorf("error making me request: %s", err) } - paramsMap := params.AsMap() - title := paramsMap["title"].(string) - description := paramsMap["description"].(string) + if folder == "" { + if mresp.PersonalFolderId == nil || *mresp.PersonalFolderId == "" { + return nil, fmt.Errorf("user does not have a personal folder. A folder must be specified") + } + folder = *mresp.PersonalFolderId + } - looks, err := sdk.FolderLooks(*mresp.PersonalFolderId, "title", source.LookerApiSettings()) + looks, err := sdk.FolderLooks(folder, "title", source.LookerApiSettings()) if err != nil { return nil, fmt.Errorf("error getting existing looks in folder: %s", err) } @@ -161,10 +172,9 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } if slices.Contains(lookTitles, title) { lt, _ := json.Marshal(lookTitles) - return nil, fmt.Errorf("title %s already used in user's folder. Currently used titles are %v. Make the call again with a unique title", title, string(lt)) + return nil, fmt.Errorf("title %s already used in folder. Currently used titles are %v. Make the call again with a unique title", title, string(lt)) } - visConfig := paramsMap["vis_config"].(map[string]any) wq.VisConfig = &visConfig qrespFields := "id" @@ -178,7 +188,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para UserId: mresp.Id, Description: &description, QueryId: qresp.Id, - FolderId: mresp.PersonalFolderId, + FolderId: &folder, } resp, err := sdk.CreateLook(wlwq, "", source.LookerApiSettings()) if err != nil { diff --git a/tests/looker/looker_integration_test.go b/tests/looker/looker_integration_test.go index 06ee5c0277..d179cf0483 100644 --- a/tests/looker/looker_integration_test.go +++ b/tests/looker/looker_integration_test.go @@ -799,6 +799,13 @@ func TestLooker(t *testing.T) { "required": false, "type": "string", }, + map[string]any{ + "authSources": []any{}, + "description": "The folder id where the Look will be created. Leave blank to use the user's personal folder", + "name": "folder", + "required": false, + "type": "string", + }, map[string]any{ "additionalProperties": true, "authSources": []any{}, @@ -869,6 +876,13 @@ func TestLooker(t *testing.T) { "required": false, "type": "string", }, + map[string]any{ + "authSources": []any{}, + "description": "The folder id where the Dashboard will be created. Leave blank to use the user's personal folder", + "name": "folder", + "required": false, + "type": "string", + }, }, }, },