Skip to content

chore(dbt/workspace): remove sandbox bridge, add keboola_snowflake profile#2562

Draft
Matovidlo wants to merge 9 commits intomainfrom
mvasko/cleanup-sandbox-keboola-dbt-profile
Draft

chore(dbt/workspace): remove sandbox bridge, add keboola_snowflake profile#2562
Matovidlo wants to merge 9 commits intomainfrom
mvasko/cleanup-sandbox-keboola-dbt-profile

Conversation

@Matovidlo
Copy link
Copy Markdown
Contributor

Release Notes

  • Removes the temporary internal/pkg/keboola/sandbox bridge package; all workspace commands now use keboola.DataScienceApp / keboola.EditorSession directly
  • New WorkspaceWithConfig type in pkg/lib/operation/project/remote/workspace replaces sandbox.SandboxWorkspaceWithConfig across all callers
  • dbt generate profile now generates two outputs in profiles.yml: {target_name} (direct Snowflake access, default) and keboola_{target_name} (Keboola keboola_snowflake adapter via Query Service)
  • dbt generate env and dbt init now write DBT_KBC_*_BASE_URL, _BRANCH_ID, _WORKSPACE_ID to .env.local for use with the keboola adapter target

Plans for customer communication

None.

Impact analysis

  • internal/pkg/keboola/sandboxdeleted; no external consumers
  • pkg/lib/operation/project/remote/workspace/workspaceinfo.go — new file, new exported WorkspaceWithConfig type
  • pkg/lib/operation/project/remote/workspace/listListPyRWorkspaces exported (was unexported); callers updated
  • profiles.yml generated by dbt generate profile / dbt init — gains a second output keboola_{target_name}; existing {target_name} output is unchanged (fully backwards-compatible)
  • .env.local generated by dbt generate env / dbt init — gains three new vars (DBT_KBC_*_BASE_URL, _BRANCH_ID, _WORKSPACE_ID); existing vars unchanged

Change type

Chore + Feature — remove sandbox bridge and add keboola_snowflake dbt adapter support

Justification

The sandbox bridge was added in the parent PR as a temporary shim when keboola-sdk-go v2.17.1 removed Python/R sandbox types. This PR inlines the bridge logic directly into callers, eliminating the shim. At the same time, dbt users need a path to use the Keboola Query Service adapter (keboola_snowflake) as an alternative to direct Snowflake access; both targets are now generated by default in a single profiles.yml.

Deployment

Merge & automatic deploy.

Rollback plan

Revert of this PR.

Post release support plan

None.

)

// WorkspaceDetails holds the connection details for a workspace used in dbt env generation.
type WorkspaceDetails struct {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should not be here either in SDK or somewhere else , everything should be served via Editorservice API or data science

Comment on lines +62 to +82
// createPyRWorkspace creates a Python/R workspace: creates the sandboxes config, then calls
// the DataScience sandbox service to provision the instance.
func createPyRWorkspace(ctx context.Context, api *keboola.AuthorizedAPI, branchID keboola.BranchID, name string, wsType workspace.WorkspaceType, size string) (keboola.ConfigID, error) {
config, err := api.CreateSandboxWorkspaceConfigRequest(branchID, name).Send(ctx)
if err != nil {
return "", err
}

_, err = api.CreateDataScienceSandboxRequest(keboola.CreateDataScienceSandboxPayload{
Type: keboola.DataScienceAppType(wsType),
ConfigurationID: string(config.ID),
ComponentID: string(keboola.SandboxWorkspacesComponent),
BranchID: branchID.String(),
Size: keboola.DataScienceSandboxSize(size),
}).Send(ctx)
if err != nil {
return "", err
}

return config.ID, nil
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helpere should not be needed or reused. Or part of SDK

Comment on lines +49 to +56
// deletePyRWorkspace deletes the DataScience sandbox instance then removes the config.
func deletePyRWorkspace(ctx context.Context, api *keboola.AuthorizedAPI, branchID keboola.BranchID, configID keboola.ConfigID, appID keboola.DataScienceAppID) error {
if _, err := api.DeleteDataScienceSandboxRequest(appID).Send(ctx); err != nil {
return err
}
_, err := api.DeleteSandboxWorkspaceConfigRequest(branchID, configID).Send(ctx)
return err
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alsop part of sdk or helper

@Matovidlo Matovidlo force-pushed the mvasko/update-keboola-sdk-go-v2.17.1-458a40d branch from 484a984 to bc5cd01 Compare March 30, 2026 08:07
@Matovidlo Matovidlo force-pushed the mvasko/cleanup-sandbox-keboola-dbt-profile branch from 8aa966a to 5a53a03 Compare March 30, 2026 08:11
Base automatically changed from mvasko/update-keboola-sdk-go-v2.17.1-458a40d to main March 30, 2026 10:52
Matovidlo and others added 9 commits March 30, 2026 14:28
- Introduce WorkspaceWithConfig in pkg/lib/operation/project/remote/workspace
  as the canonical type replacing sandbox.SandboxWorkspaceWithConfig; holds
  App (*keboola.DataScienceApp, non-nil for Python/R) or Session
  (*keboola.EditorSession, non-nil for SQL) alongside Config
- Export ListPyRWorkspaces from workspace/list for use by callers outside
  the package (delete cmd, dbt env cmd)
- Inline createPyRWorkspace queue-job logic into workspace/create; inline
  deletePyRWorkspace into workspace/delete; remove sandbox import from
  workspace/detail (uses DataScienceApp directly)
- Update remote/workspace/delete cmd and cli/dialog/workspaces to use the
  new WorkspaceWithConfig type
- Replace sandbox.ListSandboxWorkspaces / GetSandboxWorkspaceID in
  testproject/snapshot with ListPyRWorkspaces and an inlined helper
- Replace sandbox.CreateSandboxWorkspace in testproject/project with direct
  CreateSandboxWorkspaceConfigRequest + NewCreateJobRequest calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generate a second dbt profile output alongside the existing direct-Snowflake
target so users can switch between direct access and the Keboola Query Service
adapter with a single flag:

  dbt run                              # uses {target_name} (direct Snowflake)
  dbt run --target keboola_{target_name}  # uses keboola_snowflake adapter

Changes:
- profile/operation.go: append keboola_{target_name} output to profiles.yml
  with type: keboola_snowflake and env-var refs for base_url, token,
  branch_id, workspace_id, database, schema, warehouse
- env/operation.go: introduce WorkspaceDetails struct (replaces *sandbox.SandboxWorkspace)
  with BaseURL / BranchID / WorkspaceID fields; write DBT_KBC_*_BASE_URL,
  _BRANCH_ID, _WORKSPACE_ID to .env.local when BaseURL is set
- dbt init/operation.go: construct WorkspaceDetails from StorageWorkspace
  credentials, pass BaseURL (derived from API host) and WorkspaceID through
  to env generation
- dbt init cmd: set BaseURL via baseURLFromHost(d.StorageAPIHost())
- dbt generate-env cmd + dialog: use WorkspaceWithConfig instead of sandbox
  types; construct WorkspaceDetails inline from StorageWorkspace; set BranchID
  and WorkspaceID from matched EditorSession

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…dpoints

- Update keboola-sdk-go/v2 to v2.17.1-0.20260326212557-482d079b522e
- Replace all NewCreateJobRequest(keboola.sandboxes) queue-job calls with
  CreateDataScienceSandboxRequest (workspace/create, testproject)
- Replace DeleteSandboxWorkspaceJobRequest with DeleteDataScienceSandboxRequest
  (workspace/delete)
- Define local WorkspaceType = string alias + helpers (SupportsSizes, TypesOrdered,
  TypesMap, SizesOrdered, SizesMap) in workspaceinfo.go to replace the removed
  keboola.SandboxWorkspaceType SDK type
- Change fixtures.Sandbox.Type and WorkspaceDetails.Type from keboola.SandboxWorkspaceType
  to string; drop SandboxWorkspaceType casts throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…test fixture

- detail/operation.go: GetNested("parameters.id") returns an error when the
  intermediate "parameters" key is absent (SQL workspace with no config params).
  Treat err != nil and !found identically — both mean "fall through to editor
  session lookup". Previously this propagated as a fatal error for Snowflake
  workspaces.
- push/delete-config-row-dev-force expected-stderr: keboola.ex-db-mysql schema
  now requires port/user/#password; update fixture to accept the validation warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add schema validation warning to expected-stderr for pull-ignore-configs (mocked API now requires port/user/#password)
- Add schema validation warning to create-test-two/expected-stderr (real API requires port/user)
- Clear template-test-run/local-one/expected-stderr (real API no longer emits warnings)
- Update create/config and create/config-row output fixtures: SDK v2.18.0 now returns normalized default values instead of {}
- Revert ok-legacy .env.local: BASE_URL/BRANCH_ID/WORKSPACE_ID are not generated for Snowflake legacy workspaces

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v2.18.0 renamed DataScienceSandbox* symbols to SandboxWorkspace* and
removed CreateDataScienceSandboxRequest/DeleteDataScienceSandboxRequest.
Revert create/delete to queue-job approach; use SandboxWorkspaceID cast
for delete (same pattern as CleanSandboxWorkspaceInstances in the SDK).
Update workspaceinfo.go to use renamed SandboxWorkspace* helpers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ce sandbox API

Revert the v2.18.0 workarounds: restore CreateDataScienceSandboxRequest,
DeleteDataScienceSandboxRequest, DataScienceSandboxSupportsSizes, and
DataScienceSandboxSizesOrdered from pseudo-version 482d079b522e which
provides these endpoints. v2.18.0 dropped them prematurely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant