diff --git a/.codegen/_openapi_sha b/.codegen/_openapi_sha index e5a90379123..15378345074 100644 --- a/.codegen/_openapi_sha +++ b/.codegen/_openapi_sha @@ -1 +1 @@ -d09dbd77f5a9560cbb816746773da43a8bdbde08 \ No newline at end of file +11ae6f9d98f0d0838a5e53c27032f178fecc4ee0 \ No newline at end of file diff --git a/.github/workflows/tagging.yml b/.github/workflows/tagging.yml index 94c8980b8e4..cbb9cfb591c 100644 --- a/.github/workflows/tagging.yml +++ b/.github/workflows/tagging.yml @@ -6,10 +6,12 @@ on: workflow_dispatch: # No inputs are required for the manual dispatch. + # NOTE: Temporarily disable automated releases. + # # Runs at 8:00 UTC on Monday, Tuesday, Wednesday, and Thursday. To enable automated # tagging for a repository, simply add it to the if block of the tag job. - schedule: - - cron: '0 8 * * MON,TUE,WED,THU' + # schedule: + # - cron: '0 8 * * MON,TUE,WED,THU' # Ensure that only a single instance of the workflow is running at a time. concurrency: diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 0db4b902e1f..0e4d6de08f4 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,8 +6,12 @@ ### CLI +* Added `--limit` flag to all paginated list commands for client-side result capping ([#4984](https://github.com/databricks/cli/pull/4984)). + ### Bundles ### Dependency updates +* Bump `github.com/databricks/databricks-sdk-go` from v0.126.0 to v0.127.0 ([#4984](https://github.com/databricks/cli/pull/4984)). + ### API Changes diff --git a/acceptance/bundle/refschema/out.fields.txt b/acceptance/bundle/refschema/out.fields.txt index 256a5195dd5..c4d5be9ccf6 100644 --- a/acceptance/bundle/refschema/out.fields.txt +++ b/acceptance/bundle/refschema/out.fields.txt @@ -162,6 +162,8 @@ resources.apps.*.pending_deployment.update_time string ALL resources.apps.*.resources []apps.AppResource ALL resources.apps.*.resources[*] apps.AppResource ALL resources.apps.*.resources[*].app *apps.AppResourceApp ALL +resources.apps.*.resources[*].app.name string ALL +resources.apps.*.resources[*].app.permission apps.AppResourceAppAppPermission ALL resources.apps.*.resources[*].database *apps.AppResourceDatabase ALL resources.apps.*.resources[*].database.database_name string ALL resources.apps.*.resources[*].database.instance_name string ALL @@ -236,6 +238,13 @@ resources.catalogs.*.id string INPUT resources.catalogs.*.isolation_mode catalog.CatalogIsolationMode REMOTE resources.catalogs.*.lifecycle resources.Lifecycle INPUT resources.catalogs.*.lifecycle.prevent_destroy bool INPUT +resources.catalogs.*.managed_encryption_settings *catalog.EncryptionSettings ALL +resources.catalogs.*.managed_encryption_settings.azure_encryption_settings *catalog.AzureEncryptionSettings ALL +resources.catalogs.*.managed_encryption_settings.azure_encryption_settings.azure_cmk_access_connector_id string ALL +resources.catalogs.*.managed_encryption_settings.azure_encryption_settings.azure_cmk_managed_identity_id string ALL +resources.catalogs.*.managed_encryption_settings.azure_encryption_settings.azure_tenant_id string ALL +resources.catalogs.*.managed_encryption_settings.azure_key_vault_key_id string ALL +resources.catalogs.*.managed_encryption_settings.customer_managed_key_id string ALL resources.catalogs.*.metastore_id string REMOTE resources.catalogs.*.modified_status string INPUT resources.catalogs.*.name string ALL @@ -646,6 +655,29 @@ resources.external_locations.*.created_by string REMOTE resources.external_locations.*.credential_id string REMOTE resources.external_locations.*.credential_name string ALL resources.external_locations.*.effective_enable_file_events bool ALL +resources.external_locations.*.effective_file_event_queue *catalog.FileEventQueue ALL +resources.external_locations.*.effective_file_event_queue.managed_aqs *catalog.AzureQueueStorage ALL +resources.external_locations.*.effective_file_event_queue.managed_aqs.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.managed_aqs.queue_url string ALL +resources.external_locations.*.effective_file_event_queue.managed_aqs.resource_group string ALL +resources.external_locations.*.effective_file_event_queue.managed_aqs.subscription_id string ALL +resources.external_locations.*.effective_file_event_queue.managed_pubsub *catalog.GcpPubsub ALL +resources.external_locations.*.effective_file_event_queue.managed_pubsub.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.managed_pubsub.subscription_name string ALL +resources.external_locations.*.effective_file_event_queue.managed_sqs *catalog.AwsSqsQueue ALL +resources.external_locations.*.effective_file_event_queue.managed_sqs.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.managed_sqs.queue_url string ALL +resources.external_locations.*.effective_file_event_queue.provided_aqs *catalog.AzureQueueStorage ALL +resources.external_locations.*.effective_file_event_queue.provided_aqs.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.provided_aqs.queue_url string ALL +resources.external_locations.*.effective_file_event_queue.provided_aqs.resource_group string ALL +resources.external_locations.*.effective_file_event_queue.provided_aqs.subscription_id string ALL +resources.external_locations.*.effective_file_event_queue.provided_pubsub *catalog.GcpPubsub ALL +resources.external_locations.*.effective_file_event_queue.provided_pubsub.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.provided_pubsub.subscription_name string ALL +resources.external_locations.*.effective_file_event_queue.provided_sqs *catalog.AwsSqsQueue ALL +resources.external_locations.*.effective_file_event_queue.provided_sqs.managed_resource_id string ALL +resources.external_locations.*.effective_file_event_queue.provided_sqs.queue_url string ALL resources.external_locations.*.enable_file_events bool ALL resources.external_locations.*.encryption_details *catalog.EncryptionDetails ALL resources.external_locations.*.encryption_details.sse_encryption_details *catalog.SseEncryptionDetails ALL @@ -2297,6 +2329,61 @@ resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration.workday_report_parameters.report_parameters[*].key string ALL resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration.workday_report_parameters.report_parameters[*].value string ALL resources.pipelines.*.ingestion_definition.objects[*].schema *pipelines.SchemaSpec ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options *pipelines.ConnectorOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options *pipelines.GoogleDriveOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.entity_type pipelines.GoogleDriveOptionsGoogleDriveEntityType ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options *pipelines.FileIngestionOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.corrupt_record_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.file_filters []pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.file_filters[*] pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.file_filters[*].modified_after string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.file_filters[*].modified_before string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.file_filters[*].path_filter string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.format pipelines.FileIngestionOptionsFileFormat ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.format_options map[string]string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.format_options.* string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.ignore_corrupt_files bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.infer_column_types bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.reader_case_sensitive bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.rescued_data_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.schema_evolution_mode pipelines.FileIngestionOptionsSchemaEvolutionMode ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.schema_hints string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.single_variant_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.url string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.google_ads_options *pipelines.GoogleAdsOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.google_ads_options.lookback_window_days int ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.google_ads_options.manager_account_id string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.google_ads_options.sync_start_date string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options *pipelines.SharepointOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.entity_type pipelines.SharepointOptionsSharepointEntityType ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options *pipelines.FileIngestionOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.corrupt_record_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.file_filters []pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.file_filters[*] pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].modified_after string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].modified_before string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].path_filter string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.format pipelines.FileIngestionOptionsFileFormat ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.format_options map[string]string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.format_options.* string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.ignore_corrupt_files bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.infer_column_types bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.reader_case_sensitive bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.rescued_data_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.schema_evolution_mode pipelines.FileIngestionOptionsSchemaEvolutionMode ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.schema_hints string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.single_variant_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.url string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options *pipelines.TikTokAdsOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.data_level pipelines.TikTokAdsOptionsTikTokDataLevel ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.dimensions []string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.dimensions[*] string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.lookback_window_days int ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.metrics []string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.metrics[*] string ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.query_lifetime bool ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.report_type pipelines.TikTokAdsOptionsTikTokReportType ALL +resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.sync_start_date string ALL resources.pipelines.*.ingestion_definition.objects[*].schema.destination_catalog string ALL resources.pipelines.*.ingestion_definition.objects[*].schema.destination_schema string ALL resources.pipelines.*.ingestion_definition.objects[*].schema.source_catalog string ALL @@ -2330,6 +2417,61 @@ resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration.workday_report_parameters.report_parameters[*].key string ALL resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration.workday_report_parameters.report_parameters[*].value string ALL resources.pipelines.*.ingestion_definition.objects[*].table *pipelines.TableSpec ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options *pipelines.ConnectorOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options *pipelines.GoogleDriveOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.entity_type pipelines.GoogleDriveOptionsGoogleDriveEntityType ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options *pipelines.FileIngestionOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.corrupt_record_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.file_filters []pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.file_filters[*] pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.file_filters[*].modified_after string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.file_filters[*].modified_before string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.file_filters[*].path_filter string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.format pipelines.FileIngestionOptionsFileFormat ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.format_options map[string]string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.format_options.* string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.ignore_corrupt_files bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.infer_column_types bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.reader_case_sensitive bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.rescued_data_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.schema_evolution_mode pipelines.FileIngestionOptionsSchemaEvolutionMode ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.schema_hints string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.single_variant_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.url string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.google_ads_options *pipelines.GoogleAdsOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.google_ads_options.lookback_window_days int ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.google_ads_options.manager_account_id string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.google_ads_options.sync_start_date string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options *pipelines.SharepointOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.entity_type pipelines.SharepointOptionsSharepointEntityType ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options *pipelines.FileIngestionOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.corrupt_record_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.file_filters []pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.file_filters[*] pipelines.FileFilter ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].modified_after string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].modified_before string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.file_filters[*].path_filter string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.format pipelines.FileIngestionOptionsFileFormat ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.format_options map[string]string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.format_options.* string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.ignore_corrupt_files bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.infer_column_types bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.reader_case_sensitive bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.rescued_data_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.schema_evolution_mode pipelines.FileIngestionOptionsSchemaEvolutionMode ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.schema_hints string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.single_variant_column string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.url string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options *pipelines.TikTokAdsOptions ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.data_level pipelines.TikTokAdsOptionsTikTokDataLevel ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.dimensions []string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.dimensions[*] string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.lookback_window_days int ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.metrics []string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.metrics[*] string ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.query_lifetime bool ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.report_type pipelines.TikTokAdsOptionsTikTokReportType ALL +resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.sync_start_date string ALL resources.pipelines.*.ingestion_definition.objects[*].table.destination_catalog string ALL resources.pipelines.*.ingestion_definition.objects[*].table.destination_schema string ALL resources.pipelines.*.ingestion_definition.objects[*].table.destination_table string ALL @@ -2563,6 +2705,7 @@ resources.postgres_projects.*.custom_tags []postgres.ProjectCustomTag INPUT STAT resources.postgres_projects.*.custom_tags[*] postgres.ProjectCustomTag INPUT STATE resources.postgres_projects.*.custom_tags[*].key string INPUT STATE resources.postgres_projects.*.custom_tags[*].value string INPUT STATE +resources.postgres_projects.*.default_branch string INPUT STATE resources.postgres_projects.*.default_endpoint_settings *postgres.ProjectDefaultEndpointSettings INPUT STATE resources.postgres_projects.*.default_endpoint_settings.autoscaling_limit_max_cu float64 INPUT STATE resources.postgres_projects.*.default_endpoint_settings.autoscaling_limit_min_cu float64 INPUT STATE @@ -2591,6 +2734,7 @@ resources.postgres_projects.*.spec.custom_tags []postgres.ProjectCustomTag REMOT resources.postgres_projects.*.spec.custom_tags[*] postgres.ProjectCustomTag REMOTE resources.postgres_projects.*.spec.custom_tags[*].key string REMOTE resources.postgres_projects.*.spec.custom_tags[*].value string REMOTE +resources.postgres_projects.*.spec.default_branch string REMOTE resources.postgres_projects.*.spec.default_endpoint_settings *postgres.ProjectDefaultEndpointSettings REMOTE resources.postgres_projects.*.spec.default_endpoint_settings.autoscaling_limit_max_cu float64 REMOTE resources.postgres_projects.*.spec.default_endpoint_settings.autoscaling_limit_min_cu float64 REMOTE @@ -2609,6 +2753,7 @@ resources.postgres_projects.*.status.custom_tags []postgres.ProjectCustomTag REM resources.postgres_projects.*.status.custom_tags[*] postgres.ProjectCustomTag REMOTE resources.postgres_projects.*.status.custom_tags[*].key string REMOTE resources.postgres_projects.*.status.custom_tags[*].value string REMOTE +resources.postgres_projects.*.status.default_branch string REMOTE resources.postgres_projects.*.status.default_endpoint_settings *postgres.ProjectDefaultEndpointSettings REMOTE resources.postgres_projects.*.status.default_endpoint_settings.autoscaling_limit_max_cu float64 REMOTE resources.postgres_projects.*.status.default_endpoint_settings.autoscaling_limit_min_cu float64 REMOTE diff --git a/acceptance/dbr_test.go b/acceptance/dbr_test.go index 3fef59f65d1..2fe498698a1 100644 --- a/acceptance/dbr_test.go +++ b/acceptance/dbr_test.go @@ -85,7 +85,7 @@ func setupDbrTestDir(ctx context.Context, t *testing.T, uniqueID string) (*datab // API path (without /Workspace prefix) for workspace API calls. apiPath := path.Join("/Users", currentUser.UserName, "dbr-acceptance-test", uniqueID) - err = w.Workspace.MkdirsByPath(ctx, apiPath) + err = w.Workspace.MkdirsByPath(ctx, apiPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) // Note: We do not cleanup test directories created here. They are kept around @@ -185,7 +185,7 @@ func runDbrTests(ctx context.Context, t *testing.T, w *databricks.WorkspaceClien // Create debug logs directory debugLogsDir := path.Join("/Users", currentUser.UserName, "dbr_acceptance_tests") - err = w.Workspace.MkdirsByPath(ctx, debugLogsDir) + err = w.Workspace.MkdirsByPath(ctx, debugLogsDir) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) // Create an empty debug log file so we can get its URL before the job runs. @@ -204,7 +204,7 @@ func runDbrTests(ctx context.Context, t *testing.T, w *databricks.WorkspaceClien require.NoError(t, err) // Get the file's object ID for the URL - debugLogStatus, err := w.Workspace.GetStatusByPath(ctx, debugLogPath) + debugLogStatus, err := w.Workspace.GetStatusByPath(ctx, debugLogPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) // Build cloud test parameters (Cloud=true tests, run with CLOUD_ENV set) diff --git a/acceptance/help/output.txt b/acceptance/help/output.txt index dd59847c64e..d9f379f5bbf 100644 --- a/acceptance/help/output.txt +++ b/acceptance/help/output.txt @@ -8,7 +8,7 @@ Databricks Workspace git-credentials Registers personal access token for Databricks to do operations on behalf of the user. repos The Repos API allows users to manage their git repos. secrets The Secrets API allows you to manage secrets, secret scopes, and access permissions. - workspace The Workspace API allows you to list, import, export, and delete notebooks and folders. + workspace The Workspace API allows you to list, import, export, and delete workspace objects such as notebooks, files, folders, and dashboards. Compute cluster-policies You can use cluster policies to control users' ability to configure clusters based on a set of rules. diff --git a/acceptance/pipelines/databricks-cli-help/output.txt b/acceptance/pipelines/databricks-cli-help/output.txt index b5d7e4a4835..9043af0f127 100644 --- a/acceptance/pipelines/databricks-cli-help/output.txt +++ b/acceptance/pipelines/databricks-cli-help/output.txt @@ -31,6 +31,7 @@ Available Commands stop Stop a pipeline Management Commands + apply-environment Apply the latest environment to the pipeline. clone Clone a pipeline. create Create a pipeline. delete Delete a pipeline. diff --git a/bundle/config/validate/folder_permissions.go b/bundle/config/validate/folder_permissions.go index 575702c34cb..1481bcca383 100644 --- a/bundle/config/validate/folder_permissions.go +++ b/bundle/config/validate/folder_permissions.go @@ -73,7 +73,7 @@ func checkFolderPermission(ctx context.Context, b *bundle.Bundle, folderPath str func getClosestExistingObject(ctx context.Context, w workspace.WorkspaceInterface, folderPath string) (*workspace.ObjectInfo, error) { for { - obj, err := w.GetStatusByPath(ctx, folderPath) + obj, err := w.GetStatusByPath(ctx, folderPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err == nil { return obj, nil } diff --git a/bundle/deploy/files/delete.go b/bundle/deploy/files/delete.go index 971186d5b07..fc97c3880b2 100644 --- a/bundle/deploy/files/delete.go +++ b/bundle/deploy/files/delete.go @@ -23,7 +23,7 @@ func (m *delete) Name() string { func (m *delete) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { cmdio.LogString(ctx, "Deleting files...") - err := b.WorkspaceClient().Workspace.Delete(ctx, workspace.Delete{ + err := b.WorkspaceClient().Workspace.Delete(ctx, workspace.Delete{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: b.Config.Workspace.RootPath, Recursive: true, }) diff --git a/bundle/deploy/resource_path_mkdir.go b/bundle/deploy/resource_path_mkdir.go index 14d29d78692..051c1ca1737 100644 --- a/bundle/deploy/resource_path_mkdir.go +++ b/bundle/deploy/resource_path_mkdir.go @@ -28,7 +28,7 @@ func (m *resourcePathMkdir) Apply(ctx context.Context, b *bundle.Bundle) diag.Di w := b.WorkspaceClient() // Optimisitcally create the resource path. If it already exists ignore the error. - err := w.Workspace.MkdirsByPath(ctx, b.Config.Workspace.ResourcePath) + err := w.Workspace.MkdirsByPath(ctx, b.Config.Workspace.ResourcePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. var aerr *apierr.APIError if errors.As(err, &aerr) && aerr.ErrorCode == "RESOURCE_ALREADY_EXISTS" { return nil diff --git a/bundle/direct/dresources/all_test.go b/bundle/direct/dresources/all_test.go index 63caa5cfed3..8401fcc71b2 100644 --- a/bundle/direct/dresources/all_test.go +++ b/bundle/direct/dresources/all_test.go @@ -421,7 +421,7 @@ var testDeps = map[string]prepareWorkspace{ parentPath := "/Workspace/Users/user@example.com" // Create parent directory if it doesn't exist - err := client.Workspace.MkdirsByPath(ctx, parentPath) + err := client.Workspace.MkdirsByPath(ctx, parentPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return nil, err } diff --git a/bundle/direct/dresources/apitypes.generated.yml b/bundle/direct/dresources/apitypes.generated.yml index 8dfabd1098e..49002f97e8f 100644 --- a/bundle/direct/dresources/apitypes.generated.yml +++ b/bundle/direct/dresources/apitypes.generated.yml @@ -30,7 +30,7 @@ postgres_branches: postgres.BranchSpec postgres_endpoints: postgres.EndpointSpec -postgres_projects: postgres.ProjectSpec +postgres_projects: postgres.ProjectStatus quality_monitors: catalog.CreateMonitor diff --git a/bundle/direct/dresources/catalog.go b/bundle/direct/dresources/catalog.go index a9afa71cbf0..2e090ddfb8e 100644 --- a/bundle/direct/dresources/catalog.go +++ b/bundle/direct/dresources/catalog.go @@ -23,15 +23,16 @@ func (*ResourceCatalog) PrepareState(input *resources.Catalog) *catalog.CreateCa func (*ResourceCatalog) RemapState(info *catalog.CatalogInfo) *catalog.CreateCatalog { return &catalog.CreateCatalog{ - Comment: info.Comment, - ConnectionName: info.ConnectionName, - Name: info.Name, - Options: info.Options, - Properties: info.Properties, - ProviderName: info.ProviderName, - ShareName: info.ShareName, - StorageRoot: info.StorageRoot, - ForceSendFields: utils.FilterFields[catalog.CreateCatalog](info.ForceSendFields), + Comment: info.Comment, + ConnectionName: info.ConnectionName, + ManagedEncryptionSettings: info.ManagedEncryptionSettings, + Name: info.Name, + Options: info.Options, + Properties: info.Properties, + ProviderName: info.ProviderName, + ShareName: info.ShareName, + StorageRoot: info.StorageRoot, + ForceSendFields: utils.FilterFields[catalog.CreateCatalog](info.ForceSendFields), } } @@ -53,6 +54,7 @@ func (r *ResourceCatalog) DoUpdate(ctx context.Context, id string, config *catal Comment: config.Comment, EnablePredictiveOptimization: "", // Not supported by DABs IsolationMode: "", // Not supported by DABs + ManagedEncryptionSettings: config.ManagedEncryptionSettings, Name: id, NewName: "", // Only set if name actually changes (see DoUpdateWithID) Options: config.Options, @@ -75,6 +77,7 @@ func (r *ResourceCatalog) DoUpdateWithID(ctx context.Context, id string, config Comment: config.Comment, EnablePredictiveOptimization: "", // Not supported by DABs IsolationMode: "", // Not supported by DABs + ManagedEncryptionSettings: config.ManagedEncryptionSettings, Name: id, NewName: "", // Initialized below if needed Options: config.Options, diff --git a/bundle/direct/dresources/dashboard.go b/bundle/direct/dresources/dashboard.go index f33d7946e8c..6c4a9f1f611 100644 --- a/bundle/direct/dresources/dashboard.go +++ b/bundle/direct/dresources/dashboard.go @@ -281,7 +281,7 @@ func (r *ResourceDashboard) DoCreate(ctx context.Context, config *DashboardState // The API returns 404 if the parent directory doesn't exist. // If the parent directory doesn't exist, create it and try again. if err != nil && apierr.IsMissing(err) { - err = r.client.Workspace.MkdirsByPath(ctx, config.ParentPath) + err = r.client.Workspace.MkdirsByPath(ctx, config.ParentPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return "", nil, fmt.Errorf("failed to create parent directory: %w", err) } diff --git a/bundle/direct/dresources/external_location.go b/bundle/direct/dresources/external_location.go index f9416567cbb..a9715b06190 100644 --- a/bundle/direct/dresources/external_location.go +++ b/bundle/direct/dresources/external_location.go @@ -25,8 +25,9 @@ func (*ResourceExternalLocation) RemapState(info *catalog.ExternalLocationInfo) return &catalog.CreateExternalLocation{ Comment: info.Comment, CredentialName: info.CredentialName, - // Output-only field mirrored into state to avoid churn in remapped config. + // Output-only fields mirrored into state to avoid churn in remapped config. EffectiveEnableFileEvents: info.EffectiveEnableFileEvents, + EffectiveFileEventQueue: info.EffectiveFileEventQueue, EnableFileEvents: info.EnableFileEvents, EncryptionDetails: info.EncryptionDetails, Fallback: info.Fallback, @@ -54,10 +55,10 @@ func (r *ResourceExternalLocation) DoCreate(ctx context.Context, config *catalog // DoUpdate updates the external location in place and returns remote state. func (r *ResourceExternalLocation) DoUpdate(ctx context.Context, id string, config *catalog.CreateExternalLocation, _ *PlanEntry) (*catalog.ExternalLocationInfo, error) { updateRequest := catalog.UpdateExternalLocation{ - Comment: config.Comment, - CredentialName: config.CredentialName, - // Output-only field; never sent in update payload. - EffectiveEnableFileEvents: false, + Comment: config.Comment, + CredentialName: config.CredentialName, + EffectiveEnableFileEvents: false, // Output-only field; never sent in update payload. + EffectiveFileEventQueue: nil, EnableFileEvents: config.EnableFileEvents, EncryptionDetails: config.EncryptionDetails, Fallback: config.Fallback, @@ -79,10 +80,10 @@ func (r *ResourceExternalLocation) DoUpdate(ctx context.Context, id string, conf // DoUpdateWithID updates the external location and returns the new ID if the name changes. func (r *ResourceExternalLocation) DoUpdateWithID(ctx context.Context, id string, config *catalog.CreateExternalLocation) (string, *catalog.ExternalLocationInfo, error) { updateRequest := catalog.UpdateExternalLocation{ - Comment: config.Comment, - CredentialName: config.CredentialName, - // Output-only field; never sent in update payload. - EffectiveEnableFileEvents: false, + Comment: config.Comment, + CredentialName: config.CredentialName, + EffectiveEnableFileEvents: false, // Output-only field; never sent in update payload. + EffectiveFileEventQueue: nil, EnableFileEvents: config.EnableFileEvents, EncryptionDetails: config.EncryptionDetails, Fallback: config.Fallback, diff --git a/bundle/direct/dresources/postgres_project.go b/bundle/direct/dresources/postgres_project.go index 222d201d8f1..e1e802b2678 100644 --- a/bundle/direct/dresources/postgres_project.go +++ b/bundle/direct/dresources/postgres_project.go @@ -40,6 +40,7 @@ func (*ResourcePostgresProject) RemapState(remote *postgres.Project) *PostgresPr ProjectSpec: postgres.ProjectSpec{ BudgetPolicyId: "", CustomTags: nil, + DefaultBranch: "", DefaultEndpointSettings: nil, DisplayName: "", EnablePgNativeLogin: false, diff --git a/bundle/direct/dresources/resources.generated.yml b/bundle/direct/dresources/resources.generated.yml index 5a02c184f4e..fd0c5c0dcc4 100644 --- a/bundle/direct/dresources/resources.generated.yml +++ b/bundle/direct/dresources/resources.generated.yml @@ -165,11 +165,7 @@ resources: ignore_remote_changes: - field: effective_enable_file_events reason: spec:output_only - - field: file_event_queue.managed_aqs.managed_resource_id - reason: spec:output_only - - field: file_event_queue.managed_pubsub.managed_resource_id - reason: spec:output_only - - field: file_event_queue.managed_sqs.managed_resource_id + - field: effective_file_event_queue reason: spec:output_only # jobs: no api field behaviors @@ -245,6 +241,8 @@ resources: reason: spec:input_only - field: custom_tags reason: spec:input_only + - field: default_branch + reason: spec:input_only - field: default_endpoint_settings reason: spec:input_only - field: display_name diff --git a/bundle/direct/dresources/type_test.go b/bundle/direct/dresources/type_test.go index 3321725049f..a15de1d54cc 100644 --- a/bundle/direct/dresources/type_test.go +++ b/bundle/direct/dresources/type_test.go @@ -67,6 +67,7 @@ var knownMissingInRemoteType = map[string][]string{ "postgres_projects": { "budget_policy_id", "custom_tags", + "default_branch", "default_endpoint_settings", "display_name", "enable_pg_native_login", diff --git a/bundle/generate/downloader.go b/bundle/generate/downloader.go index 30b91c05399..d37f2a12f47 100644 --- a/bundle/generate/downloader.go +++ b/bundle/generate/downloader.go @@ -55,7 +55,7 @@ func (n *Downloader) MarkPipelineLibraryForDownload(ctx context.Context, lib *pi } func (n *Downloader) markFileForDownload(ctx context.Context, filePath *string) error { - _, err := n.w.Workspace.GetStatusByPath(ctx, *filePath) + _, err := n.w.Workspace.GetStatusByPath(ctx, *filePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return err } @@ -78,7 +78,7 @@ func (n *Downloader) markFileForDownload(ctx context.Context, filePath *string) } func (n *Downloader) MarkDirectoryForDownload(ctx context.Context, dirPath *string) error { - _, err := n.w.Workspace.GetStatusByPath(ctx, *dirPath) + _, err := n.w.Workspace.GetStatusByPath(ctx, *dirPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return err } @@ -118,7 +118,7 @@ func (n *Downloader) MarkDirectoryForDownload(ctx context.Context, dirPath *stri func (n *Downloader) recursiveListWithExclusions(ctx context.Context, dirPath string) ([]workspace.ObjectInfo, error) { var result []workspace.ObjectInfo - objects, err := n.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ + objects, err := n.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: dirPath, }) if err != nil { diff --git a/bundle/internal/schema/annotations.yml b/bundle/internal/schema/annotations.yml index 459d2c19f6f..58f64268ae5 100644 --- a/bundle/internal/schema/annotations.yml +++ b/bundle/internal/schema/annotations.yml @@ -849,6 +849,9 @@ github.com/databricks/cli/bundle/config/resources.PostgresProject: "custom_tags": "description": |- PLACEHOLDER + "default_branch": + "description": |- + PLACEHOLDER "default_endpoint_settings": "description": |- PLACEHOLDER diff --git a/bundle/internal/schema/annotations_openapi.yml b/bundle/internal/schema/annotations_openapi.yml index c196c7799a8..d688086e7f9 100644 --- a/bundle/internal/schema/annotations_openapi.yml +++ b/bundle/internal/schema/annotations_openapi.yml @@ -180,6 +180,11 @@ github.com/databricks/cli/bundle/config/resources.Catalog: "connection_name": "description": |- The name of the connection to an external data source. + "managed_encryption_settings": + "description": |- + Control CMK encryption for managed catalog data + "x-databricks-preview": |- + PRIVATE "name": "description": |- Name of catalog. @@ -566,6 +571,14 @@ github.com/databricks/cli/bundle/config/resources.ExternalLocation: The effective value of `enable_file_events` after applying server-side defaults. "x-databricks-field-behaviors_output_only": |- true + "effective_file_event_queue": + "description": |- + The effective file event queue configuration after applying server-side defaults. + Always populated when a queue is provisioned, regardless of whether the user explicitly + set `enable_file_events`. Use this field instead of `file_event_queue` for reading + the actual queue state. + "x-databricks-field-behaviors_output_only": |- + true "enable_file_events": "description": |- Whether to enable file events on this external location. Default to `true`. Set to `false` to disable file events. @@ -1240,14 +1253,19 @@ github.com/databricks/databricks-sdk-go/service/apps.AppResource: "name": "description": |- Name of the App Resource. - "postgres": - "x-databricks-preview": |- - PRIVATE + "postgres": {} "secret": {} "serving_endpoint": {} "sql_warehouse": {} "uc_securable": {} -github.com/databricks/databricks-sdk-go/service/apps.AppResourceApp: {} +github.com/databricks/databricks-sdk-go/service/apps.AppResourceApp: + "name": {} + "permission": {} +github.com/databricks/databricks-sdk-go/service/apps.AppResourceAppAppPermission: + "_": + "enum": + - |- + CAN_USE github.com/databricks/databricks-sdk-go/service/apps.AppResourceDatabase: "database_name": {} "instance_name": {} @@ -1303,15 +1321,9 @@ github.com/databricks/databricks-sdk-go/service/apps.AppResourceJobJobPermission - |- CAN_VIEW github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgres: - "branch": - "x-databricks-preview": |- - PRIVATE - "database": - "x-databricks-preview": |- - PRIVATE - "permission": - "x-databricks-preview": |- - PRIVATE + "branch": {} + "database": {} + "permission": {} github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgresPostgresPermission: "_": "enum": @@ -1555,6 +1567,10 @@ github.com/databricks/databricks-sdk-go/service/catalog.AwsSqsQueue: "description": |- The AQS queue url in the format https://sqs.{region}.amazonaws.com/{account id}/{queue name}. Only required for provided_sqs. +github.com/databricks/databricks-sdk-go/service/catalog.AzureEncryptionSettings: + "azure_cmk_access_connector_id": {} + "azure_cmk_managed_identity_id": {} + "azure_tenant_id": {} github.com/databricks/databricks-sdk-go/service/catalog.AzureQueueStorage: "managed_resource_id": "description": |- @@ -1582,6 +1598,20 @@ github.com/databricks/databricks-sdk-go/service/catalog.EncryptionDetails: "sse_encryption_details": "description": |- Server-Side Encryption properties for clients communicating with AWS s3. +github.com/databricks/databricks-sdk-go/service/catalog.EncryptionSettings: + "_": + "description": |- + Encryption Settings are used to carry metadata for securable encryption at rest. + Currently used for catalogs, we can use the information supplied here to interact with a CMK. + "azure_encryption_settings": + "description": |- + optional Azure settings - only required if an Azure CMK is used. + "azure_key_vault_key_id": + "description": |- + the AKV URL in Azure, null otherwise. + "customer_managed_key_id": + "description": |- + the CMK uuid in AWS and GCP, null otherwise. github.com/databricks/databricks-sdk-go/service/catalog.FileEventQueue: "managed_aqs": {} "managed_pubsub": {} @@ -2349,8 +2379,12 @@ github.com/databricks/databricks-sdk-go/service/compute.Environment: In this minimal environment spec, only pip and java dependencies are supported. "base_environment": "description": |- - The `base_environment` key refers to an `env.yaml` file that specifies an environment version and a collection of dependencies required for the environment setup. - This `env.yaml` file may itself include a `base_environment` reference pointing to another `env_1.yaml` file. However, when used as a base environment, `env_1.yaml` (or further nested references) will not be processed or included in the final environment, meaning that the resolution of `base_environment` references is not recursive. + The base environment this environment is built on top of. A base environment defines the environment version and a + list of dependencies for serverless compute. The value can be a file path to a custom `env.yaml` file + (e.g., `/Workspace/path/to/env.yaml`). Support for a Databricks-provided base environment ID + (e.g., `workspace-base-environments/databricks_ai_v4`) and workspace base environment ID + (e.g., `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in Beta. + Either `environment_version` or `base_environment` can be provided. For more information, see "client": "description": |- Use `environment_version` instead. @@ -4018,7 +4052,8 @@ github.com/databricks/databricks-sdk-go/service/jobs.TableUpdateTriggerConfigura github.com/databricks/databricks-sdk-go/service/jobs.Task: "alert_task": "description": |- - New alert v2 task + The task evaluates a Databricks alert and sends notifications to subscribers + when the `alert_task` field is present. "clean_rooms_notebook_task": "description": |- The task runs a [clean rooms](https://docs.databricks.com/clean-rooms/index.html) notebook @@ -4310,6 +4345,28 @@ github.com/databricks/databricks-sdk-go/service/pipelines.ConnectionParameters: For Oracle databases, this maps to a service name. "x-databricks-preview": |- PRIVATE +github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions: + "_": + "description": |- + Wrapper message for source-specific options to support multiple connector types + "gdrive_options": + "x-databricks-preview": |- + PRIVATE + "google_ads_options": + "description": |- + Google Ads specific options for ingestion (object-level). + When set, these values override the corresponding fields in GoogleAdsConfig + (source_configurations). + "x-databricks-preview": |- + PRIVATE + "sharepoint_options": + "x-databricks-preview": |- + PRIVATE + "tiktok_ads_options": + "description": |- + TikTok Ads specific options for ingestion + "x-databricks-preview": |- + PRIVATE github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorType: "_": "description": |- @@ -4382,6 +4439,82 @@ github.com/databricks/databricks-sdk-go/service/pipelines.EventLogSpec: "schema": "description": |- The UC schema the event log is published under. +github.com/databricks/databricks-sdk-go/service/pipelines.FileFilter: + "modified_after": + "description": |- + Include files with modification times occurring after the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + "modified_before": + "description": |- + Include files with modification times occurring before the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + "path_filter": + "description": |- + Include files with file names matching the pattern + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter +github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions: + "corrupt_record_column": {} + "file_filters": + "description": |- + Generic options + "format": + "description": |- + required for TableSpec + "format_options": + "description": |- + Format-specific options + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options + "ignore_corrupt_files": {} + "infer_column_types": {} + "reader_case_sensitive": + "description": |- + Column name case sensitivity + https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior + "rescued_data_column": {} + "schema_evolution_mode": + "description": |- + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work + "schema_hints": + "description": |- + Override inferred schema of specific columns + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints + "single_variant_column": {} +github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsFileFormat: + "_": + "enum": + - |- + BINARYFILE + - |- + JSON + - |- + CSV + - |- + XML + - |- + EXCEL + - |- + PARQUET + - |- + AVRO + - |- + ORC +github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsSchemaEvolutionMode: + "_": + "description": |- + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work + "enum": + - |- + ADD_NEW_COLUMNS_WITH_TYPE_WIDENING + - |- + ADD_NEW_COLUMNS + - |- + RESCUE + - |- + FAIL_ON_NEW_COLUMNS + - |- + NONE github.com/databricks/databricks-sdk-go/service/pipelines.FileLibrary: "path": "description": |- @@ -4393,6 +4526,41 @@ github.com/databricks/databricks-sdk-go/service/pipelines.Filters: "include": "description": |- Paths to include. +github.com/databricks/databricks-sdk-go/service/pipelines.GoogleAdsOptions: + "_": + "description": |- + Google Ads specific options for ingestion (object-level). + When set, these values override the corresponding fields in GoogleAdsConfig + (source_configurations). + "lookback_window_days": + "description": |- + (Optional) Number of days to look back for report tables to capture late-arriving data. + If not specified, defaults to 30 days. + "manager_account_id": + "description": |- + (Optional at this level) Manager Account ID (also called MCC Account ID) used to list + and access customer accounts under this manager account. + Overrides GoogleAdsConfig.manager_account_id from source_configurations when set. + "sync_start_date": + "description": |- + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 2 years of historical data. +github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptions: + "entity_type": {} + "file_ingestion_options": {} + "url": + "description": |- + Google Drive URL. +github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptionsGoogleDriveEntityType: + "_": + "enum": + - |- + FILE + - |- + FILE_METADATA + - |- + PERMISSION github.com/databricks/databricks-sdk-go/service/pipelines.IngestionConfig: "report": "description": |- @@ -4594,6 +4762,8 @@ github.com/databricks/databricks-sdk-go/service/pipelines.IngestionSourceType: SHAREPOINT - |- DYNAMICS365 + - |- + GOOGLE_DRIVE - |- FOREIGN_CATALOG github.com/databricks/databricks-sdk-go/service/pipelines.ManualTrigger: {} @@ -4892,6 +5062,11 @@ github.com/databricks/databricks-sdk-go/service/pipelines.RunAs: "description": |- The email of an active workspace user. Users can only set this field to their own email. github.com/databricks/databricks-sdk-go/service/pipelines.SchemaSpec: + "connector_options": + "description": |- + (Optional) Source Specific Connector Options + "x-databricks-preview": |- + PRIVATE "destination_catalog": "description": |- Required. Destination catalog to store tables. @@ -4907,6 +5082,28 @@ github.com/databricks/databricks-sdk-go/service/pipelines.SchemaSpec: "table_configuration": "description": |- Configuration settings to control the ingestion of tables. These settings are applied to all tables in this schema and override the table_configuration defined in the IngestionPipelineDefinition object. +github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptions: + "entity_type": + "description": |- + (Optional) The type of SharePoint entity to ingest. + If not specified, defaults to FILE. + "file_ingestion_options": + "description": |- + (Optional) File ingestion options for processing files. + "url": + "description": |- + Required. The SharePoint URL. +github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptionsSharepointEntityType: + "_": + "enum": + - |- + FILE + - |- + FILE_METADATA + - |- + PERMISSION + - |- + LIST github.com/databricks/databricks-sdk-go/service/pipelines.SourceCatalogConfig: "_": "description": |- @@ -4922,6 +5119,11 @@ github.com/databricks/databricks-sdk-go/service/pipelines.SourceConfig: "description": |- Catalog-level source configuration parameters github.com/databricks/databricks-sdk-go/service/pipelines.TableSpec: + "connector_options": + "description": |- + (Optional) Source Specific Connector Options + "x-databricks-preview": |- + PRIVATE "destination_catalog": "description": |- Required. Destination catalog to store table. @@ -5014,6 +5216,74 @@ github.com/databricks/databricks-sdk-go/service/pipelines.TableSpecificConfigScd SCD_TYPE_2 - |- APPEND_ONLY +github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptions: + "_": + "description": |- + TikTok Ads specific options for ingestion + "data_level": + "description": |- + (Optional) Data level for the report. + If not specified, defaults to AUCTION_CAMPAIGN. + "dimensions": + "description": |- + (Optional) Dimensions to include in the report. + Examples: "campaign_id", "adgroup_id", "ad_id", "stat_time_day", "stat_time_hour" + If not specified, defaults to campaign_id. + "lookback_window_days": + "description": |- + (Optional) Number of days to look back for report tables during incremental sync + to capture late-arriving conversions and attribution data. + If not specified, defaults to 7 days. + "metrics": + "description": |- + (Optional) Metrics to include in the report. + Examples: "spend", "impressions", "clicks", "conversion", "cpc" + If not specified, defaults to basic metrics (spend, impressions, clicks, etc.) + "query_lifetime": + "description": |- + (Optional) Whether to request lifetime metrics (all-time aggregated data). + When true, the report returns all-time data. + If not specified, defaults to false. + "report_type": + "description": |- + (Optional) Report type for the TikTok Ads API. + If not specified, defaults to BASIC. + "sync_start_date": + "description": |- + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 1 year of historical data for daily reports + and 30 days for hourly reports. +github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokDataLevel: + "_": + "description": |- + Data level for TikTok Ads report aggregation. + "enum": + - |- + AUCTION_ADVERTISER + - |- + AUCTION_CAMPAIGN + - |- + AUCTION_ADGROUP + - |- + AUCTION_AD +github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokReportType: + "_": + "description": |- + Report type for TikTok Ads API. + "enum": + - |- + BASIC + - |- + AUDIENCE + - |- + PLAYABLE_AD + - |- + DSA + - |- + BUSINESS_CENTER + - |- + GMV_MAX github.com/databricks/databricks-sdk-go/service/postgres.EndpointGroupSpec: "enable_readable_secondaries": "description": |- diff --git a/bundle/internal/schema/annotations_openapi_overrides.yml b/bundle/internal/schema/annotations_openapi_overrides.yml index 611289083e7..184cc77cebd 100644 --- a/bundle/internal/schema/annotations_openapi_overrides.yml +++ b/bundle/internal/schema/annotations_openapi_overrides.yml @@ -635,6 +635,13 @@ github.com/databricks/databricks-sdk-go/service/apps.AppResource: "uc_securable": "description": |- PLACEHOLDER +github.com/databricks/databricks-sdk-go/service/apps.AppResourceApp: + "name": + "description": |- + PLACEHOLDER + "permission": + "description": |- + PLACEHOLDER github.com/databricks/databricks-sdk-go/service/apps.AppResourceDatabase: "database_name": "description": |- @@ -732,6 +739,16 @@ github.com/databricks/databricks-sdk-go/service/catalog.AwsSqsQueue: "queue_url": "description": |- PLACEHOLDER +github.com/databricks/databricks-sdk-go/service/catalog.AzureEncryptionSettings: + "azure_cmk_access_connector_id": + "description": |- + PLACEHOLDER + "azure_cmk_managed_identity_id": + "description": |- + PLACEHOLDER + "azure_tenant_id": + "description": |- + PLACEHOLDER github.com/databricks/databricks-sdk-go/service/catalog.AzureQueueStorage: "managed_resource_id": "description": |- @@ -947,6 +964,13 @@ github.com/databricks/databricks-sdk-go/service/jobs.Webhook: "id": "description": |- PLACEHOLDER +github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions: + "gdrive_options": + "description": |- + PLACEHOLDER + "sharepoint_options": + "description": |- + PLACEHOLDER github.com/databricks/databricks-sdk-go/service/pipelines.CronTrigger: "quartz_cron_schedule": "description": |- @@ -954,6 +978,29 @@ github.com/databricks/databricks-sdk-go/service/pipelines.CronTrigger: "timezone_id": "description": |- PLACEHOLDER +github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions: + "corrupt_record_column": + "description": |- + PLACEHOLDER + "ignore_corrupt_files": + "description": |- + PLACEHOLDER + "infer_column_types": + "description": |- + PLACEHOLDER + "rescued_data_column": + "description": |- + PLACEHOLDER + "single_variant_column": + "description": |- + PLACEHOLDER +github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptions: + "entity_type": + "description": |- + PLACEHOLDER + "file_ingestion_options": + "description": |- + PLACEHOLDER github.com/databricks/databricks-sdk-go/service/pipelines.IngestionPipelineDefinition: "netsuite_jar_path": "description": |- diff --git a/bundle/internal/validation/generated/enum_fields.go b/bundle/internal/validation/generated/enum_fields.go index c1e098ed80f..fbedbca51d9 100644 --- a/bundle/internal/validation/generated/enum_fields.go +++ b/bundle/internal/validation/generated/enum_fields.go @@ -27,6 +27,7 @@ var EnumFields = map[string][]string{ "resources.apps.*.pending_deployment.mode": {"AUTO_SYNC", "SNAPSHOT"}, "resources.apps.*.pending_deployment.status.state": {"CANCELLED", "FAILED", "IN_PROGRESS", "SUCCEEDED"}, "resources.apps.*.permissions[*].level": {"CAN_MANAGE", "CAN_USE"}, + "resources.apps.*.resources[*].app.permission": {"CAN_USE"}, "resources.apps.*.resources[*].database.permission": {"CAN_CONNECT_AND_CREATE"}, "resources.apps.*.resources[*].experiment.permission": {"CAN_EDIT", "CAN_MANAGE", "CAN_READ"}, "resources.apps.*.resources[*].genie_space.permission": {"CAN_EDIT", "CAN_MANAGE", "CAN_RUN", "CAN_VIEW"}, @@ -138,21 +139,37 @@ var EnumFields = map[string][]string{ "resources.models.*.permissions[*].level": {"CAN_EDIT", "CAN_MANAGE", "CAN_MANAGE_PRODUCTION_VERSIONS", "CAN_MANAGE_STAGING_VERSIONS", "CAN_READ"}, - "resources.pipelines.*.clusters[*].autoscale.mode": {"ENHANCED", "LEGACY"}, - "resources.pipelines.*.clusters[*].aws_attributes.availability": {"ON_DEMAND", "SPOT", "SPOT_WITH_FALLBACK"}, - "resources.pipelines.*.clusters[*].aws_attributes.ebs_volume_type": {"GENERAL_PURPOSE_SSD", "THROUGHPUT_OPTIMIZED_HDD"}, - "resources.pipelines.*.clusters[*].azure_attributes.availability": {"ON_DEMAND_AZURE", "SPOT_AZURE", "SPOT_WITH_FALLBACK_AZURE"}, - "resources.pipelines.*.clusters[*].gcp_attributes.availability": {"ON_DEMAND_GCP", "PREEMPTIBLE_GCP", "PREEMPTIBLE_WITH_FALLBACK_GCP"}, - "resources.pipelines.*.deployment.kind": {"BUNDLE"}, - "resources.pipelines.*.ingestion_definition.connector_type": {"CDC", "QUERY_BASED"}, - "resources.pipelines.*.ingestion_definition.full_refresh_window.days_of_week[*]": {"FRIDAY", "MONDAY", "SATURDAY", "SUNDAY", "THURSDAY", "TUESDAY", "WEDNESDAY"}, - "resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, - "resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, - "resources.pipelines.*.ingestion_definition.objects[*].table.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, - "resources.pipelines.*.ingestion_definition.source_type": {"BIGQUERY", "DYNAMICS365", "FOREIGN_CATALOG", "GA4_RAW_DATA", "MANAGED_POSTGRESQL", "MYSQL", "NETSUITE", "ORACLE", "POSTGRESQL", "SALESFORCE", "SERVICENOW", "SHAREPOINT", "SQLSERVER", "TERADATA", "WORKDAY_RAAS"}, - "resources.pipelines.*.ingestion_definition.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, - "resources.pipelines.*.permissions[*].level": {"CAN_MANAGE", "CAN_RUN", "CAN_VIEW", "IS_OWNER"}, - "resources.pipelines.*.restart_window.days_of_week[*]": {"FRIDAY", "MONDAY", "SATURDAY", "SUNDAY", "THURSDAY", "TUESDAY", "WEDNESDAY"}, + "resources.pipelines.*.clusters[*].autoscale.mode": {"ENHANCED", "LEGACY"}, + "resources.pipelines.*.clusters[*].aws_attributes.availability": {"ON_DEMAND", "SPOT", "SPOT_WITH_FALLBACK"}, + "resources.pipelines.*.clusters[*].aws_attributes.ebs_volume_type": {"GENERAL_PURPOSE_SSD", "THROUGHPUT_OPTIMIZED_HDD"}, + "resources.pipelines.*.clusters[*].azure_attributes.availability": {"ON_DEMAND_AZURE", "SPOT_AZURE", "SPOT_WITH_FALLBACK_AZURE"}, + "resources.pipelines.*.clusters[*].gcp_attributes.availability": {"ON_DEMAND_GCP", "PREEMPTIBLE_GCP", "PREEMPTIBLE_WITH_FALLBACK_GCP"}, + "resources.pipelines.*.deployment.kind": {"BUNDLE"}, + "resources.pipelines.*.ingestion_definition.connector_type": {"CDC", "QUERY_BASED"}, + "resources.pipelines.*.ingestion_definition.full_refresh_window.days_of_week[*]": {"FRIDAY", "MONDAY", "SATURDAY", "SUNDAY", "THURSDAY", "TUESDAY", "WEDNESDAY"}, + "resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.entity_type": {"FILE", "FILE_METADATA", "PERMISSION"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.format": {"AVRO", "BINARYFILE", "CSV", "EXCEL", "JSON", "ORC", "PARQUET", "XML"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.gdrive_options.file_ingestion_options.schema_evolution_mode": {"ADD_NEW_COLUMNS", "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", "FAIL_ON_NEW_COLUMNS", "NONE", "RESCUE"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.entity_type": {"FILE", "FILE_METADATA", "LIST", "PERMISSION"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.format": {"AVRO", "BINARYFILE", "CSV", "EXCEL", "JSON", "ORC", "PARQUET", "XML"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.sharepoint_options.file_ingestion_options.schema_evolution_mode": {"ADD_NEW_COLUMNS", "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", "FAIL_ON_NEW_COLUMNS", "NONE", "RESCUE"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.data_level": {"AUCTION_AD", "AUCTION_ADGROUP", "AUCTION_ADVERTISER", "AUCTION_CAMPAIGN"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.tiktok_ads_options.report_type": {"AUDIENCE", "BASIC", "BUSINESS_CENTER", "DSA", "GMV_MAX", "PLAYABLE_AD"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.entity_type": {"FILE", "FILE_METADATA", "PERMISSION"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.format": {"AVRO", "BINARYFILE", "CSV", "EXCEL", "JSON", "ORC", "PARQUET", "XML"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.gdrive_options.file_ingestion_options.schema_evolution_mode": {"ADD_NEW_COLUMNS", "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", "FAIL_ON_NEW_COLUMNS", "NONE", "RESCUE"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.entity_type": {"FILE", "FILE_METADATA", "LIST", "PERMISSION"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.format": {"AVRO", "BINARYFILE", "CSV", "EXCEL", "JSON", "ORC", "PARQUET", "XML"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.sharepoint_options.file_ingestion_options.schema_evolution_mode": {"ADD_NEW_COLUMNS", "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", "FAIL_ON_NEW_COLUMNS", "NONE", "RESCUE"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.data_level": {"AUCTION_AD", "AUCTION_ADGROUP", "AUCTION_ADVERTISER", "AUCTION_CAMPAIGN"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.tiktok_ads_options.report_type": {"AUDIENCE", "BASIC", "BUSINESS_CENTER", "DSA", "GMV_MAX", "PLAYABLE_AD"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, + "resources.pipelines.*.ingestion_definition.source_type": {"BIGQUERY", "DYNAMICS365", "FOREIGN_CATALOG", "GA4_RAW_DATA", "GOOGLE_DRIVE", "MANAGED_POSTGRESQL", "MYSQL", "NETSUITE", "ORACLE", "POSTGRESQL", "SALESFORCE", "SERVICENOW", "SHAREPOINT", "SQLSERVER", "TERADATA", "WORKDAY_RAAS"}, + "resources.pipelines.*.ingestion_definition.table_configuration.scd_type": {"APPEND_ONLY", "SCD_TYPE_1", "SCD_TYPE_2"}, + "resources.pipelines.*.permissions[*].level": {"CAN_MANAGE", "CAN_RUN", "CAN_VIEW", "IS_OWNER"}, + "resources.pipelines.*.restart_window.days_of_week[*]": {"FRIDAY", "MONDAY", "SATURDAY", "SUNDAY", "THURSDAY", "TUESDAY", "WEDNESDAY"}, "resources.postgres_endpoints.*.endpoint_type": {"ENDPOINT_TYPE_READ_ONLY", "ENDPOINT_TYPE_READ_WRITE"}, diff --git a/bundle/internal/validation/generated/required_fields.go b/bundle/internal/validation/generated/required_fields.go index d90345f83f1..8c2607cdd45 100644 --- a/bundle/internal/validation/generated/required_fields.go +++ b/bundle/internal/validation/generated/required_fields.go @@ -37,6 +37,7 @@ var RequiredFields = map[string][]string{ "resources.apps.*.telemetry_export_destinations[*].unity_catalog": {"logs_table", "metrics_table", "traces_table"}, "resources.catalogs.*": {"name"}, + "resources.catalogs.*.managed_encryption_settings.azure_encryption_settings": {"azure_tenant_id"}, "resources.clusters.*.cluster_log_conf.dbfs": {"destination"}, "resources.clusters.*.cluster_log_conf.s3": {"destination"}, @@ -206,8 +207,10 @@ var RequiredFields = map[string][]string{ "resources.pipelines.*.ingestion_definition.objects[*].report": {"destination_catalog", "destination_schema", "source_url"}, "resources.pipelines.*.ingestion_definition.objects[*].report.table_configuration.auto_full_refresh_policy": {"enabled"}, "resources.pipelines.*.ingestion_definition.objects[*].schema": {"destination_catalog", "destination_schema", "source_schema"}, + "resources.pipelines.*.ingestion_definition.objects[*].schema.connector_options.google_ads_options": {"manager_account_id"}, "resources.pipelines.*.ingestion_definition.objects[*].schema.table_configuration.auto_full_refresh_policy": {"enabled"}, "resources.pipelines.*.ingestion_definition.objects[*].table": {"destination_catalog", "destination_schema", "source_table"}, + "resources.pipelines.*.ingestion_definition.objects[*].table.connector_options.google_ads_options": {"manager_account_id"}, "resources.pipelines.*.ingestion_definition.objects[*].table.table_configuration.auto_full_refresh_policy": {"enabled"}, "resources.pipelines.*.ingestion_definition.table_configuration.auto_full_refresh_policy": {"enabled"}, "resources.pipelines.*.libraries[*].maven": {"coordinates"}, diff --git a/bundle/permissions/workspace_root.go b/bundle/permissions/workspace_root.go index e8fc82813dd..efb0c711311 100644 --- a/bundle/permissions/workspace_root.go +++ b/bundle/permissions/workspace_root.go @@ -73,7 +73,7 @@ func setPermissions(ctx context.Context, w workspace.WorkspaceInterface, path st return nil } - obj, err := w.GetStatusByPath(ctx, path) + obj, err := w.GetStatusByPath(ctx, path) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return err } diff --git a/bundle/phases/destroy.go b/bundle/phases/destroy.go index 12720f1dc58..f45173dc88f 100644 --- a/bundle/phases/destroy.go +++ b/bundle/phases/destroy.go @@ -21,7 +21,7 @@ import ( func assertRootPathExists(ctx context.Context, b *bundle.Bundle) (bool, error) { w := b.WorkspaceClient() - _, err := w.Workspace.GetStatusByPath(ctx, b.Config.Workspace.RootPath) + _, err := w.Workspace.GetStatusByPath(ctx, b.Config.Workspace.RootPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. var aerr *apierr.APIError if errors.As(err, &aerr) && aerr.StatusCode == http.StatusNotFound { diff --git a/bundle/schema/jsonschema.json b/bundle/schema/jsonschema.json index 993adec7935..6b7288e9d5d 100644 --- a/bundle/schema/jsonschema.json +++ b/bundle/schema/jsonschema.json @@ -301,6 +301,12 @@ "lifecycle": { "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Lifecycle" }, + "managed_encryption_settings": { + "description": "Control CMK encryption for managed catalog data", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.EncryptionSettings", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "name": { "$ref": "#/$defs/string" }, @@ -1470,6 +1476,9 @@ "custom_tags": { "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/postgres.ProjectCustomTag" }, + "default_branch": { + "$ref": "#/$defs/string" + }, "default_endpoint_settings": { "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/postgres.ProjectDefaultEndpointSettings" }, @@ -2905,9 +2914,7 @@ "$ref": "#/$defs/string" }, "postgres": { - "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgres", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgres" }, "secret": { "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourceSecret" @@ -2937,6 +2944,14 @@ "oneOf": [ { "type": "object", + "properties": { + "name": { + "$ref": "#/$defs/string" + }, + "permission": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourceAppAppPermission" + } + }, "additionalProperties": false }, { @@ -2945,6 +2960,20 @@ } ] }, + "apps.AppResourceAppAppPermission": { + "oneOf": [ + { + "type": "string", + "enum": [ + "CAN_USE" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "apps.AppResourceDatabase": { "oneOf": [ { @@ -3119,19 +3148,13 @@ "type": "object", "properties": { "branch": { - "$ref": "#/$defs/string", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "$ref": "#/$defs/string" }, "database": { - "$ref": "#/$defs/string", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "$ref": "#/$defs/string" }, "permission": { - "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgresPostgresPermission", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgresPostgresPermission" } }, "additionalProperties": false @@ -3573,6 +3596,32 @@ } ] }, + "catalog.AzureEncryptionSettings": { + "oneOf": [ + { + "type": "object", + "properties": { + "azure_cmk_access_connector_id": { + "$ref": "#/$defs/string" + }, + "azure_cmk_managed_identity_id": { + "$ref": "#/$defs/string" + }, + "azure_tenant_id": { + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false, + "required": [ + "azure_tenant_id" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "catalog.AzureQueueStorage": { "oneOf": [ { @@ -3614,6 +3663,33 @@ } ] }, + "catalog.EncryptionSettings": { + "oneOf": [ + { + "type": "object", + "description": "Encryption Settings are used to carry metadata for securable encryption at rest.\nCurrently used for catalogs, we can use the information supplied here to interact with a CMK.", + "properties": { + "azure_encryption_settings": { + "description": "optional Azure settings - only required if an Azure CMK is used.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.AzureEncryptionSettings" + }, + "azure_key_vault_key_id": { + "description": "the AKV URL in Azure, null otherwise.", + "$ref": "#/$defs/string" + }, + "customer_managed_key_id": { + "description": "the CMK uuid in AWS and GCP, null otherwise.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "catalog.FileEventQueue": { "oneOf": [ { @@ -4592,7 +4668,7 @@ "description": "The environment entity used to preserve serverless environment side panel, jobs' environment for non-notebook task, and DLT's environment for classic and serverless pipelines.\nIn this minimal environment spec, only pip and java dependencies are supported.", "properties": { "base_environment": { - "description": "The `base_environment` key refers to an `env.yaml` file that specifies an environment version and a collection of dependencies required for the environment setup.\nThis `env.yaml` file may itself include a `base_environment` reference pointing to another `env_1.yaml` file. However, when used as a base environment, `env_1.yaml` (or further nested references) will not be processed or included in the final environment, meaning that the resolution of `base_environment` references is not recursive.", + "description": "The base environment this environment is built on top of. A base environment defines the environment version and a\nlist of dependencies for serverless compute. The value can be a file path to a custom `env.yaml` file\n(e.g., `/Workspace/path/to/env.yaml`). Support for a Databricks-provided base environment ID\n(e.g., `workspace-base-environments/databricks_ai_v4`) and workspace base environment ID\n(e.g., `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in Beta.\nEither `environment_version` or `base_environment` can be provided. For more information, see", "$ref": "#/$defs/string" }, "client": { @@ -7282,7 +7358,7 @@ "type": "object", "properties": { "alert_task": { - "description": "New alert v2 task", + "description": "The task evaluates a Databricks alert and sends notifications to subscribers\nwhen the `alert_task` field is present.", "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/jobs.AlertTask" }, "clean_rooms_notebook_task": { @@ -7777,6 +7853,43 @@ } ] }, + "pipelines.ConnectorOptions": { + "oneOf": [ + { + "type": "object", + "description": "Wrapper message for source-specific options to support multiple connector types", + "properties": { + "gdrive_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "google_ads_options": { + "description": "Google Ads specific options for ingestion (object-level).\nWhen set, these values override the corresponding fields in GoogleAdsConfig\n(source_configurations).", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleAdsOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "sharepoint_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "tiktok_ads_options": { + "description": "TikTok Ads specific options for ingestion", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "pipelines.ConnectorType": { "oneOf": [ { @@ -7907,6 +8020,125 @@ } ] }, + "pipelines.FileFilter": { + "oneOf": [ + { + "type": "object", + "properties": { + "modified_after": { + "description": "Include files with modification times occurring after the specified time.\nTimestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00)\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters", + "$ref": "#/$defs/string" + }, + "modified_before": { + "description": "Include files with modification times occurring before the specified time.\nTimestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00)\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters", + "$ref": "#/$defs/string" + }, + "path_filter": { + "description": "Include files with file names matching the pattern\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.FileIngestionOptions": { + "oneOf": [ + { + "type": "object", + "properties": { + "corrupt_record_column": { + "$ref": "#/$defs/string" + }, + "file_filters": { + "description": "Generic options", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/pipelines.FileFilter" + }, + "format": { + "description": "required for TableSpec", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsFileFormat" + }, + "format_options": { + "description": "Format-specific options\nBased on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options", + "$ref": "#/$defs/map/string" + }, + "ignore_corrupt_files": { + "$ref": "#/$defs/bool" + }, + "infer_column_types": { + "$ref": "#/$defs/bool" + }, + "reader_case_sensitive": { + "description": "Column name case sensitivity\nhttps://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior", + "$ref": "#/$defs/bool" + }, + "rescued_data_column": { + "$ref": "#/$defs/string" + }, + "schema_evolution_mode": { + "description": "Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsSchemaEvolutionMode" + }, + "schema_hints": { + "description": "Override inferred schema of specific columns\nBased on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints", + "$ref": "#/$defs/string" + }, + "single_variant_column": { + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.FileIngestionOptionsFileFormat": { + "oneOf": [ + { + "type": "string", + "enum": [ + "BINARYFILE", + "JSON", + "CSV", + "XML", + "EXCEL", + "PARQUET", + "AVRO", + "ORC" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.FileIngestionOptionsSchemaEvolutionMode": { + "oneOf": [ + { + "type": "string", + "description": "Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work", + "enum": [ + "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", + "ADD_NEW_COLUMNS", + "RESCUE", + "FAIL_ON_NEW_COLUMNS", + "NONE" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "pipelines.FileLibrary": { "oneOf": [ { @@ -7947,6 +8179,76 @@ } ] }, + "pipelines.GoogleAdsOptions": { + "oneOf": [ + { + "type": "object", + "description": "Google Ads specific options for ingestion (object-level).\nWhen set, these values override the corresponding fields in GoogleAdsConfig\n(source_configurations).", + "properties": { + "lookback_window_days": { + "description": "(Optional) Number of days to look back for report tables to capture late-arriving data.\nIf not specified, defaults to 30 days.", + "$ref": "#/$defs/int" + }, + "manager_account_id": { + "description": "(Optional at this level) Manager Account ID (also called MCC Account ID) used to list\nand access customer accounts under this manager account.\nOverrides GoogleAdsConfig.manager_account_id from source_configurations when set.", + "$ref": "#/$defs/string" + }, + "sync_start_date": { + "description": "(Optional) Start date for the initial sync of report tables in YYYY-MM-DD format.\nThis determines the earliest date from which to sync historical data.\nIf not specified, defaults to 2 years of historical data.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false, + "required": [ + "manager_account_id" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.GoogleDriveOptions": { + "oneOf": [ + { + "type": "object", + "properties": { + "entity_type": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptionsGoogleDriveEntityType" + }, + "file_ingestion_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions" + }, + "url": { + "description": "Google Drive URL.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.GoogleDriveOptionsGoogleDriveEntityType": { + "oneOf": [ + { + "type": "string", + "enum": [ + "FILE", + "FILE_METADATA", + "PERMISSION" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "pipelines.IngestionConfig": { "oneOf": [ { @@ -8185,6 +8487,7 @@ "TERADATA", "SHAREPOINT", "DYNAMICS365", + "GOOGLE_DRIVE", "FOREIGN_CATALOG" ] }, @@ -8700,6 +9003,12 @@ { "type": "object", "properties": { + "connector_options": { + "description": "(Optional) Source Specific Connector Options", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "destination_catalog": { "description": "Required. Destination catalog to store tables.", "$ref": "#/$defs/string" @@ -8734,6 +9043,49 @@ } ] }, + "pipelines.SharepointOptions": { + "oneOf": [ + { + "type": "object", + "properties": { + "entity_type": { + "description": "(Optional) The type of SharePoint entity to ingest.\nIf not specified, defaults to FILE.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptionsSharepointEntityType" + }, + "file_ingestion_options": { + "description": "(Optional) File ingestion options for processing files.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions" + }, + "url": { + "description": "Required. The SharePoint URL.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.SharepointOptionsSharepointEntityType": { + "oneOf": [ + { + "type": "string", + "enum": [ + "FILE", + "FILE_METADATA", + "PERMISSION", + "LIST" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "pipelines.SourceCatalogConfig": { "oneOf": [ { @@ -8780,6 +9132,12 @@ { "type": "object", "properties": { + "connector_options": { + "description": "(Optional) Source Specific Connector Options", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "destination_catalog": { "description": "Required. Destination catalog to store table.", "$ref": "#/$defs/string" @@ -8902,6 +9260,87 @@ } ] }, + "pipelines.TikTokAdsOptions": { + "oneOf": [ + { + "type": "object", + "description": "TikTok Ads specific options for ingestion", + "properties": { + "data_level": { + "description": "(Optional) Data level for the report.\nIf not specified, defaults to AUCTION_CAMPAIGN.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokDataLevel" + }, + "dimensions": { + "description": "(Optional) Dimensions to include in the report.\nExamples: \"campaign_id\", \"adgroup_id\", \"ad_id\", \"stat_time_day\", \"stat_time_hour\"\nIf not specified, defaults to campaign_id.", + "$ref": "#/$defs/slice/string" + }, + "lookback_window_days": { + "description": "(Optional) Number of days to look back for report tables during incremental sync\nto capture late-arriving conversions and attribution data.\nIf not specified, defaults to 7 days.", + "$ref": "#/$defs/int" + }, + "metrics": { + "description": "(Optional) Metrics to include in the report.\nExamples: \"spend\", \"impressions\", \"clicks\", \"conversion\", \"cpc\"\nIf not specified, defaults to basic metrics (spend, impressions, clicks, etc.)", + "$ref": "#/$defs/slice/string" + }, + "query_lifetime": { + "description": "(Optional) Whether to request lifetime metrics (all-time aggregated data).\nWhen true, the report returns all-time data.\nIf not specified, defaults to false.", + "$ref": "#/$defs/bool" + }, + "report_type": { + "description": "(Optional) Report type for the TikTok Ads API.\nIf not specified, defaults to BASIC.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokReportType" + }, + "sync_start_date": { + "description": "(Optional) Start date for the initial sync of report tables in YYYY-MM-DD format.\nThis determines the earliest date from which to sync historical data.\nIf not specified, defaults to 1 year of historical data for daily reports\nand 30 days for hourly reports.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.TikTokAdsOptionsTikTokDataLevel": { + "oneOf": [ + { + "type": "string", + "description": "Data level for TikTok Ads report aggregation.", + "enum": [ + "AUCTION_ADVERTISER", + "AUCTION_CAMPAIGN", + "AUCTION_ADGROUP", + "AUCTION_AD" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "pipelines.TikTokAdsOptionsTikTokReportType": { + "oneOf": [ + { + "type": "string", + "description": "Report type for TikTok Ads API.", + "enum": [ + "BASIC", + "AUDIENCE", + "PLAYABLE_AD", + "DSA", + "BUSINESS_CENTER", + "GMV_MAX" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "postgres.EndpointGroupSpec": { "oneOf": [ { @@ -11629,6 +12068,20 @@ } ] }, + "pipelines.FileFilter": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileFilter" + } + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "pipelines.IngestionConfig": { "oneOf": [ { diff --git a/bundle/schema/jsonschema_for_docs.json b/bundle/schema/jsonschema_for_docs.json index bcb68662967..e5d1b20a458 100644 --- a/bundle/schema/jsonschema_for_docs.json +++ b/bundle/schema/jsonschema_for_docs.json @@ -119,7 +119,7 @@ }, "lifecycle": { "description": "Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.", - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Lifecycle", + "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.LifecycleWithStarted", "x-since-version": "v0.268.0" }, "name": { @@ -244,6 +244,12 @@ "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Lifecycle", "x-since-version": "v0.287.0" }, + "managed_encryption_settings": { + "description": "Control CMK encryption for managed catalog data", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.EncryptionSettings", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "name": { "$ref": "#/$defs/string", "x-since-version": "v0.287.0" @@ -890,6 +896,22 @@ }, "additionalProperties": false }, + "resources.LifecycleWithStarted": { + "type": "object", + "properties": { + "prevent_destroy": { + "description": "Lifecycle setting to prevent the resource from being destroyed.", + "$ref": "#/$defs/bool", + "x-since-version": "v0.297.0" + }, + "started": { + "description": "Lifecycle setting to deploy the resource in started mode. Only supported for apps, clusters, and sql_warehouses in direct deployment mode.", + "$ref": "#/$defs/bool", + "x-since-version": "v0.297.0" + } + }, + "additionalProperties": false + }, "resources.MlflowExperiment": { "type": "object", "properties": { @@ -1438,6 +1460,9 @@ "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/postgres.ProjectCustomTag", "x-since-version": "v0.290.0" }, + "default_branch": { + "$ref": "#/$defs/string" + }, "default_endpoint_settings": { "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/postgres.ProjectDefaultEndpointSettings", "x-since-version": "v0.287.0" @@ -2592,6 +2617,11 @@ "config.Workspace": { "type": "object", "properties": { + "account_id": { + "description": "The Databricks account ID.", + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" + }, "artifact_path": { "description": "The artifact path to use within the workspace for both deployments and workflow runs", "$ref": "#/$defs/string", @@ -2813,8 +2843,6 @@ }, "postgres": { "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgres", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true, "x-since-version": "v0.294.0" }, "secret": { @@ -2841,8 +2869,22 @@ }, "apps.AppResourceApp": { "type": "object", + "properties": { + "name": { + "$ref": "#/$defs/string" + }, + "permission": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourceAppAppPermission" + } + }, "additionalProperties": false }, + "apps.AppResourceAppAppPermission": { + "type": "string", + "enum": [ + "CAN_USE" + ] + }, "apps.AppResourceDatabase": { "type": "object", "properties": { @@ -2962,20 +3004,14 @@ "properties": { "branch": { "$ref": "#/$defs/string", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true, "x-since-version": "v0.294.0" }, "database": { "$ref": "#/$defs/string", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true, "x-since-version": "v0.294.0" }, "permission": { "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/apps.AppResourcePostgresPostgresPermission", - "x-databricks-preview": "PRIVATE", - "doNotSuggest": true, "x-since-version": "v0.294.0" } }, @@ -3268,6 +3304,24 @@ }, "additionalProperties": false }, + "catalog.AzureEncryptionSettings": { + "type": "object", + "properties": { + "azure_cmk_access_connector_id": { + "$ref": "#/$defs/string" + }, + "azure_cmk_managed_identity_id": { + "$ref": "#/$defs/string" + }, + "azure_tenant_id": { + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false, + "required": [ + "azure_tenant_id" + ] + }, "catalog.AzureQueueStorage": { "type": "object", "properties": { @@ -3297,6 +3351,25 @@ }, "additionalProperties": false }, + "catalog.EncryptionSettings": { + "type": "object", + "description": "Encryption Settings are used to carry metadata for securable encryption at rest.\nCurrently used for catalogs, we can use the information supplied here to interact with a CMK.", + "properties": { + "azure_encryption_settings": { + "description": "optional Azure settings - only required if an Azure CMK is used.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.AzureEncryptionSettings" + }, + "azure_key_vault_key_id": { + "description": "the AKV URL in Azure, null otherwise.", + "$ref": "#/$defs/string" + }, + "customer_managed_key_id": { + "description": "the CMK uuid in AWS and GCP, null otherwise.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, "catalog.FileEventQueue": { "type": "object", "properties": { @@ -4100,7 +4173,7 @@ "description": "The environment entity used to preserve serverless environment side panel, jobs' environment for non-notebook task, and DLT's environment for classic and serverless pipelines.\nIn this minimal environment spec, only pip and java dependencies are supported.", "properties": { "base_environment": { - "description": "The `base_environment` key refers to an `env.yaml` file that specifies an environment version and a collection of dependencies required for the environment setup.\nThis `env.yaml` file may itself include a `base_environment` reference pointing to another `env_1.yaml` file. However, when used as a base environment, `env_1.yaml` (or further nested references) will not be processed or included in the final environment, meaning that the resolution of `base_environment` references is not recursive.", + "description": "The base environment this environment is built on top of. A base environment defines the environment version and a\nlist of dependencies for serverless compute. The value can be a file path to a custom `env.yaml` file\n(e.g., `/Workspace/path/to/env.yaml`). Support for a Databricks-provided base environment ID\n(e.g., `workspace-base-environments/databricks_ai_v4`) and workspace base environment ID\n(e.g., `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in Beta.\nEither `environment_version` or `base_environment` can be provided. For more information, see", "$ref": "#/$defs/string", "x-since-version": "v0.289.0" }, @@ -4753,19 +4826,23 @@ "properties": { "alert_id": { "description": "The alert_id is the canonical identifier of the alert.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" }, "subscribers": { "description": "The subscribers receive alert evaluation result notifications after the alert task is completed.\nThe number of subscriptions is limited to 100.", - "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/jobs.AlertTaskSubscriber" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/jobs.AlertTaskSubscriber", + "x-since-version": "v0.296.0" }, "warehouse_id": { "description": "The warehouse_id identifies the warehouse settings used by the alert task.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" }, "workspace_path": { "description": "The workspace_path is the path to the alert file in the workspace. The path:\n* must start with \"/Workspace\"\n* must be a normalized path.\nUser has to select only one of alert_id or workspace_path to identify the alert.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" } }, "additionalProperties": false @@ -4775,11 +4852,13 @@ "description": "Represents a subscriber that will receive alert notifications.\nA subscriber can be either a user (via email) or a notification destination (via destination_id).", "properties": { "destination_id": { - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" }, "user_name": { "description": "A valid workspace email address.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" } }, "additionalProperties": false @@ -6158,8 +6237,9 @@ "type": "object", "properties": { "alert_task": { - "description": "New alert v2 task", - "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/jobs.AlertTask" + "description": "The task evaluates a Databricks alert and sends notifications to subscribers\nwhen the `alert_task` field is present.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/jobs.AlertTask", + "x-since-version": "v0.296.0" }, "clean_rooms_notebook_task": { "description": "The task runs a [clean rooms](https://docs.databricks.com/clean-rooms/index.html) notebook\nwhen the `clean_rooms_notebook_task` field is present.", @@ -6609,6 +6689,35 @@ }, "additionalProperties": false }, + "pipelines.ConnectorOptions": { + "type": "object", + "description": "Wrapper message for source-specific options to support multiple connector types", + "properties": { + "gdrive_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "google_ads_options": { + "description": "Google Ads specific options for ingestion (object-level).\nWhen set, these values override the corresponding fields in GoogleAdsConfig\n(source_configurations).", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleAdsOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "sharepoint_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, + "tiktok_ads_options": { + "description": "TikTok Ads specific options for ingestion", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + } + }, + "additionalProperties": false + }, "pipelines.ConnectorType": { "type": "string", "description": "For certain database sources LakeFlow Connect offers both query based and cdc\ningestion, ConnectorType can bse used to convey the type of ingestion.\nIf connection_name is provided for database sources, we default to Query Based ingestion", @@ -6637,15 +6746,18 @@ "properties": { "catalog_name": { "description": "(Required, Immutable) The name of the catalog for the connector's staging storage location.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" }, "schema_name": { "description": "(Required, Immutable) The name of the schema for the connector's staging storage location.", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" }, "volume_name": { "description": "(Optional) The Unity Catalog-compatible name for the storage location.\nThis is the volume to use for the data that is extracted by the connector.\nSpark Declarative Pipelines system will automatically create the volume under the catalog and schema.\nFor Combined Cdc Managed Ingestion pipelines default name for the volume would be :\n__databricks_ingestion_gateway_staging_data-$pipelineId", - "$ref": "#/$defs/string" + "$ref": "#/$defs/string", + "x-since-version": "v0.296.0" } }, "additionalProperties": false, @@ -6696,6 +6808,93 @@ }, "additionalProperties": false }, + "pipelines.FileFilter": { + "type": "object", + "properties": { + "modified_after": { + "description": "Include files with modification times occurring after the specified time.\nTimestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00)\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters", + "$ref": "#/$defs/string" + }, + "modified_before": { + "description": "Include files with modification times occurring before the specified time.\nTimestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00)\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters", + "$ref": "#/$defs/string" + }, + "path_filter": { + "description": "Include files with file names matching the pattern\nBased on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + "pipelines.FileIngestionOptions": { + "type": "object", + "properties": { + "corrupt_record_column": { + "$ref": "#/$defs/string" + }, + "file_filters": { + "description": "Generic options", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/pipelines.FileFilter" + }, + "format": { + "description": "required for TableSpec", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsFileFormat" + }, + "format_options": { + "description": "Format-specific options\nBased on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options", + "$ref": "#/$defs/map/string" + }, + "ignore_corrupt_files": { + "$ref": "#/$defs/bool" + }, + "infer_column_types": { + "$ref": "#/$defs/bool" + }, + "reader_case_sensitive": { + "description": "Column name case sensitivity\nhttps://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior", + "$ref": "#/$defs/bool" + }, + "rescued_data_column": { + "$ref": "#/$defs/string" + }, + "schema_evolution_mode": { + "description": "Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptionsSchemaEvolutionMode" + }, + "schema_hints": { + "description": "Override inferred schema of specific columns\nBased on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints", + "$ref": "#/$defs/string" + }, + "single_variant_column": { + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + "pipelines.FileIngestionOptionsFileFormat": { + "type": "string", + "enum": [ + "BINARYFILE", + "JSON", + "CSV", + "XML", + "EXCEL", + "PARQUET", + "AVRO", + "ORC" + ] + }, + "pipelines.FileIngestionOptionsSchemaEvolutionMode": { + "type": "string", + "description": "Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work", + "enum": [ + "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", + "ADD_NEW_COLUMNS", + "RESCUE", + "FAIL_ON_NEW_COLUMNS", + "NONE" + ] + }, "pipelines.FileLibrary": { "type": "object", "properties": { @@ -6723,6 +6922,52 @@ }, "additionalProperties": false }, + "pipelines.GoogleAdsOptions": { + "type": "object", + "description": "Google Ads specific options for ingestion (object-level).\nWhen set, these values override the corresponding fields in GoogleAdsConfig\n(source_configurations).", + "properties": { + "lookback_window_days": { + "description": "(Optional) Number of days to look back for report tables to capture late-arriving data.\nIf not specified, defaults to 30 days.", + "$ref": "#/$defs/int" + }, + "manager_account_id": { + "description": "(Optional at this level) Manager Account ID (also called MCC Account ID) used to list\nand access customer accounts under this manager account.\nOverrides GoogleAdsConfig.manager_account_id from source_configurations when set.", + "$ref": "#/$defs/string" + }, + "sync_start_date": { + "description": "(Optional) Start date for the initial sync of report tables in YYYY-MM-DD format.\nThis determines the earliest date from which to sync historical data.\nIf not specified, defaults to 2 years of historical data.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false, + "required": [ + "manager_account_id" + ] + }, + "pipelines.GoogleDriveOptions": { + "type": "object", + "properties": { + "entity_type": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.GoogleDriveOptionsGoogleDriveEntityType" + }, + "file_ingestion_options": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions" + }, + "url": { + "description": "Google Drive URL.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + "pipelines.GoogleDriveOptionsGoogleDriveEntityType": { + "type": "string", + "enum": [ + "FILE", + "FILE_METADATA", + "PERMISSION" + ] + }, "pipelines.IngestionConfig": { "type": "object", "properties": { @@ -6801,13 +7046,15 @@ "description": "(Optional) Connector Type for sources. Ex: CDC, Query Based.", "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorType", "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "doNotSuggest": true, + "x-since-version": "v0.296.0" }, "data_staging_options": { "description": "(Optional) Location of staged data storage. This is required for migration from Cdc Managed Ingestion Pipeline\nwith Gateway pipeline to Combined Cdc Managed Ingestion Pipeline.\nIf not specified, the volume for staged data will be created in catalog and schema/target specified in the\ntop level pipeline definition.", "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.DataStagingOptions", "x-databricks-preview": "PRIVATE", - "doNotSuggest": true + "doNotSuggest": true, + "x-since-version": "v0.296.0" }, "full_refresh_window": { "description": "(Optional) A window that specifies a set of time ranges for snapshot queries in CDC.", @@ -6936,6 +7183,7 @@ "TERADATA", "SHAREPOINT", "DYNAMICS365", + "GOOGLE_DRIVE", "FOREIGN_CATALOG" ] }, @@ -7353,6 +7601,12 @@ "pipelines.SchemaSpec": { "type": "object", "properties": { + "connector_options": { + "description": "(Optional) Source Specific Connector Options", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "destination_catalog": { "description": "Required. Destination catalog to store tables.", "$ref": "#/$defs/string", @@ -7386,6 +7640,33 @@ "source_schema" ] }, + "pipelines.SharepointOptions": { + "type": "object", + "properties": { + "entity_type": { + "description": "(Optional) The type of SharePoint entity to ingest.\nIf not specified, defaults to FILE.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.SharepointOptionsSharepointEntityType" + }, + "file_ingestion_options": { + "description": "(Optional) File ingestion options for processing files.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileIngestionOptions" + }, + "url": { + "description": "Required. The SharePoint URL.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + "pipelines.SharepointOptionsSharepointEntityType": { + "type": "string", + "enum": [ + "FILE", + "FILE_METADATA", + "PERMISSION", + "LIST" + ] + }, "pipelines.SourceCatalogConfig": { "type": "object", "description": "SourceCatalogConfig contains catalog-level custom configuration parameters for each source", @@ -7417,6 +7698,12 @@ "pipelines.TableSpec": { "type": "object", "properties": { + "connector_options": { + "description": "(Optional) Source Specific Connector Options", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.ConnectorOptions", + "x-databricks-preview": "PRIVATE", + "doNotSuggest": true + }, "destination_catalog": { "description": "Required. Destination catalog to store table.", "$ref": "#/$defs/string", @@ -7534,6 +7821,63 @@ "APPEND_ONLY" ] }, + "pipelines.TikTokAdsOptions": { + "type": "object", + "description": "TikTok Ads specific options for ingestion", + "properties": { + "data_level": { + "description": "(Optional) Data level for the report.\nIf not specified, defaults to AUCTION_CAMPAIGN.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokDataLevel" + }, + "dimensions": { + "description": "(Optional) Dimensions to include in the report.\nExamples: \"campaign_id\", \"adgroup_id\", \"ad_id\", \"stat_time_day\", \"stat_time_hour\"\nIf not specified, defaults to campaign_id.", + "$ref": "#/$defs/slice/string" + }, + "lookback_window_days": { + "description": "(Optional) Number of days to look back for report tables during incremental sync\nto capture late-arriving conversions and attribution data.\nIf not specified, defaults to 7 days.", + "$ref": "#/$defs/int" + }, + "metrics": { + "description": "(Optional) Metrics to include in the report.\nExamples: \"spend\", \"impressions\", \"clicks\", \"conversion\", \"cpc\"\nIf not specified, defaults to basic metrics (spend, impressions, clicks, etc.)", + "$ref": "#/$defs/slice/string" + }, + "query_lifetime": { + "description": "(Optional) Whether to request lifetime metrics (all-time aggregated data).\nWhen true, the report returns all-time data.\nIf not specified, defaults to false.", + "$ref": "#/$defs/bool" + }, + "report_type": { + "description": "(Optional) Report type for the TikTok Ads API.\nIf not specified, defaults to BASIC.", + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.TikTokAdsOptionsTikTokReportType" + }, + "sync_start_date": { + "description": "(Optional) Start date for the initial sync of report tables in YYYY-MM-DD format.\nThis determines the earliest date from which to sync historical data.\nIf not specified, defaults to 1 year of historical data for daily reports\nand 30 days for hourly reports.", + "$ref": "#/$defs/string" + } + }, + "additionalProperties": false + }, + "pipelines.TikTokAdsOptionsTikTokDataLevel": { + "type": "string", + "description": "Data level for TikTok Ads report aggregation.", + "enum": [ + "AUCTION_ADVERTISER", + "AUCTION_CAMPAIGN", + "AUCTION_ADGROUP", + "AUCTION_AD" + ] + }, + "pipelines.TikTokAdsOptionsTikTokReportType": { + "type": "string", + "description": "Report type for TikTok Ads API.", + "enum": [ + "BASIC", + "AUDIENCE", + "PLAYABLE_AD", + "DSA", + "BUSINESS_CENTER", + "GMV_MAX" + ] + }, "postgres.EndpointGroupSpec": { "type": "object", "properties": { @@ -9315,6 +9659,12 @@ "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.DayOfWeek" } }, + "pipelines.FileFilter": { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/pipelines.FileFilter" + } + }, "pipelines.IngestionConfig": { "type": "array", "items": { diff --git a/cmd/account/access-control/access-control.go b/cmd/account/access-control/access-control.go index 9dc0566f1ee..2dab1d83a99 100755 --- a/cmd/account/access-control/access-control.go +++ b/cmd/account/access-control/access-control.go @@ -92,6 +92,7 @@ func newGetAssignableRolesForResource() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -174,6 +175,7 @@ func newGetRuleSet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -240,6 +242,7 @@ func newUpdateRuleSet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/billable-usage/billable-usage.go b/cmd/account/billable-usage/billable-usage.go index 624c23c7384..d89b87e4440 100755 --- a/cmd/account/billable-usage/billable-usage.go +++ b/cmd/account/billable-usage/billable-usage.go @@ -95,6 +95,7 @@ func newDownload() *cobra.Command { if err != nil { return err } + defer response.Contents.Close() return cmdio.Render(ctx, response.Contents) } diff --git a/cmd/account/budget-policy/budget-policy.go b/cmd/account/budget-policy/budget-policy.go index 37adb68b13b..419168fd9ee 100755 --- a/cmd/account/budget-policy/budget-policy.go +++ b/cmd/account/budget-policy/budget-policy.go @@ -3,6 +3,8 @@ package budget_policy import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -94,6 +96,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -206,6 +209,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -234,12 +238,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq billing.ListBudgetPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int // TODO: complex arg: filter_by cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `The maximum number of budget policies to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A page token, received from a previous ListServerlessPolicies call.`) // TODO: complex arg: sort_spec + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List policies.` cmd.Long = `List policies. @@ -260,6 +274,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.BudgetPolicy.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -338,6 +359,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/budgets/budgets.go b/cmd/account/budgets/budgets.go index 9fb34e4664d..b6dfed84376 100755 --- a/cmd/account/budgets/budgets.go +++ b/cmd/account/budgets/budgets.go @@ -94,6 +94,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -208,6 +209,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -236,8 +238,17 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq billing.ListBudgetConfigurationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A page token received from a previous get all budget configurations call.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `Get all budgets.` @@ -258,6 +269,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.Budgets.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -332,6 +350,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/credentials/credentials.go b/cmd/account/credentials/credentials.go index 2c117acf06b..a940bf547d7 100755 --- a/cmd/account/credentials/credentials.go +++ b/cmd/account/credentials/credentials.go @@ -106,6 +106,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -164,6 +165,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -221,6 +223,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -264,6 +267,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/csp-enablement-account/csp-enablement-account.go b/cmd/account/csp-enablement-account/csp-enablement-account.go index 657f12c4eb8..f4d5388981f 100755 --- a/cmd/account/csp-enablement-account/csp-enablement-account.go +++ b/cmd/account/csp-enablement-account/csp-enablement-account.go @@ -81,6 +81,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -146,6 +147,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/custom-app-integration/custom-app-integration.go b/cmd/account/custom-app-integration/custom-app-integration.go index 3a6d9d151d9..7e1f79bcef8 100755 --- a/cmd/account/custom-app-integration/custom-app-integration.go +++ b/cmd/account/custom-app-integration/custom-app-integration.go @@ -3,6 +3,8 @@ package custom_app_integration import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -103,6 +105,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -213,6 +216,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -241,10 +245,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListCustomAppIntegrationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeCreatorUsername, "include-creator-username", listReq.IncludeCreatorUsername, ``) cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `Get custom oauth app integrations.` @@ -266,6 +280,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.CustomAppIntegration.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/disable-legacy-features/disable-legacy-features.go b/cmd/account/disable-legacy-features/disable-legacy-features.go index cd34fa7af09..32d554869d2 100755 --- a/cmd/account/disable-legacy-features/disable-legacy-features.go +++ b/cmd/account/disable-legacy-features/disable-legacy-features.go @@ -80,6 +80,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -133,6 +134,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -197,6 +199,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/enable-ip-access-lists/enable-ip-access-lists.go b/cmd/account/enable-ip-access-lists/enable-ip-access-lists.go index 8c9da2ba77d..f1329c9732c 100755 --- a/cmd/account/enable-ip-access-lists/enable-ip-access-lists.go +++ b/cmd/account/enable-ip-access-lists/enable-ip-access-lists.go @@ -80,6 +80,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -133,6 +134,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -197,6 +199,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/encryption-keys/encryption-keys.go b/cmd/account/encryption-keys/encryption-keys.go index a60cf1fe4d8..dd0ee03b2c8 100755 --- a/cmd/account/encryption-keys/encryption-keys.go +++ b/cmd/account/encryption-keys/encryption-keys.go @@ -123,6 +123,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -180,6 +181,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -250,6 +252,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -292,6 +295,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/endpoints/endpoints.go b/cmd/account/endpoints/endpoints.go index 9e1d3e7bac1..3c8a78bbd1d 100755 --- a/cmd/account/endpoints/endpoints.go +++ b/cmd/account/endpoints/endpoints.go @@ -125,6 +125,7 @@ func newCreateEndpoint() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +234,7 @@ func newGetEndpoint() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,9 +263,19 @@ func newListEndpoints() *cobra.Command { cmd := &cobra.Command{} var listEndpointsReq networking.ListEndpointsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listEndpointsLimit int cmd.Flags().IntVar(&listEndpointsReq.PageSize, "page-size", listEndpointsReq.PageSize, ``) - cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listEndpointsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-endpoints PARENT" cmd.Short = `List network endpoints.` @@ -290,6 +302,13 @@ func newListEndpoints() *cobra.Command { listEndpointsReq.Parent = args[0] response := a.Endpoints.ListEndpoints(ctx, listEndpointsReq) + if listEndpointsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listEndpointsLimit) + } + if listEndpointsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listEndpointsLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/esm-enablement-account/esm-enablement-account.go b/cmd/account/esm-enablement-account/esm-enablement-account.go index 3cbc8d5afaf..d7468cf8f68 100755 --- a/cmd/account/esm-enablement-account/esm-enablement-account.go +++ b/cmd/account/esm-enablement-account/esm-enablement-account.go @@ -79,6 +79,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -144,6 +145,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/federation-policy/federation-policy.go b/cmd/account/federation-policy/federation-policy.go index e8aba32696b..64610ef39df 100755 --- a/cmd/account/federation-policy/federation-policy.go +++ b/cmd/account/federation-policy/federation-policy.go @@ -3,6 +3,8 @@ package federation_policy import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -142,6 +144,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -250,6 +253,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -278,9 +282,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListAccountFederationPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List account federation policies.` @@ -299,6 +313,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.FederationPolicy.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -373,6 +394,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/groups-v2/groups-v2.go b/cmd/account/groups-v2/groups-v2.go index 669b21f84a9..678a9f5bb84 100755 --- a/cmd/account/groups-v2/groups-v2.go +++ b/cmd/account/groups-v2/groups-v2.go @@ -3,6 +3,8 @@ package groups_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -106,6 +108,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -218,6 +221,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -246,14 +250,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListAccountGroupsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List group details.` @@ -278,6 +293,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.GroupsV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/iam-v2/iam-v2.go b/cmd/account/iam-v2/iam-v2.go index d3617145c0b..028c48b47b9 100755 --- a/cmd/account/iam-v2/iam-v2.go +++ b/cmd/account/iam-v2/iam-v2.go @@ -100,6 +100,7 @@ func newGetWorkspaceAccessDetail() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -150,7 +151,7 @@ func newResolveGroup() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -183,6 +184,7 @@ func newResolveGroup() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -232,7 +234,7 @@ func newResolveServicePrincipal() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -265,6 +267,7 @@ func newResolveServicePrincipal() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -314,7 +317,7 @@ func newResolveUser() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -347,6 +350,7 @@ func newResolveUser() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/ip-access-lists/ip-access-lists.go b/cmd/account/ip-access-lists/ip-access-lists.go index 32bf120db51..187cce71305 100755 --- a/cmd/account/ip-access-lists/ip-access-lists.go +++ b/cmd/account/ip-access-lists/ip-access-lists.go @@ -112,7 +112,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'label', 'list_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'label', 'list_type' in your JSON input") } return nil } @@ -152,6 +152,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -288,6 +289,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -313,6 +315,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `Get access lists.` @@ -327,6 +338,13 @@ func newList() *cobra.Command { ctx := cmd.Context() a := cmdctx.AccountClient(ctx) response := a.IpAccessLists.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/llm-proxy-partner-powered-account/llm-proxy-partner-powered-account.go b/cmd/account/llm-proxy-partner-powered-account/llm-proxy-partner-powered-account.go index e80753e5991..fa094ed844b 100755 --- a/cmd/account/llm-proxy-partner-powered-account/llm-proxy-partner-powered-account.go +++ b/cmd/account/llm-proxy-partner-powered-account/llm-proxy-partner-powered-account.go @@ -78,6 +78,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -142,6 +143,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/llm-proxy-partner-powered-enforce/llm-proxy-partner-powered-enforce.go b/cmd/account/llm-proxy-partner-powered-enforce/llm-proxy-partner-powered-enforce.go index e5972a1aa2f..94428f62769 100755 --- a/cmd/account/llm-proxy-partner-powered-enforce/llm-proxy-partner-powered-enforce.go +++ b/cmd/account/llm-proxy-partner-powered-enforce/llm-proxy-partner-powered-enforce.go @@ -79,6 +79,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -144,6 +145,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/log-delivery/log-delivery.go b/cmd/account/log-delivery/log-delivery.go index e94e4194353..348df018025 100755 --- a/cmd/account/log-delivery/log-delivery.go +++ b/cmd/account/log-delivery/log-delivery.go @@ -178,6 +178,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -247,6 +248,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -275,12 +277,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq billing.ListLogDeliveryRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.CredentialsId, "credentials-id", listReq.CredentialsId, `The Credentials id to filter the search results with.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A page token received from a previous get all budget configurations call.`) cmd.Flags().Var(&listReq.Status, "status", `The log delivery status to filter the search results with. Supported values: [DISABLED, ENABLED]`) cmd.Flags().StringVar(&listReq.StorageConfigurationId, "storage-configuration-id", listReq.StorageConfigurationId, `The Storage Configuration id to filter the search results with.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `Get all log delivery configurations.` cmd.Long = `Get all log delivery configurations. @@ -301,6 +313,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.LogDelivery.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/metastore-assignments/metastore-assignments.go b/cmd/account/metastore-assignments/metastore-assignments.go index b1e574596f0..124d059cea1 100755 --- a/cmd/account/metastore-assignments/metastore-assignments.go +++ b/cmd/account/metastore-assignments/metastore-assignments.go @@ -105,6 +105,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -168,6 +169,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -230,6 +232,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -258,6 +261,15 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListAccountMetastoreAssignmentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list METASTORE_ID" cmd.Short = `Get all workspaces assigned to a metastore.` @@ -284,6 +296,13 @@ func newList() *cobra.Command { listReq.MetastoreId = args[0] response := a.MetastoreAssignments.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -364,6 +383,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/metastores/metastores.go b/cmd/account/metastores/metastores.go index f2bfebacb18..8d58352bc3b 100755 --- a/cmd/account/metastores/metastores.go +++ b/cmd/account/metastores/metastores.go @@ -3,6 +3,8 @@ package metastores import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -94,6 +96,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -152,6 +155,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -208,6 +212,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +238,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `Get all metastores associated with an account.` @@ -247,6 +261,13 @@ func newList() *cobra.Command { ctx := cmd.Context() a := cmdctx.AccountClient(ctx) response := a.Metastores.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -320,6 +341,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/network-connectivity/network-connectivity.go b/cmd/account/network-connectivity/network-connectivity.go index 23c4e85dded..3f8c32ed001 100755 --- a/cmd/account/network-connectivity/network-connectivity.go +++ b/cmd/account/network-connectivity/network-connectivity.go @@ -103,7 +103,7 @@ func newCreateNetworkConnectivityConfiguration() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'region' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'region' in your JSON input") } return nil } @@ -139,6 +139,7 @@ func newCreateNetworkConnectivityConfiguration() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -175,6 +176,7 @@ func newCreatePrivateEndpointRule() *cobra.Command { // TODO: array: domain_names cmd.Flags().StringVar(&createPrivateEndpointRuleReq.PrivateEndpointRule.EndpointService, "endpoint-service", createPrivateEndpointRuleReq.PrivateEndpointRule.EndpointService, `The full target AWS endpoint service name that connects to the destination resources of the private endpoint.`) cmd.Flags().StringVar(&createPrivateEndpointRuleReq.PrivateEndpointRule.ErrorMessage, "error-message", createPrivateEndpointRuleReq.PrivateEndpointRule.ErrorMessage, ``) + // TODO: complex arg: gcp_endpoint cmd.Flags().StringVar(&createPrivateEndpointRuleReq.PrivateEndpointRule.GroupId, "group-id", createPrivateEndpointRuleReq.PrivateEndpointRule.GroupId, `Not used by customer-managed private endpoint services.`) cmd.Flags().StringVar(&createPrivateEndpointRuleReq.PrivateEndpointRule.ResourceId, "resource-id", createPrivateEndpointRuleReq.PrivateEndpointRule.ResourceId, `The Azure resource ID of the target resource.`) // TODO: array: resource_names @@ -227,6 +229,7 @@ func newCreatePrivateEndpointRule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -346,6 +349,7 @@ func newDeletePrivateEndpointRule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -402,6 +406,7 @@ func newGetNetworkConnectivityConfiguration() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -460,6 +465,7 @@ func newGetPrivateEndpointRule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -488,8 +494,17 @@ func newListNetworkConnectivityConfigurations() *cobra.Command { cmd := &cobra.Command{} var listNetworkConnectivityConfigurationsReq settings.ListNetworkConnectivityConfigurationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listNetworkConnectivityConfigurationsLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listNetworkConnectivityConfigurationsLimit, "limit", 0, `Maximum number of results to return.`) - cmd.Flags().StringVar(&listNetworkConnectivityConfigurationsReq.PageToken, "page-token", listNetworkConnectivityConfigurationsReq.PageToken, `Pagination token to go to next page based on previous query.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listNetworkConnectivityConfigurationsReq.PageToken, "page-token", listNetworkConnectivityConfigurationsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-network-connectivity-configurations" cmd.Short = `List network connectivity configurations.` @@ -510,6 +525,13 @@ func newListNetworkConnectivityConfigurations() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.NetworkConnectivity.ListNetworkConnectivityConfigurations(ctx, listNetworkConnectivityConfigurationsReq) + if listNetworkConnectivityConfigurationsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listNetworkConnectivityConfigurationsLimit) + } + if listNetworkConnectivityConfigurationsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listNetworkConnectivityConfigurationsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -538,8 +560,17 @@ func newListPrivateEndpointRules() *cobra.Command { cmd := &cobra.Command{} var listPrivateEndpointRulesReq settings.ListPrivateEndpointRulesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listPrivateEndpointRulesLimit int - cmd.Flags().StringVar(&listPrivateEndpointRulesReq.PageToken, "page-token", listPrivateEndpointRulesReq.PageToken, `Pagination token to go to next page based on previous query.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listPrivateEndpointRulesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listPrivateEndpointRulesReq.PageToken, "page-token", listPrivateEndpointRulesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-private-endpoint-rules NETWORK_CONNECTIVITY_CONFIG_ID" cmd.Short = `List private endpoint rules.` @@ -565,6 +596,13 @@ func newListPrivateEndpointRules() *cobra.Command { listPrivateEndpointRulesReq.NetworkConnectivityConfigId = args[0] response := a.NetworkConnectivity.ListPrivateEndpointRules(ctx, listPrivateEndpointRulesReq) + if listPrivateEndpointRulesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listPrivateEndpointRulesLimit) + } + if listPrivateEndpointRulesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listPrivateEndpointRulesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -601,6 +639,7 @@ func newUpdatePrivateEndpointRule() *cobra.Command { // TODO: array: domain_names cmd.Flags().BoolVar(&updatePrivateEndpointRuleReq.PrivateEndpointRule.Enabled, "enabled", updatePrivateEndpointRuleReq.PrivateEndpointRule.Enabled, `Only used by private endpoints towards an AWS S3 service.`) cmd.Flags().StringVar(&updatePrivateEndpointRuleReq.PrivateEndpointRule.ErrorMessage, "error-message", updatePrivateEndpointRuleReq.PrivateEndpointRule.ErrorMessage, ``) + // TODO: complex arg: gcp_endpoint // TODO: array: resource_names cmd.Use = "update-private-endpoint-rule NETWORK_CONNECTIVITY_CONFIG_ID PRIVATE_ENDPOINT_RULE_ID UPDATE_MASK" @@ -653,6 +692,7 @@ func newUpdatePrivateEndpointRule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/network-policies/network-policies.go b/cmd/account/network-policies/network-policies.go index 4165773e646..229012a888a 100755 --- a/cmd/account/network-policies/network-policies.go +++ b/cmd/account/network-policies/network-policies.go @@ -3,6 +3,8 @@ package network_policies import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -63,8 +65,9 @@ func newCreateNetworkPolicyRpc() *cobra.Command { cmd.Flags().Var(&createNetworkPolicyRpcJson, "json", `either inline JSON string or @path/to/file.json with request body`) - cmd.Flags().StringVar(&createNetworkPolicyRpcReq.NetworkPolicy.AccountId, "account-id", createNetworkPolicyRpcReq.NetworkPolicy.AccountId, `The associated account ID for this Network Policy object.`) // TODO: complex arg: egress + // TODO: complex arg: ingress + // TODO: complex arg: ingress_dry_run cmd.Flags().StringVar(&createNetworkPolicyRpcReq.NetworkPolicy.NetworkPolicyId, "network-policy-id", createNetworkPolicyRpcReq.NetworkPolicy.NetworkPolicyId, `The unique identifier for the network policy.`) cmd.Use = "create-network-policy-rpc" @@ -103,6 +106,7 @@ func newCreateNetworkPolicyRpc() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -215,6 +219,7 @@ func newGetNetworkPolicyRpc() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -243,8 +248,17 @@ func newListNetworkPoliciesRpc() *cobra.Command { cmd := &cobra.Command{} var listNetworkPoliciesRpcReq settings.ListNetworkPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listNetworkPoliciesRpcLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listNetworkPoliciesRpcLimit, "limit", 0, `Maximum number of results to return.`) - cmd.Flags().StringVar(&listNetworkPoliciesRpcReq.PageToken, "page-token", listNetworkPoliciesRpcReq.PageToken, `Pagination token to go to next page based on previous query.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listNetworkPoliciesRpcReq.PageToken, "page-token", listNetworkPoliciesRpcReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-network-policies-rpc" cmd.Short = `List network policies.` @@ -265,6 +279,13 @@ func newListNetworkPoliciesRpc() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.NetworkPolicies.ListNetworkPoliciesRpc(ctx, listNetworkPoliciesRpcReq) + if listNetworkPoliciesRpcLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listNetworkPoliciesRpcLimit) + } + if listNetworkPoliciesRpcLimit > 0 { + ctx = cmdio.WithLimit(ctx, listNetworkPoliciesRpcLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -298,8 +319,9 @@ func newUpdateNetworkPolicyRpc() *cobra.Command { cmd.Flags().Var(&updateNetworkPolicyRpcJson, "json", `either inline JSON string or @path/to/file.json with request body`) - cmd.Flags().StringVar(&updateNetworkPolicyRpcReq.NetworkPolicy.AccountId, "account-id", updateNetworkPolicyRpcReq.NetworkPolicy.AccountId, `The associated account ID for this Network Policy object.`) // TODO: complex arg: egress + // TODO: complex arg: ingress + // TODO: complex arg: ingress_dry_run cmd.Flags().StringVar(&updateNetworkPolicyRpcReq.NetworkPolicy.NetworkPolicyId, "network-policy-id", updateNetworkPolicyRpcReq.NetworkPolicy.NetworkPolicyId, `The unique identifier for the network policy.`) cmd.Use = "update-network-policy-rpc NETWORK_POLICY_ID" @@ -342,6 +364,7 @@ func newUpdateNetworkPolicyRpc() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/networks/networks.go b/cmd/account/networks/networks.go index 54b80cb8ce0..4845a1aa3b2 100755 --- a/cmd/account/networks/networks.go +++ b/cmd/account/networks/networks.go @@ -100,6 +100,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -161,6 +162,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -218,6 +220,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -260,6 +263,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/o-auth-published-apps/o-auth-published-apps.go b/cmd/account/o-auth-published-apps/o-auth-published-apps.go index 254ef5324c1..2bade901da7 100755 --- a/cmd/account/o-auth-published-apps/o-auth-published-apps.go +++ b/cmd/account/o-auth-published-apps/o-auth-published-apps.go @@ -3,6 +3,8 @@ package o_auth_published_apps import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -50,9 +52,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListOAuthPublishedAppsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `The max number of OAuth published apps to return in one page.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `Get all the published OAuth apps.` @@ -73,6 +85,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.OAuthPublishedApps.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/personal-compute/personal-compute.go b/cmd/account/personal-compute/personal-compute.go index e2e5b2f9c5e..1888fc237fe 100755 --- a/cmd/account/personal-compute/personal-compute.go +++ b/cmd/account/personal-compute/personal-compute.go @@ -87,6 +87,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -140,6 +141,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -204,6 +206,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/private-access/private-access.go b/cmd/account/private-access/private-access.go index d3c8f9fde32..2933414a449 100755 --- a/cmd/account/private-access/private-access.go +++ b/cmd/account/private-access/private-access.go @@ -100,6 +100,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -154,6 +155,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -207,6 +209,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -249,6 +252,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -339,6 +343,7 @@ func newReplace() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/published-app-integration/published-app-integration.go b/cmd/account/published-app-integration/published-app-integration.go index 58e3fc923dc..693767985a2 100755 --- a/cmd/account/published-app-integration/published-app-integration.go +++ b/cmd/account/published-app-integration/published-app-integration.go @@ -3,6 +3,8 @@ package published_app_integration import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -99,6 +101,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -206,6 +209,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -234,9 +238,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListPublishedAppIntegrationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `Get published oauth app integrations.` @@ -258,6 +272,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.PublishedAppIntegration.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/service-principal-federation-policy/service-principal-federation-policy.go b/cmd/account/service-principal-federation-policy/service-principal-federation-policy.go index 13edacfb9ac..233c5e2e730 100755 --- a/cmd/account/service-principal-federation-policy/service-principal-federation-policy.go +++ b/cmd/account/service-principal-federation-policy/service-principal-federation-policy.go @@ -158,6 +158,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -282,6 +283,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -310,9 +312,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListServicePrincipalFederationPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list SERVICE_PRINCIPAL_ID" cmd.Short = `List service principal federation policies.` @@ -341,6 +353,13 @@ func newList() *cobra.Command { } response := a.ServicePrincipalFederationPolicy.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -423,6 +442,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/service-principal-secrets/service-principal-secrets.go b/cmd/account/service-principal-secrets/service-principal-secrets.go index 022e8090fc4..cf17cb035f2 100755 --- a/cmd/account/service-principal-secrets/service-principal-secrets.go +++ b/cmd/account/service-principal-secrets/service-principal-secrets.go @@ -3,6 +3,8 @@ package service_principal_secrets import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -107,6 +109,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -193,9 +196,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListServicePrincipalSecretsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `An opaque page token which was the next_page_token in the response of the previous request to list the secrets for this service principal.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list SERVICE_PRINCIPAL_ID" cmd.Short = `List service principal secrets.` @@ -223,6 +236,13 @@ func newList() *cobra.Command { listReq.ServicePrincipalId = args[0] response := a.ServicePrincipalSecrets.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/service-principals-v2/service-principals-v2.go b/cmd/account/service-principals-v2/service-principals-v2.go index dfdd40c36cb..4604dfa3256 100755 --- a/cmd/account/service-principals-v2/service-principals-v2.go +++ b/cmd/account/service-principals-v2/service-principals-v2.go @@ -3,6 +3,8 @@ package service_principals_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -104,6 +106,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -217,6 +220,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -245,14 +249,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListAccountServicePrincipalsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List service principals.` @@ -273,6 +288,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.ServicePrincipalsV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/settings-v2/settings-v2.go b/cmd/account/settings-v2/settings-v2.go index 11883f11f67..f2d464d1804 100755 --- a/cmd/account/settings-v2/settings-v2.go +++ b/cmd/account/settings-v2/settings-v2.go @@ -3,6 +3,8 @@ package settings_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -80,6 +82,7 @@ func newGetPublicAccountSetting() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -122,9 +125,6 @@ func newGetPublicAccountUserPreference() *cobra.Command { USER_ID: User ID of the user whose setting is being retrieved. NAME: User Setting name.` - // This command is being previewed; hide from help output. - cmd.Hidden = true - cmd.Annotations = make(map[string]string) cmd.Args = func(cmd *cobra.Command, args []string) error { @@ -144,6 +144,7 @@ func newGetPublicAccountUserPreference() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -172,9 +173,19 @@ func newListAccountSettingsMetadata() *cobra.Command { cmd := &cobra.Command{} var listAccountSettingsMetadataReq settingsv2.ListAccountSettingsMetadataRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listAccountSettingsMetadataLimit int cmd.Flags().IntVar(&listAccountSettingsMetadataReq.PageSize, "page-size", listAccountSettingsMetadataReq.PageSize, `The maximum number of settings to return.`) - cmd.Flags().StringVar(&listAccountSettingsMetadataReq.PageToken, "page-token", listAccountSettingsMetadataReq.PageToken, `A page token, received from a previous ListAccountSettingsMetadataRequest call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listAccountSettingsMetadataLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listAccountSettingsMetadataReq.PageToken, "page-token", listAccountSettingsMetadataReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-account-settings-metadata" cmd.Short = `List valid setting keys and their metadata.` @@ -197,6 +208,13 @@ func newListAccountSettingsMetadata() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.SettingsV2.ListAccountSettingsMetadata(ctx, listAccountSettingsMetadataReq) + if listAccountSettingsMetadataLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listAccountSettingsMetadataLimit) + } + if listAccountSettingsMetadataLimit > 0 { + ctx = cmdio.WithLimit(ctx, listAccountSettingsMetadataLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -225,9 +243,19 @@ func newListAccountUserPreferencesMetadata() *cobra.Command { cmd := &cobra.Command{} var listAccountUserPreferencesMetadataReq settingsv2.ListAccountUserPreferencesMetadataRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listAccountUserPreferencesMetadataLimit int cmd.Flags().IntVar(&listAccountUserPreferencesMetadataReq.PageSize, "page-size", listAccountUserPreferencesMetadataReq.PageSize, `The maximum number of settings to return.`) - cmd.Flags().StringVar(&listAccountUserPreferencesMetadataReq.PageToken, "page-token", listAccountUserPreferencesMetadataReq.PageToken, `A page token, received from a previous ListAccountUserPreferencesMetadataRequest call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listAccountUserPreferencesMetadataLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listAccountUserPreferencesMetadataReq.PageToken, "page-token", listAccountUserPreferencesMetadataReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-account-user-preferences-metadata USER_ID" cmd.Short = `List user preferences and their metadata.` @@ -242,9 +270,6 @@ func newListAccountUserPreferencesMetadata() *cobra.Command { Arguments: USER_ID: User ID of the user whose settings metadata is being retrieved.` - // This command is being previewed; hide from help output. - cmd.Hidden = true - cmd.Annotations = make(map[string]string) cmd.Args = func(cmd *cobra.Command, args []string) error { @@ -260,6 +285,13 @@ func newListAccountUserPreferencesMetadata() *cobra.Command { listAccountUserPreferencesMetadataReq.UserId = args[0] response := a.SettingsV2.ListAccountUserPreferencesMetadata(ctx, listAccountUserPreferencesMetadataReq) + if listAccountUserPreferencesMetadataLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listAccountUserPreferencesMetadataLimit) + } + if listAccountUserPreferencesMetadataLimit > 0 { + ctx = cmdio.WithLimit(ctx, listAccountUserPreferencesMetadataLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -353,6 +385,7 @@ func newPatchPublicAccountSetting() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -408,9 +441,6 @@ func newPatchPublicAccountUserPreference() *cobra.Command { USER_ID: User ID of the user whose setting is being updated. NAME: ` - // This command is being previewed; hide from help output. - cmd.Hidden = true - cmd.Annotations = make(map[string]string) cmd.Args = func(cmd *cobra.Command, args []string) error { @@ -442,6 +472,7 @@ func newPatchPublicAccountUserPreference() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/storage-credentials/storage-credentials.go b/cmd/account/storage-credentials/storage-credentials.go index c3fce95ea29..2eaee847d60 100755 --- a/cmd/account/storage-credentials/storage-credentials.go +++ b/cmd/account/storage-credentials/storage-credentials.go @@ -3,6 +3,8 @@ package storage_credentials import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -103,6 +105,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -164,6 +167,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -224,6 +228,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -252,6 +257,15 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListAccountStorageCredentialsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list METASTORE_ID" cmd.Short = `Get all storage credentials assigned to a metastore.` @@ -278,6 +292,13 @@ func newList() *cobra.Command { listReq.MetastoreId = args[0] response := a.StorageCredentials.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -356,6 +377,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/storage/storage.go b/cmd/account/storage/storage.go index fd9cfbcb8a2..c852a05084f 100755 --- a/cmd/account/storage/storage.go +++ b/cmd/account/storage/storage.go @@ -96,6 +96,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -150,6 +151,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -203,6 +205,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -245,6 +248,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/usage-dashboards/usage-dashboards.go b/cmd/account/usage-dashboards/usage-dashboards.go index 1efa6f236a6..7e08d033845 100755 --- a/cmd/account/usage-dashboards/usage-dashboards.go +++ b/cmd/account/usage-dashboards/usage-dashboards.go @@ -95,6 +95,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -149,6 +150,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/users-v2/users-v2.go b/cmd/account/users-v2/users-v2.go index b7ddd391b4e..3a401ce16cd 100755 --- a/cmd/account/users-v2/users-v2.go +++ b/cmd/account/users-v2/users-v2.go @@ -3,6 +3,8 @@ package users_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -112,6 +114,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +236,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,14 +265,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListAccountUsersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List users.` @@ -289,6 +304,13 @@ func newList() *cobra.Command { a := cmdctx.AccountClient(ctx) response := a.UsersV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/account/vpc-endpoints/vpc-endpoints.go b/cmd/account/vpc-endpoints/vpc-endpoints.go index a6402b8b281..ee2bf1aa6a6 100755 --- a/cmd/account/vpc-endpoints/vpc-endpoints.go +++ b/cmd/account/vpc-endpoints/vpc-endpoints.go @@ -107,6 +107,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -161,6 +162,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -221,6 +223,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -263,6 +266,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/workspace-assignment/workspace-assignment.go b/cmd/account/workspace-assignment/workspace-assignment.go index 16c163cd6bf..43146462329 100755 --- a/cmd/account/workspace-assignment/workspace-assignment.go +++ b/cmd/account/workspace-assignment/workspace-assignment.go @@ -151,6 +151,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -179,6 +180,15 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListWorkspaceAssignmentRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list WORKSPACE_ID" cmd.Short = `Get permission assignments.` @@ -208,6 +218,13 @@ func newList() *cobra.Command { } response := a.WorkspaceAssignment.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -291,6 +308,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/workspace-network-configuration/workspace-network-configuration.go b/cmd/account/workspace-network-configuration/workspace-network-configuration.go index fa49a5f0893..4dd194c9462 100755 --- a/cmd/account/workspace-network-configuration/workspace-network-configuration.go +++ b/cmd/account/workspace-network-configuration/workspace-network-configuration.go @@ -90,6 +90,7 @@ func newGetWorkspaceNetworkOptionRpc() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -170,6 +171,7 @@ func newUpdateWorkspaceNetworkOptionRpc() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/account/workspaces/workspaces.go b/cmd/account/workspaces/workspaces.go index 429407d431c..4ee0ab08f52 100755 --- a/cmd/account/workspaces/workspaces.go +++ b/cmd/account/workspaces/workspaces.go @@ -236,6 +236,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -300,6 +301,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -342,6 +344,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/apps/import.go b/cmd/apps/import.go index fb073ac2fc3..2fda7c23a50 100644 --- a/cmd/apps/import.go +++ b/cmd/apps/import.go @@ -196,7 +196,7 @@ Examples: cmdio.LogString(ctx, "Cleaning up previous app folder") } - err = w.Workspace.Delete(ctx, workspace.Delete{ + err = w.Workspace.Delete(ctx, workspace.Delete{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: oldSourceCodePath, Recursive: true, }) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index eaf42a3c925..afcf967ab9a 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -417,7 +417,7 @@ func setHostAndAccountId(ctx context.Context, existingProfile *profile.Profile, Experimental_IsUnifiedHost: authArguments.IsUnifiedHost, } - switch cfg.HostType() { + switch cfg.HostType() { //nolint:staticcheck // HostType() deprecated in SDK v0.127.0; SDK moving to host-agnostic behavior. case config.AccountHost: // Account host: prompt for account ID if not provided if authArguments.AccountID == "" { @@ -449,7 +449,7 @@ func setHostAndAccountId(ctx context.Context, existingProfile *profile.Profile, // Regular workspace host: no additional prompts needed. // If discovery already populated account_id/workspace_id, those are kept. default: - return fmt.Errorf("unknown host type: %v", cfg.HostType()) + return fmt.Errorf("unknown host type: %v", cfg.HostType()) //nolint:staticcheck // HostType() deprecated in SDK v0.127.0; SDK moving to host-agnostic behavior. } return nil diff --git a/cmd/bundle/generate/dashboard.go b/cmd/bundle/generate/dashboard.go index 412f09001d4..9ca09c0f625 100644 --- a/cmd/bundle/generate/dashboard.go +++ b/cmd/bundle/generate/dashboard.go @@ -83,7 +83,7 @@ func (d *dashboard) resolveID(ctx context.Context, b *bundle.Bundle) string { func (d *dashboard) resolveFromPath(ctx context.Context, b *bundle.Bundle) string { w := b.WorkspaceClient() - obj, err := w.Workspace.GetStatusByPath(ctx, d.existingPath) + obj, err := w.Workspace.GetStatusByPath(ctx, d.existingPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { if apierr.IsMissing(err) { logdiag.LogError(ctx, fmt.Errorf("dashboard %q not found", path.Base(d.existingPath))) @@ -261,7 +261,7 @@ func waitForChanges(ctx context.Context, w *databricks.WorkspaceClient, dashboar } for { - obj, err := w.Workspace.GetStatusByPath(ctx, dashboard.Path) + obj, err := w.Workspace.GetStatusByPath(ctx, dashboard.Path) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { logdiag.LogError(ctx, err) return diff --git a/cmd/root/auth.go b/cmd/root/auth.go index 477db143370..4a4bd9ab87e 100644 --- a/cmd/root/auth.go +++ b/cmd/root/auth.go @@ -19,6 +19,19 @@ import ( "github.com/spf13/cobra" ) +// errNotWorkspaceClient is a CLI-internal sentinel error. It signals that the +// configured host is an account host, not a workspace host. +// +// workspaceClientOrPrompt synthesizes this error (line ~214) when it detects a +// wrong host type via cfg.HostType(). MustAnyClient checks for it to decide +// whether to fall through and try an account client instead. +// +// The SDK exported this as databricks.ErrNotWorkspaceClient until v0.126.0. The +// SDK stopped *returning* it in v0.125.0 (host-type validation moved to host +// metadata resolution), but the CLI was already synthesizing it locally. The +// SDK removed the variable entirely in v0.127.0, so we now own it here. +var errNotWorkspaceClient = errors.New("invalid Databricks Workspace configuration - host is not a workspace host") + type ErrNoWorkspaceProfiles struct { path string } @@ -69,7 +82,7 @@ func accountClientOrPrompt(ctx context.Context, cfg *config.Config, allowPrompt // (as of v0.125.0, host-type validation was removed in favor of host // metadata resolution). Use HostType() to detect the wrong host type. var needsPrompt bool - switch cfg.HostType() { + switch cfg.HostType() { //nolint:staticcheck // HostType() deprecated in SDK v0.127.0; SDK moving to host-agnostic behavior. case config.AccountHost, config.UnifiedHost: // Valid host type for account client, but still need account ID. needsPrompt = cfg.AccountID == "" @@ -117,7 +130,7 @@ func MustAnyClient(cmd *cobra.Command, args []string) (bool, error) { // If the error indicates a wrong config type (workspace host used for account client, // or config type mismatch detected by workspaceClientOrPrompt), fall through to try // account client. - if !errors.Is(werr, databricks.ErrNotWorkspaceClient) && !errors.As(werr, &ErrNoWorkspaceProfiles{}) { + if !errors.Is(werr, errNotWorkspaceClient) && !errors.As(werr, &ErrNoWorkspaceProfiles{}) { return false, werr } @@ -193,7 +206,7 @@ func workspaceClientOrPrompt(ctx context.Context, cfg *config.Config, allowPromp // ErrNotWorkspaceClient from NewWorkspaceClient (as of v0.125.0, host-type // validation was removed in favor of host metadata resolution). Use // HostType() to detect wrong host type, and check for ErrCannotConfigureDefault. - wrongHostType := cfg.HostType() == config.AccountHost + wrongHostType := cfg.HostType() == config.AccountHost //nolint:staticcheck // HostType() deprecated in SDK v0.127.0; SDK moving to host-agnostic behavior. needsPrompt := wrongHostType || errors.Is(err, config.ErrCannotConfigureDefault) if !needsPrompt { @@ -206,7 +219,7 @@ func workspaceClientOrPrompt(ctx context.Context, cfg *config.Config, allowPromp // For other errors (e.g. ErrCannotConfigureDefault), return the // original error to preserve actionable error messages. if wrongHostType { - return w, databricks.ErrNotWorkspaceClient + return w, errNotWorkspaceClient } return w, err } diff --git a/cmd/sync/completion.go b/cmd/sync/completion.go index 771bb52ebdb..52d49d6cb1c 100644 --- a/cmd/sync/completion.go +++ b/cmd/sync/completion.go @@ -17,7 +17,7 @@ func fetchDirs(ctx context.Context, wsc *databricks.WorkspaceClient, path string go func() { defer close(ch) - files, err := wsc.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ + files, err := wsc.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: path, }) if err != nil { diff --git a/cmd/workspace/access-control/access-control.go b/cmd/workspace/access-control/access-control.go index 85ec90b60cb..b5db3d2a313 100755 --- a/cmd/workspace/access-control/access-control.go +++ b/cmd/workspace/access-control/access-control.go @@ -89,6 +89,7 @@ func newCheckPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/agent-bricks/agent-bricks.go b/cmd/workspace/agent-bricks/agent-bricks.go index d7176964a4a..0a043ce8203 100755 --- a/cmd/workspace/agent-bricks/agent-bricks.go +++ b/cmd/workspace/agent-bricks/agent-bricks.go @@ -132,7 +132,7 @@ func newCreateCustomLlm() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'instructions' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'instructions' in your JSON input") } return nil } @@ -168,6 +168,7 @@ func newCreateCustomLlm() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -276,6 +277,7 @@ func newGetCustomLlm() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -330,6 +332,7 @@ func newStartOptimize() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -401,6 +404,7 @@ func newUpdateCustomLlm() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/aibi-dashboard-embedding-access-policy/aibi-dashboard-embedding-access-policy.go b/cmd/workspace/aibi-dashboard-embedding-access-policy/aibi-dashboard-embedding-access-policy.go index 0301e48320c..4c063bb9c73 100755 --- a/cmd/workspace/aibi-dashboard-embedding-access-policy/aibi-dashboard-embedding-access-policy.go +++ b/cmd/workspace/aibi-dashboard-embedding-access-policy/aibi-dashboard-embedding-access-policy.go @@ -79,6 +79,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -134,6 +135,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -198,6 +200,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/aibi-dashboard-embedding-approved-domains/aibi-dashboard-embedding-approved-domains.go b/cmd/workspace/aibi-dashboard-embedding-approved-domains/aibi-dashboard-embedding-approved-domains.go index c19c210d8af..148905979f7 100755 --- a/cmd/workspace/aibi-dashboard-embedding-approved-domains/aibi-dashboard-embedding-approved-domains.go +++ b/cmd/workspace/aibi-dashboard-embedding-approved-domains/aibi-dashboard-embedding-approved-domains.go @@ -79,6 +79,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -132,6 +133,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -198,6 +200,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/alerts-legacy/alerts-legacy.go b/cmd/workspace/alerts-legacy/alerts-legacy.go index 7743caec04a..1f211a621d0 100755 --- a/cmd/workspace/alerts-legacy/alerts-legacy.go +++ b/cmd/workspace/alerts-legacy/alerts-legacy.go @@ -109,6 +109,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -227,6 +228,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -274,6 +276,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/alerts-v2/alerts-v2.go b/cmd/workspace/alerts-v2/alerts-v2.go index cffe9760401..11ec795d8ba 100755 --- a/cmd/workspace/alerts-v2/alerts-v2.go +++ b/cmd/workspace/alerts-v2/alerts-v2.go @@ -85,7 +85,7 @@ func newCreateAlert() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'display_name', 'query_text', 'warehouse_id', 'evaluation', 'schedule' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'display_name', 'query_text', 'warehouse_id', 'evaluation', 'schedule' in your JSON input") } return nil } @@ -138,6 +138,7 @@ func newCreateAlert() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -203,6 +204,7 @@ func newGetAlert() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -231,9 +233,19 @@ func newListAlerts() *cobra.Command { cmd := &cobra.Command{} var listAlertsReq sql.ListAlertsV2Request + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listAlertsLimit int cmd.Flags().IntVar(&listAlertsReq.PageSize, "page-size", listAlertsReq.PageSize, ``) - cmd.Flags().StringVar(&listAlertsReq.PageToken, "page-token", listAlertsReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listAlertsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listAlertsReq.PageToken, "page-token", listAlertsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-alerts" cmd.Short = `List alerts.` @@ -254,6 +266,13 @@ func newListAlerts() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.AlertsV2.ListAlerts(ctx, listAlertsReq) + if listAlertsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listAlertsLimit) + } + if listAlertsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listAlertsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -449,6 +468,7 @@ func newUpdateAlert() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/alerts/alerts.go b/cmd/workspace/alerts/alerts.go index 38c012d2603..10ef4937fb5 100755 --- a/cmd/workspace/alerts/alerts.go +++ b/cmd/workspace/alerts/alerts.go @@ -100,6 +100,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -232,6 +233,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -260,9 +262,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sql.ListAlertsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List alerts.` @@ -285,6 +297,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Alerts.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -380,6 +399,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/apps-settings/apps-settings.go b/cmd/workspace/apps-settings/apps-settings.go index a3306c04686..7966bf91108 100755 --- a/cmd/workspace/apps-settings/apps-settings.go +++ b/cmd/workspace/apps-settings/apps-settings.go @@ -87,7 +87,7 @@ func newCreateCustomTemplate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'git_repo', 'path', 'manifest', 'git_provider' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'git_repo', 'path', 'manifest', 'git_provider' in your JSON input") } return nil } @@ -136,6 +136,7 @@ func newCreateCustomTemplate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -192,6 +193,7 @@ func newDeleteCustomTemplate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -248,6 +250,7 @@ func newGetCustomTemplate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -276,9 +279,19 @@ func newListCustomTemplates() *cobra.Command { cmd := &cobra.Command{} var listCustomTemplatesReq apps.ListCustomTemplatesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listCustomTemplatesLimit int cmd.Flags().IntVar(&listCustomTemplatesReq.PageSize, "page-size", listCustomTemplatesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listCustomTemplatesReq.PageToken, "page-token", listCustomTemplatesReq.PageToken, `Pagination token to go to the next page of custom templates.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listCustomTemplatesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listCustomTemplatesReq.PageToken, "page-token", listCustomTemplatesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-custom-templates" cmd.Short = `List templates.` @@ -299,6 +312,13 @@ func newListCustomTemplates() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.AppsSettings.ListCustomTemplates(ctx, listCustomTemplatesReq) + if listCustomTemplatesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listCustomTemplatesLimit) + } + if listCustomTemplatesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listCustomTemplatesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -404,6 +424,7 @@ func newUpdateCustomTemplate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/apps/apps.go b/cmd/workspace/apps/apps.go index dd6f6b5dfa6..b2b9c7eb222 100755 --- a/cmd/workspace/apps/apps.go +++ b/cmd/workspace/apps/apps.go @@ -37,6 +37,7 @@ func New() *cobra.Command { cmd.AddCommand(newCreateSpace()) cmd.AddCommand(newCreateUpdate()) cmd.AddCommand(newDelete()) + cmd.AddCommand(newDeleteAppThumbnail()) cmd.AddCommand(newDeleteSpace()) cmd.AddCommand(newDeploy()) cmd.AddCommand(newGet()) @@ -53,6 +54,7 @@ func New() *cobra.Command { cmd.AddCommand(newStart()) cmd.AddCommand(newStop()) cmd.AddCommand(newUpdate()) + cmd.AddCommand(newUpdateAppThumbnail()) cmd.AddCommand(newUpdatePermissions()) cmd.AddCommand(newUpdateSpace()) @@ -120,7 +122,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -243,7 +245,7 @@ func newCreateSpace() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -484,6 +486,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -499,6 +502,62 @@ func newDelete() *cobra.Command { return cmd } +// start delete-app-thumbnail command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteAppThumbnailOverrides []func( + *cobra.Command, + *apps.DeleteAppThumbnailRequest, +) + +func newDeleteAppThumbnail() *cobra.Command { + cmd := &cobra.Command{} + + var deleteAppThumbnailReq apps.DeleteAppThumbnailRequest + + cmd.Use = "delete-app-thumbnail NAME" + cmd.Short = `Delete an app thumbnail.` + cmd.Long = `Delete an app thumbnail. + + Deletes the thumbnail for an app. + + Arguments: + NAME: The name of the app.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + deleteAppThumbnailReq.Name = args[0] + + err = w.Apps.DeleteAppThumbnail(ctx, deleteAppThumbnailReq) + if err != nil { + return err + } + return nil + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteAppThumbnailOverrides { + fn(cmd, &deleteAppThumbnailReq) + } + + return cmd +} + // start delete-space command // Slice with functions to override default command behavior. @@ -748,6 +807,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -807,6 +867,7 @@ func newGetDeployment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -863,6 +924,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -920,6 +982,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -979,6 +1042,7 @@ func newGetSpace() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1038,6 +1102,7 @@ func newGetSpaceOperation() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1094,6 +1159,7 @@ func newGetUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1122,11 +1188,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq apps.ListAppsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token to go to the next page of apps.`) cmd.Flags().StringVar(&listReq.Space, "space", listReq.Space, `Filter apps by app space name.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List apps.` cmd.Long = `List apps. @@ -1146,6 +1222,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Apps.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1174,9 +1257,19 @@ func newListDeployments() *cobra.Command { cmd := &cobra.Command{} var listDeploymentsReq apps.ListAppDeploymentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDeploymentsLimit int cmd.Flags().IntVar(&listDeploymentsReq.PageSize, "page-size", listDeploymentsReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listDeploymentsReq.PageToken, "page-token", listDeploymentsReq.PageToken, `Pagination token to go to the next page of apps.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDeploymentsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDeploymentsReq.PageToken, "page-token", listDeploymentsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-deployments APP_NAME" cmd.Short = `List app deployments.` @@ -1202,6 +1295,13 @@ func newListDeployments() *cobra.Command { listDeploymentsReq.AppName = args[0] response := w.Apps.ListDeployments(ctx, listDeploymentsReq) + if listDeploymentsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDeploymentsLimit) + } + if listDeploymentsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDeploymentsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1230,9 +1330,19 @@ func newListSpaces() *cobra.Command { cmd := &cobra.Command{} var listSpacesReq apps.ListSpacesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSpacesLimit int cmd.Flags().IntVar(&listSpacesReq.PageSize, "page-size", listSpacesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listSpacesReq.PageToken, "page-token", listSpacesReq.PageToken, `Pagination token to go to the next page of app spaces.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSpacesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSpacesReq.PageToken, "page-token", listSpacesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-spaces" cmd.Short = `List app spaces.` @@ -1256,6 +1366,13 @@ func newListSpaces() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Apps.ListSpaces(ctx, listSpacesReq) + if listSpacesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSpacesLimit) + } + if listSpacesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSpacesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1331,6 +1448,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1581,6 +1699,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1596,6 +1715,80 @@ func newUpdate() *cobra.Command { return cmd } +// start update-app-thumbnail command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var updateAppThumbnailOverrides []func( + *cobra.Command, + *apps.UpdateAppThumbnailRequest, +) + +func newUpdateAppThumbnail() *cobra.Command { + cmd := &cobra.Command{} + + var updateAppThumbnailReq apps.UpdateAppThumbnailRequest + var updateAppThumbnailJson flags.JsonFlag + + cmd.Flags().Var(&updateAppThumbnailJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + // TODO: complex arg: app_thumbnail + + cmd.Use = "update-app-thumbnail NAME" + cmd.Short = `Update an app thumbnail.` + cmd.Long = `Update an app thumbnail. + + Updates the thumbnail for an app. + + Arguments: + NAME: The name of the app.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + if cmd.Flags().Changed("json") { + diags := updateAppThumbnailJson.Unmarshal(&updateAppThumbnailReq) + if diags.HasError() { + return diags.Error() + } + if len(diags) > 0 { + err := cmdio.RenderDiagnostics(ctx, diags) + if err != nil { + return err + } + } + } + updateAppThumbnailReq.Name = args[0] + + response, err := w.Apps.UpdateAppThumbnail(ctx, updateAppThumbnailReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range updateAppThumbnailOverrides { + fn(cmd, &updateAppThumbnailReq) + } + + return cmd +} + // start update-permissions command // Slice with functions to override default command behavior. @@ -1655,6 +1848,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/artifact-allowlists/artifact-allowlists.go b/cmd/workspace/artifact-allowlists/artifact-allowlists.go index 58b07298ef1..540e754e996 100755 --- a/cmd/workspace/artifact-allowlists/artifact-allowlists.go +++ b/cmd/workspace/artifact-allowlists/artifact-allowlists.go @@ -86,6 +86,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -165,6 +166,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/automatic-cluster-update/automatic-cluster-update.go b/cmd/workspace/automatic-cluster-update/automatic-cluster-update.go index b2079e1334e..e8978c755da 100755 --- a/cmd/workspace/automatic-cluster-update/automatic-cluster-update.go +++ b/cmd/workspace/automatic-cluster-update/automatic-cluster-update.go @@ -76,6 +76,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -144,6 +145,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/catalogs/catalogs.go b/cmd/workspace/catalogs/catalogs.go index 43ff7642078..f8eccfa6114 100755 --- a/cmd/workspace/catalogs/catalogs.go +++ b/cmd/workspace/catalogs/catalogs.go @@ -67,6 +67,7 @@ func newCreate() *cobra.Command { cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) cmd.Flags().StringVar(&createReq.ConnectionName, "connection-name", createReq.ConnectionName, `The name of the connection to an external data source.`) + // TODO: complex arg: managed_encryption_settings // TODO: map via StringToStringVar: options // TODO: map via StringToStringVar: properties cmd.Flags().StringVar(&createReq.ProviderName, "provider-name", createReq.ProviderName, `The name of delta sharing provider.`) @@ -89,7 +90,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -122,6 +123,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -241,6 +243,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -269,11 +272,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListCatalogsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include catalogs in the response for which the principal can only access selective metadata for.`) cmd.Flags().BoolVar(&listReq.IncludeUnbound, "include-unbound", listReq.IncludeUnbound, `Whether to include catalogs not bound to the workspace.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of catalogs to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List catalogs.` @@ -306,6 +320,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Catalogs.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -341,6 +362,7 @@ func newUpdate() *cobra.Command { cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) cmd.Flags().Var(&updateReq.EnablePredictiveOptimization, "enable-predictive-optimization", `Whether predictive optimization should be enabled for this object and objects under it. Supported values: [DISABLE, ENABLE, INHERIT]`) cmd.Flags().Var(&updateReq.IsolationMode, "isolation-mode", `Whether the current securable is accessible from all workspaces or a specific set of workspaces. Supported values: [ISOLATED, OPEN]`) + // TODO: complex arg: managed_encryption_settings cmd.Flags().StringVar(&updateReq.NewName, "new-name", updateReq.NewName, `New name for the catalog.`) // TODO: map via StringToStringVar: options cmd.Flags().StringVar(&updateReq.Owner, "owner", updateReq.Owner, `Username of current owner of catalog.`) @@ -387,6 +409,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/clean-room-asset-revisions/clean-room-asset-revisions.go b/cmd/workspace/clean-room-asset-revisions/clean-room-asset-revisions.go index b836f0be266..9e773e0617e 100755 --- a/cmd/workspace/clean-room-asset-revisions/clean-room-asset-revisions.go +++ b/cmd/workspace/clean-room-asset-revisions/clean-room-asset-revisions.go @@ -91,6 +91,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -119,9 +120,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq cleanrooms.ListCleanRoomAssetRevisionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Maximum number of asset revisions to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on the previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list CLEAN_ROOM_NAME ASSET_TYPE NAME" cmd.Short = `List asset revisions.` @@ -156,6 +167,13 @@ func newList() *cobra.Command { listReq.Name = args[2] response := w.CleanRoomAssetRevisions.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/clean-room-assets/clean-room-assets.go b/cmd/workspace/clean-room-assets/clean-room-assets.go index 4654d9b3572..4b371d1d22f 100755 --- a/cmd/workspace/clean-room-assets/clean-room-assets.go +++ b/cmd/workspace/clean-room-assets/clean-room-assets.go @@ -142,6 +142,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -224,6 +225,7 @@ func newCreateCleanRoomAssetReview() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -356,6 +358,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -384,8 +387,17 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq cleanrooms.ListCleanRoomAssetsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list CLEAN_ROOM_NAME" cmd.Short = `List assets.` @@ -409,6 +421,13 @@ func newList() *cobra.Command { listReq.CleanRoomName = args[0] response := w.CleanRoomAssets.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -508,6 +527,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/clean-room-auto-approval-rules/clean-room-auto-approval-rules.go b/cmd/workspace/clean-room-auto-approval-rules/clean-room-auto-approval-rules.go index b45d0b8745d..7cefc4a57e8 100755 --- a/cmd/workspace/clean-room-auto-approval-rules/clean-room-auto-approval-rules.go +++ b/cmd/workspace/clean-room-auto-approval-rules/clean-room-auto-approval-rules.go @@ -101,6 +101,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -209,6 +210,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -237,9 +239,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq cleanrooms.ListCleanRoomAutoApprovalRulesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Maximum number of auto-approval rules to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list CLEAN_ROOM_NAME" cmd.Short = `List auto-approval rules.` @@ -262,6 +274,13 @@ func newList() *cobra.Command { listReq.CleanRoomName = args[0] response := w.CleanRoomAutoApprovalRules.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -341,6 +360,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/clean-room-task-runs/clean-room-task-runs.go b/cmd/workspace/clean-room-task-runs/clean-room-task-runs.go index a889675a60b..6469e9bc882 100755 --- a/cmd/workspace/clean-room-task-runs/clean-room-task-runs.go +++ b/cmd/workspace/clean-room-task-runs/clean-room-task-runs.go @@ -3,6 +3,8 @@ package clean_room_task_runs import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -47,10 +49,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq cleanrooms.ListCleanRoomNotebookTaskRunsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.NotebookName, "notebook-name", listReq.NotebookName, `Notebook name.`) cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `The maximum number of task runs to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list CLEAN_ROOM_NAME" cmd.Short = `List notebook task runs.` @@ -76,6 +88,13 @@ func newList() *cobra.Command { listReq.CleanRoomName = args[0] response := w.CleanRoomTaskRuns.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/clean-rooms/clean-rooms.go b/cmd/workspace/clean-rooms/clean-rooms.go index 3aea991abff..2a323554425 100755 --- a/cmd/workspace/clean-rooms/clean-rooms.go +++ b/cmd/workspace/clean-rooms/clean-rooms.go @@ -205,6 +205,7 @@ func newCreateOutputCatalog() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -317,6 +318,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -345,9 +347,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq cleanrooms.ListCleanRoomsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Maximum number of clean rooms to return (i.e., the page length).`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List clean rooms.` @@ -369,6 +381,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.CleanRooms.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -445,6 +464,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/cluster-policies/cluster-policies.go b/cmd/workspace/cluster-policies/cluster-policies.go index 83df4ae3117..4aa257d5692 100755 --- a/cmd/workspace/cluster-policies/cluster-policies.go +++ b/cmd/workspace/cluster-policies/cluster-policies.go @@ -127,6 +127,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -175,7 +176,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'policy_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'policy_id' in your JSON input") } return nil } @@ -279,7 +280,7 @@ func newEdit() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'policy_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'policy_id' in your JSON input") } return nil } @@ -396,6 +397,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -464,6 +466,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -533,6 +536,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -561,10 +565,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq compute.ListClusterPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Var(&listReq.SortColumn, "sort-column", `The cluster policy attribute to sort by. Supported values: [POLICY_CREATION_TIME, POLICY_NAME]`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order in which the policies get listed. Supported values: [ASC, DESC]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Use = "list" cmd.Short = `List cluster policies.` cmd.Long = `List cluster policies. @@ -584,6 +597,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ClusterPolicies.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -671,6 +691,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -757,6 +778,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/clusters/clusters.go b/cmd/workspace/clusters/clusters.go index 64f2d810971..ca8ed39838c 100755 --- a/cmd/workspace/clusters/clusters.go +++ b/cmd/workspace/clusters/clusters.go @@ -118,7 +118,7 @@ func newChangeOwner() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id', 'owner_username' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id', 'owner_username' in your JSON input") } return nil } @@ -271,7 +271,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'spark_version' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'spark_version' in your JSON input") } return nil } @@ -372,7 +372,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -544,7 +544,7 @@ func newEdit() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id', 'spark_version' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id', 'spark_version' in your JSON input") } return nil } @@ -621,18 +621,27 @@ func newEvents() *cobra.Command { var eventsReq compute.GetEvents var eventsJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var eventsLimit int cmd.Flags().Var(&eventsJson, "json", `either inline JSON string or @path/to/file.json with request body`) cmd.Flags().Int64Var(&eventsReq.EndTime, "end-time", eventsReq.EndTime, `The end time in epoch milliseconds.`) // TODO: array: event_types - cmd.Flags().Int64Var(&eventsReq.Limit, "limit", eventsReq.Limit, `Deprecated: use page_token in combination with page_size instead.`) - cmd.Flags().Int64Var(&eventsReq.Offset, "offset", eventsReq.Offset, `Deprecated: use page_token in combination with page_size instead.`) cmd.Flags().Var(&eventsReq.Order, "order", `The order to list events in; either "ASC" or "DESC". Supported values: [ASC, DESC]`) cmd.Flags().IntVar(&eventsReq.PageSize, "page-size", eventsReq.PageSize, `The maximum number of events to include in a page of events.`) cmd.Flags().StringVar(&eventsReq.PageToken, "page-token", eventsReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of events respectively.`) cmd.Flags().Int64Var(&eventsReq.StartTime, "start-time", eventsReq.StartTime, `The start time in epoch milliseconds.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&eventsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().Int64Var(&eventsReq.Offset, "offset", eventsReq.Offset, `Deprecated: use page_token in combination with page_size instead.`) + cmd.Flags().Lookup("offset").Hidden = true + cmd.Use = "events CLUSTER_ID" cmd.Short = `List cluster activity events.` cmd.Long = `List cluster activity events. @@ -650,7 +659,7 @@ func newEvents() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -696,6 +705,13 @@ func newEvents() *cobra.Command { } response := w.Clusters.Events(ctx, eventsReq) + if eventsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", eventsLimit) + } + if eventsLimit > 0 { + ctx = cmdio.WithLimit(ctx, eventsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -765,6 +781,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -833,6 +850,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -902,6 +920,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -930,12 +949,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq compute.ListClustersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int // TODO: complex arg: filter_by cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Use this field to specify the maximum number of results to be returned by the server.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of clusters respectively.`) // TODO: complex arg: sort_by + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List clusters.` cmd.Long = `List clusters. @@ -957,6 +986,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Clusters.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1000,6 +1036,7 @@ func newListNodeTypes() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1043,6 +1080,7 @@ func newListZones() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1095,7 +1133,7 @@ func newPermanentDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1189,7 +1227,7 @@ func newPin() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1294,7 +1332,7 @@ func newResize() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1411,7 +1449,7 @@ func newRestart() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1559,6 +1597,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1602,6 +1641,7 @@ func newSparkVersions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1661,7 +1701,7 @@ func newStart() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1767,7 +1807,7 @@ func newUnpin() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -1893,7 +1933,7 @@ func newUpdate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id', 'update_mask' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id', 'update_mask' in your JSON input") } return nil } @@ -2027,6 +2067,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/compliance-security-profile/compliance-security-profile.go b/cmd/workspace/compliance-security-profile/compliance-security-profile.go index 5bb73f73743..570c2e1897a 100755 --- a/cmd/workspace/compliance-security-profile/compliance-security-profile.go +++ b/cmd/workspace/compliance-security-profile/compliance-security-profile.go @@ -79,6 +79,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -147,6 +148,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/connections/connections.go b/cmd/workspace/connections/connections.go index f7a291e51c4..5507ed839af 100755 --- a/cmd/workspace/connections/connections.go +++ b/cmd/workspace/connections/connections.go @@ -108,6 +108,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -244,6 +245,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -272,9 +274,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListConnectionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of connections to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List connections.` @@ -303,6 +315,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Connections.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -379,6 +398,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/consumer-fulfillments/consumer-fulfillments.go b/cmd/workspace/consumer-fulfillments/consumer-fulfillments.go index d08d1165454..6bf3a6169a5 100755 --- a/cmd/workspace/consumer-fulfillments/consumer-fulfillments.go +++ b/cmd/workspace/consumer-fulfillments/consumer-fulfillments.go @@ -3,6 +3,8 @@ package consumer_fulfillments import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -48,9 +50,19 @@ func newGet() *cobra.Command { cmd := &cobra.Command{} var getReq marketplace.GetListingContentMetadataRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var getLimit int cmd.Flags().IntVar(&getReq.PageSize, "page-size", getReq.PageSize, ``) - cmd.Flags().StringVar(&getReq.PageToken, "page-token", getReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&getLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&getReq.PageToken, "page-token", getReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "get LISTING_ID" cmd.Short = `Get listing content metadata.` @@ -73,6 +85,13 @@ func newGet() *cobra.Command { getReq.ListingId = args[0] response := w.ConsumerFulfillments.Get(ctx, getReq) + if getLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", getLimit) + } + if getLimit > 0 { + ctx = cmdio.WithLimit(ctx, getLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -101,9 +120,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListFulfillmentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list LISTING_ID" cmd.Short = `List all listing fulfillments.` @@ -130,6 +159,13 @@ func newList() *cobra.Command { listReq.ListingId = args[0] response := w.ConsumerFulfillments.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/consumer-installations/consumer-installations.go b/cmd/workspace/consumer-installations/consumer-installations.go index 09ecadd8a23..352b8380764 100755 --- a/cmd/workspace/consumer-installations/consumer-installations.go +++ b/cmd/workspace/consumer-installations/consumer-installations.go @@ -101,6 +101,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -183,9 +184,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListAllInstallationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List all installations.` @@ -206,6 +217,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ConsumerInstallations.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -234,9 +252,19 @@ func newListListingInstallations() *cobra.Command { cmd := &cobra.Command{} var listListingInstallationsReq marketplace.ListInstallationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listListingInstallationsLimit int cmd.Flags().IntVar(&listListingInstallationsReq.PageSize, "page-size", listListingInstallationsReq.PageSize, ``) - cmd.Flags().StringVar(&listListingInstallationsReq.PageToken, "page-token", listListingInstallationsReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listListingInstallationsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listListingInstallationsReq.PageToken, "page-token", listListingInstallationsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-listing-installations LISTING_ID" cmd.Short = `List installations for a listing.` @@ -259,6 +287,13 @@ func newListListingInstallations() *cobra.Command { listListingInstallationsReq.ListingId = args[0] response := w.ConsumerInstallations.ListListingInstallations(ctx, listListingInstallationsReq) + if listListingInstallationsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listListingInstallationsLimit) + } + if listListingInstallationsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listListingInstallationsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -336,6 +371,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/consumer-listings/consumer-listings.go b/cmd/workspace/consumer-listings/consumer-listings.go index 43e7ea74c03..a3bfe6f9c30 100755 --- a/cmd/workspace/consumer-listings/consumer-listings.go +++ b/cmd/workspace/consumer-listings/consumer-listings.go @@ -79,6 +79,7 @@ func newBatchGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -145,6 +146,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -173,6 +175,10 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListListingsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int // TODO: array: assets // TODO: array: categories @@ -180,10 +186,16 @@ func newList() *cobra.Command { cmd.Flags().BoolVar(&listReq.IsPrivateExchange, "is-private-exchange", listReq.IsPrivateExchange, `Filters each listing based on if it is a private exchange.`) cmd.Flags().BoolVar(&listReq.IsStaffPick, "is-staff-pick", listReq.IsStaffPick, `Filters each listing based on whether it is a staff pick.`) cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) // TODO: array: provider_ids // TODO: array: tags + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List listings.` cmd.Long = `List listings. @@ -204,6 +216,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ConsumerListings.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -232,15 +251,25 @@ func newSearch() *cobra.Command { cmd := &cobra.Command{} var searchReq marketplace.SearchListingsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var searchLimit int // TODO: array: assets // TODO: array: categories cmd.Flags().BoolVar(&searchReq.IsFree, "is-free", searchReq.IsFree, ``) cmd.Flags().BoolVar(&searchReq.IsPrivateExchange, "is-private-exchange", searchReq.IsPrivateExchange, ``) cmd.Flags().IntVar(&searchReq.PageSize, "page-size", searchReq.PageSize, ``) - cmd.Flags().StringVar(&searchReq.PageToken, "page-token", searchReq.PageToken, ``) // TODO: array: provider_ids + // Limit flag for total result capping. + cmd.Flags().IntVar(&searchLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&searchReq.PageToken, "page-token", searchReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "search QUERY" cmd.Short = `Search listings.` cmd.Long = `Search listings. @@ -279,6 +308,13 @@ func newSearch() *cobra.Command { searchReq.Query = args[0] response := w.ConsumerListings.Search(ctx, searchReq) + if searchLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", searchLimit) + } + if searchLimit > 0 { + ctx = cmdio.WithLimit(ctx, searchLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/consumer-personalization-requests/consumer-personalization-requests.go b/cmd/workspace/consumer-personalization-requests/consumer-personalization-requests.go index e1ed812c4c4..74f6f7e5a95 100755 --- a/cmd/workspace/consumer-personalization-requests/consumer-personalization-requests.go +++ b/cmd/workspace/consumer-personalization-requests/consumer-personalization-requests.go @@ -102,6 +102,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -156,6 +157,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -184,9 +186,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListAllPersonalizationRequestsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List all personalization requests.` @@ -207,6 +219,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ConsumerPersonalizationRequests.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/consumer-providers/consumer-providers.go b/cmd/workspace/consumer-providers/consumer-providers.go index 058accfa1ff..9c579c5d610 100755 --- a/cmd/workspace/consumer-providers/consumer-providers.go +++ b/cmd/workspace/consumer-providers/consumer-providers.go @@ -77,6 +77,7 @@ func newBatchGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -143,6 +144,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -171,10 +173,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListConsumerProvidersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IsFeatured, "is-featured", listReq.IsFeatured, ``) cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List providers.` @@ -196,6 +208,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ConsumerProviders.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/credentials-manager/credentials-manager.go b/cmd/workspace/credentials-manager/credentials-manager.go index a5706d4e1b6..4e0d2a10d84 100755 --- a/cmd/workspace/credentials-manager/credentials-manager.go +++ b/cmd/workspace/credentials-manager/credentials-manager.go @@ -91,6 +91,7 @@ func newExchangeToken() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/credentials/credentials.go b/cmd/workspace/credentials/credentials.go index f0e37742688..cd743f0edf8 100755 --- a/cmd/workspace/credentials/credentials.go +++ b/cmd/workspace/credentials/credentials.go @@ -97,7 +97,7 @@ func newCreateCredential() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -130,6 +130,7 @@ func newCreateCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -241,7 +242,7 @@ func newGenerateTemporaryServiceCredential() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'credential_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'credential_name' in your JSON input") } return nil } @@ -274,6 +275,7 @@ func newGenerateTemporaryServiceCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -332,6 +334,7 @@ func newGetCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -360,12 +363,22 @@ func newListCredentials() *cobra.Command { cmd := &cobra.Command{} var listCredentialsReq catalog.ListCredentialsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listCredentialsLimit int cmd.Flags().BoolVar(&listCredentialsReq.IncludeUnbound, "include-unbound", listCredentialsReq.IncludeUnbound, `Whether to include credentials not bound to the workspace.`) cmd.Flags().IntVar(&listCredentialsReq.MaxResults, "max-results", listCredentialsReq.MaxResults, `Maximum number of credentials to return.`) - cmd.Flags().StringVar(&listCredentialsReq.PageToken, "page-token", listCredentialsReq.PageToken, `Opaque token to retrieve the next page of results.`) cmd.Flags().Var(&listCredentialsReq.Purpose, "purpose", `Return only credentials for the specified purpose. Supported values: [SERVICE, STORAGE]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listCredentialsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listCredentialsReq.PageToken, "page-token", listCredentialsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list-credentials" cmd.Short = `List credentials.` cmd.Long = `List credentials. @@ -395,6 +408,13 @@ func newListCredentials() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Credentials.ListCredentials(ctx, listCredentialsReq) + if listCredentialsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listCredentialsLimit) + } + if listCredentialsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listCredentialsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -482,6 +502,7 @@ func newUpdateCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -572,6 +593,7 @@ func newValidateCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/current-user/current-user.go b/cmd/workspace/current-user/current-user.go index b9c63a78dcf..7a11844f6c5 100755 --- a/cmd/workspace/current-user/current-user.go +++ b/cmd/workspace/current-user/current-user.go @@ -61,6 +61,7 @@ func newMe() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/dashboard-email-subscriptions/dashboard-email-subscriptions.go b/cmd/workspace/dashboard-email-subscriptions/dashboard-email-subscriptions.go index c76faea9858..702bf376d54 100755 --- a/cmd/workspace/dashboard-email-subscriptions/dashboard-email-subscriptions.go +++ b/cmd/workspace/dashboard-email-subscriptions/dashboard-email-subscriptions.go @@ -78,6 +78,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -131,6 +132,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -195,6 +197,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/dashboard-widgets/dashboard-widgets.go b/cmd/workspace/dashboard-widgets/dashboard-widgets.go index aa853cc40e9..89d584ecac8 100755 --- a/cmd/workspace/dashboard-widgets/dashboard-widgets.go +++ b/cmd/workspace/dashboard-widgets/dashboard-widgets.go @@ -96,6 +96,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -228,6 +229,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/dashboards/dashboards.go b/cmd/workspace/dashboards/dashboards.go index 95ee2111bef..fedffb5a397 100755 --- a/cmd/workspace/dashboards/dashboards.go +++ b/cmd/workspace/dashboards/dashboards.go @@ -3,6 +3,8 @@ package dashboards import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -152,6 +154,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -180,12 +183,23 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sql.ListDashboardsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Var(&listReq.Order, "order", `Name of dashboard attribute to order by. Supported values: [created_at, name]`) - cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) - cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of dashboards to return per page.`) cmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) + cmd.Flags().Lookup("page").Hidden = true + cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of results per API page.`) + cmd.Flags().Lookup("page-size").Hidden = true + cmd.Use = "list" cmd.Short = `Get dashboard objects.` cmd.Long = `Get dashboard objects. @@ -213,6 +227,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Dashboards.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -351,6 +372,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/data-classification/data-classification.go b/cmd/workspace/data-classification/data-classification.go index 8e13587e2ed..e3a87558072 100755 --- a/cmd/workspace/data-classification/data-classification.go +++ b/cmd/workspace/data-classification/data-classification.go @@ -108,6 +108,7 @@ func newCreateCatalogConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -220,6 +221,7 @@ func newGetCatalogConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -303,6 +305,7 @@ func newUpdateCatalogConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/data-quality/data-quality.go b/cmd/workspace/data-quality/data-quality.go index 59dfb28a99e..905a0076d51 100755 --- a/cmd/workspace/data-quality/data-quality.go +++ b/cmd/workspace/data-quality/data-quality.go @@ -119,6 +119,7 @@ func newCancelRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -203,7 +204,7 @@ func newCreateMonitor() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'object_type', 'object_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'object_type', 'object_id' in your JSON input") } return nil } @@ -239,6 +240,7 @@ func newCreateMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -335,6 +337,7 @@ func newCreateRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -588,6 +591,7 @@ func newGetMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -678,6 +682,7 @@ func newGetRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -706,9 +711,19 @@ func newListMonitor() *cobra.Command { cmd := &cobra.Command{} var listMonitorReq dataquality.ListMonitorRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listMonitorLimit int cmd.Flags().IntVar(&listMonitorReq.PageSize, "page-size", listMonitorReq.PageSize, ``) - cmd.Flags().StringVar(&listMonitorReq.PageToken, "page-token", listMonitorReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listMonitorLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listMonitorReq.PageToken, "page-token", listMonitorReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-monitor" cmd.Short = `List monitors.` @@ -729,6 +744,13 @@ func newListMonitor() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.DataQuality.ListMonitor(ctx, listMonitorReq) + if listMonitorLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listMonitorLimit) + } + if listMonitorLimit > 0 { + ctx = cmdio.WithLimit(ctx, listMonitorLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -757,9 +779,19 @@ func newListRefresh() *cobra.Command { cmd := &cobra.Command{} var listRefreshReq dataquality.ListRefreshRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listRefreshLimit int cmd.Flags().IntVar(&listRefreshReq.PageSize, "page-size", listRefreshReq.PageSize, ``) - cmd.Flags().StringVar(&listRefreshReq.PageToken, "page-token", listRefreshReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listRefreshLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listRefreshReq.PageToken, "page-token", listRefreshReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-refresh OBJECT_TYPE OBJECT_ID" cmd.Short = `List refreshes.` @@ -814,6 +846,13 @@ func newListRefresh() *cobra.Command { listRefreshReq.ObjectId = args[1] response := w.DataQuality.ListRefresh(ctx, listRefreshReq) + if listRefreshLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listRefreshLimit) + } + if listRefreshLimit > 0 { + ctx = cmdio.WithLimit(ctx, listRefreshLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -950,6 +989,7 @@ func newUpdateMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1075,6 +1115,7 @@ func newUpdateRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/data-sources/data-sources.go b/cmd/workspace/data-sources/data-sources.go index 920c01c5c0d..637522c1126 100755 --- a/cmd/workspace/data-sources/data-sources.go +++ b/cmd/workspace/data-sources/data-sources.go @@ -81,6 +81,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/database/database.go b/cmd/workspace/database/database.go index a84f9a09713..b2476255bb0 100755 --- a/cmd/workspace/database/database.go +++ b/cmd/workspace/database/database.go @@ -96,7 +96,7 @@ func newCreateDatabaseCatalog() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'database_instance_name', 'database_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'database_instance_name', 'database_name' in your JSON input") } return nil } @@ -135,6 +135,7 @@ func newCreateDatabaseCatalog() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -199,7 +200,7 @@ func newCreateDatabaseInstance() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -337,6 +338,7 @@ func newCreateDatabaseInstanceRole() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -390,7 +392,7 @@ func newCreateDatabaseTable() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -423,6 +425,7 @@ func newCreateDatabaseTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -474,7 +477,7 @@ func newCreateSyncedDatabaseTable() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -507,6 +510,7 @@ func newCreateSyncedDatabaseTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -830,6 +834,7 @@ func newFindDatabaseInstanceByUid() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -899,6 +904,7 @@ func newGenerateDatabaseCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -950,6 +956,7 @@ func newGetDatabaseCatalog() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1004,6 +1011,7 @@ func newGetDatabaseInstance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1061,6 +1069,7 @@ func newGetDatabaseInstanceRole() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1112,6 +1121,7 @@ func newGetDatabaseTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1163,6 +1173,7 @@ func newGetSyncedDatabaseTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1191,9 +1202,19 @@ func newListDatabaseCatalogs() *cobra.Command { cmd := &cobra.Command{} var listDatabaseCatalogsReq database.ListDatabaseCatalogsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDatabaseCatalogsLimit int cmd.Flags().IntVar(&listDatabaseCatalogsReq.PageSize, "page-size", listDatabaseCatalogsReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listDatabaseCatalogsReq.PageToken, "page-token", listDatabaseCatalogsReq.PageToken, `Pagination token to go to the next page of synced database tables.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDatabaseCatalogsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDatabaseCatalogsReq.PageToken, "page-token", listDatabaseCatalogsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-database-catalogs INSTANCE_NAME" cmd.Short = `List all Database Catalogs in a Database Instance.` @@ -1222,6 +1243,13 @@ func newListDatabaseCatalogs() *cobra.Command { listDatabaseCatalogsReq.InstanceName = args[0] response := w.Database.ListDatabaseCatalogs(ctx, listDatabaseCatalogsReq) + if listDatabaseCatalogsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDatabaseCatalogsLimit) + } + if listDatabaseCatalogsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDatabaseCatalogsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1250,9 +1278,19 @@ func newListDatabaseInstanceRoles() *cobra.Command { cmd := &cobra.Command{} var listDatabaseInstanceRolesReq database.ListDatabaseInstanceRolesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDatabaseInstanceRolesLimit int cmd.Flags().IntVar(&listDatabaseInstanceRolesReq.PageSize, "page-size", listDatabaseInstanceRolesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listDatabaseInstanceRolesReq.PageToken, "page-token", listDatabaseInstanceRolesReq.PageToken, `Pagination token to go to the next page of Database Instances.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDatabaseInstanceRolesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDatabaseInstanceRolesReq.PageToken, "page-token", listDatabaseInstanceRolesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-database-instance-roles INSTANCE_NAME" cmd.Short = `List roles for a Database Instance.` @@ -1282,6 +1320,13 @@ func newListDatabaseInstanceRoles() *cobra.Command { listDatabaseInstanceRolesReq.InstanceName = args[0] response := w.Database.ListDatabaseInstanceRoles(ctx, listDatabaseInstanceRolesReq) + if listDatabaseInstanceRolesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDatabaseInstanceRolesLimit) + } + if listDatabaseInstanceRolesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDatabaseInstanceRolesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1310,9 +1355,19 @@ func newListDatabaseInstances() *cobra.Command { cmd := &cobra.Command{} var listDatabaseInstancesReq database.ListDatabaseInstancesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDatabaseInstancesLimit int cmd.Flags().IntVar(&listDatabaseInstancesReq.PageSize, "page-size", listDatabaseInstancesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listDatabaseInstancesReq.PageToken, "page-token", listDatabaseInstancesReq.PageToken, `Pagination token to go to the next page of Database Instances.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDatabaseInstancesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDatabaseInstancesReq.PageToken, "page-token", listDatabaseInstancesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-database-instances" cmd.Short = `List Database Instances.` @@ -1331,6 +1386,13 @@ func newListDatabaseInstances() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Database.ListDatabaseInstances(ctx, listDatabaseInstancesReq) + if listDatabaseInstancesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDatabaseInstancesLimit) + } + if listDatabaseInstancesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDatabaseInstancesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1359,9 +1421,19 @@ func newListSyncedDatabaseTables() *cobra.Command { cmd := &cobra.Command{} var listSyncedDatabaseTablesReq database.ListSyncedDatabaseTablesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSyncedDatabaseTablesLimit int cmd.Flags().IntVar(&listSyncedDatabaseTablesReq.PageSize, "page-size", listSyncedDatabaseTablesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listSyncedDatabaseTablesReq.PageToken, "page-token", listSyncedDatabaseTablesReq.PageToken, `Pagination token to go to the next page of synced database tables.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSyncedDatabaseTablesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSyncedDatabaseTablesReq.PageToken, "page-token", listSyncedDatabaseTablesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-synced-database-tables INSTANCE_NAME" cmd.Short = `List all synced database tables in a Database Instance.` @@ -1390,6 +1462,13 @@ func newListSyncedDatabaseTables() *cobra.Command { listSyncedDatabaseTablesReq.InstanceName = args[0] response := w.Database.ListSyncedDatabaseTables(ctx, listSyncedDatabaseTablesReq) + if listSyncedDatabaseTablesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSyncedDatabaseTablesLimit) + } + if listSyncedDatabaseTablesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSyncedDatabaseTablesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1484,6 +1563,7 @@ func newUpdateDatabaseCatalog() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1570,6 +1650,7 @@ func newUpdateDatabaseInstance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1652,6 +1733,7 @@ func newUpdateSyncedDatabaseTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/default-namespace/default-namespace.go b/cmd/workspace/default-namespace/default-namespace.go index 8d669c7db59..5ec635652f2 100755 --- a/cmd/workspace/default-namespace/default-namespace.go +++ b/cmd/workspace/default-namespace/default-namespace.go @@ -91,6 +91,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -144,6 +145,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -214,6 +216,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/default-warehouse-id/default-warehouse-id.go b/cmd/workspace/default-warehouse-id/default-warehouse-id.go index b246a149861..1b9a61e41ff 100755 --- a/cmd/workspace/default-warehouse-id/default-warehouse-id.go +++ b/cmd/workspace/default-warehouse-id/default-warehouse-id.go @@ -80,6 +80,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -133,6 +134,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -197,6 +199,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/disable-legacy-access/disable-legacy-access.go b/cmd/workspace/disable-legacy-access/disable-legacy-access.go index 455e2d4c4c6..317546ea068 100755 --- a/cmd/workspace/disable-legacy-access/disable-legacy-access.go +++ b/cmd/workspace/disable-legacy-access/disable-legacy-access.go @@ -81,6 +81,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -134,6 +135,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -198,6 +200,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/disable-legacy-dbfs/disable-legacy-dbfs.go b/cmd/workspace/disable-legacy-dbfs/disable-legacy-dbfs.go index 9f4e2702001..5630444ee17 100755 --- a/cmd/workspace/disable-legacy-dbfs/disable-legacy-dbfs.go +++ b/cmd/workspace/disable-legacy-dbfs/disable-legacy-dbfs.go @@ -85,6 +85,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -138,6 +139,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -202,6 +204,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/enable-export-notebook/enable-export-notebook.go b/cmd/workspace/enable-export-notebook/enable-export-notebook.go index d0d75997d18..c9670c88034 100755 --- a/cmd/workspace/enable-export-notebook/enable-export-notebook.go +++ b/cmd/workspace/enable-export-notebook/enable-export-notebook.go @@ -65,6 +65,7 @@ func newGetEnableExportNotebook() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -131,6 +132,7 @@ func newPatchEnableExportNotebook() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/enable-notebook-table-clipboard/enable-notebook-table-clipboard.go b/cmd/workspace/enable-notebook-table-clipboard/enable-notebook-table-clipboard.go index 15b4814af8c..0ec3f7135fd 100755 --- a/cmd/workspace/enable-notebook-table-clipboard/enable-notebook-table-clipboard.go +++ b/cmd/workspace/enable-notebook-table-clipboard/enable-notebook-table-clipboard.go @@ -65,6 +65,7 @@ func newGetEnableNotebookTableClipboard() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -131,6 +132,7 @@ func newPatchEnableNotebookTableClipboard() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/enable-results-downloading/enable-results-downloading.go b/cmd/workspace/enable-results-downloading/enable-results-downloading.go index c844780f61e..efec5fecf82 100755 --- a/cmd/workspace/enable-results-downloading/enable-results-downloading.go +++ b/cmd/workspace/enable-results-downloading/enable-results-downloading.go @@ -65,6 +65,7 @@ func newGetEnableResultsDownloading() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -131,6 +132,7 @@ func newPatchEnableResultsDownloading() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/enhanced-security-monitoring/enhanced-security-monitoring.go b/cmd/workspace/enhanced-security-monitoring/enhanced-security-monitoring.go index 69b222012c6..7582c7f363e 100755 --- a/cmd/workspace/enhanced-security-monitoring/enhanced-security-monitoring.go +++ b/cmd/workspace/enhanced-security-monitoring/enhanced-security-monitoring.go @@ -81,6 +81,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -149,6 +150,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/entity-tag-assignments/entity-tag-assignments.go b/cmd/workspace/entity-tag-assignments/entity-tag-assignments.go index b8893a9c806..b29ac06da3b 100755 --- a/cmd/workspace/entity-tag-assignments/entity-tag-assignments.go +++ b/cmd/workspace/entity-tag-assignments/entity-tag-assignments.go @@ -84,8 +84,7 @@ func newCreate() *cobra.Command { Arguments: ENTITY_NAME: The fully qualified name of the entity to which the tag is assigned TAG_KEY: The key of the tag - ENTITY_TYPE: The type of the entity to which the tag is assigned. Allowed values are: - catalogs, schemas, tables, columns, volumes.` + ENTITY_TYPE: The type of the entity to which the tag is assigned.` cmd.Annotations = make(map[string]string) @@ -93,7 +92,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'entity_name', 'tag_key', 'entity_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'entity_name', 'tag_key', 'entity_type' in your JSON input") } return nil } @@ -132,6 +131,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -178,8 +178,7 @@ func newDelete() *cobra.Command { [Manage tag policy permissions]: https://docs.databricks.com/aws/en/admin/tag-policies/manage-permissions Arguments: - ENTITY_TYPE: The type of the entity to which the tag is assigned. Allowed values are: - catalogs, schemas, tables, columns, volumes. + ENTITY_TYPE: The type of the entity to which the tag is assigned. ENTITY_NAME: The fully qualified name of the entity to which the tag is assigned TAG_KEY: Required. The key of the tag to delete` @@ -239,8 +238,7 @@ func newGet() *cobra.Command { Gets a tag assignment for an Unity Catalog entity by tag key. Arguments: - ENTITY_TYPE: The type of the entity to which the tag is assigned. Allowed values are: - catalogs, schemas, tables, columns, volumes. + ENTITY_TYPE: The type of the entity to which the tag is assigned. ENTITY_NAME: The fully qualified name of the entity to which the tag is assigned TAG_KEY: Required. The key of the tag` @@ -264,6 +262,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -292,9 +291,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListEntityTagAssignmentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Optional.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Optional.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list ENTITY_TYPE ENTITY_NAME" cmd.Short = `List entity tag assignments.` @@ -308,8 +317,7 @@ func newList() *cobra.Command { end of results has been reached. Arguments: - ENTITY_TYPE: The type of the entity to which the tag is assigned. Allowed values are: - catalogs, schemas, tables, columns, volumes. + ENTITY_TYPE: The type of the entity to which the tag is assigned. ENTITY_NAME: The fully qualified name of the entity to which the tag is assigned` cmd.Annotations = make(map[string]string) @@ -328,6 +336,13 @@ func newList() *cobra.Command { listReq.EntityName = args[1] response := w.EntityTagAssignments.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -380,8 +395,7 @@ func newUpdate() *cobra.Command { [Manage tag policy permissions]: https://docs.databricks.com/aws/en/admin/tag-policies/manage-permissions Arguments: - ENTITY_TYPE: The type of the entity to which the tag is assigned. Allowed values are: - catalogs, schemas, tables, columns, volumes. + ENTITY_TYPE: The type of the entity to which the tag is assigned. ENTITY_NAME: The fully qualified name of the entity to which the tag is assigned TAG_KEY: The key of the tag UPDATE_MASK: The field mask must be a single string, with multiple fields separated by @@ -429,6 +443,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/environments/environments.go b/cmd/workspace/environments/environments.go index 6afb38437bc..385467dffd4 100755 --- a/cmd/workspace/environments/environments.go +++ b/cmd/workspace/environments/environments.go @@ -107,7 +107,7 @@ func newCreateWorkspaceBaseEnvironment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'display_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'display_name' in your JSON input") } return nil } @@ -289,6 +289,7 @@ func newGetDefaultWorkspaceBaseEnvironment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -346,6 +347,7 @@ func newGetOperation() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -403,6 +405,7 @@ func newGetWorkspaceBaseEnvironment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -431,9 +434,19 @@ func newListWorkspaceBaseEnvironments() *cobra.Command { cmd := &cobra.Command{} var listWorkspaceBaseEnvironmentsReq environments.ListWorkspaceBaseEnvironmentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listWorkspaceBaseEnvironmentsLimit int cmd.Flags().IntVar(&listWorkspaceBaseEnvironmentsReq.PageSize, "page-size", listWorkspaceBaseEnvironmentsReq.PageSize, `The maximum number of environments to return per page.`) - cmd.Flags().StringVar(&listWorkspaceBaseEnvironmentsReq.PageToken, "page-token", listWorkspaceBaseEnvironmentsReq.PageToken, `Page token for pagination.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listWorkspaceBaseEnvironmentsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listWorkspaceBaseEnvironmentsReq.PageToken, "page-token", listWorkspaceBaseEnvironmentsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-workspace-base-environments" cmd.Short = `List workspace base environments.` @@ -454,6 +467,13 @@ func newListWorkspaceBaseEnvironments() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Environments.ListWorkspaceBaseEnvironments(ctx, listWorkspaceBaseEnvironmentsReq) + if listWorkspaceBaseEnvironmentsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listWorkspaceBaseEnvironmentsLimit) + } + if listWorkspaceBaseEnvironmentsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listWorkspaceBaseEnvironmentsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -648,6 +668,7 @@ func newUpdateDefaultWorkspaceBaseEnvironment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/experiments/experiments.go b/cmd/workspace/experiments/experiments.go index 5527006c238..5f24b7e95bf 100755 --- a/cmd/workspace/experiments/experiments.go +++ b/cmd/workspace/experiments/experiments.go @@ -123,7 +123,7 @@ func newCreateExperiment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -156,6 +156,7 @@ func newCreateExperiment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -207,7 +208,7 @@ func newCreateLoggedModel() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id' in your JSON input") } return nil } @@ -240,6 +241,7 @@ func newCreateLoggedModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -316,6 +318,7 @@ func newCreateRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -365,7 +368,7 @@ func newDeleteExperiment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id' in your JSON input") } return nil } @@ -555,7 +558,7 @@ func newDeleteRun() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -642,7 +645,7 @@ func newDeleteRuns() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id', 'max_timestamp_millis' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id', 'max_timestamp_millis' in your JSON input") } return nil } @@ -682,6 +685,7 @@ func newDeleteRuns() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -731,7 +735,7 @@ func newDeleteTag() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id', 'key' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id', 'key' in your JSON input") } return nil } @@ -854,6 +858,7 @@ func newFinalizeLoggedModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -918,6 +923,7 @@ func newGetByName() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -974,6 +980,7 @@ func newGetExperiment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1002,12 +1009,22 @@ func newGetHistory() *cobra.Command { cmd := &cobra.Command{} var getHistoryReq ml.GetHistoryRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var getHistoryLimit int cmd.Flags().IntVar(&getHistoryReq.MaxResults, "max-results", getHistoryReq.MaxResults, `Maximum number of Metric records to return per paginated request.`) - cmd.Flags().StringVar(&getHistoryReq.PageToken, "page-token", getHistoryReq.PageToken, `Token indicating the page of metric histories to fetch.`) cmd.Flags().StringVar(&getHistoryReq.RunId, "run-id", getHistoryReq.RunId, `ID of the run from which to fetch metric values.`) cmd.Flags().StringVar(&getHistoryReq.RunUuid, "run-uuid", getHistoryReq.RunUuid, `[Deprecated, use run_id instead] ID of the run from which to fetch metric values.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&getHistoryLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&getHistoryReq.PageToken, "page-token", getHistoryReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "get-history METRIC_KEY" cmd.Short = `Get metric history for a run.` cmd.Long = `Get metric history for a run. @@ -1032,6 +1049,13 @@ func newGetHistory() *cobra.Command { getHistoryReq.MetricKey = args[0] response := w.Experiments.GetHistory(ctx, getHistoryReq) + if getHistoryLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", getHistoryLimit) + } + if getHistoryLimit > 0 { + ctx = cmdio.WithLimit(ctx, getHistoryLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1086,6 +1110,7 @@ func newGetLoggedModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1142,6 +1167,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1199,6 +1225,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1262,6 +1289,7 @@ func newGetRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1290,12 +1318,22 @@ func newListArtifacts() *cobra.Command { cmd := &cobra.Command{} var listArtifactsReq ml.ListArtifactsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listArtifactsLimit int - cmd.Flags().StringVar(&listArtifactsReq.PageToken, "page-token", listArtifactsReq.PageToken, `The token indicating the page of artifact results to fetch.`) cmd.Flags().StringVar(&listArtifactsReq.Path, "path", listArtifactsReq.Path, `Filter artifacts matching this path (a relative path from the root artifact directory).`) cmd.Flags().StringVar(&listArtifactsReq.RunId, "run-id", listArtifactsReq.RunId, `ID of the run whose artifacts to list.`) cmd.Flags().StringVar(&listArtifactsReq.RunUuid, "run-uuid", listArtifactsReq.RunUuid, `[Deprecated, use run_id instead] ID of the run whose artifacts to list.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listArtifactsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listArtifactsReq.PageToken, "page-token", listArtifactsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list-artifacts" cmd.Short = `List artifacts.` cmd.Long = `List artifacts. @@ -1320,6 +1358,13 @@ func newListArtifacts() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Experiments.ListArtifacts(ctx, listArtifactsReq) + if listArtifactsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listArtifactsLimit) + } + if listArtifactsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listArtifactsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1348,11 +1393,21 @@ func newListExperiments() *cobra.Command { cmd := &cobra.Command{} var listExperimentsReq ml.ListExperimentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listExperimentsLimit int cmd.Flags().Int64Var(&listExperimentsReq.MaxResults, "max-results", listExperimentsReq.MaxResults, `Maximum number of experiments desired.`) - cmd.Flags().StringVar(&listExperimentsReq.PageToken, "page-token", listExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) cmd.Flags().Var(&listExperimentsReq.ViewType, "view-type", `Qualifier for type of experiments to be returned. Supported values: [ACTIVE_ONLY, ALL, DELETED_ONLY]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listExperimentsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listExperimentsReq.PageToken, "page-token", listExperimentsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list-experiments" cmd.Short = `List experiments.` cmd.Long = `List experiments. @@ -1372,6 +1427,13 @@ func newListExperiments() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Experiments.ListExperiments(ctx, listExperimentsReq) + if listExperimentsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listExperimentsLimit) + } + if listExperimentsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listExperimentsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1536,7 +1598,7 @@ func newLogInputs() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -1703,7 +1765,7 @@ func newLogMetric() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'key', 'value', 'timestamp' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'key', 'value', 'timestamp' in your JSON input") } return nil } @@ -1873,7 +1935,7 @@ func newLogOutputs() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -1960,7 +2022,7 @@ func newLogParam() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'key', 'value' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'key', 'value' in your JSON input") } return nil } @@ -2048,7 +2110,7 @@ func newRestoreExperiment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id' in your JSON input") } return nil } @@ -2132,7 +2194,7 @@ func newRestoreRun() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -2219,7 +2281,7 @@ func newRestoreRuns() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id', 'min_timestamp_millis' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id', 'min_timestamp_millis' in your JSON input") } return nil } @@ -2259,6 +2321,7 @@ func newRestoreRuns() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2288,15 +2351,25 @@ func newSearchExperiments() *cobra.Command { var searchExperimentsReq ml.SearchExperiments var searchExperimentsJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var searchExperimentsLimit int cmd.Flags().Var(&searchExperimentsJson, "json", `either inline JSON string or @path/to/file.json with request body`) cmd.Flags().StringVar(&searchExperimentsReq.Filter, "filter", searchExperimentsReq.Filter, `String representing a SQL filter condition (e.g.`) cmd.Flags().Int64Var(&searchExperimentsReq.MaxResults, "max-results", searchExperimentsReq.MaxResults, `Maximum number of experiments desired.`) // TODO: array: order_by - cmd.Flags().StringVar(&searchExperimentsReq.PageToken, "page-token", searchExperimentsReq.PageToken, `Token indicating the page of experiments to fetch.`) cmd.Flags().Var(&searchExperimentsReq.ViewType, "view-type", `Qualifier for type of experiments to be returned. Supported values: [ACTIVE_ONLY, ALL, DELETED_ONLY]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&searchExperimentsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&searchExperimentsReq.PageToken, "page-token", searchExperimentsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "search-experiments" cmd.Short = `Search experiments.` cmd.Long = `Search experiments. @@ -2329,6 +2402,13 @@ func newSearchExperiments() *cobra.Command { } response := w.Experiments.SearchExperiments(ctx, searchExperimentsReq) + if searchExperimentsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", searchExperimentsLimit) + } + if searchExperimentsLimit > 0 { + ctx = cmdio.WithLimit(ctx, searchExperimentsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -2403,6 +2483,7 @@ func newSearchLoggedModels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2432,6 +2513,10 @@ func newSearchRuns() *cobra.Command { var searchRunsReq ml.SearchRuns var searchRunsJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var searchRunsLimit int cmd.Flags().Var(&searchRunsJson, "json", `either inline JSON string or @path/to/file.json with request body`) @@ -2439,9 +2524,15 @@ func newSearchRuns() *cobra.Command { cmd.Flags().StringVar(&searchRunsReq.Filter, "filter", searchRunsReq.Filter, `A filter expression over params, metrics, and tags, that allows returning a subset of runs.`) cmd.Flags().IntVar(&searchRunsReq.MaxResults, "max-results", searchRunsReq.MaxResults, `Maximum number of runs desired.`) // TODO: array: order_by - cmd.Flags().StringVar(&searchRunsReq.PageToken, "page-token", searchRunsReq.PageToken, `Token for the current page of runs.`) cmd.Flags().Var(&searchRunsReq.RunViewType, "run-view-type", `Whether to display only active, only deleted, or all runs. Supported values: [ACTIVE_ONLY, ALL, DELETED_ONLY]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&searchRunsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&searchRunsReq.PageToken, "page-token", searchRunsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "search-runs" cmd.Short = `Search for runs.` cmd.Long = `Search for runs. @@ -2476,6 +2567,13 @@ func newSearchRuns() *cobra.Command { } response := w.Experiments.SearchRuns(ctx, searchRunsReq) + if searchRunsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", searchRunsLimit) + } + if searchRunsLimit > 0 { + ctx = cmdio.WithLimit(ctx, searchRunsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -2526,7 +2624,7 @@ func newSetExperimentTag() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id', 'key', 'value' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id', 'key', 'value' in your JSON input") } return nil } @@ -2711,6 +2809,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2764,7 +2863,7 @@ func newSetTag() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'key', 'value' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'key', 'value' in your JSON input") } return nil } @@ -2849,7 +2948,7 @@ func newUpdateExperiment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'experiment_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'experiment_id' in your JSON input") } return nil } @@ -2956,6 +3055,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -3029,6 +3129,7 @@ func newUpdateRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/external-lineage/external-lineage.go b/cmd/workspace/external-lineage/external-lineage.go index be80f67c90a..9c871b5defc 100755 --- a/cmd/workspace/external-lineage/external-lineage.go +++ b/cmd/workspace/external-lineage/external-lineage.go @@ -84,7 +84,7 @@ func newCreateExternalLineageRelationship() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'source', 'target' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'source', 'target' in your JSON input") } return nil } @@ -128,6 +128,7 @@ func newCreateExternalLineageRelationship() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -222,11 +223,21 @@ func newListExternalLineageRelationships() *cobra.Command { var listExternalLineageRelationshipsReq catalog.ListExternalLineageRelationshipsRequest var listExternalLineageRelationshipsJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listExternalLineageRelationshipsLimit int cmd.Flags().Var(&listExternalLineageRelationshipsJson, "json", `either inline JSON string or @path/to/file.json with request body`) cmd.Flags().IntVar(&listExternalLineageRelationshipsReq.PageSize, "page-size", listExternalLineageRelationshipsReq.PageSize, `Specifies the maximum number of external lineage relationships to return in a single response.`) - cmd.Flags().StringVar(&listExternalLineageRelationshipsReq.PageToken, "page-token", listExternalLineageRelationshipsReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listExternalLineageRelationshipsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listExternalLineageRelationshipsReq.PageToken, "page-token", listExternalLineageRelationshipsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-external-lineage-relationships" cmd.Short = `List external lineage relationships.` @@ -258,6 +269,13 @@ func newListExternalLineageRelationships() *cobra.Command { } response := w.ExternalLineage.ListExternalLineageRelationships(ctx, listExternalLineageRelationshipsReq) + if listExternalLineageRelationshipsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listExternalLineageRelationshipsLimit) + } + if listExternalLineageRelationshipsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listExternalLineageRelationshipsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -367,6 +385,7 @@ func newUpdateExternalLineageRelationship() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/external-locations/external-locations.go b/cmd/workspace/external-locations/external-locations.go index ea3a855921e..cd9c1b2ab0f 100755 --- a/cmd/workspace/external-locations/external-locations.go +++ b/cmd/workspace/external-locations/external-locations.go @@ -71,6 +71,7 @@ func newCreate() *cobra.Command { cmd.Flags().Var(&createJson, "json", `either inline JSON string or @path/to/file.json with request body`) cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `User-provided free-form text description.`) + // TODO: complex arg: effective_file_event_queue cmd.Flags().BoolVar(&createReq.EnableFileEvents, "enable-file-events", createReq.EnableFileEvents, `Whether to enable file events on this external location.`) // TODO: complex arg: encryption_details cmd.Flags().BoolVar(&createReq.Fallback, "fallback", createReq.Fallback, `Indicates whether fallback mode is enabled for this external location.`) @@ -97,7 +98,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'url', 'credential_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'url', 'credential_name' in your JSON input") } return nil } @@ -136,6 +137,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -255,6 +257,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -283,11 +286,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListExternalLocationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include external locations in the response for which the principal can only access selective metadata for.`) cmd.Flags().BoolVar(&listReq.IncludeUnbound, "include-unbound", listReq.IncludeUnbound, `Whether to include external locations not bound to the workspace.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of external locations to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List external locations.` @@ -319,6 +333,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ExternalLocations.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -353,6 +374,7 @@ func newUpdate() *cobra.Command { cmd.Flags().StringVar(&updateReq.Comment, "comment", updateReq.Comment, `User-provided free-form text description.`) cmd.Flags().StringVar(&updateReq.CredentialName, "credential-name", updateReq.CredentialName, `Name of the storage credential used with this location.`) + // TODO: complex arg: effective_file_event_queue cmd.Flags().BoolVar(&updateReq.EnableFileEvents, "enable-file-events", updateReq.EnableFileEvents, `Whether to enable file events on this external location.`) // TODO: complex arg: encryption_details cmd.Flags().BoolVar(&updateReq.Fallback, "fallback", updateReq.Fallback, `Indicates whether fallback mode is enabled for this external location.`) @@ -406,6 +428,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/external-metadata/external-metadata.go b/cmd/workspace/external-metadata/external-metadata.go index 7768c5e99bd..79a9c335599 100755 --- a/cmd/workspace/external-metadata/external-metadata.go +++ b/cmd/workspace/external-metadata/external-metadata.go @@ -115,7 +115,7 @@ func newCreateExternalMetadata() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'system_type', 'entity_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'system_type', 'entity_type' in your JSON input") } return nil } @@ -158,6 +158,7 @@ func newCreateExternalMetadata() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -268,6 +269,7 @@ func newGetExternalMetadata() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -296,9 +298,19 @@ func newListExternalMetadata() *cobra.Command { cmd := &cobra.Command{} var listExternalMetadataReq catalog.ListExternalMetadataRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listExternalMetadataLimit int cmd.Flags().IntVar(&listExternalMetadataReq.PageSize, "page-size", listExternalMetadataReq.PageSize, `Specifies the maximum number of external metadata objects to return in a single response.`) - cmd.Flags().StringVar(&listExternalMetadataReq.PageToken, "page-token", listExternalMetadataReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listExternalMetadataLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listExternalMetadataReq.PageToken, "page-token", listExternalMetadataReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-external-metadata" cmd.Short = `List external metadata objects.` @@ -323,6 +335,13 @@ func newListExternalMetadata() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ExternalMetadata.ListExternalMetadata(ctx, listExternalMetadataReq) + if listExternalMetadataLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listExternalMetadataLimit) + } + if listExternalMetadataLimit > 0 { + ctx = cmdio.WithLimit(ctx, listExternalMetadataLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -461,6 +480,7 @@ func newUpdateExternalMetadata() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/feature-engineering/feature-engineering.go b/cmd/workspace/feature-engineering/feature-engineering.go index 5d1e5375079..d89f65f7d4e 100755 --- a/cmd/workspace/feature-engineering/feature-engineering.go +++ b/cmd/workspace/feature-engineering/feature-engineering.go @@ -99,7 +99,7 @@ func newCreateFeature() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'full_name', 'source', 'function' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'full_name', 'source', 'function' in your JSON input") } return nil } @@ -146,6 +146,7 @@ func newCreateFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -206,7 +207,7 @@ func newCreateKafkaConfig() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'bootstrap_servers', 'subscription_mode', 'auth_config' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'bootstrap_servers', 'subscription_mode', 'auth_config' in your JSON input") } return nil } @@ -256,6 +257,7 @@ func newCreateKafkaConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -308,7 +310,7 @@ func newCreateMaterializedFeature() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'feature_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'feature_name' in your JSON input") } return nil } @@ -341,6 +343,7 @@ func newCreateMaterializedFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -565,6 +568,7 @@ func newGetFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -623,6 +627,7 @@ func newGetKafkaConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -677,6 +682,7 @@ func newGetMaterializedFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -705,9 +711,19 @@ func newListFeatures() *cobra.Command { cmd := &cobra.Command{} var listFeaturesReq ml.ListFeaturesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listFeaturesLimit int cmd.Flags().IntVar(&listFeaturesReq.PageSize, "page-size", listFeaturesReq.PageSize, `The maximum number of results to return.`) - cmd.Flags().StringVar(&listFeaturesReq.PageToken, "page-token", listFeaturesReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listFeaturesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listFeaturesReq.PageToken, "page-token", listFeaturesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-features" cmd.Short = `List features.` @@ -728,6 +744,13 @@ func newListFeatures() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.FeatureEngineering.ListFeatures(ctx, listFeaturesReq) + if listFeaturesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listFeaturesLimit) + } + if listFeaturesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listFeaturesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -756,9 +779,19 @@ func newListKafkaConfigs() *cobra.Command { cmd := &cobra.Command{} var listKafkaConfigsReq ml.ListKafkaConfigsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listKafkaConfigsLimit int cmd.Flags().IntVar(&listKafkaConfigsReq.PageSize, "page-size", listKafkaConfigsReq.PageSize, `The maximum number of results to return.`) - cmd.Flags().StringVar(&listKafkaConfigsReq.PageToken, "page-token", listKafkaConfigsReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listKafkaConfigsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listKafkaConfigsReq.PageToken, "page-token", listKafkaConfigsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-kafka-configs" cmd.Short = `List Kafka configs.` @@ -781,6 +814,13 @@ func newListKafkaConfigs() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.FeatureEngineering.ListKafkaConfigs(ctx, listKafkaConfigsReq) + if listKafkaConfigsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listKafkaConfigsLimit) + } + if listKafkaConfigsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listKafkaConfigsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -809,10 +849,20 @@ func newListMaterializedFeatures() *cobra.Command { cmd := &cobra.Command{} var listMaterializedFeaturesReq ml.ListMaterializedFeaturesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listMaterializedFeaturesLimit int cmd.Flags().StringVar(&listMaterializedFeaturesReq.FeatureName, "feature-name", listMaterializedFeaturesReq.FeatureName, `Filter by feature name.`) cmd.Flags().IntVar(&listMaterializedFeaturesReq.PageSize, "page-size", listMaterializedFeaturesReq.PageSize, `The maximum number of results to return.`) - cmd.Flags().StringVar(&listMaterializedFeaturesReq.PageToken, "page-token", listMaterializedFeaturesReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listMaterializedFeaturesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listMaterializedFeaturesReq.PageToken, "page-token", listMaterializedFeaturesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-materialized-features" cmd.Short = `List materialized features.` @@ -831,6 +881,13 @@ func newListMaterializedFeatures() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.FeatureEngineering.ListMaterializedFeatures(ctx, listMaterializedFeaturesReq) + if listMaterializedFeaturesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listMaterializedFeaturesLimit) + } + if listMaterializedFeaturesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listMaterializedFeaturesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -936,6 +993,7 @@ func newUpdateFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1049,6 +1107,7 @@ func newUpdateKafkaConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1141,6 +1200,7 @@ func newUpdateMaterializedFeature() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/feature-store/feature-store.go b/cmd/workspace/feature-store/feature-store.go index d9bb4633292..4b1a7a0150c 100755 --- a/cmd/workspace/feature-store/feature-store.go +++ b/cmd/workspace/feature-store/feature-store.go @@ -89,7 +89,7 @@ func newCreateOnlineStore() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'capacity' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'capacity' in your JSON input") } return nil } @@ -125,6 +125,7 @@ func newCreateOnlineStore() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -289,6 +290,7 @@ func newGetOnlineStore() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -317,9 +319,19 @@ func newListOnlineStores() *cobra.Command { cmd := &cobra.Command{} var listOnlineStoresReq ml.ListOnlineStoresRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listOnlineStoresLimit int cmd.Flags().IntVar(&listOnlineStoresReq.PageSize, "page-size", listOnlineStoresReq.PageSize, `The maximum number of results to return.`) - cmd.Flags().StringVar(&listOnlineStoresReq.PageToken, "page-token", listOnlineStoresReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listOnlineStoresLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listOnlineStoresReq.PageToken, "page-token", listOnlineStoresReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-online-stores" cmd.Short = `List Online Feature Stores.` @@ -338,6 +350,13 @@ func newListOnlineStores() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.FeatureStore.ListOnlineStores(ctx, listOnlineStoresReq) + if listOnlineStoresLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listOnlineStoresLimit) + } + if listOnlineStoresLimit > 0 { + ctx = cmdio.WithLimit(ctx, listOnlineStoresLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -409,6 +428,7 @@ func newPublishTable() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -497,6 +517,7 @@ func newUpdateOnlineStore() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/forecasting/forecasting.go b/cmd/workspace/forecasting/forecasting.go index 2581fee940a..7802776a93d 100755 --- a/cmd/workspace/forecasting/forecasting.go +++ b/cmd/workspace/forecasting/forecasting.go @@ -108,7 +108,7 @@ func newCreateExperiment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'train_data_path', 'target_column', 'time_column', 'forecast_granularity', 'forecast_horizon' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'train_data_path', 'target_column', 'time_column', 'forecast_granularity', 'forecast_horizon' in your JSON input") } return nil } @@ -226,6 +226,7 @@ func newGetExperiment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/functions/functions.go b/cmd/workspace/functions/functions.go index 9ecf0948b39..7c02b25fb85 100755 --- a/cmd/workspace/functions/functions.go +++ b/cmd/workspace/functions/functions.go @@ -101,6 +101,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -254,6 +255,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -282,10 +284,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListFunctionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include functions in the response for which the principal can only access selective metadata for.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of functions to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list CATALOG_NAME SCHEMA_NAME" cmd.Short = `List functions.` @@ -327,6 +340,13 @@ func newList() *cobra.Command { listReq.SchemaName = args[1] response := w.Functions.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -420,6 +440,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/genie/genie.go b/cmd/workspace/genie/genie.go index e6fdb48004a..08879af3ab5 100755 --- a/cmd/workspace/genie/genie.go +++ b/cmd/workspace/genie/genie.go @@ -33,6 +33,7 @@ func New() *cobra.Command { // Add methods cmd.AddCommand(newCreateMessage()) + cmd.AddCommand(newCreateMessageComment()) cmd.AddCommand(newCreateSpace()) cmd.AddCommand(newDeleteConversation()) cmd.AddCommand(newDeleteConversationMessage()) @@ -50,8 +51,10 @@ func New() *cobra.Command { cmd.AddCommand(newGetMessageQueryResult()) cmd.AddCommand(newGetMessageQueryResultByAttachment()) cmd.AddCommand(newGetSpace()) + cmd.AddCommand(newListConversationComments()) cmd.AddCommand(newListConversationMessages()) cmd.AddCommand(newListConversations()) + cmd.AddCommand(newListMessageComments()) cmd.AddCommand(newListSpaces()) cmd.AddCommand(newSendMessageFeedback()) cmd.AddCommand(newStartConversation()) @@ -171,6 +174,93 @@ func newCreateMessage() *cobra.Command { return cmd } +// start create-message-comment command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createMessageCommentOverrides []func( + *cobra.Command, + *dashboards.GenieCreateMessageCommentRequest, +) + +func newCreateMessageComment() *cobra.Command { + cmd := &cobra.Command{} + + var createMessageCommentReq dashboards.GenieCreateMessageCommentRequest + var createMessageCommentJson flags.JsonFlag + + cmd.Flags().Var(&createMessageCommentJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Use = "create-message-comment SPACE_ID CONVERSATION_ID MESSAGE_ID CONTENT" + cmd.Short = `Create message comment.` + cmd.Long = `Create message comment. + + Create a comment on a conversation message. + + Arguments: + SPACE_ID: The ID associated with the Genie space. + CONVERSATION_ID: The ID associated with the conversation. + MESSAGE_ID: The ID associated with the message. + CONTENT: Comment text content.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + if cmd.Flags().Changed("json") { + err := root.ExactArgs(3)(cmd, args) + if err != nil { + return fmt.Errorf("when --json flag is specified, provide only SPACE_ID, CONVERSATION_ID, MESSAGE_ID as positional arguments. Provide 'content' in your JSON input") + } + return nil + } + check := root.ExactArgs(4) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + if cmd.Flags().Changed("json") { + diags := createMessageCommentJson.Unmarshal(&createMessageCommentReq) + if diags.HasError() { + return diags.Error() + } + if len(diags) > 0 { + err := cmdio.RenderDiagnostics(ctx, diags) + if err != nil { + return err + } + } + } + createMessageCommentReq.SpaceId = args[0] + createMessageCommentReq.ConversationId = args[1] + createMessageCommentReq.MessageId = args[2] + if !cmd.Flags().Changed("json") { + createMessageCommentReq.Content = args[3] + } + + response, err := w.Genie.CreateMessageComment(ctx, createMessageCommentReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createMessageCommentOverrides { + fn(cmd, &createMessageCommentReq) + } + + return cmd +} + // start create-space command // Slice with functions to override default command behavior. @@ -212,7 +302,7 @@ func newCreateSpace() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'warehouse_id', 'serialized_space' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'warehouse_id', 'serialized_space' in your JSON input") } return nil } @@ -248,6 +338,7 @@ func newCreateSpace() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -429,6 +520,7 @@ func newExecuteMessageAttachmentQuery() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -493,6 +585,7 @@ func newExecuteMessageQuery() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -577,6 +670,7 @@ func newGenerateDownloadFullQueryResult() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -651,6 +745,7 @@ func newGenieCreateEvalRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -712,6 +807,7 @@ func newGenieGetEvalResultDetails() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -771,6 +867,7 @@ func newGenieGetEvalRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -833,6 +930,7 @@ func newGenieListEvalResults() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -893,6 +991,7 @@ func newGenieListEvalRuns() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -983,6 +1082,7 @@ func newGetDownloadFullQueryResult() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1045,6 +1145,7 @@ func newGetMessage() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1109,6 +1210,7 @@ func newGetMessageAttachmentQueryResult() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1173,6 +1275,7 @@ func newGetMessageQueryResult() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1239,6 +1342,7 @@ func newGetMessageQueryResultByAttachment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1297,6 +1401,7 @@ func newGetSpace() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1312,6 +1417,68 @@ func newGetSpace() *cobra.Command { return cmd } +// start list-conversation-comments command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listConversationCommentsOverrides []func( + *cobra.Command, + *dashboards.GenieListConversationCommentsRequest, +) + +func newListConversationComments() *cobra.Command { + cmd := &cobra.Command{} + + var listConversationCommentsReq dashboards.GenieListConversationCommentsRequest + + cmd.Flags().IntVar(&listConversationCommentsReq.PageSize, "page-size", listConversationCommentsReq.PageSize, `Maximum number of comments to return per page.`) + cmd.Flags().StringVar(&listConversationCommentsReq.PageToken, "page-token", listConversationCommentsReq.PageToken, `Pagination token for getting the next page of results.`) + + cmd.Use = "list-conversation-comments SPACE_ID CONVERSATION_ID" + cmd.Short = `List conversation comments.` + cmd.Long = `List conversation comments. + + List all comments across all messages in a conversation. + + Arguments: + SPACE_ID: The ID associated with the Genie space. + CONVERSATION_ID: The ID associated with the conversation.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(2) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + listConversationCommentsReq.SpaceId = args[0] + listConversationCommentsReq.ConversationId = args[1] + + response, err := w.Genie.ListConversationComments(ctx, listConversationCommentsReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listConversationCommentsOverrides { + fn(cmd, &listConversationCommentsReq) + } + + return cmd +} + // start list-conversation-messages command // Slice with functions to override default command behavior. @@ -1358,6 +1525,7 @@ func newListConversationMessages() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1418,6 +1586,7 @@ func newListConversations() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1433,6 +1602,70 @@ func newListConversations() *cobra.Command { return cmd } +// start list-message-comments command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var listMessageCommentsOverrides []func( + *cobra.Command, + *dashboards.GenieListMessageCommentsRequest, +) + +func newListMessageComments() *cobra.Command { + cmd := &cobra.Command{} + + var listMessageCommentsReq dashboards.GenieListMessageCommentsRequest + + cmd.Flags().IntVar(&listMessageCommentsReq.PageSize, "page-size", listMessageCommentsReq.PageSize, `Maximum number of comments to return per page.`) + cmd.Flags().StringVar(&listMessageCommentsReq.PageToken, "page-token", listMessageCommentsReq.PageToken, `Pagination token for getting the next page of results.`) + + cmd.Use = "list-message-comments SPACE_ID CONVERSATION_ID MESSAGE_ID" + cmd.Short = `List message comments.` + cmd.Long = `List message comments. + + List comments on a specific conversation message. + + Arguments: + SPACE_ID: The ID associated with the Genie space. + CONVERSATION_ID: The ID associated with the conversation. + MESSAGE_ID: The ID associated with the message.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(3) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + listMessageCommentsReq.SpaceId = args[0] + listMessageCommentsReq.ConversationId = args[1] + listMessageCommentsReq.MessageId = args[2] + + response, err := w.Genie.ListMessageComments(ctx, listMessageCommentsReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range listMessageCommentsOverrides { + fn(cmd, &listMessageCommentsReq) + } + + return cmd +} + // start list-spaces command // Slice with functions to override default command behavior. @@ -1472,6 +1705,7 @@ func newListSpaces() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1504,6 +1738,8 @@ func newSendMessageFeedback() *cobra.Command { cmd.Flags().Var(&sendMessageFeedbackJson, "json", `either inline JSON string or @path/to/file.json with request body`) + cmd.Flags().StringVar(&sendMessageFeedbackReq.Comment, "comment", sendMessageFeedbackReq.Comment, `Optional text feedback that will be stored as a comment.`) + cmd.Use = "send-message-feedback SPACE_ID CONVERSATION_ID MESSAGE_ID RATING" cmd.Short = `Send message feedback.` cmd.Long = `Send message feedback. @@ -1797,6 +2033,7 @@ func newUpdateSpace() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/git-credentials/git-credentials.go b/cmd/workspace/git-credentials/git-credentials.go index 9d3cae1b4f1..b139272f0f9 100755 --- a/cmd/workspace/git-credentials/git-credentials.go +++ b/cmd/workspace/git-credentials/git-credentials.go @@ -89,7 +89,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'git_provider' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'git_provider' in your JSON input") } return nil } @@ -122,6 +122,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -268,6 +269,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -296,9 +298,18 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq workspace.ListCredentialsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Int64Var(&listReq.PrincipalId, "principal-id", listReq.PrincipalId, `The ID of the service principal whose credentials will be listed.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Use = "list" cmd.Short = `Get Git credentials.` cmd.Long = `Get Git credentials. @@ -318,6 +329,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.GitCredentials.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/global-init-scripts/global-init-scripts.go b/cmd/workspace/global-init-scripts/global-init-scripts.go index 610ba872690..c5a10c1e479 100755 --- a/cmd/workspace/global-init-scripts/global-init-scripts.go +++ b/cmd/workspace/global-init-scripts/global-init-scripts.go @@ -85,7 +85,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'script' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'script' in your JSON input") } return nil } @@ -121,6 +121,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -257,6 +258,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -282,6 +284,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `Get init scripts.` @@ -299,6 +310,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.GlobalInitScripts.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/grants/grants.go b/cmd/workspace/grants/grants.go index ca4f29d203f..a92c3edfbd3 100755 --- a/cmd/workspace/grants/grants.go +++ b/cmd/workspace/grants/grants.go @@ -102,6 +102,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -173,6 +174,7 @@ func newGetEffective() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -248,6 +250,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/groups-v2/groups-v2.go b/cmd/workspace/groups-v2/groups-v2.go index cd3247c526b..bc51d1a4927 100755 --- a/cmd/workspace/groups-v2/groups-v2.go +++ b/cmd/workspace/groups-v2/groups-v2.go @@ -3,6 +3,8 @@ package groups_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -109,6 +111,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -221,6 +224,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -249,14 +253,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListGroupsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List group details.` @@ -277,6 +292,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.GroupsV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/instance-pools/instance-pools.go b/cmd/workspace/instance-pools/instance-pools.go index 640058629d1..e1f69f62a88 100755 --- a/cmd/workspace/instance-pools/instance-pools.go +++ b/cmd/workspace/instance-pools/instance-pools.go @@ -115,7 +115,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_pool_name', 'node_type_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_pool_name', 'node_type_id' in your JSON input") } return nil } @@ -151,6 +151,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -199,7 +200,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_pool_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_pool_id' in your JSON input") } return nil } @@ -308,7 +309,7 @@ func newEdit() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_pool_id', 'instance_pool_name', 'node_type_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_pool_id', 'instance_pool_name', 'node_type_id' in your JSON input") } return nil } @@ -415,6 +416,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -483,6 +485,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -552,6 +555,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -577,6 +581,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `List instance pool info.` @@ -591,6 +604,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.InstancePools.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -678,6 +698,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -764,6 +785,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/instance-profiles/instance-profiles.go b/cmd/workspace/instance-profiles/instance-profiles.go index 5acc3c30bf7..190ea50fb12 100755 --- a/cmd/workspace/instance-profiles/instance-profiles.go +++ b/cmd/workspace/instance-profiles/instance-profiles.go @@ -85,7 +85,7 @@ func newAdd() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_profile_arn' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_profile_arn' in your JSON input") } return nil } @@ -183,7 +183,7 @@ func newEdit() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_profile_arn' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_profile_arn' in your JSON input") } return nil } @@ -241,6 +241,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `List available instance profiles.` @@ -257,6 +266,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.InstanceProfiles.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -307,7 +323,7 @@ func newRemove() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'instance_profile_arn' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'instance_profile_arn' in your JSON input") } return nil } diff --git a/cmd/workspace/ip-access-lists/ip-access-lists.go b/cmd/workspace/ip-access-lists/ip-access-lists.go index b1a8e61ffa6..2dfec2fb473 100755 --- a/cmd/workspace/ip-access-lists/ip-access-lists.go +++ b/cmd/workspace/ip-access-lists/ip-access-lists.go @@ -113,7 +113,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'label', 'list_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'label', 'list_type' in your JSON input") } return nil } @@ -153,6 +153,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -289,6 +290,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -314,6 +316,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `Get access lists.` @@ -328,6 +339,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.IpAccessLists.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/jobs/jobs.go b/cmd/workspace/jobs/jobs.go index 93e8f29bb4a..20b1ca221cf 100755 --- a/cmd/workspace/jobs/jobs.go +++ b/cmd/workspace/jobs/jobs.go @@ -184,7 +184,7 @@ func newCancelRun() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -317,6 +317,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -364,7 +365,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'job_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'job_id' in your JSON input") } return nil } @@ -463,7 +464,7 @@ func newDeleteRun() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -588,6 +589,7 @@ func newExportRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -671,6 +673,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -739,6 +742,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -808,6 +812,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -893,6 +898,7 @@ func newGetRun() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -973,6 +979,7 @@ func newGetRunOutput() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1001,12 +1008,23 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq jobs.ListJobsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.ExpandTasks, "expand-tasks", listReq.ExpandTasks, `Whether to include task and cluster details in the response.`) - cmd.Flags().IntVar(&listReq.Limit, "limit", listReq.Limit, `The number of jobs to return.`) + cmd.Flags().IntVar(&listReq.Limit, "page-size", listReq.Limit, `The number of jobs to return.`) + cmd.Flags().Lookup("page-size").Hidden = true cmd.Flags().StringVar(&listReq.Name, "name", listReq.Name, `A filter on the list based on the exact (case insensitive) job name.`) cmd.Flags().IntVar(&listReq.Offset, "offset", listReq.Offset, `The offset of the first job to return, relative to the most recently created job.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of jobs respectively.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List jobs.` @@ -1027,6 +1045,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Jobs.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1055,18 +1080,29 @@ func newListRuns() *cobra.Command { cmd := &cobra.Command{} var listRunsReq jobs.ListRunsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listRunsLimit int cmd.Flags().BoolVar(&listRunsReq.ActiveOnly, "active-only", listRunsReq.ActiveOnly, `If active_only is true, only active runs are included in the results; otherwise, lists both active and completed runs.`) cmd.Flags().BoolVar(&listRunsReq.CompletedOnly, "completed-only", listRunsReq.CompletedOnly, `If completed_only is true, only completed runs are included in the results; otherwise, lists both active and completed runs.`) cmd.Flags().BoolVar(&listRunsReq.ExpandTasks, "expand-tasks", listRunsReq.ExpandTasks, `Whether to include task and cluster details in the response.`) cmd.Flags().Int64Var(&listRunsReq.JobId, "job-id", listRunsReq.JobId, `The job for which to list runs.`) - cmd.Flags().IntVar(&listRunsReq.Limit, "limit", listRunsReq.Limit, `The number of runs to return.`) + cmd.Flags().IntVar(&listRunsReq.Limit, "page-size", listRunsReq.Limit, `The number of runs to return.`) + cmd.Flags().Lookup("page-size").Hidden = true cmd.Flags().IntVar(&listRunsReq.Offset, "offset", listRunsReq.Offset, `The offset of the first run to return, relative to the most recent run.`) - cmd.Flags().StringVar(&listRunsReq.PageToken, "page-token", listRunsReq.PageToken, `Use next_page_token or prev_page_token returned from the previous request to list the next or previous page of runs respectively.`) cmd.Flags().Var(&listRunsReq.RunType, "run-type", `The type of runs to return. Supported values: [JOB_RUN, SUBMIT_RUN, WORKFLOW_RUN]`) cmd.Flags().Int64Var(&listRunsReq.StartTimeFrom, "start-time-from", listRunsReq.StartTimeFrom, `Show runs that started _at or after_ this value.`) cmd.Flags().Int64Var(&listRunsReq.StartTimeTo, "start-time-to", listRunsReq.StartTimeTo, `Show runs that started _at or before_ this value.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listRunsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listRunsReq.PageToken, "page-token", listRunsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list-runs" cmd.Short = `List job runs.` cmd.Long = `List job runs. @@ -1086,6 +1122,13 @@ func newListRuns() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Jobs.ListRuns(ctx, listRunsReq) + if listRunsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listRunsLimit) + } + if listRunsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listRunsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1156,7 +1199,7 @@ func newRepairRun() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'run_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'run_id' in your JSON input") } return nil } @@ -1359,7 +1402,7 @@ func newRunNow() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'job_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'job_id' in your JSON input") } return nil } @@ -1517,6 +1560,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1686,7 +1730,7 @@ func newUpdate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'job_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'job_id' in your JSON input") } return nil } @@ -1824,6 +1868,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/knowledge-assistants/knowledge-assistants.go b/cmd/workspace/knowledge-assistants/knowledge-assistants.go index a23c0fa88e9..f72403a61ab 100755 --- a/cmd/workspace/knowledge-assistants/knowledge-assistants.go +++ b/cmd/workspace/knowledge-assistants/knowledge-assistants.go @@ -90,7 +90,7 @@ func newCreateKnowledgeAssistant() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'display_name', 'description' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'display_name', 'description' in your JSON input") } return nil } @@ -126,6 +126,7 @@ func newCreateKnowledgeAssistant() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -229,6 +230,7 @@ func newCreateKnowledgeSource() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -400,6 +402,7 @@ func newGetKnowledgeAssistant() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -457,6 +460,7 @@ func newGetKnowledgeSource() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -485,9 +489,19 @@ func newListKnowledgeAssistants() *cobra.Command { cmd := &cobra.Command{} var listKnowledgeAssistantsReq knowledgeassistants.ListKnowledgeAssistantsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listKnowledgeAssistantsLimit int cmd.Flags().IntVar(&listKnowledgeAssistantsReq.PageSize, "page-size", listKnowledgeAssistantsReq.PageSize, `The maximum number of knowledge assistants to return.`) - cmd.Flags().StringVar(&listKnowledgeAssistantsReq.PageToken, "page-token", listKnowledgeAssistantsReq.PageToken, `A page token, received from a previous ListKnowledgeAssistants call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listKnowledgeAssistantsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listKnowledgeAssistantsReq.PageToken, "page-token", listKnowledgeAssistantsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-knowledge-assistants" cmd.Short = `List Knowledge Assistants.` @@ -508,6 +522,13 @@ func newListKnowledgeAssistants() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.KnowledgeAssistants.ListKnowledgeAssistants(ctx, listKnowledgeAssistantsReq) + if listKnowledgeAssistantsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listKnowledgeAssistantsLimit) + } + if listKnowledgeAssistantsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listKnowledgeAssistantsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -536,9 +557,19 @@ func newListKnowledgeSources() *cobra.Command { cmd := &cobra.Command{} var listKnowledgeSourcesReq knowledgeassistants.ListKnowledgeSourcesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listKnowledgeSourcesLimit int cmd.Flags().IntVar(&listKnowledgeSourcesReq.PageSize, "page-size", listKnowledgeSourcesReq.PageSize, ``) - cmd.Flags().StringVar(&listKnowledgeSourcesReq.PageToken, "page-token", listKnowledgeSourcesReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listKnowledgeSourcesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listKnowledgeSourcesReq.PageToken, "page-token", listKnowledgeSourcesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-knowledge-sources PARENT" cmd.Short = `List Knowledge Sources.` @@ -565,6 +596,13 @@ func newListKnowledgeSources() *cobra.Command { listKnowledgeSourcesReq.Parent = args[0] response := w.KnowledgeAssistants.ListKnowledgeSources(ctx, listKnowledgeSourcesReq) + if listKnowledgeSourcesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listKnowledgeSourcesLimit) + } + if listKnowledgeSourcesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listKnowledgeSourcesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -725,6 +763,7 @@ func newUpdateKnowledgeAssistant() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -835,6 +874,7 @@ func newUpdateKnowledgeSource() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/lakeview-embedded/lakeview-embedded.go b/cmd/workspace/lakeview-embedded/lakeview-embedded.go index dce42dabf79..8034e8086a8 100755 --- a/cmd/workspace/lakeview-embedded/lakeview-embedded.go +++ b/cmd/workspace/lakeview-embedded/lakeview-embedded.go @@ -79,6 +79,7 @@ func newGetPublishedDashboardTokenInfo() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/lakeview/lakeview.go b/cmd/workspace/lakeview/lakeview.go index 4dd071a903c..f9ea06c4690 100755 --- a/cmd/workspace/lakeview/lakeview.go +++ b/cmd/workspace/lakeview/lakeview.go @@ -115,6 +115,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -205,6 +206,7 @@ func newCreateSchedule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -295,6 +297,7 @@ func newCreateSubscription() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -469,6 +472,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -525,6 +529,7 @@ func newGetPublished() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -581,6 +586,7 @@ func newGetSchedule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -639,6 +645,7 @@ func newGetSubscription() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -667,12 +674,22 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq dashboards.ListDashboardsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `The number of dashboards to return per page.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A page token, received from a previous ListDashboards call.`) cmd.Flags().BoolVar(&listReq.ShowTrashed, "show-trashed", listReq.ShowTrashed, `The flag to include dashboards located in the trash.`) cmd.Flags().Var(&listReq.View, "view", `DASHBOARD_VIEW_BASIConly includes summary metadata from the dashboard. Supported values: [DASHBOARD_VIEW_BASIC]`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List dashboards.` cmd.Long = `List dashboards.` @@ -690,6 +707,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Lakeview.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -718,9 +742,19 @@ func newListSchedules() *cobra.Command { cmd := &cobra.Command{} var listSchedulesReq dashboards.ListSchedulesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSchedulesLimit int cmd.Flags().IntVar(&listSchedulesReq.PageSize, "page-size", listSchedulesReq.PageSize, `The number of schedules to return per page.`) - cmd.Flags().StringVar(&listSchedulesReq.PageToken, "page-token", listSchedulesReq.PageToken, `A page token, received from a previous ListSchedules call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSchedulesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSchedulesReq.PageToken, "page-token", listSchedulesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-schedules DASHBOARD_ID" cmd.Short = `List dashboard schedules.` @@ -744,6 +778,13 @@ func newListSchedules() *cobra.Command { listSchedulesReq.DashboardId = args[0] response := w.Lakeview.ListSchedules(ctx, listSchedulesReq) + if listSchedulesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSchedulesLimit) + } + if listSchedulesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSchedulesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -772,9 +813,19 @@ func newListSubscriptions() *cobra.Command { cmd := &cobra.Command{} var listSubscriptionsReq dashboards.ListSubscriptionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSubscriptionsLimit int cmd.Flags().IntVar(&listSubscriptionsReq.PageSize, "page-size", listSubscriptionsReq.PageSize, `The number of subscriptions to return per page.`) - cmd.Flags().StringVar(&listSubscriptionsReq.PageToken, "page-token", listSubscriptionsReq.PageToken, `A page token, received from a previous ListSubscriptions call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSubscriptionsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSubscriptionsReq.PageToken, "page-token", listSubscriptionsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-subscriptions DASHBOARD_ID SCHEDULE_ID" cmd.Short = `List schedule subscriptions.` @@ -800,6 +851,13 @@ func newListSubscriptions() *cobra.Command { listSubscriptionsReq.ScheduleId = args[1] response := w.Lakeview.ListSubscriptions(ctx, listSubscriptionsReq) + if listSubscriptionsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSubscriptionsLimit) + } + if listSubscriptionsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSubscriptionsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -851,7 +909,7 @@ func newMigrate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'source_dashboard_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'source_dashboard_id' in your JSON input") } return nil } @@ -884,6 +942,7 @@ func newMigrate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -958,6 +1017,7 @@ func newPublish() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1148,6 +1208,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1240,6 +1301,7 @@ func newUpdateSchedule() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/libraries/libraries.go b/cmd/workspace/libraries/libraries.go index db2225d9e1c..5f890d86819 100755 --- a/cmd/workspace/libraries/libraries.go +++ b/cmd/workspace/libraries/libraries.go @@ -65,6 +65,15 @@ var allClusterStatusesOverrides []func( func newAllClusterStatuses() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var allClusterStatusesLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&allClusterStatusesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "all-cluster-statuses" cmd.Short = `Get all statuses.` @@ -80,6 +89,13 @@ func newAllClusterStatuses() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.Libraries.AllClusterStatuses(ctx) + if allClusterStatusesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", allClusterStatusesLimit) + } + if allClusterStatusesLimit > 0 { + ctx = cmdio.WithLimit(ctx, allClusterStatusesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -108,6 +124,15 @@ func newClusterStatus() *cobra.Command { cmd := &cobra.Command{} var clusterStatusReq compute.ClusterStatus + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var clusterStatusLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&clusterStatusLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "cluster-status CLUSTER_ID" cmd.Short = `Get status.` @@ -139,6 +164,13 @@ func newClusterStatus() *cobra.Command { clusterStatusReq.ClusterId = args[0] response := w.Libraries.ClusterStatus(ctx, clusterStatusReq) + if clusterStatusLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", clusterStatusLimit) + } + if clusterStatusLimit > 0 { + ctx = cmdio.WithLimit(ctx, clusterStatusLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/llm-proxy-partner-powered-workspace/llm-proxy-partner-powered-workspace.go b/cmd/workspace/llm-proxy-partner-powered-workspace/llm-proxy-partner-powered-workspace.go index 77b9e4d8dda..90c003e216d 100755 --- a/cmd/workspace/llm-proxy-partner-powered-workspace/llm-proxy-partner-powered-workspace.go +++ b/cmd/workspace/llm-proxy-partner-powered-workspace/llm-proxy-partner-powered-workspace.go @@ -81,6 +81,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -134,6 +135,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -198,6 +200,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/materialized-features/materialized-features.go b/cmd/workspace/materialized-features/materialized-features.go index 12194b38fee..a9a7f55b142 100755 --- a/cmd/workspace/materialized-features/materialized-features.go +++ b/cmd/workspace/materialized-features/materialized-features.go @@ -113,6 +113,7 @@ func newCreateFeatureTag() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -229,6 +230,7 @@ func newGetFeatureLineage() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -284,6 +286,7 @@ func newGetFeatureTag() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -312,9 +315,19 @@ func newListFeatureTags() *cobra.Command { cmd := &cobra.Command{} var listFeatureTagsReq ml.ListFeatureTagsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listFeatureTagsLimit int cmd.Flags().IntVar(&listFeatureTagsReq.PageSize, "page-size", listFeatureTagsReq.PageSize, `The maximum number of results to return.`) - cmd.Flags().StringVar(&listFeatureTagsReq.PageToken, "page-token", listFeatureTagsReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listFeatureTagsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listFeatureTagsReq.PageToken, "page-token", listFeatureTagsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-feature-tags TABLE_NAME FEATURE_NAME" cmd.Short = `List all feature tags.` @@ -338,6 +351,13 @@ func newListFeatureTags() *cobra.Command { listFeatureTagsReq.FeatureName = args[1] response := w.MaterializedFeatures.ListFeatureTags(ctx, listFeatureTagsReq) + if listFeatureTagsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listFeatureTagsLimit) + } + if listFeatureTagsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listFeatureTagsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -412,6 +432,7 @@ func newUpdateFeatureTag() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/metastores/metastores.go b/cmd/workspace/metastores/metastores.go index 9f00ed1bfd9..95decff8409 100755 --- a/cmd/workspace/metastores/metastores.go +++ b/cmd/workspace/metastores/metastores.go @@ -192,7 +192,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -225,6 +225,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -267,6 +268,7 @@ func newCurrent() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -382,6 +384,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -410,9 +413,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListMetastoresRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of metastores to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List metastores.` @@ -443,6 +456,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Metastores.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -486,6 +506,7 @@ func newSummary() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -630,6 +651,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/model-registry/model-registry.go b/cmd/workspace/model-registry/model-registry.go index 047040ce46e..f742fe8a666 100755 --- a/cmd/workspace/model-registry/model-registry.go +++ b/cmd/workspace/model-registry/model-registry.go @@ -125,7 +125,7 @@ func newApproveTransitionRequest() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'stage', 'archive_existing_versions' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'stage', 'archive_existing_versions' in your JSON input") } return nil } @@ -171,6 +171,7 @@ func newApproveTransitionRequest() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -222,7 +223,7 @@ func newCreateComment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'comment' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'comment' in your JSON input") } return nil } @@ -261,6 +262,7 @@ func newCreateComment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -313,7 +315,7 @@ func newCreateModel() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -346,6 +348,7 @@ func newCreateModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -399,7 +402,7 @@ func newCreateModelVersion() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'source' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'source' in your JSON input") } return nil } @@ -435,6 +438,7 @@ func newCreateModelVersion() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -494,7 +498,7 @@ func newCreateTransitionRequest() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'stage' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'stage' in your JSON input") } return nil } @@ -533,6 +537,7 @@ func newCreateTransitionRequest() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -603,6 +608,7 @@ func newCreateWebhook() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -967,6 +973,7 @@ func newDeleteTransitionRequest() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1052,11 +1059,20 @@ func newGetLatestVersions() *cobra.Command { var getLatestVersionsReq ml.GetLatestVersionsRequest var getLatestVersionsJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var getLatestVersionsLimit int cmd.Flags().Var(&getLatestVersionsJson, "json", `either inline JSON string or @path/to/file.json with request body`) // TODO: array: stages + // Limit flag for total result capping. + cmd.Flags().IntVar(&getLatestVersionsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Use = "get-latest-versions NAME" cmd.Short = `Get the latest version.` cmd.Long = `Get the latest version. @@ -1072,7 +1088,7 @@ func newGetLatestVersions() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -1102,6 +1118,13 @@ func newGetLatestVersions() *cobra.Command { } response := w.ModelRegistry.GetLatestVersions(ctx, getLatestVersionsReq) + if getLatestVersionsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", getLatestVersionsLimit) + } + if getLatestVersionsLimit > 0 { + ctx = cmdio.WithLimit(ctx, getLatestVersionsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1162,6 +1185,7 @@ func newGetModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1218,6 +1242,7 @@ func newGetModelVersion() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1276,6 +1301,7 @@ func newGetModelVersionDownloadUri() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1332,6 +1358,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1389,6 +1416,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1417,9 +1445,19 @@ func newListModels() *cobra.Command { cmd := &cobra.Command{} var listModelsReq ml.ListModelsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listModelsLimit int cmd.Flags().Int64Var(&listModelsReq.MaxResults, "max-results", listModelsReq.MaxResults, `Maximum number of registered models desired.`) - cmd.Flags().StringVar(&listModelsReq.PageToken, "page-token", listModelsReq.PageToken, `Pagination token to go to the next page based on a previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listModelsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listModelsReq.PageToken, "page-token", listModelsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-models" cmd.Short = `List models.` @@ -1441,6 +1479,13 @@ func newListModels() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ModelRegistry.ListModels(ctx, listModelsReq) + if listModelsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listModelsLimit) + } + if listModelsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listModelsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1469,6 +1514,15 @@ func newListTransitionRequests() *cobra.Command { cmd := &cobra.Command{} var listTransitionRequestsReq ml.ListTransitionRequestsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listTransitionRequestsLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listTransitionRequestsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list-transition-requests NAME VERSION" cmd.Short = `List transition requests.` @@ -1496,6 +1550,13 @@ func newListTransitionRequests() *cobra.Command { listTransitionRequestsReq.Version = args[1] response := w.ModelRegistry.ListTransitionRequests(ctx, listTransitionRequestsReq) + if listTransitionRequestsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listTransitionRequestsLimit) + } + if listTransitionRequestsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listTransitionRequestsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1524,11 +1585,21 @@ func newListWebhooks() *cobra.Command { cmd := &cobra.Command{} var listWebhooksReq ml.ListWebhooksRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listWebhooksLimit int // TODO: array: events cmd.Flags().Int64Var(&listWebhooksReq.MaxResults, "max-results", listWebhooksReq.MaxResults, ``) cmd.Flags().StringVar(&listWebhooksReq.ModelName, "model-name", listWebhooksReq.ModelName, `Registered model name If not specified, all webhooks associated with the specified events are listed, regardless of their associated model.`) - cmd.Flags().StringVar(&listWebhooksReq.PageToken, "page-token", listWebhooksReq.PageToken, `Token indicating the page of artifact results to fetch.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listWebhooksLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listWebhooksReq.PageToken, "page-token", listWebhooksReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-webhooks" cmd.Short = `List registry webhooks.` @@ -1549,6 +1620,13 @@ func newListWebhooks() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ModelRegistry.ListWebhooks(ctx, listWebhooksReq) + if listWebhooksLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listWebhooksLimit) + } + if listWebhooksLimit > 0 { + ctx = cmdio.WithLimit(ctx, listWebhooksLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1608,7 +1686,7 @@ func newRejectTransitionRequest() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'stage' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'stage' in your JSON input") } return nil } @@ -1647,6 +1725,7 @@ func newRejectTransitionRequest() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1696,7 +1775,7 @@ func newRenameModel() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -1729,6 +1808,7 @@ func newRenameModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1757,11 +1837,21 @@ func newSearchModelVersions() *cobra.Command { cmd := &cobra.Command{} var searchModelVersionsReq ml.SearchModelVersionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var searchModelVersionsLimit int cmd.Flags().StringVar(&searchModelVersionsReq.Filter, "filter", searchModelVersionsReq.Filter, `String filter condition, like "name='my-model-name'".`) cmd.Flags().Int64Var(&searchModelVersionsReq.MaxResults, "max-results", searchModelVersionsReq.MaxResults, `Maximum number of models desired.`) // TODO: array: order_by - cmd.Flags().StringVar(&searchModelVersionsReq.PageToken, "page-token", searchModelVersionsReq.PageToken, `Pagination token to go to next page based on previous search query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&searchModelVersionsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&searchModelVersionsReq.PageToken, "page-token", searchModelVersionsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "search-model-versions" cmd.Short = `Search model versions.` @@ -1782,6 +1872,13 @@ func newSearchModelVersions() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ModelRegistry.SearchModelVersions(ctx, searchModelVersionsReq) + if searchModelVersionsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", searchModelVersionsLimit) + } + if searchModelVersionsLimit > 0 { + ctx = cmdio.WithLimit(ctx, searchModelVersionsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1810,11 +1907,21 @@ func newSearchModels() *cobra.Command { cmd := &cobra.Command{} var searchModelsReq ml.SearchModelsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var searchModelsLimit int cmd.Flags().StringVar(&searchModelsReq.Filter, "filter", searchModelsReq.Filter, `String filter condition, like "name LIKE 'my-model-name'".`) cmd.Flags().Int64Var(&searchModelsReq.MaxResults, "max-results", searchModelsReq.MaxResults, `Maximum number of models desired.`) // TODO: array: order_by - cmd.Flags().StringVar(&searchModelsReq.PageToken, "page-token", searchModelsReq.PageToken, `Pagination token to go to the next page based on a previous search query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&searchModelsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&searchModelsReq.PageToken, "page-token", searchModelsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "search-models" cmd.Short = `Search models.` @@ -1835,6 +1942,13 @@ func newSearchModels() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ModelRegistry.SearchModels(ctx, searchModelsReq) + if searchModelsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", searchModelsLimit) + } + if searchModelsLimit > 0 { + ctx = cmdio.WithLimit(ctx, searchModelsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1889,7 +2003,7 @@ func newSetModelTag() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'key', 'value' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'key', 'value' in your JSON input") } return nil } @@ -1983,7 +2097,7 @@ func newSetModelVersionTag() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'key', 'value' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'key', 'value' in your JSON input") } return nil } @@ -2100,6 +2214,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2162,7 +2277,7 @@ func newTestRegistryWebhook() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'id' in your JSON input") } return nil } @@ -2195,6 +2310,7 @@ func newTestRegistryWebhook() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2260,7 +2376,7 @@ func newTransitionStage() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version', 'stage', 'archive_existing_versions' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version', 'stage', 'archive_existing_versions' in your JSON input") } return nil } @@ -2306,6 +2422,7 @@ func newTransitionStage() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2354,7 +2471,7 @@ func newUpdateComment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'id', 'comment' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'id', 'comment' in your JSON input") } return nil } @@ -2390,6 +2507,7 @@ func newUpdateComment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2439,7 +2557,7 @@ func newUpdateModel() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -2472,6 +2590,7 @@ func newUpdateModel() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2522,7 +2641,7 @@ func newUpdateModelVersion() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'version' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'version' in your JSON input") } return nil } @@ -2558,6 +2677,7 @@ func newUpdateModelVersion() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2632,6 +2752,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -2685,7 +2806,7 @@ func newUpdateWebhook() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'id' in your JSON input") } return nil } @@ -2718,6 +2839,7 @@ func newUpdateWebhook() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/model-versions/model-versions.go b/cmd/workspace/model-versions/model-versions.go index b2ceca74321..2432693d89c 100755 --- a/cmd/workspace/model-versions/model-versions.go +++ b/cmd/workspace/model-versions/model-versions.go @@ -168,6 +168,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +234,7 @@ func newGetByAlias() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,10 +263,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListModelVersionsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include model versions in the response for which the principal can only access selective metadata for.`) cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of model versions to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list FULL_NAME" cmd.Short = `List Model Versions.` @@ -308,6 +320,13 @@ func newList() *cobra.Command { listReq.FullName = args[0] response := w.ModelVersions.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -409,6 +428,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/notification-destinations/notification-destinations.go b/cmd/workspace/notification-destinations/notification-destinations.go index cc365c9e7e7..b028cf80d69 100755 --- a/cmd/workspace/notification-destinations/notification-destinations.go +++ b/cmd/workspace/notification-destinations/notification-destinations.go @@ -3,6 +3,8 @@ package notification_destinations import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -98,6 +100,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -204,6 +207,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -232,9 +236,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq settings.ListNotificationDestinationsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Int64Var(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List notification destinations.` @@ -255,6 +269,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.NotificationDestinations.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -330,6 +351,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/online-tables/online-tables.go b/cmd/workspace/online-tables/online-tables.go index fde740b410f..fb43d85e8a9 100755 --- a/cmd/workspace/online-tables/online-tables.go +++ b/cmd/workspace/online-tables/online-tables.go @@ -231,6 +231,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/permission-migration/permission-migration.go b/cmd/workspace/permission-migration/permission-migration.go index 62f1546662a..0bcf145740e 100755 --- a/cmd/workspace/permission-migration/permission-migration.go +++ b/cmd/workspace/permission-migration/permission-migration.go @@ -76,7 +76,7 @@ func newMigratePermissions() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'workspace_id', 'from_workspace_group_name', 'to_account_group_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'workspace_id', 'from_workspace_group_name', 'to_account_group_name' in your JSON input") } return nil } @@ -119,6 +119,7 @@ func newMigratePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/permissions/permissions.go b/cmd/workspace/permissions/permissions.go index 9b644776aa9..f12e2f9e41c 100755 --- a/cmd/workspace/permissions/permissions.go +++ b/cmd/workspace/permissions/permissions.go @@ -116,6 +116,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -178,6 +179,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -259,6 +261,7 @@ func newSet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -339,6 +342,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/pipelines/pipelines.go b/cmd/workspace/pipelines/pipelines.go index 56138c45a19..2401b325371 100755 --- a/cmd/workspace/pipelines/pipelines.go +++ b/cmd/workspace/pipelines/pipelines.go @@ -42,6 +42,7 @@ func New() *cobra.Command { } // Add methods + cmd.AddCommand(newApplyEnvironment()) cmd.AddCommand(newClone()) cmd.AddCommand(newCreate()) cmd.AddCommand(newDelete()) @@ -66,6 +67,73 @@ func New() *cobra.Command { return cmd } +// start apply-environment command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var applyEnvironmentOverrides []func( + *cobra.Command, + *pipelines.ApplyEnvironmentRequest, +) + +func newApplyEnvironment() *cobra.Command { + cmd := &cobra.Command{} + + var applyEnvironmentReq pipelines.ApplyEnvironmentRequest + + cmd.Use = "apply-environment PIPELINE_ID" + cmd.Short = `Apply the latest environment to the pipeline.` + cmd.Long = `Apply the latest environment to the pipeline. + + * Applies the current pipeline environment onto the pipeline compute. The + environment applied can be used by subsequent dev-mode updates.` + + cmd.Annotations = make(map[string]string) + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + if len(args) == 0 { + sp := cmdio.NewSpinner(ctx) + sp.Update("No PIPELINE_ID argument specified. Loading names for Pipelines drop-down.") + names, err := w.Pipelines.PipelineStateInfoNameToPipelineIdMap(ctx, pipelines.ListPipelinesRequest{}) + sp.Close() + if err != nil { + return fmt.Errorf("failed to load names for Pipelines drop-down. Please manually specify required arguments. Original error: %w", err) + } + id, err := cmdio.Select(ctx, names, "") + if err != nil { + return err + } + args = append(args, id) + } + if len(args) != 1 { + return fmt.Errorf("expected to have ") + } + applyEnvironmentReq.PipelineId = args[0] + + response, err := w.Pipelines.ApplyEnvironment(ctx, applyEnvironmentReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range applyEnvironmentOverrides { + fn(cmd, &applyEnvironmentReq) + } + + return cmd +} + // start clone command // Slice with functions to override default command behavior. @@ -126,6 +194,7 @@ func newClone() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -191,6 +260,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -220,6 +290,7 @@ func newDelete() *cobra.Command { var deleteReq pipelines.DeletePipelineRequest + cmd.Flags().BoolVar(&deleteReq.Cascade, "cascade", deleteReq.Cascade, `If false, pipeline deletion will not cascade to its datasets (MVs, STs, Views).`) cmd.Flags().BoolVar(&deleteReq.Force, "force", deleteReq.Force, `If true, deletion will proceed even if resource cleanup fails.`) cmd.Use = "delete PIPELINE_ID" @@ -323,6 +394,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -391,6 +463,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -460,6 +533,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -518,6 +592,7 @@ func newGetUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -546,11 +621,21 @@ func newListPipelineEvents() *cobra.Command { cmd := &cobra.Command{} var listPipelineEventsReq pipelines.ListPipelineEventsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listPipelineEventsLimit int cmd.Flags().StringVar(&listPipelineEventsReq.Filter, "filter", listPipelineEventsReq.Filter, `Criteria to select a subset of results, expressed using a SQL-like syntax.`) cmd.Flags().IntVar(&listPipelineEventsReq.MaxResults, "max-results", listPipelineEventsReq.MaxResults, `Max number of entries to return in a single page.`) // TODO: array: order_by - cmd.Flags().StringVar(&listPipelineEventsReq.PageToken, "page-token", listPipelineEventsReq.PageToken, `Page token returned by previous call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listPipelineEventsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listPipelineEventsReq.PageToken, "page-token", listPipelineEventsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-pipeline-events PIPELINE_ID" cmd.Short = `List pipeline events.` @@ -588,6 +673,13 @@ func newListPipelineEvents() *cobra.Command { listPipelineEventsReq.PipelineId = args[0] response := w.Pipelines.ListPipelineEvents(ctx, listPipelineEventsReq) + if listPipelineEventsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listPipelineEventsLimit) + } + if listPipelineEventsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listPipelineEventsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -616,11 +708,21 @@ func newListPipelines() *cobra.Command { cmd := &cobra.Command{} var listPipelinesReq pipelines.ListPipelinesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listPipelinesLimit int cmd.Flags().StringVar(&listPipelinesReq.Filter, "filter", listPipelinesReq.Filter, `Select a subset of results based on the specified criteria.`) cmd.Flags().IntVar(&listPipelinesReq.MaxResults, "max-results", listPipelinesReq.MaxResults, `The maximum number of entries to return in a single page.`) // TODO: array: order_by - cmd.Flags().StringVar(&listPipelinesReq.PageToken, "page-token", listPipelinesReq.PageToken, `Page token returned by previous call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listPipelinesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listPipelinesReq.PageToken, "page-token", listPipelinesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-pipelines" cmd.Short = `List pipelines.` @@ -641,6 +743,13 @@ func newListPipelines() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Pipelines.ListPipelines(ctx, listPipelinesReq) + if listPipelinesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listPipelinesLimit) + } + if listPipelinesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listPipelinesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -713,6 +822,7 @@ func newListUpdates() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -800,6 +910,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -899,6 +1010,7 @@ func newStartUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1184,6 +1296,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/policies/policies.go b/cmd/workspace/policies/policies.go index 35e8d0cfab7..8bde169cdc0 100755 --- a/cmd/workspace/policies/policies.go +++ b/cmd/workspace/policies/policies.go @@ -134,7 +134,7 @@ func newCreatePolicy() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'to_principals', 'for_securable_type', 'policy_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'to_principals', 'for_securable_type', 'policy_type' in your JSON input") } return nil } @@ -185,6 +185,7 @@ func newCreatePolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -246,6 +247,7 @@ func newDeletePolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -306,6 +308,7 @@ func newGetPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -334,10 +337,20 @@ func newListPolicies() *cobra.Command { cmd := &cobra.Command{} var listPoliciesReq catalog.ListPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listPoliciesLimit int cmd.Flags().BoolVar(&listPoliciesReq.IncludeInherited, "include-inherited", listPoliciesReq.IncludeInherited, `Optional.`) cmd.Flags().IntVar(&listPoliciesReq.MaxResults, "max-results", listPoliciesReq.MaxResults, `Optional.`) - cmd.Flags().StringVar(&listPoliciesReq.PageToken, "page-token", listPoliciesReq.PageToken, `Optional.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listPoliciesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listPoliciesReq.PageToken, "page-token", listPoliciesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-policies ON_SECURABLE_TYPE ON_SECURABLE_FULLNAME" cmd.Short = `List ABAC policies.` @@ -371,6 +384,13 @@ func newListPolicies() *cobra.Command { listPoliciesReq.OnSecurableFullname = args[1] response := w.Policies.ListPolicies(ctx, listPoliciesReq) + if listPoliciesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listPoliciesLimit) + } + if listPoliciesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listPoliciesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -530,6 +550,7 @@ func newUpdatePolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/policy-compliance-for-clusters/policy-compliance-for-clusters.go b/cmd/workspace/policy-compliance-for-clusters/policy-compliance-for-clusters.go index 8d715bd6d72..a4ba0f4f9d7 100755 --- a/cmd/workspace/policy-compliance-for-clusters/policy-compliance-for-clusters.go +++ b/cmd/workspace/policy-compliance-for-clusters/policy-compliance-for-clusters.go @@ -94,7 +94,7 @@ func newEnforceCompliance() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'cluster_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'cluster_id' in your JSON input") } return nil } @@ -127,6 +127,7 @@ func newEnforceCompliance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -184,6 +185,7 @@ func newGetCompliance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -212,9 +214,19 @@ func newListCompliance() *cobra.Command { cmd := &cobra.Command{} var listComplianceReq compute.ListClusterCompliancesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listComplianceLimit int cmd.Flags().IntVar(&listComplianceReq.PageSize, "page-size", listComplianceReq.PageSize, `Use this field to specify the maximum number of results to be returned by the server.`) - cmd.Flags().StringVar(&listComplianceReq.PageToken, "page-token", listComplianceReq.PageToken, `A page token that can be used to navigate to the next page or previous page as returned by next_page_token or prev_page_token.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listComplianceLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listComplianceReq.PageToken, "page-token", listComplianceReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-compliance POLICY_ID" cmd.Short = `List cluster policy compliance.` @@ -242,6 +254,13 @@ func newListCompliance() *cobra.Command { listComplianceReq.PolicyId = args[0] response := w.PolicyComplianceForClusters.ListCompliance(ctx, listComplianceReq) + if listComplianceLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listComplianceLimit) + } + if listComplianceLimit > 0 { + ctx = cmdio.WithLimit(ctx, listComplianceLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/policy-compliance-for-jobs/policy-compliance-for-jobs.go b/cmd/workspace/policy-compliance-for-jobs/policy-compliance-for-jobs.go index 4a025f4ba1a..2a081689035 100755 --- a/cmd/workspace/policy-compliance-for-jobs/policy-compliance-for-jobs.go +++ b/cmd/workspace/policy-compliance-for-jobs/policy-compliance-for-jobs.go @@ -88,7 +88,7 @@ func newEnforceCompliance() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'job_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'job_id' in your JSON input") } return nil } @@ -125,6 +125,7 @@ func newEnforceCompliance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -186,6 +187,7 @@ func newGetCompliance() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -214,9 +216,19 @@ func newListCompliance() *cobra.Command { cmd := &cobra.Command{} var listComplianceReq jobs.ListJobComplianceRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listComplianceLimit int cmd.Flags().IntVar(&listComplianceReq.PageSize, "page-size", listComplianceReq.PageSize, `Use this field to specify the maximum number of results to be returned by the server.`) - cmd.Flags().StringVar(&listComplianceReq.PageToken, "page-token", listComplianceReq.PageToken, `A page token that can be used to navigate to the next page or previous page as returned by next_page_token or prev_page_token.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listComplianceLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listComplianceReq.PageToken, "page-token", listComplianceReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-compliance POLICY_ID" cmd.Short = `List job policy compliance.` @@ -245,6 +257,13 @@ func newListCompliance() *cobra.Command { listComplianceReq.PolicyId = args[0] response := w.PolicyComplianceForJobs.ListCompliance(ctx, listComplianceReq) + if listComplianceLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listComplianceLimit) + } + if listComplianceLimit > 0 { + ctx = cmdio.WithLimit(ctx, listComplianceLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/policy-families/policy-families.go b/cmd/workspace/policy-families/policy-families.go index f5b65a6a3a7..2926c04f260 100755 --- a/cmd/workspace/policy-families/policy-families.go +++ b/cmd/workspace/policy-families/policy-families.go @@ -3,6 +3,8 @@ package policy_families import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -87,6 +89,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -115,9 +118,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq compute.ListPolicyFamiliesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Int64Var(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of policy families to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A token that can be used to get the next page of results.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List policy families.` @@ -139,6 +152,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.PolicyFamilies.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/postgres/postgres.go b/cmd/workspace/postgres/postgres.go index f098764d032..e60842b1e76 100755 --- a/cmd/workspace/postgres/postgres.go +++ b/cmd/workspace/postgres/postgres.go @@ -43,22 +43,28 @@ func New() *cobra.Command { // Add methods cmd.AddCommand(newCreateBranch()) + cmd.AddCommand(newCreateCatalog()) cmd.AddCommand(newCreateDatabase()) cmd.AddCommand(newCreateEndpoint()) cmd.AddCommand(newCreateProject()) cmd.AddCommand(newCreateRole()) + cmd.AddCommand(newCreateSyncedTable()) cmd.AddCommand(newDeleteBranch()) + cmd.AddCommand(newDeleteCatalog()) cmd.AddCommand(newDeleteDatabase()) cmd.AddCommand(newDeleteEndpoint()) cmd.AddCommand(newDeleteProject()) cmd.AddCommand(newDeleteRole()) + cmd.AddCommand(newDeleteSyncedTable()) cmd.AddCommand(newGenerateDatabaseCredential()) cmd.AddCommand(newGetBranch()) + cmd.AddCommand(newGetCatalog()) cmd.AddCommand(newGetDatabase()) cmd.AddCommand(newGetEndpoint()) cmd.AddCommand(newGetOperation()) cmd.AddCommand(newGetProject()) cmd.AddCommand(newGetRole()) + cmd.AddCommand(newGetSyncedTable()) cmd.AddCommand(newListBranches()) cmd.AddCommand(newListDatabases()) cmd.AddCommand(newListEndpoints()) @@ -203,6 +209,125 @@ func newCreateBranch() *cobra.Command { return cmd } +// start create-catalog command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createCatalogOverrides []func( + *cobra.Command, + *postgres.CreateCatalogRequest, +) + +func newCreateCatalog() *cobra.Command { + cmd := &cobra.Command{} + + var createCatalogReq postgres.CreateCatalogRequest + createCatalogReq.Catalog = postgres.Catalog{} + var createCatalogJson flags.JsonFlag + + var createCatalogSkipWait bool + var createCatalogTimeout time.Duration + + cmd.Flags().BoolVar(&createCatalogSkipWait, "no-wait", createCatalogSkipWait, `do not wait to reach DONE state`) + cmd.Flags().DurationVar(&createCatalogTimeout, "timeout", 0, `maximum amount of time to reach DONE state`) + + cmd.Flags().Var(&createCatalogJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createCatalogReq.Catalog.Name, "name", createCatalogReq.Catalog.Name, `Output only.`) + // TODO: complex arg: spec + // TODO: complex arg: status + + cmd.Use = "create-catalog CATALOG_ID" + cmd.Short = `Register a Database in UC.` + cmd.Long = `Register a Database in UC. + + Register a Postgres database in the Unity Catalog. + + This is a long-running operation. By default, the command waits for the + operation to complete. Use --no-wait to return immediately with the raw + operation details. The operation's 'name' field can then be used to poll for + completion using the get-operation command. + + Arguments: + CATALOG_ID: The ID in the Unity Catalog. It becomes the full resource name, for + example "my_catalog" becomes "catalogs/my_catalog".` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + if cmd.Flags().Changed("json") { + diags := createCatalogJson.Unmarshal(&createCatalogReq.Catalog) + if diags.HasError() { + return diags.Error() + } + if len(diags) > 0 { + err := cmdio.RenderDiagnostics(ctx, diags) + if err != nil { + return err + } + } + } + createCatalogReq.CatalogId = args[0] + + // Determine which mode to execute based on flags. + switch { + case createCatalogSkipWait: + wait, err := w.Postgres.CreateCatalog(ctx, createCatalogReq) + if err != nil { + return err + } + + // Return operation immediately without waiting. + operation, err := w.Postgres.GetOperation(ctx, postgres.GetOperationRequest{ + Name: wait.Name(), + }) + if err != nil { + return err + } + return cmdio.Render(ctx, operation) + + default: + wait, err := w.Postgres.CreateCatalog(ctx, createCatalogReq) + if err != nil { + return err + } + + // Show spinner while waiting for completion. + sp := cmdio.NewSpinner(ctx) + sp.Update("Waiting for create-catalog to complete...") + + // Wait for completion. + opts := api.WithTimeout(createCatalogTimeout) + response, err := wait.Wait(ctx, opts) + if err != nil { + return err + } + sp.Close() + return cmdio.Render(ctx, response) + } + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createCatalogOverrides { + fn(cmd, &createCatalogReq) + } + + return cmd +} + // start create-database command // Slice with functions to override default command behavior. @@ -697,6 +822,135 @@ func newCreateRole() *cobra.Command { return cmd } +// start create-synced-table command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var createSyncedTableOverrides []func( + *cobra.Command, + *postgres.CreateSyncedTableRequest, +) + +func newCreateSyncedTable() *cobra.Command { + cmd := &cobra.Command{} + + var createSyncedTableReq postgres.CreateSyncedTableRequest + createSyncedTableReq.SyncedTable = postgres.SyncedTable{} + var createSyncedTableJson flags.JsonFlag + + var createSyncedTableSkipWait bool + var createSyncedTableTimeout time.Duration + + cmd.Flags().BoolVar(&createSyncedTableSkipWait, "no-wait", createSyncedTableSkipWait, `do not wait to reach DONE state`) + cmd.Flags().DurationVar(&createSyncedTableTimeout, "timeout", 0, `maximum amount of time to reach DONE state`) + + cmd.Flags().Var(&createSyncedTableJson, "json", `either inline JSON string or @path/to/file.json with request body`) + + cmd.Flags().StringVar(&createSyncedTableReq.SyncedTable.Name, "name", createSyncedTableReq.SyncedTable.Name, `Output only.`) + // TODO: complex arg: spec + // TODO: complex arg: status + + cmd.Use = "create-synced-table SYNCED_TABLE_ID" + cmd.Short = `Create a Synced Database Table.` + cmd.Long = `Create a Synced Database Table. + + Create a Synced Table. + + This is a long-running operation. By default, the command waits for the + operation to complete. Use --no-wait to return immediately with the raw + operation details. The operation's 'name' field can then be used to poll for + completion using the get-operation command. + + Arguments: + SYNCED_TABLE_ID: The ID to use for the Synced Table. This becomes the final component of + the SyncedTable's resource name. ID is required and is the synced table + name, containing (catalog, schema, table) tuple. Elements of the tuple are + the UC entity names. + + Example: "{catalog}.{schema}.{table}" + + synced_table_id represents both of the following: + + 1. An online VIEW virtual table in the Unity Catalog accessible via the + Lakehouse Federation. 2. Postgres table named "{table}" in schema + "{schema}" in the connected Postgres database` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + if cmd.Flags().Changed("json") { + diags := createSyncedTableJson.Unmarshal(&createSyncedTableReq.SyncedTable) + if diags.HasError() { + return diags.Error() + } + if len(diags) > 0 { + err := cmdio.RenderDiagnostics(ctx, diags) + if err != nil { + return err + } + } + } + createSyncedTableReq.SyncedTableId = args[0] + + // Determine which mode to execute based on flags. + switch { + case createSyncedTableSkipWait: + wait, err := w.Postgres.CreateSyncedTable(ctx, createSyncedTableReq) + if err != nil { + return err + } + + // Return operation immediately without waiting. + operation, err := w.Postgres.GetOperation(ctx, postgres.GetOperationRequest{ + Name: wait.Name(), + }) + if err != nil { + return err + } + return cmdio.Render(ctx, operation) + + default: + wait, err := w.Postgres.CreateSyncedTable(ctx, createSyncedTableReq) + if err != nil { + return err + } + + // Show spinner while waiting for completion. + sp := cmdio.NewSpinner(ctx) + sp.Update("Waiting for create-synced-table to complete...") + + // Wait for completion. + opts := api.WithTimeout(createSyncedTableTimeout) + response, err := wait.Wait(ctx, opts) + if err != nil { + return err + } + sp.Close() + return cmdio.Render(ctx, response) + } + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range createSyncedTableOverrides { + fn(cmd, &createSyncedTableReq) + } + + return cmd +} + // start delete-branch command // Slice with functions to override default command behavior. @@ -797,6 +1051,105 @@ func newDeleteBranch() *cobra.Command { return cmd } +// start delete-catalog command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteCatalogOverrides []func( + *cobra.Command, + *postgres.DeleteCatalogRequest, +) + +func newDeleteCatalog() *cobra.Command { + cmd := &cobra.Command{} + + var deleteCatalogReq postgres.DeleteCatalogRequest + + var deleteCatalogSkipWait bool + var deleteCatalogTimeout time.Duration + + cmd.Flags().BoolVar(&deleteCatalogSkipWait, "no-wait", deleteCatalogSkipWait, `do not wait to reach DONE state`) + cmd.Flags().DurationVar(&deleteCatalogTimeout, "timeout", 0, `maximum amount of time to reach DONE state`) + + cmd.Use = "delete-catalog NAME" + cmd.Short = `Delete a Database Catalog.` + cmd.Long = `Delete a Database Catalog. + + This is a long-running operation. By default, the command waits for the + operation to complete. Use --no-wait to return immediately with the raw + operation details. The operation's 'name' field can then be used to poll for + completion using the get-operation command. + + Arguments: + NAME: The full resource path of the catalog to delete. + + Format: "catalogs/{catalog_id}".` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + deleteCatalogReq.Name = args[0] + + // Determine which mode to execute based on flags. + switch { + case deleteCatalogSkipWait: + wait, err := w.Postgres.DeleteCatalog(ctx, deleteCatalogReq) + if err != nil { + return err + } + + // Return operation immediately without waiting. + operation, err := w.Postgres.GetOperation(ctx, postgres.GetOperationRequest{ + Name: wait.Name(), + }) + if err != nil { + return err + } + return cmdio.Render(ctx, operation) + + default: + wait, err := w.Postgres.DeleteCatalog(ctx, deleteCatalogReq) + if err != nil { + return err + } + + // Show spinner while waiting for completion. + sp := cmdio.NewSpinner(ctx) + sp.Update("Waiting for delete-catalog to complete...") + + // Wait for completion. + opts := api.WithTimeout(deleteCatalogTimeout) + + err = wait.Wait(ctx, opts) + if err != nil { + return err + } + sp.Close() + return nil + } + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteCatalogOverrides { + fn(cmd, &deleteCatalogReq) + } + + return cmd +} + // start delete-database command // Slice with functions to override default command behavior. @@ -1200,6 +1553,107 @@ func newDeleteRole() *cobra.Command { return cmd } +// start delete-synced-table command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var deleteSyncedTableOverrides []func( + *cobra.Command, + *postgres.DeleteSyncedTableRequest, +) + +func newDeleteSyncedTable() *cobra.Command { + cmd := &cobra.Command{} + + var deleteSyncedTableReq postgres.DeleteSyncedTableRequest + + var deleteSyncedTableSkipWait bool + var deleteSyncedTableTimeout time.Duration + + cmd.Flags().BoolVar(&deleteSyncedTableSkipWait, "no-wait", deleteSyncedTableSkipWait, `do not wait to reach DONE state`) + cmd.Flags().DurationVar(&deleteSyncedTableTimeout, "timeout", 0, `maximum amount of time to reach DONE state`) + + cmd.Use = "delete-synced-table NAME" + cmd.Short = `Delete a Synced Database Table.` + cmd.Long = `Delete a Synced Database Table. + + Delete a Synced Table. + + This is a long-running operation. By default, the command waits for the + operation to complete. Use --no-wait to return immediately with the raw + operation details. The operation's 'name' field can then be used to poll for + completion using the get-operation command. + + Arguments: + NAME: The Full resource name of the synced table, of the format + "synced_tables/{catalog}.{schema}.{table}", where (catalog, schema, table) + are the UC entity names.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + deleteSyncedTableReq.Name = args[0] + + // Determine which mode to execute based on flags. + switch { + case deleteSyncedTableSkipWait: + wait, err := w.Postgres.DeleteSyncedTable(ctx, deleteSyncedTableReq) + if err != nil { + return err + } + + // Return operation immediately without waiting. + operation, err := w.Postgres.GetOperation(ctx, postgres.GetOperationRequest{ + Name: wait.Name(), + }) + if err != nil { + return err + } + return cmdio.Render(ctx, operation) + + default: + wait, err := w.Postgres.DeleteSyncedTable(ctx, deleteSyncedTableReq) + if err != nil { + return err + } + + // Show spinner while waiting for completion. + sp := cmdio.NewSpinner(ctx) + sp.Update("Waiting for delete-synced-table to complete...") + + // Wait for completion. + opts := api.WithTimeout(deleteSyncedTableTimeout) + + err = wait.Wait(ctx, opts) + if err != nil { + return err + } + sp.Close() + return nil + } + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range deleteSyncedTableOverrides { + fn(cmd, &deleteSyncedTableReq) + } + + return cmd +} + // start generate-database-credential command // Slice with functions to override default command behavior. @@ -1234,7 +1688,7 @@ func newGenerateDatabaseCredential() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'endpoint' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'endpoint' in your JSON input") } return nil } @@ -1267,6 +1721,7 @@ func newGenerateDatabaseCredential() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1324,6 +1779,7 @@ func newGetBranch() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1339,6 +1795,63 @@ func newGetBranch() *cobra.Command { return cmd } +// start get-catalog command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getCatalogOverrides []func( + *cobra.Command, + *postgres.GetCatalogRequest, +) + +func newGetCatalog() *cobra.Command { + cmd := &cobra.Command{} + + var getCatalogReq postgres.GetCatalogRequest + + cmd.Use = "get-catalog NAME" + cmd.Short = `Get a Database Catalog.` + cmd.Long = `Get a Database Catalog. + + Arguments: + NAME: The full resource path of the catalog to retrieve. + + Format: "catalogs/{catalog_id}".` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + getCatalogReq.Name = args[0] + + response, err := w.Postgres.GetCatalog(ctx, getCatalogReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getCatalogOverrides { + fn(cmd, &getCatalogReq) + } + + return cmd +} + // start get-database command // Slice with functions to override default command behavior. @@ -1382,6 +1895,7 @@ func newGetDatabase() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1440,6 +1954,7 @@ func newGetEndpoint() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1496,6 +2011,7 @@ func newGetOperation() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1553,6 +2069,7 @@ func newGetProject() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1611,6 +2128,7 @@ func newGetRole() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1626,6 +2144,64 @@ func newGetRole() *cobra.Command { return cmd } +// start get-synced-table command + +// Slice with functions to override default command behavior. +// Functions can be added from the `init()` function in manually curated files in this directory. +var getSyncedTableOverrides []func( + *cobra.Command, + *postgres.GetSyncedTableRequest, +) + +func newGetSyncedTable() *cobra.Command { + cmd := &cobra.Command{} + + var getSyncedTableReq postgres.GetSyncedTableRequest + + cmd.Use = "get-synced-table NAME" + cmd.Short = `Get a Synced Database Table.` + cmd.Long = `Get a Synced Database Table. + + Get a Synced Table. + + Arguments: + NAME: Format: "synced_tables/{catalog}.{schema}.{table}", where (catalog, + schema, table) are the entity names in the Unity Catalog.` + + cmd.Annotations = make(map[string]string) + + cmd.Args = func(cmd *cobra.Command, args []string) error { + check := root.ExactArgs(1) + return check(cmd, args) + } + + cmd.PreRunE = root.MustWorkspaceClient + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + ctx := cmd.Context() + w := cmdctx.WorkspaceClient(ctx) + + getSyncedTableReq.Name = args[0] + + response, err := w.Postgres.GetSyncedTable(ctx, getSyncedTableReq) + if err != nil { + return err + } + + return cmdio.Render(ctx, response) + } + + // Disable completions since they are not applicable. + // Can be overridden by manual implementation in `override.go`. + cmd.ValidArgsFunction = cobra.NoFileCompletions + + // Apply optional overrides to this command. + for _, fn := range getSyncedTableOverrides { + fn(cmd, &getSyncedTableReq) + } + + return cmd +} + // start list-branches command // Slice with functions to override default command behavior. @@ -1639,9 +2215,19 @@ func newListBranches() *cobra.Command { cmd := &cobra.Command{} var listBranchesReq postgres.ListBranchesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listBranchesLimit int cmd.Flags().IntVar(&listBranchesReq.PageSize, "page-size", listBranchesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listBranchesReq.PageToken, "page-token", listBranchesReq.PageToken, `Page token from a previous response.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listBranchesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listBranchesReq.PageToken, "page-token", listBranchesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-branches PARENT" cmd.Short = `List Branches.` @@ -1668,6 +2254,13 @@ func newListBranches() *cobra.Command { listBranchesReq.Parent = args[0] response := w.Postgres.ListBranches(ctx, listBranchesReq) + if listBranchesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listBranchesLimit) + } + if listBranchesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listBranchesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1696,9 +2289,19 @@ func newListDatabases() *cobra.Command { cmd := &cobra.Command{} var listDatabasesReq postgres.ListDatabasesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDatabasesLimit int cmd.Flags().IntVar(&listDatabasesReq.PageSize, "page-size", listDatabasesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listDatabasesReq.PageToken, "page-token", listDatabasesReq.PageToken, `Pagination token to go to the next page of Databases.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDatabasesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDatabasesReq.PageToken, "page-token", listDatabasesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-databases PARENT" cmd.Short = `List postgres databases in a branch.` @@ -1728,6 +2331,13 @@ func newListDatabases() *cobra.Command { listDatabasesReq.Parent = args[0] response := w.Postgres.ListDatabases(ctx, listDatabasesReq) + if listDatabasesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDatabasesLimit) + } + if listDatabasesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDatabasesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1756,9 +2366,19 @@ func newListEndpoints() *cobra.Command { cmd := &cobra.Command{} var listEndpointsReq postgres.ListEndpointsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listEndpointsLimit int cmd.Flags().IntVar(&listEndpointsReq.PageSize, "page-size", listEndpointsReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, `Page token from a previous response.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listEndpointsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-endpoints PARENT" cmd.Short = `List Endpoints.` @@ -1785,6 +2405,13 @@ func newListEndpoints() *cobra.Command { listEndpointsReq.Parent = args[0] response := w.Postgres.ListEndpoints(ctx, listEndpointsReq) + if listEndpointsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listEndpointsLimit) + } + if listEndpointsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listEndpointsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1813,9 +2440,19 @@ func newListProjects() *cobra.Command { cmd := &cobra.Command{} var listProjectsReq postgres.ListProjectsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listProjectsLimit int cmd.Flags().IntVar(&listProjectsReq.PageSize, "page-size", listProjectsReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listProjectsReq.PageToken, "page-token", listProjectsReq.PageToken, `Page token from a previous response.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listProjectsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listProjectsReq.PageToken, "page-token", listProjectsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-projects" cmd.Short = `List Projects.` @@ -1837,6 +2474,13 @@ func newListProjects() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Postgres.ListProjects(ctx, listProjectsReq) + if listProjectsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listProjectsLimit) + } + if listProjectsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listProjectsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1865,9 +2509,19 @@ func newListRoles() *cobra.Command { cmd := &cobra.Command{} var listRolesReq postgres.ListRolesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listRolesLimit int cmd.Flags().IntVar(&listRolesReq.PageSize, "page-size", listRolesReq.PageSize, `Upper bound for items returned.`) - cmd.Flags().StringVar(&listRolesReq.PageToken, "page-token", listRolesReq.PageToken, `Page token from a previous response.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listRolesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listRolesReq.PageToken, "page-token", listRolesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-roles PARENT" cmd.Short = `List Postgres Roles for a Branch.` @@ -1894,6 +2548,13 @@ func newListRoles() *cobra.Command { listRolesReq.Parent = args[0] response := w.Postgres.ListRoles(ctx, listRolesReq) + if listRolesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listRolesLimit) + } + if listRolesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listRolesLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/provider-exchange-filters/provider-exchange-filters.go b/cmd/workspace/provider-exchange-filters/provider-exchange-filters.go index 4c62276bf6b..2f3e43779b5 100755 --- a/cmd/workspace/provider-exchange-filters/provider-exchange-filters.go +++ b/cmd/workspace/provider-exchange-filters/provider-exchange-filters.go @@ -89,6 +89,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -182,9 +183,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListExchangeFiltersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list EXCHANGE_ID" cmd.Short = `List exchange filters.` @@ -207,6 +218,13 @@ func newList() *cobra.Command { listReq.ExchangeId = args[0] response := w.ProviderExchangeFilters.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -277,6 +295,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/provider-exchanges/provider-exchanges.go b/cmd/workspace/provider-exchanges/provider-exchanges.go index da333288ca1..5410ad8a038 100755 --- a/cmd/workspace/provider-exchanges/provider-exchanges.go +++ b/cmd/workspace/provider-exchanges/provider-exchanges.go @@ -75,7 +75,7 @@ func newAddListingToExchange() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'listing_id', 'exchange_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'listing_id', 'exchange_id' in your JSON input") } return nil } @@ -111,6 +111,7 @@ func newAddListingToExchange() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -175,6 +176,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -332,6 +334,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -360,9 +363,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListExchangesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List exchanges.` @@ -383,6 +396,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ProviderExchanges.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -411,9 +431,19 @@ func newListExchangesForListing() *cobra.Command { cmd := &cobra.Command{} var listExchangesForListingReq marketplace.ListExchangesForListingRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listExchangesForListingLimit int cmd.Flags().IntVar(&listExchangesForListingReq.PageSize, "page-size", listExchangesForListingReq.PageSize, ``) - cmd.Flags().StringVar(&listExchangesForListingReq.PageToken, "page-token", listExchangesForListingReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listExchangesForListingLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listExchangesForListingReq.PageToken, "page-token", listExchangesForListingReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-exchanges-for-listing LISTING_ID" cmd.Short = `List exchanges for listing.` @@ -436,6 +466,13 @@ func newListExchangesForListing() *cobra.Command { listExchangesForListingReq.ListingId = args[0] response := w.ProviderExchanges.ListExchangesForListing(ctx, listExchangesForListingReq) + if listExchangesForListingLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listExchangesForListingLimit) + } + if listExchangesForListingLimit > 0 { + ctx = cmdio.WithLimit(ctx, listExchangesForListingLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -464,9 +501,19 @@ func newListListingsForExchange() *cobra.Command { cmd := &cobra.Command{} var listListingsForExchangeReq marketplace.ListListingsForExchangeRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listListingsForExchangeLimit int cmd.Flags().IntVar(&listListingsForExchangeReq.PageSize, "page-size", listListingsForExchangeReq.PageSize, ``) - cmd.Flags().StringVar(&listListingsForExchangeReq.PageToken, "page-token", listListingsForExchangeReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listListingsForExchangeLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listListingsForExchangeReq.PageToken, "page-token", listListingsForExchangeReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-listings-for-exchange EXCHANGE_ID" cmd.Short = `List listings for exchange.` @@ -489,6 +536,13 @@ func newListListingsForExchange() *cobra.Command { listListingsForExchangeReq.ExchangeId = args[0] response := w.ProviderExchanges.ListListingsForExchange(ctx, listListingsForExchangeReq) + if listListingsForExchangeLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listListingsForExchangeLimit) + } + if listListingsForExchangeLimit > 0 { + ctx = cmdio.WithLimit(ctx, listListingsForExchangeLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -559,6 +613,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/provider-files/provider-files.go b/cmd/workspace/provider-files/provider-files.go index 69de0a23ec2..ceb4ff5479f 100755 --- a/cmd/workspace/provider-files/provider-files.go +++ b/cmd/workspace/provider-files/provider-files.go @@ -93,6 +93,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -223,6 +224,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -252,11 +254,21 @@ func newList() *cobra.Command { var listReq marketplace.ListFilesRequest var listJson flags.JsonFlag + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Var(&listJson, "json", `either inline JSON string or @path/to/file.json with request body`) cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List files.` @@ -287,6 +299,13 @@ func newList() *cobra.Command { } response := w.ProviderFiles.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/provider-listings/provider-listings.go b/cmd/workspace/provider-listings/provider-listings.go index 9686737d2e7..f50e2d743c2 100755 --- a/cmd/workspace/provider-listings/provider-listings.go +++ b/cmd/workspace/provider-listings/provider-listings.go @@ -91,6 +91,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -221,6 +222,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -249,9 +251,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.GetListingsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List listings.` @@ -272,6 +284,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ProviderListings.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -342,6 +361,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/provider-personalization-requests/provider-personalization-requests.go b/cmd/workspace/provider-personalization-requests/provider-personalization-requests.go index 57eccbdbd5d..dac5c529062 100755 --- a/cmd/workspace/provider-personalization-requests/provider-personalization-requests.go +++ b/cmd/workspace/provider-personalization-requests/provider-personalization-requests.go @@ -52,9 +52,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListAllPersonalizationRequestsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `All personalization requests across all listings.` @@ -76,6 +86,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ProviderPersonalizationRequests.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -163,6 +180,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/provider-provider-analytics-dashboards/provider-provider-analytics-dashboards.go b/cmd/workspace/provider-provider-analytics-dashboards/provider-provider-analytics-dashboards.go index 5dfa706f8db..b03523c0ac2 100755 --- a/cmd/workspace/provider-provider-analytics-dashboards/provider-provider-analytics-dashboards.go +++ b/cmd/workspace/provider-provider-analytics-dashboards/provider-provider-analytics-dashboards.go @@ -66,6 +66,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -106,6 +107,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -146,6 +148,7 @@ func newGetLatestVersion() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -217,6 +220,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/provider-providers/provider-providers.go b/cmd/workspace/provider-providers/provider-providers.go index 68f0198ac9d..2646c166cdf 100755 --- a/cmd/workspace/provider-providers/provider-providers.go +++ b/cmd/workspace/provider-providers/provider-providers.go @@ -90,6 +90,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -220,6 +221,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -248,9 +250,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq marketplace.ListProvidersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List providers.` @@ -271,6 +283,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ProviderProviders.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -341,6 +360,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/providers/providers.go b/cmd/workspace/providers/providers.go index a7fa13a2351..2c4521f553e 100755 --- a/cmd/workspace/providers/providers.go +++ b/cmd/workspace/providers/providers.go @@ -83,7 +83,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'authentication_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'authentication_type' in your JSON input") } return nil } @@ -123,6 +123,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -262,6 +263,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -290,10 +292,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sharing.ListProvidersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.DataProviderGlobalMetastoreId, "data-provider-global-metastore-id", listReq.DataProviderGlobalMetastoreId, `If not provided, all providers will be returned.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of providers to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List providers.` @@ -319,6 +332,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Providers.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -383,6 +403,7 @@ func newListProviderShareAssets() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -411,9 +432,19 @@ func newListShares() *cobra.Command { cmd := &cobra.Command{} var listSharesReq sharing.ListSharesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSharesLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSharesLimit, "limit", 0, `Maximum number of results to return.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSharesReq.PageToken, "page-token", listSharesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listSharesReq.MaxResults, "max-results", listSharesReq.MaxResults, `Maximum number of shares to return.`) - cmd.Flags().StringVar(&listSharesReq.PageToken, "page-token", listSharesReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list-shares NAME" cmd.Short = `List shares by Provider.` @@ -453,6 +484,13 @@ func newListShares() *cobra.Command { listSharesReq.Name = args[0] response := w.Providers.ListShares(ctx, listSharesReq) + if listSharesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSharesLimit) + } + if listSharesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSharesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -544,6 +582,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/quality-monitor-v2/quality-monitor-v2.go b/cmd/workspace/quality-monitor-v2/quality-monitor-v2.go index 8c5e3547bdb..313cc96eb55 100755 --- a/cmd/workspace/quality-monitor-v2/quality-monitor-v2.go +++ b/cmd/workspace/quality-monitor-v2/quality-monitor-v2.go @@ -81,7 +81,7 @@ func newCreateQualityMonitor() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'object_type', 'object_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'object_type', 'object_id' in your JSON input") } return nil } @@ -117,6 +117,7 @@ func newCreateQualityMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -235,6 +236,7 @@ func newGetQualityMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -263,9 +265,19 @@ func newListQualityMonitor() *cobra.Command { cmd := &cobra.Command{} var listQualityMonitorReq qualitymonitorv2.ListQualityMonitorRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listQualityMonitorLimit int cmd.Flags().IntVar(&listQualityMonitorReq.PageSize, "page-size", listQualityMonitorReq.PageSize, ``) - cmd.Flags().StringVar(&listQualityMonitorReq.PageToken, "page-token", listQualityMonitorReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listQualityMonitorLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listQualityMonitorReq.PageToken, "page-token", listQualityMonitorReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-quality-monitor" cmd.Short = `List quality monitors.` @@ -287,6 +299,13 @@ func newListQualityMonitor() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.QualityMonitorV2.ListQualityMonitor(ctx, listQualityMonitorReq) + if listQualityMonitorLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listQualityMonitorLimit) + } + if listQualityMonitorLimit > 0 { + ctx = cmdio.WithLimit(ctx, listQualityMonitorLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -381,6 +400,7 @@ func newUpdateQualityMonitor() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/quality-monitors/quality-monitors.go b/cmd/workspace/quality-monitors/quality-monitors.go index 05f5f5f3c48..ae801caa0ff 100755 --- a/cmd/workspace/quality-monitors/quality-monitors.go +++ b/cmd/workspace/quality-monitors/quality-monitors.go @@ -221,6 +221,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -291,6 +292,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -360,6 +362,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -432,6 +435,7 @@ func newGetRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -500,6 +504,7 @@ func newListRefreshes() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -589,6 +594,7 @@ func newRegenerateDashboard() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -657,6 +663,7 @@ func newRunRefresh() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -766,6 +773,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/queries-legacy/queries-legacy.go b/cmd/workspace/queries-legacy/queries-legacy.go index 8537645e24e..e3dcc2402b3 100755 --- a/cmd/workspace/queries-legacy/queries-legacy.go +++ b/cmd/workspace/queries-legacy/queries-legacy.go @@ -3,6 +3,8 @@ package queries_legacy import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -122,6 +124,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -241,6 +244,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -269,12 +273,23 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sql.ListQueriesLegacyRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Order, "order", listReq.Order, `Name of query attribute to order by.`) - cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) - cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of queries to return per page.`) cmd.Flags().StringVar(&listReq.Q, "q", listReq.Q, `Full text search term.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().IntVar(&listReq.Page, "page", listReq.Page, `Page number to retrieve.`) + cmd.Flags().Lookup("page").Hidden = true + cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `Number of results per API page.`) + cmd.Flags().Lookup("page-size").Hidden = true + cmd.Use = "list" cmd.Short = `Get a list of queries.` cmd.Long = `Get a list of queries. @@ -303,6 +318,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.QueriesLegacy.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -445,6 +467,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/queries/queries.go b/cmd/workspace/queries/queries.go index 64c94f0df05..e654b765d7b 100755 --- a/cmd/workspace/queries/queries.go +++ b/cmd/workspace/queries/queries.go @@ -100,6 +100,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +234,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,9 +263,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sql.ListQueriesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list" cmd.Short = `List queries.` @@ -286,6 +298,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Queries.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -314,9 +333,19 @@ func newListVisualizations() *cobra.Command { cmd := &cobra.Command{} var listVisualizationsReq sql.ListVisualizationsForQueryRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listVisualizationsLimit int cmd.Flags().IntVar(&listVisualizationsReq.PageSize, "page-size", listVisualizationsReq.PageSize, ``) - cmd.Flags().StringVar(&listVisualizationsReq.PageToken, "page-token", listVisualizationsReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listVisualizationsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listVisualizationsReq.PageToken, "page-token", listVisualizationsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-visualizations ID" cmd.Short = `List visualizations on a query.` @@ -354,6 +383,13 @@ func newListVisualizations() *cobra.Command { listVisualizationsReq.Id = args[0] response := w.Queries.ListVisualizations(ctx, listVisualizationsReq) + if listVisualizationsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listVisualizationsLimit) + } + if listVisualizationsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listVisualizationsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -449,6 +485,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/query-history/query-history.go b/cmd/workspace/query-history/query-history.go index a6b4d59b12c..b56fb149140 100755 --- a/cmd/workspace/query-history/query-history.go +++ b/cmd/workspace/query-history/query-history.go @@ -81,6 +81,7 @@ func newList() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/query-visualizations-legacy/query-visualizations-legacy.go b/cmd/workspace/query-visualizations-legacy/query-visualizations-legacy.go index c73345a7df1..511ce8c60a6 100755 --- a/cmd/workspace/query-visualizations-legacy/query-visualizations-legacy.go +++ b/cmd/workspace/query-visualizations-legacy/query-visualizations-legacy.go @@ -106,6 +106,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -248,6 +249,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/query-visualizations/query-visualizations.go b/cmd/workspace/query-visualizations/query-visualizations.go index 665fc2f82d0..1017b51554e 100755 --- a/cmd/workspace/query-visualizations/query-visualizations.go +++ b/cmd/workspace/query-visualizations/query-visualizations.go @@ -98,6 +98,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -245,6 +246,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/recipient-activation/recipient-activation.go b/cmd/workspace/recipient-activation/recipient-activation.go index 07306fac48e..8505cbfb98e 100755 --- a/cmd/workspace/recipient-activation/recipient-activation.go +++ b/cmd/workspace/recipient-activation/recipient-activation.go @@ -142,6 +142,7 @@ func newRetrieveToken() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/recipient-federation-policies/recipient-federation-policies.go b/cmd/workspace/recipient-federation-policies/recipient-federation-policies.go index 5ff07221f92..a8da9431289 100755 --- a/cmd/workspace/recipient-federation-policies/recipient-federation-policies.go +++ b/cmd/workspace/recipient-federation-policies/recipient-federation-policies.go @@ -3,6 +3,8 @@ package recipient_federation_policies import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -149,6 +151,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -270,6 +273,7 @@ func newGetFederationPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -298,9 +302,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sharing.ListFederationPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, ``) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list RECIPIENT_NAME" cmd.Short = `List recipient federation policies.` @@ -329,6 +343,13 @@ func newList() *cobra.Command { listReq.RecipientName = args[0] response := w.RecipientFederationPolicies.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/recipients/recipients.go b/cmd/workspace/recipients/recipients.go index 9722aab9827..93eab8b7485 100755 --- a/cmd/workspace/recipients/recipients.go +++ b/cmd/workspace/recipients/recipients.go @@ -103,7 +103,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'authentication_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'authentication_type' in your JSON input") } return nil } @@ -143,6 +143,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -258,6 +259,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -286,10 +288,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sharing.ListRecipientsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.DataRecipientGlobalMetastoreId, "data-recipient-global-metastore-id", listReq.DataRecipientGlobalMetastoreId, `If not provided, all recipients will be returned.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of recipients to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List share recipients.` @@ -313,6 +326,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Recipients.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -403,6 +423,7 @@ func newRotateToken() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -464,6 +485,7 @@ func newSharePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -544,6 +566,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/redash-config/redash-config.go b/cmd/workspace/redash-config/redash-config.go index f46dd0201c1..ce173b6bb55 100755 --- a/cmd/workspace/redash-config/redash-config.go +++ b/cmd/workspace/redash-config/redash-config.go @@ -61,6 +61,7 @@ func newGetConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/registered-models/registered-models.go b/cmd/workspace/registered-models/registered-models.go index f60b1d10a17..e776c537aa3 100755 --- a/cmd/workspace/registered-models/registered-models.go +++ b/cmd/workspace/registered-models/registered-models.go @@ -149,6 +149,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -362,6 +363,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -390,13 +392,23 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListRegisteredModelsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.CatalogName, "catalog-name", listReq.CatalogName, `The identifier of the catalog under which to list registered models.`) cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include registered models in the response for which the principal can only access selective metadata for.`) cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Max number of registered models to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque token to send for the next page of results (pagination).`) cmd.Flags().StringVar(&listReq.SchemaName, "schema-name", listReq.SchemaName, `The identifier of the schema under which to list registered models.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List Registered Models.` cmd.Long = `List Registered Models. @@ -432,6 +444,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.RegisteredModels.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -525,6 +544,7 @@ func newSetAlias() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -631,6 +651,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/repos/overrides.go b/cmd/workspace/repos/overrides.go index 72f58bb5010..17ef8111ba0 100644 --- a/cmd/workspace/repos/overrides.go +++ b/cmd/workspace/repos/overrides.go @@ -167,7 +167,7 @@ func repoArgumentToRepoID(ctx context.Context, w *databricks.WorkspaceClient, ar } // If the argument cannot be parsed as a repo ID, try to look it up by name. - oi, err := w.Workspace.GetStatusByPath(ctx, arg) + oi, err := w.Workspace.GetStatusByPath(ctx, arg) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return 0, fmt.Errorf("failed to look up repo by path: %w", err) } diff --git a/cmd/workspace/repos/repos.go b/cmd/workspace/repos/repos.go index 24075353f08..40e4dacf3a7 100755 --- a/cmd/workspace/repos/repos.go +++ b/cmd/workspace/repos/repos.go @@ -95,7 +95,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'url', 'provider' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'url', 'provider' in your JSON input") } return nil } @@ -131,6 +131,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -273,6 +274,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -341,6 +343,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -410,6 +413,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -438,10 +442,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq workspace.ListReposRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int - cmd.Flags().StringVar(&listReq.NextPageToken, "next-page-token", listReq.NextPageToken, `Token used to get the next page of results.`) cmd.Flags().StringVar(&listReq.PathPrefix, "path-prefix", listReq.PathPrefix, `Filters repos that have paths starting with the given path prefix.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.NextPageToken, "next-page-token", listReq.NextPageToken, `Pagination token.`) + cmd.Flags().Lookup("next-page-token").Hidden = true + cmd.Use = "list" cmd.Short = `Get repos.` cmd.Long = `Get repos. @@ -462,6 +476,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Repos.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -549,6 +570,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -726,6 +748,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/resource-quotas/resource-quotas.go b/cmd/workspace/resource-quotas/resource-quotas.go index d639c5fb4ea..e5ac51456f4 100755 --- a/cmd/workspace/resource-quotas/resource-quotas.go +++ b/cmd/workspace/resource-quotas/resource-quotas.go @@ -3,6 +3,8 @@ package resource_quotas import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -92,6 +94,7 @@ func newGetQuota() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -120,9 +123,19 @@ func newListQuotas() *cobra.Command { cmd := &cobra.Command{} var listQuotasReq catalog.ListQuotasRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listQuotasLimit int cmd.Flags().IntVar(&listQuotasReq.MaxResults, "max-results", listQuotasReq.MaxResults, `The number of quotas to return.`) - cmd.Flags().StringVar(&listQuotasReq.PageToken, "page-token", listQuotasReq.PageToken, `Opaque token for the next page of results.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listQuotasLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listQuotasReq.PageToken, "page-token", listQuotasReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-quotas" cmd.Short = `List all resource quotas under a metastore.` @@ -150,6 +163,13 @@ func newListQuotas() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ResourceQuotas.ListQuotas(ctx, listQuotasReq) + if listQuotasLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listQuotasLimit) + } + if listQuotasLimit > 0 { + ctx = cmdio.WithLimit(ctx, listQuotasLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/restrict-workspace-admins/restrict-workspace-admins.go b/cmd/workspace/restrict-workspace-admins/restrict-workspace-admins.go index 71168e9ec4b..d81e8e34f03 100755 --- a/cmd/workspace/restrict-workspace-admins/restrict-workspace-admins.go +++ b/cmd/workspace/restrict-workspace-admins/restrict-workspace-admins.go @@ -91,6 +91,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -144,6 +145,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -212,6 +214,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/rfa/rfa.go b/cmd/workspace/rfa/rfa.go index b8234f16d5a..51cd9b25cab 100755 --- a/cmd/workspace/rfa/rfa.go +++ b/cmd/workspace/rfa/rfa.go @@ -105,6 +105,7 @@ func newBatchCreateAccessRequests() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -170,6 +171,7 @@ func newGetAccessRequestDestinations() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -283,6 +285,7 @@ func newUpdateAccessRequestDestinations() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/schemas/schemas.go b/cmd/workspace/schemas/schemas.go index e51261aae1c..dcc49042d12 100755 --- a/cmd/workspace/schemas/schemas.go +++ b/cmd/workspace/schemas/schemas.go @@ -84,7 +84,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'catalog_name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'catalog_name' in your JSON input") } return nil } @@ -120,6 +120,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -239,6 +240,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -267,10 +269,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListSchemasRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include schemas in the response for which the principal can only access selective metadata for.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of schemas to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list CATALOG_NAME" cmd.Short = `List schemas.` @@ -308,6 +321,13 @@ func newList() *cobra.Command { listReq.CatalogName = args[0] response := w.Schemas.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -389,6 +409,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/secrets/secrets.go b/cmd/workspace/secrets/secrets.go index 34f356d841c..0edd4f049f2 100755 --- a/cmd/workspace/secrets/secrets.go +++ b/cmd/workspace/secrets/secrets.go @@ -129,7 +129,7 @@ func newCreateScope() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'scope' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'scope' in your JSON input") } return nil } @@ -223,7 +223,7 @@ func newDeleteAcl() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'scope', 'principal' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'scope', 'principal' in your JSON input") } return nil } @@ -317,7 +317,7 @@ func newDeleteScope() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'scope' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'scope' in your JSON input") } return nil } @@ -410,7 +410,7 @@ func newDeleteSecret() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'scope', 'key' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'scope', 'key' in your JSON input") } return nil } @@ -517,6 +517,7 @@ func newGetAcl() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -601,6 +602,7 @@ func newGetSecret() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -629,6 +631,15 @@ func newListAcls() *cobra.Command { cmd := &cobra.Command{} var listAclsReq workspace.ListAclsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listAclsLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listAclsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list-acls SCOPE" cmd.Short = `Lists ACLs.` @@ -667,6 +678,13 @@ func newListAcls() *cobra.Command { listAclsReq.Scope = args[0] response := w.Secrets.ListAcls(ctx, listAclsReq) + if listAclsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listAclsLimit) + } + if listAclsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listAclsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -692,6 +710,15 @@ var listScopesOverrides []func( func newListScopes() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listScopesLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listScopesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list-scopes" cmd.Short = `List all scopes.` @@ -716,6 +743,13 @@ func newListScopes() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.Secrets.ListScopes(ctx) + if listScopesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listScopesLimit) + } + if listScopesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listScopesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -744,6 +778,15 @@ func newListSecrets() *cobra.Command { cmd := &cobra.Command{} var listSecretsReq workspace.ListSecretsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSecretsLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSecretsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list-secrets SCOPE" cmd.Short = `List secret keys.` @@ -785,6 +828,13 @@ func newListSecrets() *cobra.Command { listSecretsReq.Scope = args[0] response := w.Secrets.ListSecrets(ctx, listSecretsReq) + if listSecretsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSecretsLimit) + } + if listSecretsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSecretsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -867,7 +917,7 @@ func newPutAcl() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'scope', 'principal', 'permission' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'scope', 'principal', 'permission' in your JSON input") } return nil } diff --git a/cmd/workspace/service-principal-secrets-proxy/service-principal-secrets-proxy.go b/cmd/workspace/service-principal-secrets-proxy/service-principal-secrets-proxy.go index c213797bbe1..f556a26644c 100755 --- a/cmd/workspace/service-principal-secrets-proxy/service-principal-secrets-proxy.go +++ b/cmd/workspace/service-principal-secrets-proxy/service-principal-secrets-proxy.go @@ -3,6 +3,8 @@ package service_principal_secrets_proxy import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -109,6 +111,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -195,9 +198,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq oauth2.ListServicePrincipalSecretsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, ``) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `An opaque page token which was the next_page_token in the response of the previous request to list the secrets for this service principal.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list SERVICE_PRINCIPAL_ID" cmd.Short = `List service principal secrets.` @@ -225,6 +238,13 @@ func newList() *cobra.Command { listReq.ServicePrincipalId = args[0] response := w.ServicePrincipalSecretsProxy.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/service-principals-v2/service-principals-v2.go b/cmd/workspace/service-principals-v2/service-principals-v2.go index 1620df923db..6e23e348923 100755 --- a/cmd/workspace/service-principals-v2/service-principals-v2.go +++ b/cmd/workspace/service-principals-v2/service-principals-v2.go @@ -3,6 +3,8 @@ package service_principals_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -107,6 +109,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -220,6 +223,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -248,14 +252,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListServicePrincipalsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List service principals.` @@ -276,6 +291,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.ServicePrincipalsV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/serving-endpoints/serving-endpoints.go b/cmd/workspace/serving-endpoints/serving-endpoints.go index 84313eed21b..88c70401064 100755 --- a/cmd/workspace/serving-endpoints/serving-endpoints.go +++ b/cmd/workspace/serving-endpoints/serving-endpoints.go @@ -115,6 +115,7 @@ func newBuildLogs() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -177,7 +178,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -418,6 +419,7 @@ func newExportMetrics() *cobra.Command { if err != nil { return err } + defer response.Contents.Close() return cmdio.Render(ctx, response.Contents) } @@ -475,6 +477,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -534,6 +537,7 @@ func newGetOpenApi() *cobra.Command { if err != nil { return err } + defer response.Contents.Close() return cmdio.Render(ctx, response.Contents) } @@ -591,6 +595,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -648,6 +653,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -720,6 +726,7 @@ func newHttpRequest() *cobra.Command { if err != nil { return err } + defer response.Contents.Close() return cmdio.Render(ctx, response.Contents) } @@ -746,6 +753,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `Get all serving endpoints.` @@ -758,6 +774,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.ServingEndpoints.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -818,6 +841,7 @@ func newLogs() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -894,6 +918,7 @@ func newPatch() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -968,6 +993,7 @@ func newPut() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1048,6 +1074,7 @@ func newPutAiGateway() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1136,6 +1163,7 @@ func newQuery() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1211,6 +1239,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1383,6 +1412,7 @@ func newUpdateNotifications() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1457,6 +1487,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/shares/shares.go b/cmd/workspace/shares/shares.go index 1902cc8c73b..47615ce4d7f 100755 --- a/cmd/workspace/shares/shares.go +++ b/cmd/workspace/shares/shares.go @@ -84,7 +84,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -117,6 +117,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +234,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,9 +263,19 @@ func newListShares() *cobra.Command { cmd := &cobra.Command{} var listSharesReq sharing.SharesListRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSharesLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSharesLimit, "limit", 0, `Maximum number of results to return.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSharesReq.PageToken, "page-token", listSharesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listSharesReq.MaxResults, "max-results", listSharesReq.MaxResults, `Maximum number of shares to return.`) - cmd.Flags().StringVar(&listSharesReq.PageToken, "page-token", listSharesReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list-shares" cmd.Short = `List shares.` @@ -287,6 +299,13 @@ func newListShares() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Shares.ListShares(ctx, listSharesReq) + if listSharesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSharesLimit) + } + if listSharesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSharesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -347,6 +366,7 @@ func newSharePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -440,6 +460,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -519,6 +540,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/sql-results-download/sql-results-download.go b/cmd/workspace/sql-results-download/sql-results-download.go index 6174cd61a10..b929a79cc49 100755 --- a/cmd/workspace/sql-results-download/sql-results-download.go +++ b/cmd/workspace/sql-results-download/sql-results-download.go @@ -78,6 +78,7 @@ func newDelete() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -131,6 +132,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -195,6 +197,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/storage-credentials/storage-credentials.go b/cmd/workspace/storage-credentials/storage-credentials.go index 196a57f047e..878ba367a8f 100755 --- a/cmd/workspace/storage-credentials/storage-credentials.go +++ b/cmd/workspace/storage-credentials/storage-credentials.go @@ -99,7 +99,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name' in your JSON input") } return nil } @@ -132,6 +132,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -249,6 +250,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -277,10 +279,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListStorageCredentialsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeUnbound, "include-unbound", listReq.IncludeUnbound, `Whether to include credentials not bound to the workspace.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of storage credentials to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list" cmd.Short = `List credentials.` @@ -313,6 +326,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.StorageCredentials.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -400,6 +420,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -488,6 +509,7 @@ func newValidate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/system-schemas/system-schemas.go b/cmd/workspace/system-schemas/system-schemas.go index 813715c454e..8b41369ba37 100755 --- a/cmd/workspace/system-schemas/system-schemas.go +++ b/cmd/workspace/system-schemas/system-schemas.go @@ -3,6 +3,8 @@ package system_schemas import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -187,9 +189,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListSystemSchemasRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of schemas to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list METASTORE_ID" cmd.Short = `List system schemas.` @@ -224,6 +236,13 @@ func newList() *cobra.Command { listReq.MetastoreId = args[0] response := w.SystemSchemas.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/table-constraints/table-constraints.go b/cmd/workspace/table-constraints/table-constraints.go index 5e2dede6cb7..369907f0108 100755 --- a/cmd/workspace/table-constraints/table-constraints.go +++ b/cmd/workspace/table-constraints/table-constraints.go @@ -108,6 +108,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/tables/tables.go b/cmd/workspace/tables/tables.go index 30892e44b75..3003fdfd3a7 100755 --- a/cmd/workspace/tables/tables.go +++ b/cmd/workspace/tables/tables.go @@ -157,7 +157,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'catalog_name', 'schema_name', 'table_type', 'data_source_format', 'storage_location' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'catalog_name', 'schema_name', 'table_type', 'data_source_format', 'storage_location' in your JSON input") } return nil } @@ -213,6 +213,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -336,6 +337,7 @@ func newExists() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -402,6 +404,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -430,14 +433,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListTablesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include tables in the response for which the principal can only access selective metadata for.`) cmd.Flags().BoolVar(&listReq.IncludeManifestCapabilities, "include-manifest-capabilities", listReq.IncludeManifestCapabilities, `Whether to include a manifest containing table capabilities in the response.`) - cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of tables to return.`) cmd.Flags().BoolVar(&listReq.OmitColumns, "omit-columns", listReq.OmitColumns, `Whether to omit the columns of the table from the response or not.`) cmd.Flags().BoolVar(&listReq.OmitProperties, "omit-properties", listReq.OmitProperties, `Whether to omit the properties of the table from the response or not.`) cmd.Flags().BoolVar(&listReq.OmitUsername, "omit-username", listReq.OmitUsername, `Whether to omit the username of the table (e.g.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque token to send for the next page of results (pagination).`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of tables to return.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "list CATALOG_NAME SCHEMA_NAME" cmd.Short = `List tables.` @@ -481,6 +495,13 @@ func newList() *cobra.Command { listReq.SchemaName = args[1] response := w.Tables.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -509,13 +530,23 @@ func newListSummaries() *cobra.Command { cmd := &cobra.Command{} var listSummariesReq catalog.ListSummariesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listSummariesLimit int cmd.Flags().BoolVar(&listSummariesReq.IncludeManifestCapabilities, "include-manifest-capabilities", listSummariesReq.IncludeManifestCapabilities, `Whether to include a manifest containing table capabilities in the response.`) cmd.Flags().IntVar(&listSummariesReq.MaxResults, "max-results", listSummariesReq.MaxResults, `Maximum number of summaries for tables to return.`) - cmd.Flags().StringVar(&listSummariesReq.PageToken, "page-token", listSummariesReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) cmd.Flags().StringVar(&listSummariesReq.SchemaNamePattern, "schema-name-pattern", listSummariesReq.SchemaNamePattern, `A sql LIKE pattern (% and _) for schema names.`) cmd.Flags().StringVar(&listSummariesReq.TableNamePattern, "table-name-pattern", listSummariesReq.TableNamePattern, `A sql LIKE pattern (% and _) for table names.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listSummariesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listSummariesReq.PageToken, "page-token", listSummariesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list-summaries CATALOG_NAME" cmd.Short = `List table summaries.` cmd.Long = `List table summaries. @@ -555,6 +586,13 @@ func newListSummaries() *cobra.Command { listSummariesReq.CatalogName = args[0] response := w.Tables.ListSummaries(ctx, listSummariesReq) + if listSummariesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listSummariesLimit) + } + if listSummariesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listSummariesLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/tag-policies/tag-policies.go b/cmd/workspace/tag-policies/tag-policies.go index 97c64a74c44..178d9b399a4 100755 --- a/cmd/workspace/tag-policies/tag-policies.go +++ b/cmd/workspace/tag-policies/tag-policies.go @@ -85,7 +85,7 @@ func newCreateTagPolicy() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'tag_key' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'tag_key' in your JSON input") } return nil } @@ -118,6 +118,7 @@ func newCreateTagPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -233,6 +234,7 @@ func newGetTagPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -261,9 +263,19 @@ func newListTagPolicies() *cobra.Command { cmd := &cobra.Command{} var listTagPoliciesReq tags.ListTagPoliciesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listTagPoliciesLimit int cmd.Flags().IntVar(&listTagPoliciesReq.PageSize, "page-size", listTagPoliciesReq.PageSize, `The maximum number of results to return in this request.`) - cmd.Flags().StringVar(&listTagPoliciesReq.PageToken, "page-token", listTagPoliciesReq.PageToken, `An optional page token received from a previous list tag policies call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listTagPoliciesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listTagPoliciesReq.PageToken, "page-token", listTagPoliciesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-tag-policies" cmd.Short = `List tag policies.` @@ -289,6 +301,13 @@ func newListTagPolicies() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.TagPolicies.ListTagPolicies(ctx, listTagPoliciesReq) + if listTagPoliciesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listTagPoliciesLimit) + } + if listTagPoliciesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listTagPoliciesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -381,6 +400,7 @@ func newUpdateTagPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/temporary-path-credentials/temporary-path-credentials.go b/cmd/workspace/temporary-path-credentials/temporary-path-credentials.go index 103fc7803c2..98eda3ccf54 100755 --- a/cmd/workspace/temporary-path-credentials/temporary-path-credentials.go +++ b/cmd/workspace/temporary-path-credentials/temporary-path-credentials.go @@ -107,7 +107,7 @@ func newGenerateTemporaryPathCredentials() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'url', 'operation' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'url', 'operation' in your JSON input") } return nil } @@ -147,6 +147,7 @@ func newGenerateTemporaryPathCredentials() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/temporary-table-credentials/temporary-table-credentials.go b/cmd/workspace/temporary-table-credentials/temporary-table-credentials.go index 7193c5e9022..ebc93e63ec1 100755 --- a/cmd/workspace/temporary-table-credentials/temporary-table-credentials.go +++ b/cmd/workspace/temporary-table-credentials/temporary-table-credentials.go @@ -109,6 +109,7 @@ func newGenerateTemporaryTableCredentials() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/token-management/token-management.go b/cmd/workspace/token-management/token-management.go index 83ef0879247..b62e185f460 100755 --- a/cmd/workspace/token-management/token-management.go +++ b/cmd/workspace/token-management/token-management.go @@ -65,6 +65,7 @@ func newCreateOboToken() *cobra.Command { cmd.Flags().StringVar(&createOboTokenReq.Comment, "comment", createOboTokenReq.Comment, `Comment that describes the purpose of the token.`) cmd.Flags().Int64Var(&createOboTokenReq.LifetimeSeconds, "lifetime-seconds", createOboTokenReq.LifetimeSeconds, `The number of seconds before the token expires.`) + // TODO: array: scopes cmd.Use = "create-obo-token APPLICATION_ID" cmd.Short = `Create on-behalf token.` @@ -81,7 +82,7 @@ func newCreateOboToken() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'application_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'application_id' in your JSON input") } return nil } @@ -130,6 +131,7 @@ func newCreateOboToken() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -266,6 +268,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -308,6 +311,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -351,6 +355,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -379,10 +384,19 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq settings.ListTokenManagementRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Int64Var(&listReq.CreatedById, "created-by-id", listReq.CreatedById, `User ID of the user that created the token.`) cmd.Flags().StringVar(&listReq.CreatedByUsername, "created-by-username", listReq.CreatedByUsername, `Username of the user that created the token.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Use = "list" cmd.Short = `List all tokens.` cmd.Long = `List all tokens. @@ -402,6 +416,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.TokenManagement.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -473,6 +494,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -543,6 +565,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/tokens/tokens.go b/cmd/workspace/tokens/tokens.go index 715db5485de..5acda52a379 100755 --- a/cmd/workspace/tokens/tokens.go +++ b/cmd/workspace/tokens/tokens.go @@ -59,6 +59,7 @@ func newCreate() *cobra.Command { cmd.Flags().StringVar(&createReq.Comment, "comment", createReq.Comment, `Optional description to attach to the token.`) cmd.Flags().Int64Var(&createReq.LifetimeSeconds, "lifetime-seconds", createReq.LifetimeSeconds, `The lifetime of the token, in seconds.`) + // TODO: array: scopes cmd.Use = "create" cmd.Short = `Create a user token.` @@ -98,6 +99,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -148,7 +150,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'token_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'token_id' in your JSON input") } return nil } @@ -221,6 +223,15 @@ var listOverrides []func( func newList() *cobra.Command { cmd := &cobra.Command{} + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Use = "list" cmd.Short = `List tokens.` @@ -235,6 +246,13 @@ func newList() *cobra.Command { ctx := cmd.Context() w := cmdctx.WorkspaceClient(ctx) response := w.Tokens.List(ctx) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } diff --git a/cmd/workspace/users-v2/users-v2.go b/cmd/workspace/users-v2/users-v2.go index c104c9a861f..e54d8c2377f 100755 --- a/cmd/workspace/users-v2/users-v2.go +++ b/cmd/workspace/users-v2/users-v2.go @@ -3,6 +3,8 @@ package users_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -119,6 +121,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -240,6 +243,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -286,6 +290,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -333,6 +338,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -361,14 +367,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq iam.ListUsersRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().StringVar(&listReq.Attributes, "attributes", listReq.Attributes, `Comma-separated list of attributes to return in response.`) - cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Desired number of results per page.`) cmd.Flags().StringVar(&listReq.ExcludedAttributes, "excluded-attributes", listReq.ExcludedAttributes, `Comma-separated list of attributes to exclude in response.`) cmd.Flags().StringVar(&listReq.Filter, "filter", listReq.Filter, `Query by which the results have to be filtered.`) cmd.Flags().StringVar(&listReq.SortBy, "sort-by", listReq.SortBy, `Attribute to sort the results.`) cmd.Flags().Var(&listReq.SortOrder, "sort-order", `The order to sort the results. Supported values: [ascending, descending]`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). cmd.Flags().Int64Var(&listReq.StartIndex, "start-index", listReq.StartIndex, `Specifies the index of the first result.`) + cmd.Flags().Lookup("start-index").Hidden = true + cmd.Flags().Int64Var(&listReq.Count, "count", listReq.Count, `Number of results per API page.`) + cmd.Flags().Lookup("count").Hidden = true cmd.Use = "list" cmd.Short = `List users.` @@ -389,6 +406,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.UsersV2.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -535,6 +559,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -687,6 +712,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/vector-search-endpoints/vector-search-endpoints.go b/cmd/workspace/vector-search-endpoints/vector-search-endpoints.go index d11b5f22151..6a0afdd565c 100755 --- a/cmd/workspace/vector-search-endpoints/vector-search-endpoints.go +++ b/cmd/workspace/vector-search-endpoints/vector-search-endpoints.go @@ -70,6 +70,7 @@ func newCreateEndpoint() *cobra.Command { cmd.Flags().StringVar(&createEndpointReq.BudgetPolicyId, "budget-policy-id", createEndpointReq.BudgetPolicyId, `The budget policy id to be applied.`) cmd.Flags().Int64Var(&createEndpointReq.MinQps, "min-qps", createEndpointReq.MinQps, `Min QPS for the endpoint.`) + cmd.Flags().StringVar(&createEndpointReq.UsagePolicyId, "usage-policy-id", createEndpointReq.UsagePolicyId, `The usage policy id to be applied once we've migrated to usage policies.`) cmd.Use = "create-endpoint NAME ENDPOINT_TYPE" cmd.Short = `Create an endpoint.` @@ -80,7 +81,7 @@ func newCreateEndpoint() *cobra.Command { Arguments: NAME: Name of the vector search endpoint ENDPOINT_TYPE: Type of endpoint - Supported values: [STANDARD]` + Supported values: [STANDARD, STORAGE_OPTIMIZED]` cmd.Annotations = make(map[string]string) @@ -88,7 +89,7 @@ func newCreateEndpoint() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'endpoint_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'endpoint_type' in your JSON input") } return nil } @@ -259,6 +260,7 @@ func newGetEndpoint() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -287,8 +289,17 @@ func newListEndpoints() *cobra.Command { cmd := &cobra.Command{} var listEndpointsReq vectorsearch.ListEndpointsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listEndpointsLimit int + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listEndpointsLimit, "limit", 0, `Maximum number of results to return.`) - cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, `Token for pagination.`) + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listEndpointsReq.PageToken, "page-token", listEndpointsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-endpoints" cmd.Short = `List all endpoints.` @@ -309,6 +320,13 @@ func newListEndpoints() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.VectorSearchEndpoints.ListEndpoints(ctx, listEndpointsReq) + if listEndpointsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listEndpointsLimit) + } + if listEndpointsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listEndpointsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -382,6 +400,7 @@ func newPatchEndpoint() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -459,6 +478,7 @@ func newRetrieveUserVisibleMetrics() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -541,6 +561,7 @@ func newUpdateEndpointBudgetPolicy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -615,6 +636,7 @@ func newUpdateEndpointCustomTags() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/vector-search-indexes/vector-search-indexes.go b/cmd/workspace/vector-search-indexes/vector-search-indexes.go index c7ecade2bb4..60802ee9f11 100755 --- a/cmd/workspace/vector-search-indexes/vector-search-indexes.go +++ b/cmd/workspace/vector-search-indexes/vector-search-indexes.go @@ -73,6 +73,7 @@ func newCreateIndex() *cobra.Command { // TODO: complex arg: delta_sync_index_spec // TODO: complex arg: direct_access_index_spec + cmd.Flags().Var(&createIndexReq.IndexSubtype, "index-subtype", `The subtype of the index. Supported values: [FULL_TEXT, HYBRID, VECTOR]`) cmd.Use = "create-index NAME ENDPOINT_NAME PRIMARY_KEY INDEX_TYPE" cmd.Short = `Create an index.` @@ -93,7 +94,7 @@ func newCreateIndex() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'name', 'endpoint_name', 'primary_key', 'index_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'name', 'endpoint_name', 'primary_key', 'index_type' in your JSON input") } return nil } @@ -139,6 +140,7 @@ func newCreateIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -213,6 +215,7 @@ func newDeleteDataVectorIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -323,6 +326,7 @@ func newGetIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -351,8 +355,17 @@ func newListIndexes() *cobra.Command { cmd := &cobra.Command{} var listIndexesReq vectorsearch.ListIndexesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listIndexesLimit int - cmd.Flags().StringVar(&listIndexesReq.PageToken, "page-token", listIndexesReq.PageToken, `Token for pagination.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listIndexesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listIndexesReq.PageToken, "page-token", listIndexesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-indexes ENDPOINT_NAME" cmd.Short = `List indexes.` @@ -378,6 +391,13 @@ func newListIndexes() *cobra.Command { listIndexesReq.EndpointName = args[0] response := w.VectorSearchIndexes.ListIndexes(ctx, listIndexesReq) + if listIndexesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listIndexesLimit) + } + if listIndexesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listIndexesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -460,6 +480,7 @@ func newQueryIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -535,6 +556,7 @@ func newQueryNextPage() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -610,6 +632,7 @@ func newScanIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -749,6 +772,7 @@ func newUpsertDataVectorIndex() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/volumes/volumes.go b/cmd/workspace/volumes/volumes.go index 15988f01c28..994c61656f4 100755 --- a/cmd/workspace/volumes/volumes.go +++ b/cmd/workspace/volumes/volumes.go @@ -109,7 +109,7 @@ func newCreate() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'catalog_name', 'schema_name', 'name', 'volume_type' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'catalog_name', 'schema_name', 'name', 'volume_type' in your JSON input") } return nil } @@ -155,6 +155,7 @@ func newCreate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -255,10 +256,20 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq catalog.ListVolumesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().BoolVar(&listReq.IncludeBrowse, "include-browse", listReq.IncludeBrowse, `Whether to include volumes in the response for which the principal can only access selective metadata for.`) cmd.Flags().IntVar(&listReq.MaxResults, "max-results", listReq.MaxResults, `Maximum number of volumes to return (page length).`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Opaque token returned by a previous request.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list CATALOG_NAME SCHEMA_NAME" cmd.Short = `List Volumes.` @@ -301,6 +312,13 @@ func newList() *cobra.Command { listReq.SchemaName = args[1] response := w.Volumes.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -376,6 +394,7 @@ func newRead() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -470,6 +489,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/warehouses/warehouses.go b/cmd/workspace/warehouses/warehouses.go index 8003dfd2cf2..7d64d24a542 100755 --- a/cmd/workspace/warehouses/warehouses.go +++ b/cmd/workspace/warehouses/warehouses.go @@ -244,6 +244,7 @@ func newCreateDefaultWarehouseOverride() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -575,6 +576,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -648,6 +650,7 @@ func newGetDefaultWarehouseOverride() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -716,6 +719,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -785,6 +789,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -828,6 +833,7 @@ func newGetWorkspaceWarehouseConfig() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -856,11 +862,21 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq sql.ListWarehousesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().IntVar(&listReq.PageSize, "page-size", listReq.PageSize, `The max number of warehouses to return.`) - cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `A page token, received from a previous ListWarehouses call.`) cmd.Flags().IntVar(&listReq.RunAsUserId, "run-as-user-id", listReq.RunAsUserId, `Deprecated: this field is ignored by the server.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listReq.PageToken, "page-token", listReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true + cmd.Use = "list" cmd.Short = `List warehouses.` cmd.Long = `List warehouses. @@ -880,6 +896,13 @@ func newList() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Warehouses.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -908,9 +931,19 @@ func newListDefaultWarehouseOverrides() *cobra.Command { cmd := &cobra.Command{} var listDefaultWarehouseOverridesReq sql.ListDefaultWarehouseOverridesRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listDefaultWarehouseOverridesLimit int cmd.Flags().IntVar(&listDefaultWarehouseOverridesReq.PageSize, "page-size", listDefaultWarehouseOverridesReq.PageSize, `The maximum number of overrides to return.`) - cmd.Flags().StringVar(&listDefaultWarehouseOverridesReq.PageToken, "page-token", listDefaultWarehouseOverridesReq.PageToken, `A page token, received from a previous ListDefaultWarehouseOverrides call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listDefaultWarehouseOverridesLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listDefaultWarehouseOverridesReq.PageToken, "page-token", listDefaultWarehouseOverridesReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-default-warehouse-overrides" cmd.Short = `List default warehouse overrides.` @@ -932,6 +965,13 @@ func newListDefaultWarehouseOverrides() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.Warehouses.ListDefaultWarehouseOverrides(ctx, listDefaultWarehouseOverridesReq) + if listDefaultWarehouseOverridesLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listDefaultWarehouseOverridesLimit) + } + if listDefaultWarehouseOverridesLimit > 0 { + ctx = cmdio.WithLimit(ctx, listDefaultWarehouseOverridesLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -1019,6 +1059,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1400,6 +1441,7 @@ func newUpdateDefaultWarehouseOverride() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -1486,6 +1528,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace-bindings/workspace-bindings.go b/cmd/workspace/workspace-bindings/workspace-bindings.go index 04090db4ae5..abb927ce0fe 100755 --- a/cmd/workspace/workspace-bindings/workspace-bindings.go +++ b/cmd/workspace/workspace-bindings/workspace-bindings.go @@ -3,6 +3,8 @@ package workspace_bindings import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -98,6 +100,7 @@ func newGet() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -126,9 +129,19 @@ func newGetBindings() *cobra.Command { cmd := &cobra.Command{} var getBindingsReq catalog.GetBindingsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var getBindingsLimit int + // Limit flag for total result capping. + cmd.Flags().IntVar(&getBindingsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&getBindingsReq.PageToken, "page-token", getBindingsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Flags().IntVar(&getBindingsReq.MaxResults, "max-results", getBindingsReq.MaxResults, `Maximum number of workspace bindings to return.`) - cmd.Flags().StringVar(&getBindingsReq.PageToken, "page-token", getBindingsReq.PageToken, `Opaque pagination token to go to next page based on previous query.`) + cmd.Flags().Lookup("max-results").Hidden = true cmd.Use = "get-bindings SECURABLE_TYPE SECURABLE_NAME" cmd.Short = `Get securable workspace bindings.` @@ -166,6 +179,13 @@ func newGetBindings() *cobra.Command { getBindingsReq.SecurableName = args[1] response := w.WorkspaceBindings.GetBindings(ctx, getBindingsReq) + if getBindingsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", getBindingsLimit) + } + if getBindingsLimit > 0 { + ctx = cmdio.WithLimit(ctx, getBindingsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -241,6 +261,7 @@ func newUpdate() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -319,6 +340,7 @@ func newUpdateBindings() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace-conf/workspace-conf.go b/cmd/workspace/workspace-conf/workspace-conf.go index e0f7b45902c..9fc4e2b750a 100755 --- a/cmd/workspace/workspace-conf/workspace-conf.go +++ b/cmd/workspace/workspace-conf/workspace-conf.go @@ -76,6 +76,7 @@ func newGetStatus() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace-entity-tag-assignments/workspace-entity-tag-assignments.go b/cmd/workspace/workspace-entity-tag-assignments/workspace-entity-tag-assignments.go index e15733be8b1..c0154deaa9e 100755 --- a/cmd/workspace/workspace-entity-tag-assignments/workspace-entity-tag-assignments.go +++ b/cmd/workspace/workspace-entity-tag-assignments/workspace-entity-tag-assignments.go @@ -81,7 +81,7 @@ func newCreateTagAssignment() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'entity_type', 'entity_id', 'tag_key' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'entity_type', 'entity_id', 'tag_key' in your JSON input") } return nil } @@ -120,6 +120,7 @@ func newCreateTagAssignment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -246,6 +247,7 @@ func newGetTagAssignment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -274,9 +276,19 @@ func newListTagAssignments() *cobra.Command { cmd := &cobra.Command{} var listTagAssignmentsReq tags.ListTagAssignmentsRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listTagAssignmentsLimit int cmd.Flags().IntVar(&listTagAssignmentsReq.PageSize, "page-size", listTagAssignmentsReq.PageSize, `Optional.`) - cmd.Flags().StringVar(&listTagAssignmentsReq.PageToken, "page-token", listTagAssignmentsReq.PageToken, `Pagination token to go to the next page of tag assignments.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listTagAssignmentsLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listTagAssignmentsReq.PageToken, "page-token", listTagAssignmentsReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-tag-assignments ENTITY_TYPE ENTITY_ID" cmd.Short = `List tag assignments for an entity.` @@ -306,6 +318,13 @@ func newListTagAssignments() *cobra.Command { listTagAssignmentsReq.EntityId = args[1] response := w.WorkspaceEntityTagAssignments.ListTagAssignments(ctx, listTagAssignmentsReq) + if listTagAssignmentsLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listTagAssignmentsLimit) + } + if listTagAssignmentsLimit > 0 { + ctx = cmdio.WithLimit(ctx, listTagAssignmentsLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -399,6 +418,7 @@ func newUpdateTagAssignment() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace-iam-v2/workspace-iam-v2.go b/cmd/workspace/workspace-iam-v2/workspace-iam-v2.go index 25cea5e6f27..2596b765cbc 100755 --- a/cmd/workspace/workspace-iam-v2/workspace-iam-v2.go +++ b/cmd/workspace/workspace-iam-v2/workspace-iam-v2.go @@ -93,6 +93,7 @@ func newGetWorkspaceAccessDetailLocal() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -143,7 +144,7 @@ func newResolveGroupProxy() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -176,6 +177,7 @@ func newResolveGroupProxy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -225,7 +227,7 @@ func newResolveServicePrincipalProxy() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -258,6 +260,7 @@ func newResolveServicePrincipalProxy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -307,7 +310,7 @@ func newResolveUserProxy() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'external_id' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'external_id' in your JSON input") } return nil } @@ -340,6 +343,7 @@ func newResolveUserProxy() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace-settings-v2/workspace-settings-v2.go b/cmd/workspace/workspace-settings-v2/workspace-settings-v2.go index 02429a6bc1f..d4e3d213b06 100755 --- a/cmd/workspace/workspace-settings-v2/workspace-settings-v2.go +++ b/cmd/workspace/workspace-settings-v2/workspace-settings-v2.go @@ -3,6 +3,8 @@ package workspace_settings_v2 import ( + "fmt" + "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/cmdctx" "github.com/databricks/cli/libs/cmdio" @@ -80,6 +82,7 @@ func newGetPublicWorkspaceSetting() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -108,9 +111,19 @@ func newListWorkspaceSettingsMetadata() *cobra.Command { cmd := &cobra.Command{} var listWorkspaceSettingsMetadataReq settingsv2.ListWorkspaceSettingsMetadataRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listWorkspaceSettingsMetadataLimit int cmd.Flags().IntVar(&listWorkspaceSettingsMetadataReq.PageSize, "page-size", listWorkspaceSettingsMetadataReq.PageSize, `The maximum number of settings to return.`) - cmd.Flags().StringVar(&listWorkspaceSettingsMetadataReq.PageToken, "page-token", listWorkspaceSettingsMetadataReq.PageToken, `A page token, received from a previous ListWorkspaceSettingsMetadataRequest call.`) + + // Limit flag for total result capping. + cmd.Flags().IntVar(&listWorkspaceSettingsMetadataLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Flags().StringVar(&listWorkspaceSettingsMetadataReq.PageToken, "page-token", listWorkspaceSettingsMetadataReq.PageToken, `Pagination token.`) + cmd.Flags().Lookup("page-token").Hidden = true cmd.Use = "list-workspace-settings-metadata" cmd.Short = `List valid setting keys and their metadata.` @@ -133,6 +146,13 @@ func newListWorkspaceSettingsMetadata() *cobra.Command { w := cmdctx.WorkspaceClient(ctx) response := w.WorkspaceSettingsV2.ListWorkspaceSettingsMetadata(ctx, listWorkspaceSettingsMetadataReq) + if listWorkspaceSettingsMetadataLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listWorkspaceSettingsMetadataLimit) + } + if listWorkspaceSettingsMetadataLimit > 0 { + ctx = cmdio.WithLimit(ctx, listWorkspaceSettingsMetadataLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -229,6 +249,7 @@ func newPatchPublicWorkspaceSetting() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/cmd/workspace/workspace/workspace.go b/cmd/workspace/workspace/workspace.go index fa77cef4aed..b1ad85707da 100755 --- a/cmd/workspace/workspace/workspace.go +++ b/cmd/workspace/workspace/workspace.go @@ -20,9 +20,10 @@ var cmdOverrides []func(*cobra.Command) func New() *cobra.Command { cmd := &cobra.Command{ Use: "workspace", - Short: `The Workspace API allows you to list, import, export, and delete notebooks and folders.`, - Long: `The Workspace API allows you to list, import, export, and delete notebooks and - folders. + Short: `The Workspace API allows you to list, import, export, and delete workspace objects such as notebooks, files, folders, and dashboards.`, + Long: `The Workspace API allows you to list, import, export, and delete workspace + objects such as notebooks, files, folders, and dashboards. Additionally, it + provides endpoints to manage permissions for any workspace object. A notebook is a web-based interface to a document that contains runnable code, visualizations, and explanatory text.`, @@ -73,9 +74,10 @@ func newDelete() *cobra.Command { cmd.Short = `Delete a workspace object.` cmd.Long = `Delete a workspace object. - Deletes an object or a directory (and optionally recursively deletes all - objects in the directory). * If path does not exist, this call returns an - error RESOURCE_DOES_NOT_EXIST. * If path is a non-empty directory and + Deprecated: use WorkspaceHierarchyService.DeleteTreeNode instead. Deletes an + object or a directory (and optionally recursively deletes all objects in the + directory). * If path does not exist, this call returns an error + RESOURCE_DOES_NOT_EXIST. * If path is a non-empty directory and recursive is set to false, this call returns an error DIRECTORY_NOT_EMPTY. @@ -91,7 +93,7 @@ func newDelete() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'path' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'path' in your JSON input") } return nil } @@ -226,6 +228,7 @@ func newExport() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -286,6 +289,7 @@ func newGetPermissionLevels() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -347,6 +351,7 @@ func newGetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -380,8 +385,9 @@ func newGetStatus() *cobra.Command { cmd.Short = `Get status.` cmd.Long = `Get status. - Gets the status of an object or a directory. If path does not exist, this - call returns an error RESOURCE_DOES_NOT_EXIST. + Deprecated: use WorkspaceHierarchyService.GetTreeNode instead. Gets the status + of an object or a directory. If path does not exist, this call returns an + error RESOURCE_DOES_NOT_EXIST. Arguments: PATH: The absolute path of the notebook or directory.` @@ -404,6 +410,7 @@ func newGetStatus() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -470,7 +477,7 @@ func newImport() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'path' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'path' in your JSON input") } return nil } @@ -531,16 +538,25 @@ func newList() *cobra.Command { cmd := &cobra.Command{} var listReq workspace.ListWorkspaceRequest + // Registered for all paginated methods. Validated at call time in the + // method-call template. Paginated list methods never have Wait or LRO + // branches, so the method-call path is always reached. + var listLimit int cmd.Flags().Int64Var(&listReq.NotebooksModifiedAfter, "notebooks-modified-after", listReq.NotebooksModifiedAfter, `UTC timestamp in milliseconds.`) + // Limit flag for total result capping. + cmd.Flags().IntVar(&listLimit, "limit", 0, `Maximum number of results to return.`) + + // Hidden pagination flags (internal API parameters). + cmd.Use = "list PATH" cmd.Short = `List contents.` cmd.Long = `List contents. - Lists the contents of a directory, or the object if it is not a directory. If - the input path does not exist, this call returns an error - RESOURCE_DOES_NOT_EXIST. + Deprecated: use WorkspaceHierarchyService.ListTreeNodes instead. Lists the + contents of a directory, or the object if it is not a directory. If the input + path does not exist, this call returns an error RESOURCE_DOES_NOT_EXIST. Arguments: PATH: The absolute path of the notebook or directory.` @@ -560,6 +576,13 @@ func newList() *cobra.Command { listReq.Path = args[0] response := w.Workspace.List(ctx, listReq) + if listLimit < 0 { + return fmt.Errorf("--limit must be a non-negative integer, got %d", listLimit) + } + if listLimit > 0 { + ctx = cmdio.WithLimit(ctx, listLimit) + } + return cmdio.RenderIterator(ctx, response) } @@ -596,9 +619,10 @@ func newMkdirs() *cobra.Command { cmd.Short = `Create a directory.` cmd.Long = `Create a directory. - Creates the specified directory (and necessary parent directories if they do - not exist). If there is an object (not a directory) at any prefix of the input - path, this call returns an error RESOURCE_ALREADY_EXISTS. + Deprecated: use WorkspaceHierarchyService.CreateTreeNode instead. Creates the + specified directory (and necessary parent directories if they do not exist). + If there is an object (not a directory) at any prefix of the input path, this + call returns an error RESOURCE_ALREADY_EXISTS. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories. @@ -614,7 +638,7 @@ func newMkdirs() *cobra.Command { if cmd.Flags().Changed("json") { err := root.ExactArgs(0)(cmd, args) if err != nil { - return fmt.Errorf("when --json flag is specified, no positional arguments are required. Provide 'path' in your JSON input") + return fmt.Errorf("when --json flag is specified, no positional arguments are allowed. Provide 'path' in your JSON input") } return nil } @@ -741,6 +765,7 @@ func newSetPermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } @@ -819,6 +844,7 @@ func newUpdatePermissions() *cobra.Command { if err != nil { return err } + return cmdio.Render(ctx, response) } diff --git a/experimental/ssh/internal/client/client.go b/experimental/ssh/internal/client/client.go index cd6d73f51ed..6dc3f9bb2d4 100644 --- a/experimental/ssh/internal/client/client.go +++ b/experimental/ssh/internal/client/client.go @@ -476,7 +476,7 @@ func submitSSHTunnelJob(ctx context.Context, client *databricks.WorkspaceClient, return fmt.Errorf("failed to get workspace content directory: %w", err) } - err = client.Workspace.MkdirsByPath(ctx, contentDir) + err = client.Workspace.MkdirsByPath(ctx, contentDir) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return fmt.Errorf("failed to create directory in the remote workspace: %w", err) } diff --git a/go.mod b/go.mod index 866f3f48c8e..5fa1dca1515 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/charmbracelet/bubbletea v1.3.10 // MIT github.com/charmbracelet/huh v1.0.0 // MIT github.com/charmbracelet/lipgloss v1.1.0 // MIT - github.com/databricks/databricks-sdk-go v0.126.0 // Apache-2.0 + github.com/databricks/databricks-sdk-go v0.127.0 // Apache-2.0 github.com/fatih/color v1.19.0 // MIT github.com/google/jsonschema-go v0.4.2 // MIT github.com/google/uuid v1.6.0 // BSD-3-Clause diff --git a/go.sum b/go.sum index e1a95bba3a9..e2e59ac4b13 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= -github.com/databricks/databricks-sdk-go v0.126.0 h1:431TkvShD8e70Le1zdaeo+AhMVoCqZG2sYdO+lfoSF4= -github.com/databricks/databricks-sdk-go v0.126.0/go.mod h1:hWoHnHbNLjPKiTm5K/7bcIv3J3Pkgo5x9pPzh8K3RVE= +github.com/databricks/databricks-sdk-go v0.127.0 h1:PMM9AVqH+YEMYu55MWg7CWjG/o8esP/4WqskAKxngiQ= +github.com/databricks/databricks-sdk-go v0.127.0/go.mod h1:C5LNgGe6hGuRrTwoxFmuup3XtQQEaqtq0e+K8IFDIS4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/integration/assumptions/dashboard_assumptions_test.go b/integration/assumptions/dashboard_assumptions_test.go index ed4cb048983..3dec3d45bff 100644 --- a/integration/assumptions/dashboard_assumptions_test.go +++ b/integration/assumptions/dashboard_assumptions_test.go @@ -54,7 +54,7 @@ func TestDashboardAssumptions_WorkspaceImport(t *testing.T) { // Cross-check consistency with the workspace object. { - obj, err := wt.W.Workspace.GetStatusByPath(ctx, dashboard.Path) + obj, err := wt.W.Workspace.GetStatusByPath(ctx, dashboard.Path) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) // Confirm that the resource ID included in the response is equal to the dashboard ID. diff --git a/integration/cmd/sync/sync_test.go b/integration/cmd/sync/sync_test.go index 4c771258d89..5871c41db24 100644 --- a/integration/cmd/sync/sync_test.go +++ b/integration/cmd/sync/sync_test.go @@ -125,13 +125,13 @@ func (a *syncTest) waitForCompletionMarker() { func (a *syncTest) remoteDirContent(ctx context.Context, relativeDir string, expectedFiles []string) { remoteDir := path.Join(a.remoteRoot, relativeDir) a.c.Eventually(func() bool { - objects, err := a.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ + objects, err := a.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: remoteDir, }) require.NoError(a.t, err) return len(objects) == len(expectedFiles) }, 30*time.Second, 5*time.Second) - objects, err := a.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ + objects, err := a.w.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: remoteDir, }) require.NoError(a.t, err) @@ -184,7 +184,7 @@ func (a *syncTest) objectType(ctx context.Context, relativePath, expected string path := path.Join(a.remoteRoot, relativePath) a.c.Eventually(func() bool { - metadata, err := a.w.Workspace.GetStatusByPath(ctx, path) + metadata, err := a.w.Workspace.GetStatusByPath(ctx, path) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return false } @@ -196,7 +196,7 @@ func (a *syncTest) language(ctx context.Context, relativePath, expected string) path := path.Join(a.remoteRoot, relativePath) a.c.Eventually(func() bool { - metadata, err := a.w.Workspace.GetStatusByPath(ctx, path) + metadata, err := a.w.Workspace.GetStatusByPath(ctx, path) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return false } @@ -517,7 +517,7 @@ func TestSyncEnsureRemotePathIsUsableIfRepoExists(t *testing.T) { assert.NoError(t, err) // Verify that the directory has been created. - info, err := wsc.Workspace.GetStatusByPath(ctx, nestedPath) + info, err := wsc.Workspace.GetStatusByPath(ctx, nestedPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) require.Equal(t, workspace.ObjectTypeDirectory, info.ObjectType) } @@ -535,14 +535,14 @@ func TestSyncEnsureRemotePathIsUsableInWorkspace(t *testing.T) { // Clean up directory after test. defer func() { - err := wsc.Workspace.Delete(ctx, workspace.Delete{ + err := wsc.Workspace.Delete(ctx, workspace.Delete{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: remotePath, }) assert.NoError(t, err) }() // Verify that the directory has been created. - info, err := wsc.Workspace.GetStatusByPath(ctx, remotePath) + info, err := wsc.Workspace.GetStatusByPath(ctx, remotePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) require.Equal(t, workspace.ObjectTypeDirectory, info.ObjectType) } diff --git a/integration/internal/acc/fixtures.go b/integration/internal/acc/fixtures.go index 03aada077ef..d902d0b49a1 100644 --- a/integration/internal/acc/fixtures.go +++ b/integration/internal/acc/fixtures.go @@ -22,13 +22,13 @@ func TemporaryWorkspaceDir(t *WorkspaceT, name ...string) string { basePath := fmt.Sprintf("/Users/%s/%s", me.UserName, testutil.RandomName(name...)) t.Logf("Creating workspace directory %s", basePath) - err = t.W.Workspace.MkdirsByPath(ctx, basePath) + err = t.W.Workspace.MkdirsByPath(ctx, basePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) // Remove test directory on test completion. t.Cleanup(func() { t.Logf("Removing workspace directory %s", basePath) - err := t.W.Workspace.Delete(context.WithoutCancel(ctx), workspace.Delete{ + err := t.W.Workspace.Delete(context.WithoutCancel(ctx), workspace.Delete{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: basePath, Recursive: true, }) diff --git a/integration/libs/git/git_fetch_test.go b/integration/libs/git/git_fetch_test.go index 73e33de7355..9bade36bf33 100644 --- a/integration/libs/git/git_fetch_test.go +++ b/integration/libs/git/git_fetch_test.go @@ -69,7 +69,7 @@ func TestFetchRepositoryInfoAPI_FromNonRepo(t *testing.T) { rootPath := ensureWorkspacePrefix(acc.TemporaryWorkspaceDir(wt, "testing-nonrepo-")) // Create directory inside this root path (this is cleaned up as part of the root path). - err := wt.W.Workspace.MkdirsByPath(ctx, path.Join(rootPath, "a/b/c")) + err := wt.W.Workspace.MkdirsByPath(ctx, path.Join(rootPath, "a/b/c")) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. require.NoError(t, err) ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: true, Version: "15.4"}) diff --git a/libs/cmdio/limit.go b/libs/cmdio/limit.go new file mode 100644 index 00000000000..536465dd9d6 --- /dev/null +++ b/libs/cmdio/limit.go @@ -0,0 +1,20 @@ +package cmdio + +import "context" + +type limitKeyType struct{} + +// WithLimit attaches a result limit to the context. +// Iterator renderers will stop after emitting this many items. +func WithLimit(ctx context.Context, limit int) context.Context { + return context.WithValue(ctx, limitKeyType{}, limit) +} + +// limitFromContext returns the limit from the context, or 0 if none is set. +func limitFromContext(ctx context.Context) int { + v, ok := ctx.Value(limitKeyType{}).(int) + if !ok { + return 0 + } + return v +} diff --git a/libs/cmdio/render.go b/libs/cmdio/render.go index c344c3d0286..733dd53fa7f 100644 --- a/libs/cmdio/render.go +++ b/libs/cmdio/render.go @@ -101,7 +101,11 @@ func (ir iteratorRenderer[T]) renderJson(ctx context.Context, w writeFlusher) er if err != nil { return err } + limit := limitFromContext(ctx) for i := 0; ir.t.HasNext(ctx); i++ { + if limit > 0 && i >= limit { + break + } if i != 0 { _, err = w.Write([]byte(",\n ")) if err != nil { @@ -136,7 +140,11 @@ func (ir iteratorRenderer[T]) renderJson(ctx context.Context, w writeFlusher) er func (ir iteratorRenderer[T]) renderTemplate(ctx context.Context, t *template.Template, w *tabwriter.Writer) error { buf := make([]any, 0, ir.getBufferSize()) + limit := limitFromContext(ctx) for i := 0; ir.t.HasNext(ctx); i++ { + if limit > 0 && i >= limit { + break + } n, err := ir.t.Next(ctx) if err != nil { return err diff --git a/libs/filer/workspace_files_client.go b/libs/filer/workspace_files_client.go index 9f75d3ca2e7..d69faef0000 100644 --- a/libs/filer/workspace_files_client.go +++ b/libs/filer/workspace_files_client.go @@ -176,7 +176,7 @@ func (w *WorkspaceFilesClient) Write(ctx context.Context, name string, reader io } // Create parent directory. - err = w.workspaceClient.Workspace.MkdirsByPath(ctx, path.Dir(absPath)) + err = w.workspaceClient.Workspace.MkdirsByPath(ctx, path.Dir(absPath)) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { if errors.As(err, &aerr) && aerr.StatusCode == http.StatusForbidden { return permissionError{absPath} @@ -251,7 +251,7 @@ func (w *WorkspaceFilesClient) Delete(ctx context.Context, name string, mode ... recursive := slices.Contains(mode, DeleteRecursively) - err = w.workspaceClient.Workspace.Delete(ctx, workspace.Delete{ + err = w.workspaceClient.Workspace.Delete(ctx, workspace.Delete{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: absPath, Recursive: recursive, }) @@ -285,7 +285,7 @@ func (w *WorkspaceFilesClient) ReadDir(ctx context.Context, name string) ([]fs.D return nil, err } - objects, err := w.workspaceClient.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ + objects, err := w.workspaceClient.Workspace.ListAll(ctx, workspace.ListWorkspaceRequest{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: absPath, }) @@ -317,7 +317,7 @@ func (w *WorkspaceFilesClient) Mkdir(ctx context.Context, name string) error { if err != nil { return err } - return w.workspaceClient.Workspace.Mkdirs(ctx, workspace.Mkdirs{ + return w.workspaceClient.Workspace.Mkdirs(ctx, workspace.Mkdirs{ //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. Path: dirPath, }) } diff --git a/libs/structs/structwalk/walktype_test.go b/libs/structs/structwalk/walktype_test.go index c2e2940adb8..0e005fb37c4 100644 --- a/libs/structs/structwalk/walktype_test.go +++ b/libs/structs/structwalk/walktype_test.go @@ -136,7 +136,7 @@ func TestTypeJobSettings(t *testing.T) { func TestTypeRoot(t *testing.T) { testStruct(t, reflect.TypeOf(config.Root{}), - 4600, 5000, // 4814 after adding external locations support + 5000, 5500, // 5213 after SDK v0.127.0 bump map[string]any{ "bundle.target": "", `variables.*.lookup.dashboard`: "", diff --git a/libs/sync/path.go b/libs/sync/path.go index 49de7db3408..3f86e8d3446 100644 --- a/libs/sync/path.go +++ b/libs/sync/path.go @@ -39,7 +39,7 @@ func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClie // Ensure that the remote path exists. // If it is a repo, it has to exist. // If it is a workspace path, it may not exist. - info, err := wsc.Workspace.GetStatusByPath(ctx, remotePath) + info, err := wsc.Workspace.GetStatusByPath(ctx, remotePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { // We only deal with 404s below. if !apierr.IsMissing(err) { @@ -49,18 +49,18 @@ func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClie // If the path is nested under a repo, the repo has to exist. if strings.HasPrefix(remotePath, "/Repos/") { repoPath := repoPathForPath(me, remotePath) - _, err = wsc.Workspace.GetStatusByPath(ctx, repoPath) + _, err = wsc.Workspace.GetStatusByPath(ctx, repoPath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil && apierr.IsMissing(err) { return fmt.Errorf("%s does not exist; please create it first", repoPath) } } // The workspace path doesn't exist. Create it and try again. - err = wsc.Workspace.MkdirsByPath(ctx, remotePath) + err = wsc.Workspace.MkdirsByPath(ctx, remotePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return fmt.Errorf("unable to create directory at %s: %w", remotePath, err) } - info, err = wsc.Workspace.GetStatusByPath(ctx, remotePath) + info, err = wsc.Workspace.GetStatusByPath(ctx, remotePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { return err } diff --git a/python/databricks/bundles/catalogs/__init__.py b/python/databricks/bundles/catalogs/__init__.py index fc92f42e226..af3df5a2c86 100644 --- a/python/databricks/bundles/catalogs/__init__.py +++ b/python/databricks/bundles/catalogs/__init__.py @@ -1,4 +1,7 @@ __all__ = [ + "AzureEncryptionSettings", + "AzureEncryptionSettingsDict", + "AzureEncryptionSettingsParam", "Catalog", "CatalogDict", "CatalogGrant", @@ -7,6 +10,9 @@ "CatalogGrantPrivilege", "CatalogGrantPrivilegeParam", "CatalogParam", + "EncryptionSettings", + "EncryptionSettingsDict", + "EncryptionSettingsParam", "Lifecycle", "LifecycleDict", "LifecycleParam", @@ -18,11 +24,21 @@ ] +from databricks.bundles.catalogs._models.azure_encryption_settings import ( + AzureEncryptionSettings, + AzureEncryptionSettingsDict, + AzureEncryptionSettingsParam, +) from databricks.bundles.catalogs._models.catalog import ( Catalog, CatalogDict, CatalogParam, ) +from databricks.bundles.catalogs._models.encryption_settings import ( + EncryptionSettings, + EncryptionSettingsDict, + EncryptionSettingsParam, +) from databricks.bundles.catalogs._models.lifecycle import ( Lifecycle, LifecycleDict, diff --git a/python/databricks/bundles/catalogs/_models/azure_encryption_settings.py b/python/databricks/bundles/catalogs/_models/azure_encryption_settings.py new file mode 100644 index 00000000000..9c2042d135c --- /dev/null +++ b/python/databricks/bundles/catalogs/_models/azure_encryption_settings.py @@ -0,0 +1,42 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOr, VariableOrOptional + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class AzureEncryptionSettings: + """ + :meta private: [EXPERIMENTAL] + """ + + azure_tenant_id: VariableOr[str] + + azure_cmk_access_connector_id: VariableOrOptional[str] = None + + azure_cmk_managed_identity_id: VariableOrOptional[str] = None + + @classmethod + def from_dict(cls, value: "AzureEncryptionSettingsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "AzureEncryptionSettingsDict": + return _transform_to_json_value(self) # type:ignore + + +class AzureEncryptionSettingsDict(TypedDict, total=False): + """""" + + azure_tenant_id: VariableOr[str] + + azure_cmk_access_connector_id: VariableOrOptional[str] + + azure_cmk_managed_identity_id: VariableOrOptional[str] + + +AzureEncryptionSettingsParam = AzureEncryptionSettingsDict | AzureEncryptionSettings diff --git a/python/databricks/bundles/catalogs/_models/catalog.py b/python/databricks/bundles/catalogs/_models/catalog.py index 368e96a3b24..9795277408b 100644 --- a/python/databricks/bundles/catalogs/_models/catalog.py +++ b/python/databricks/bundles/catalogs/_models/catalog.py @@ -1,6 +1,10 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, TypedDict +from databricks.bundles.catalogs._models.encryption_settings import ( + EncryptionSettings, + EncryptionSettingsParam, +) from databricks.bundles.catalogs._models.lifecycle import Lifecycle, LifecycleParam from databricks.bundles.catalogs._models.privilege_assignment import ( PrivilegeAssignment, @@ -34,6 +38,13 @@ class Catalog(Resource): lifecycle: VariableOrOptional[Lifecycle] = None + managed_encryption_settings: VariableOrOptional[EncryptionSettings] = None + """ + :meta private: [EXPERIMENTAL] + + Control CMK encryption for managed catalog data + """ + options: VariableOrDict[str] = field(default_factory=dict) properties: VariableOrDict[str] = field(default_factory=dict) @@ -65,6 +76,13 @@ class CatalogDict(TypedDict, total=False): lifecycle: VariableOrOptional[LifecycleParam] + managed_encryption_settings: VariableOrOptional[EncryptionSettingsParam] + """ + :meta private: [EXPERIMENTAL] + + Control CMK encryption for managed catalog data + """ + options: VariableOrDict[str] properties: VariableOrDict[str] diff --git a/python/databricks/bundles/catalogs/_models/encryption_settings.py b/python/databricks/bundles/catalogs/_models/encryption_settings.py new file mode 100644 index 00000000000..1c8bf991fdb --- /dev/null +++ b/python/databricks/bundles/catalogs/_models/encryption_settings.py @@ -0,0 +1,67 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.catalogs._models.azure_encryption_settings import ( + AzureEncryptionSettings, + AzureEncryptionSettingsParam, +) +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrOptional + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class EncryptionSettings: + """ + :meta private: [EXPERIMENTAL] + + Encryption Settings are used to carry metadata for securable encryption at rest. + Currently used for catalogs, we can use the information supplied here to interact with a CMK. + """ + + azure_encryption_settings: VariableOrOptional[AzureEncryptionSettings] = None + """ + optional Azure settings - only required if an Azure CMK is used. + """ + + azure_key_vault_key_id: VariableOrOptional[str] = None + """ + the AKV URL in Azure, null otherwise. + """ + + customer_managed_key_id: VariableOrOptional[str] = None + """ + the CMK uuid in AWS and GCP, null otherwise. + """ + + @classmethod + def from_dict(cls, value: "EncryptionSettingsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "EncryptionSettingsDict": + return _transform_to_json_value(self) # type:ignore + + +class EncryptionSettingsDict(TypedDict, total=False): + """""" + + azure_encryption_settings: VariableOrOptional[AzureEncryptionSettingsParam] + """ + optional Azure settings - only required if an Azure CMK is used. + """ + + azure_key_vault_key_id: VariableOrOptional[str] + """ + the AKV URL in Azure, null otherwise. + """ + + customer_managed_key_id: VariableOrOptional[str] + """ + the CMK uuid in AWS and GCP, null otherwise. + """ + + +EncryptionSettingsParam = EncryptionSettingsDict | EncryptionSettings diff --git a/python/databricks/bundles/jobs/_models/environment.py b/python/databricks/bundles/jobs/_models/environment.py index 64db81e5e5f..5ad70e3a2e3 100644 --- a/python/databricks/bundles/jobs/_models/environment.py +++ b/python/databricks/bundles/jobs/_models/environment.py @@ -18,8 +18,12 @@ class Environment: base_environment: VariableOrOptional[str] = None """ - The `base_environment` key refers to an `env.yaml` file that specifies an environment version and a collection of dependencies required for the environment setup. - This `env.yaml` file may itself include a `base_environment` reference pointing to another `env_1.yaml` file. However, when used as a base environment, `env_1.yaml` (or further nested references) will not be processed or included in the final environment, meaning that the resolution of `base_environment` references is not recursive. + The base environment this environment is built on top of. A base environment defines the environment version and a + list of dependencies for serverless compute. The value can be a file path to a custom `env.yaml` file + (e.g., `/Workspace/path/to/env.yaml`). Support for a Databricks-provided base environment ID + (e.g., `workspace-base-environments/databricks_ai_v4`) and workspace base environment ID + (e.g., `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in Beta. + Either `environment_version` or `base_environment` can be provided. For more information, see """ client: VariableOrOptional[str] = None @@ -54,8 +58,12 @@ class EnvironmentDict(TypedDict, total=False): base_environment: VariableOrOptional[str] """ - The `base_environment` key refers to an `env.yaml` file that specifies an environment version and a collection of dependencies required for the environment setup. - This `env.yaml` file may itself include a `base_environment` reference pointing to another `env_1.yaml` file. However, when used as a base environment, `env_1.yaml` (or further nested references) will not be processed or included in the final environment, meaning that the resolution of `base_environment` references is not recursive. + The base environment this environment is built on top of. A base environment defines the environment version and a + list of dependencies for serverless compute. The value can be a file path to a custom `env.yaml` file + (e.g., `/Workspace/path/to/env.yaml`). Support for a Databricks-provided base environment ID + (e.g., `workspace-base-environments/databricks_ai_v4`) and workspace base environment ID + (e.g., `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in Beta. + Either `environment_version` or `base_environment` can be provided. For more information, see """ client: VariableOrOptional[str] diff --git a/python/databricks/bundles/jobs/_models/task.py b/python/databricks/bundles/jobs/_models/task.py index 4c1e2d221cf..cfac99bc571 100644 --- a/python/databricks/bundles/jobs/_models/task.py +++ b/python/databricks/bundles/jobs/_models/task.py @@ -106,7 +106,8 @@ class Task: alert_task: VariableOrOptional[AlertTask] = None """ - New alert v2 task + The task evaluates a Databricks alert and sends notifications to subscribers + when the `alert_task` field is present. """ clean_rooms_notebook_task: VariableOrOptional[CleanRoomsNotebookTask] = None @@ -318,7 +319,8 @@ class TaskDict(TypedDict, total=False): alert_task: VariableOrOptional[AlertTaskParam] """ - New alert v2 task + The task evaluates a Databricks alert and sends notifications to subscribers + when the `alert_task` field is present. """ clean_rooms_notebook_task: VariableOrOptional[CleanRoomsNotebookTaskParam] diff --git a/python/databricks/bundles/pipelines/__init__.py b/python/databricks/bundles/pipelines/__init__.py index 49a37a83de6..dad21eca069 100644 --- a/python/databricks/bundles/pipelines/__init__.py +++ b/python/databricks/bundles/pipelines/__init__.py @@ -21,6 +21,9 @@ "ConnectionParameters", "ConnectionParametersDict", "ConnectionParametersParam", + "ConnectorOptions", + "ConnectorOptionsDict", + "ConnectorOptionsParam", "ConnectorType", "ConnectorTypeParam", "DataStagingOptions", @@ -36,6 +39,16 @@ "EventLogSpec", "EventLogSpecDict", "EventLogSpecParam", + "FileFilter", + "FileFilterDict", + "FileFilterParam", + "FileIngestionOptions", + "FileIngestionOptionsDict", + "FileIngestionOptionsFileFormat", + "FileIngestionOptionsFileFormatParam", + "FileIngestionOptionsParam", + "FileIngestionOptionsSchemaEvolutionMode", + "FileIngestionOptionsSchemaEvolutionModeParam", "FileLibrary", "FileLibraryDict", "FileLibraryParam", @@ -50,6 +63,14 @@ "GcsStorageInfo", "GcsStorageInfoDict", "GcsStorageInfoParam", + "GoogleAdsOptions", + "GoogleAdsOptionsDict", + "GoogleAdsOptionsParam", + "GoogleDriveOptions", + "GoogleDriveOptionsDict", + "GoogleDriveOptionsGoogleDriveEntityType", + "GoogleDriveOptionsGoogleDriveEntityTypeParam", + "GoogleDriveOptionsParam", "IngestionConfig", "IngestionConfigDict", "IngestionConfigParam", @@ -138,6 +159,11 @@ "SchemaSpec", "SchemaSpecDict", "SchemaSpecParam", + "SharepointOptions", + "SharepointOptionsDict", + "SharepointOptionsParam", + "SharepointOptionsSharepointEntityType", + "SharepointOptionsSharepointEntityTypeParam", "SourceCatalogConfig", "SourceCatalogConfigDict", "SourceCatalogConfigParam", @@ -152,6 +178,13 @@ "TableSpecificConfigParam", "TableSpecificConfigScdType", "TableSpecificConfigScdTypeParam", + "TikTokAdsOptions", + "TikTokAdsOptionsDict", + "TikTokAdsOptionsParam", + "TikTokAdsOptionsTikTokDataLevel", + "TikTokAdsOptionsTikTokDataLevelParam", + "TikTokAdsOptionsTikTokReportType", + "TikTokAdsOptionsTikTokReportTypeParam", "VolumesStorageInfo", "VolumesStorageInfoDict", "VolumesStorageInfoParam", @@ -199,6 +232,11 @@ ConnectionParametersDict, ConnectionParametersParam, ) +from databricks.bundles.pipelines._models.connector_options import ( + ConnectorOptions, + ConnectorOptionsDict, + ConnectorOptionsParam, +) from databricks.bundles.pipelines._models.connector_type import ( ConnectorType, ConnectorTypeParam, @@ -223,6 +261,24 @@ EventLogSpecDict, EventLogSpecParam, ) +from databricks.bundles.pipelines._models.file_filter import ( + FileFilter, + FileFilterDict, + FileFilterParam, +) +from databricks.bundles.pipelines._models.file_ingestion_options import ( + FileIngestionOptions, + FileIngestionOptionsDict, + FileIngestionOptionsParam, +) +from databricks.bundles.pipelines._models.file_ingestion_options_file_format import ( + FileIngestionOptionsFileFormat, + FileIngestionOptionsFileFormatParam, +) +from databricks.bundles.pipelines._models.file_ingestion_options_schema_evolution_mode import ( + FileIngestionOptionsSchemaEvolutionMode, + FileIngestionOptionsSchemaEvolutionModeParam, +) from databricks.bundles.pipelines._models.file_library import ( FileLibrary, FileLibraryDict, @@ -247,6 +303,20 @@ GcsStorageInfoDict, GcsStorageInfoParam, ) +from databricks.bundles.pipelines._models.google_ads_options import ( + GoogleAdsOptions, + GoogleAdsOptionsDict, + GoogleAdsOptionsParam, +) +from databricks.bundles.pipelines._models.google_drive_options import ( + GoogleDriveOptions, + GoogleDriveOptionsDict, + GoogleDriveOptionsParam, +) +from databricks.bundles.pipelines._models.google_drive_options_google_drive_entity_type import ( + GoogleDriveOptionsGoogleDriveEntityType, + GoogleDriveOptionsGoogleDriveEntityTypeParam, +) from databricks.bundles.pipelines._models.ingestion_config import ( IngestionConfig, IngestionConfigDict, @@ -391,6 +461,15 @@ SchemaSpecDict, SchemaSpecParam, ) +from databricks.bundles.pipelines._models.sharepoint_options import ( + SharepointOptions, + SharepointOptionsDict, + SharepointOptionsParam, +) +from databricks.bundles.pipelines._models.sharepoint_options_sharepoint_entity_type import ( + SharepointOptionsSharepointEntityType, + SharepointOptionsSharepointEntityTypeParam, +) from databricks.bundles.pipelines._models.source_catalog_config import ( SourceCatalogConfig, SourceCatalogConfigDict, @@ -415,6 +494,19 @@ TableSpecificConfigScdType, TableSpecificConfigScdTypeParam, ) +from databricks.bundles.pipelines._models.tik_tok_ads_options import ( + TikTokAdsOptions, + TikTokAdsOptionsDict, + TikTokAdsOptionsParam, +) +from databricks.bundles.pipelines._models.tik_tok_ads_options_tik_tok_data_level import ( + TikTokAdsOptionsTikTokDataLevel, + TikTokAdsOptionsTikTokDataLevelParam, +) +from databricks.bundles.pipelines._models.tik_tok_ads_options_tik_tok_report_type import ( + TikTokAdsOptionsTikTokReportType, + TikTokAdsOptionsTikTokReportTypeParam, +) from databricks.bundles.pipelines._models.volumes_storage_info import ( VolumesStorageInfo, VolumesStorageInfoDict, diff --git a/python/databricks/bundles/pipelines/_models/connector_options.py b/python/databricks/bundles/pipelines/_models/connector_options.py new file mode 100644 index 00000000000..dfda4f6c133 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/connector_options.py @@ -0,0 +1,100 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrOptional +from databricks.bundles.pipelines._models.google_ads_options import ( + GoogleAdsOptions, + GoogleAdsOptionsParam, +) +from databricks.bundles.pipelines._models.google_drive_options import ( + GoogleDriveOptions, + GoogleDriveOptionsParam, +) +from databricks.bundles.pipelines._models.sharepoint_options import ( + SharepointOptions, + SharepointOptionsParam, +) +from databricks.bundles.pipelines._models.tik_tok_ads_options import ( + TikTokAdsOptions, + TikTokAdsOptionsParam, +) + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class ConnectorOptions: + """ + :meta private: [EXPERIMENTAL] + + Wrapper message for source-specific options to support multiple connector types + """ + + gdrive_options: VariableOrOptional[GoogleDriveOptions] = None + """ + :meta private: [EXPERIMENTAL] + """ + + google_ads_options: VariableOrOptional[GoogleAdsOptions] = None + """ + :meta private: [EXPERIMENTAL] + + Google Ads specific options for ingestion (object-level). + When set, these values override the corresponding fields in GoogleAdsConfig + (source_configurations). + """ + + sharepoint_options: VariableOrOptional[SharepointOptions] = None + """ + :meta private: [EXPERIMENTAL] + """ + + tiktok_ads_options: VariableOrOptional[TikTokAdsOptions] = None + """ + :meta private: [EXPERIMENTAL] + + TikTok Ads specific options for ingestion + """ + + @classmethod + def from_dict(cls, value: "ConnectorOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "ConnectorOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class ConnectorOptionsDict(TypedDict, total=False): + """""" + + gdrive_options: VariableOrOptional[GoogleDriveOptionsParam] + """ + :meta private: [EXPERIMENTAL] + """ + + google_ads_options: VariableOrOptional[GoogleAdsOptionsParam] + """ + :meta private: [EXPERIMENTAL] + + Google Ads specific options for ingestion (object-level). + When set, these values override the corresponding fields in GoogleAdsConfig + (source_configurations). + """ + + sharepoint_options: VariableOrOptional[SharepointOptionsParam] + """ + :meta private: [EXPERIMENTAL] + """ + + tiktok_ads_options: VariableOrOptional[TikTokAdsOptionsParam] + """ + :meta private: [EXPERIMENTAL] + + TikTok Ads specific options for ingestion + """ + + +ConnectorOptionsParam = ConnectorOptionsDict | ConnectorOptions diff --git a/python/databricks/bundles/pipelines/_models/file_filter.py b/python/databricks/bundles/pipelines/_models/file_filter.py new file mode 100644 index 00000000000..497c43acd45 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/file_filter.py @@ -0,0 +1,70 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrOptional + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class FileFilter: + """ + :meta private: [EXPERIMENTAL] + """ + + modified_after: VariableOrOptional[str] = None + """ + Include files with modification times occurring after the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + """ + + modified_before: VariableOrOptional[str] = None + """ + Include files with modification times occurring before the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + """ + + path_filter: VariableOrOptional[str] = None + """ + Include files with file names matching the pattern + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter + """ + + @classmethod + def from_dict(cls, value: "FileFilterDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "FileFilterDict": + return _transform_to_json_value(self) # type:ignore + + +class FileFilterDict(TypedDict, total=False): + """""" + + modified_after: VariableOrOptional[str] + """ + Include files with modification times occurring after the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + """ + + modified_before: VariableOrOptional[str] + """ + Include files with modification times occurring before the specified time. + Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters + """ + + path_filter: VariableOrOptional[str] + """ + Include files with file names matching the pattern + Based on https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter + """ + + +FileFilterParam = FileFilterDict | FileFilter diff --git a/python/databricks/bundles/pipelines/_models/file_ingestion_options.py b/python/databricks/bundles/pipelines/_models/file_ingestion_options.py new file mode 100644 index 00000000000..514e19ad77f --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/file_ingestion_options.py @@ -0,0 +1,136 @@ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import ( + VariableOrDict, + VariableOrList, + VariableOrOptional, +) +from databricks.bundles.pipelines._models.file_filter import ( + FileFilter, + FileFilterParam, +) +from databricks.bundles.pipelines._models.file_ingestion_options_file_format import ( + FileIngestionOptionsFileFormat, + FileIngestionOptionsFileFormatParam, +) +from databricks.bundles.pipelines._models.file_ingestion_options_schema_evolution_mode import ( + FileIngestionOptionsSchemaEvolutionMode, + FileIngestionOptionsSchemaEvolutionModeParam, +) + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class FileIngestionOptions: + """ + :meta private: [EXPERIMENTAL] + """ + + corrupt_record_column: VariableOrOptional[str] = None + + file_filters: VariableOrList[FileFilter] = field(default_factory=list) + """ + Generic options + """ + + format: VariableOrOptional[FileIngestionOptionsFileFormat] = None + """ + required for TableSpec + """ + + format_options: VariableOrDict[str] = field(default_factory=dict) + """ + Format-specific options + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options + """ + + ignore_corrupt_files: VariableOrOptional[bool] = None + + infer_column_types: VariableOrOptional[bool] = None + + reader_case_sensitive: VariableOrOptional[bool] = None + """ + Column name case sensitivity + https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior + """ + + rescued_data_column: VariableOrOptional[str] = None + + schema_evolution_mode: VariableOrOptional[ + FileIngestionOptionsSchemaEvolutionMode + ] = None + """ + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work + """ + + schema_hints: VariableOrOptional[str] = None + """ + Override inferred schema of specific columns + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints + """ + + single_variant_column: VariableOrOptional[str] = None + + @classmethod + def from_dict(cls, value: "FileIngestionOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "FileIngestionOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class FileIngestionOptionsDict(TypedDict, total=False): + """""" + + corrupt_record_column: VariableOrOptional[str] + + file_filters: VariableOrList[FileFilterParam] + """ + Generic options + """ + + format: VariableOrOptional[FileIngestionOptionsFileFormatParam] + """ + required for TableSpec + """ + + format_options: VariableOrDict[str] + """ + Format-specific options + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options + """ + + ignore_corrupt_files: VariableOrOptional[bool] + + infer_column_types: VariableOrOptional[bool] + + reader_case_sensitive: VariableOrOptional[bool] + """ + Column name case sensitivity + https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior + """ + + rescued_data_column: VariableOrOptional[str] + + schema_evolution_mode: VariableOrOptional[ + FileIngestionOptionsSchemaEvolutionModeParam + ] + """ + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work + """ + + schema_hints: VariableOrOptional[str] + """ + Override inferred schema of specific columns + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints + """ + + single_variant_column: VariableOrOptional[str] + + +FileIngestionOptionsParam = FileIngestionOptionsDict | FileIngestionOptions diff --git a/python/databricks/bundles/pipelines/_models/file_ingestion_options_file_format.py b/python/databricks/bundles/pipelines/_models/file_ingestion_options_file_format.py new file mode 100644 index 00000000000..bf5838c8701 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/file_ingestion_options_file_format.py @@ -0,0 +1,23 @@ +from enum import Enum +from typing import Literal + + +class FileIngestionOptionsFileFormat(Enum): + """ + :meta private: [EXPERIMENTAL] + """ + + BINARYFILE = "BINARYFILE" + JSON = "JSON" + CSV = "CSV" + XML = "XML" + EXCEL = "EXCEL" + PARQUET = "PARQUET" + AVRO = "AVRO" + ORC = "ORC" + + +FileIngestionOptionsFileFormatParam = ( + Literal["BINARYFILE", "JSON", "CSV", "XML", "EXCEL", "PARQUET", "AVRO", "ORC"] + | FileIngestionOptionsFileFormat +) diff --git a/python/databricks/bundles/pipelines/_models/file_ingestion_options_schema_evolution_mode.py b/python/databricks/bundles/pipelines/_models/file_ingestion_options_schema_evolution_mode.py new file mode 100644 index 00000000000..ac29b94d0cb --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/file_ingestion_options_schema_evolution_mode.py @@ -0,0 +1,28 @@ +from enum import Enum +from typing import Literal + + +class FileIngestionOptionsSchemaEvolutionMode(Enum): + """ + :meta private: [EXPERIMENTAL] + + Based on https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work + """ + + ADD_NEW_COLUMNS_WITH_TYPE_WIDENING = "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING" + ADD_NEW_COLUMNS = "ADD_NEW_COLUMNS" + RESCUE = "RESCUE" + FAIL_ON_NEW_COLUMNS = "FAIL_ON_NEW_COLUMNS" + NONE = "NONE" + + +FileIngestionOptionsSchemaEvolutionModeParam = ( + Literal[ + "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING", + "ADD_NEW_COLUMNS", + "RESCUE", + "FAIL_ON_NEW_COLUMNS", + "NONE", + ] + | FileIngestionOptionsSchemaEvolutionMode +) diff --git a/python/databricks/bundles/pipelines/_models/google_ads_options.py b/python/databricks/bundles/pipelines/_models/google_ads_options.py new file mode 100644 index 00000000000..faa76baae42 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/google_ads_options.py @@ -0,0 +1,74 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOr, VariableOrOptional + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class GoogleAdsOptions: + """ + :meta private: [EXPERIMENTAL] + + Google Ads specific options for ingestion (object-level). + When set, these values override the corresponding fields in GoogleAdsConfig + (source_configurations). + """ + + manager_account_id: VariableOr[str] + """ + (Optional at this level) Manager Account ID (also called MCC Account ID) used to list + and access customer accounts under this manager account. + Overrides GoogleAdsConfig.manager_account_id from source_configurations when set. + """ + + lookback_window_days: VariableOrOptional[int] = None + """ + (Optional) Number of days to look back for report tables to capture late-arriving data. + If not specified, defaults to 30 days. + """ + + sync_start_date: VariableOrOptional[str] = None + """ + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 2 years of historical data. + """ + + @classmethod + def from_dict(cls, value: "GoogleAdsOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "GoogleAdsOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class GoogleAdsOptionsDict(TypedDict, total=False): + """""" + + manager_account_id: VariableOr[str] + """ + (Optional at this level) Manager Account ID (also called MCC Account ID) used to list + and access customer accounts under this manager account. + Overrides GoogleAdsConfig.manager_account_id from source_configurations when set. + """ + + lookback_window_days: VariableOrOptional[int] + """ + (Optional) Number of days to look back for report tables to capture late-arriving data. + If not specified, defaults to 30 days. + """ + + sync_start_date: VariableOrOptional[str] + """ + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 2 years of historical data. + """ + + +GoogleAdsOptionsParam = GoogleAdsOptionsDict | GoogleAdsOptions diff --git a/python/databricks/bundles/pipelines/_models/google_drive_options.py b/python/databricks/bundles/pipelines/_models/google_drive_options.py new file mode 100644 index 00000000000..05c7c2aaa26 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/google_drive_options.py @@ -0,0 +1,56 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrOptional +from databricks.bundles.pipelines._models.file_ingestion_options import ( + FileIngestionOptions, + FileIngestionOptionsParam, +) +from databricks.bundles.pipelines._models.google_drive_options_google_drive_entity_type import ( + GoogleDriveOptionsGoogleDriveEntityType, + GoogleDriveOptionsGoogleDriveEntityTypeParam, +) + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class GoogleDriveOptions: + """ + :meta private: [EXPERIMENTAL] + """ + + entity_type: VariableOrOptional[GoogleDriveOptionsGoogleDriveEntityType] = None + + file_ingestion_options: VariableOrOptional[FileIngestionOptions] = None + + url: VariableOrOptional[str] = None + """ + Google Drive URL. + """ + + @classmethod + def from_dict(cls, value: "GoogleDriveOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "GoogleDriveOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class GoogleDriveOptionsDict(TypedDict, total=False): + """""" + + entity_type: VariableOrOptional[GoogleDriveOptionsGoogleDriveEntityTypeParam] + + file_ingestion_options: VariableOrOptional[FileIngestionOptionsParam] + + url: VariableOrOptional[str] + """ + Google Drive URL. + """ + + +GoogleDriveOptionsParam = GoogleDriveOptionsDict | GoogleDriveOptions diff --git a/python/databricks/bundles/pipelines/_models/google_drive_options_google_drive_entity_type.py b/python/databricks/bundles/pipelines/_models/google_drive_options_google_drive_entity_type.py new file mode 100644 index 00000000000..136b3aff953 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/google_drive_options_google_drive_entity_type.py @@ -0,0 +1,18 @@ +from enum import Enum +from typing import Literal + + +class GoogleDriveOptionsGoogleDriveEntityType(Enum): + """ + :meta private: [EXPERIMENTAL] + """ + + FILE = "FILE" + FILE_METADATA = "FILE_METADATA" + PERMISSION = "PERMISSION" + + +GoogleDriveOptionsGoogleDriveEntityTypeParam = ( + Literal["FILE", "FILE_METADATA", "PERMISSION"] + | GoogleDriveOptionsGoogleDriveEntityType +) diff --git a/python/databricks/bundles/pipelines/_models/ingestion_config.py b/python/databricks/bundles/pipelines/_models/ingestion_config.py index 988227c43e3..34b5b7d2d7e 100644 --- a/python/databricks/bundles/pipelines/_models/ingestion_config.py +++ b/python/databricks/bundles/pipelines/_models/ingestion_config.py @@ -4,12 +4,12 @@ from databricks.bundles.core._transform import _transform from databricks.bundles.core._transform_to_json import _transform_to_json_value from databricks.bundles.core._variable import VariableOrOptional -from databricks.bundles.pipelines._models.report_spec import ( - ReportSpec, - ReportSpecParam, -) +from databricks.bundles.pipelines._models.report_spec import ReportSpec, ReportSpecParam from databricks.bundles.pipelines._models.schema_spec import SchemaSpec, SchemaSpecParam -from databricks.bundles.pipelines._models.table_spec import TableSpec, TableSpecParam +from databricks.bundles.pipelines._models.table_spec import ( + TableSpec, + TableSpecParam, +) if TYPE_CHECKING: from typing_extensions import Self diff --git a/python/databricks/bundles/pipelines/_models/schema_spec.py b/python/databricks/bundles/pipelines/_models/schema_spec.py index 1307409fb4c..d113f2376c8 100644 --- a/python/databricks/bundles/pipelines/_models/schema_spec.py +++ b/python/databricks/bundles/pipelines/_models/schema_spec.py @@ -4,6 +4,10 @@ from databricks.bundles.core._transform import _transform from databricks.bundles.core._transform_to_json import _transform_to_json_value from databricks.bundles.core._variable import VariableOr, VariableOrOptional +from databricks.bundles.pipelines._models.connector_options import ( + ConnectorOptions, + ConnectorOptionsParam, +) from databricks.bundles.pipelines._models.table_specific_config import ( TableSpecificConfig, TableSpecificConfigParam, @@ -32,6 +36,13 @@ class SchemaSpec: Required. Schema name in the source database. """ + connector_options: VariableOrOptional[ConnectorOptions] = None + """ + :meta private: [EXPERIMENTAL] + + (Optional) Source Specific Connector Options + """ + source_catalog: VariableOrOptional[str] = None """ The source catalog name. Might be optional depending on the type of source. @@ -68,6 +79,13 @@ class SchemaSpecDict(TypedDict, total=False): Required. Schema name in the source database. """ + connector_options: VariableOrOptional[ConnectorOptionsParam] + """ + :meta private: [EXPERIMENTAL] + + (Optional) Source Specific Connector Options + """ + source_catalog: VariableOrOptional[str] """ The source catalog name. Might be optional depending on the type of source. diff --git a/python/databricks/bundles/pipelines/_models/sharepoint_options.py b/python/databricks/bundles/pipelines/_models/sharepoint_options.py new file mode 100644 index 00000000000..72fe41e11e1 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/sharepoint_options.py @@ -0,0 +1,70 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrOptional +from databricks.bundles.pipelines._models.file_ingestion_options import ( + FileIngestionOptions, + FileIngestionOptionsParam, +) +from databricks.bundles.pipelines._models.sharepoint_options_sharepoint_entity_type import ( + SharepointOptionsSharepointEntityType, + SharepointOptionsSharepointEntityTypeParam, +) + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class SharepointOptions: + """ + :meta private: [EXPERIMENTAL] + """ + + entity_type: VariableOrOptional[SharepointOptionsSharepointEntityType] = None + """ + (Optional) The type of SharePoint entity to ingest. + If not specified, defaults to FILE. + """ + + file_ingestion_options: VariableOrOptional[FileIngestionOptions] = None + """ + (Optional) File ingestion options for processing files. + """ + + url: VariableOrOptional[str] = None + """ + Required. The SharePoint URL. + """ + + @classmethod + def from_dict(cls, value: "SharepointOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "SharepointOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class SharepointOptionsDict(TypedDict, total=False): + """""" + + entity_type: VariableOrOptional[SharepointOptionsSharepointEntityTypeParam] + """ + (Optional) The type of SharePoint entity to ingest. + If not specified, defaults to FILE. + """ + + file_ingestion_options: VariableOrOptional[FileIngestionOptionsParam] + """ + (Optional) File ingestion options for processing files. + """ + + url: VariableOrOptional[str] + """ + Required. The SharePoint URL. + """ + + +SharepointOptionsParam = SharepointOptionsDict | SharepointOptions diff --git a/python/databricks/bundles/pipelines/_models/sharepoint_options_sharepoint_entity_type.py b/python/databricks/bundles/pipelines/_models/sharepoint_options_sharepoint_entity_type.py new file mode 100644 index 00000000000..46e15fff79d --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/sharepoint_options_sharepoint_entity_type.py @@ -0,0 +1,19 @@ +from enum import Enum +from typing import Literal + + +class SharepointOptionsSharepointEntityType(Enum): + """ + :meta private: [EXPERIMENTAL] + """ + + FILE = "FILE" + FILE_METADATA = "FILE_METADATA" + PERMISSION = "PERMISSION" + LIST = "LIST" + + +SharepointOptionsSharepointEntityTypeParam = ( + Literal["FILE", "FILE_METADATA", "PERMISSION", "LIST"] + | SharepointOptionsSharepointEntityType +) diff --git a/python/databricks/bundles/pipelines/_models/table_spec.py b/python/databricks/bundles/pipelines/_models/table_spec.py index 03155edf6a1..08e26241bf8 100644 --- a/python/databricks/bundles/pipelines/_models/table_spec.py +++ b/python/databricks/bundles/pipelines/_models/table_spec.py @@ -4,6 +4,10 @@ from databricks.bundles.core._transform import _transform from databricks.bundles.core._transform_to_json import _transform_to_json_value from databricks.bundles.core._variable import VariableOr, VariableOrOptional +from databricks.bundles.pipelines._models.connector_options import ( + ConnectorOptions, + ConnectorOptionsParam, +) from databricks.bundles.pipelines._models.table_specific_config import ( TableSpecificConfig, TableSpecificConfigParam, @@ -32,6 +36,13 @@ class TableSpec: Required. Table name in the source database. """ + connector_options: VariableOrOptional[ConnectorOptions] = None + """ + :meta private: [EXPERIMENTAL] + + (Optional) Source Specific Connector Options + """ + destination_table: VariableOrOptional[str] = None """ Optional. Destination table name. The pipeline fails if a table with that name already exists. If not set, the source table name is used. @@ -78,6 +89,13 @@ class TableSpecDict(TypedDict, total=False): Required. Table name in the source database. """ + connector_options: VariableOrOptional[ConnectorOptionsParam] + """ + :meta private: [EXPERIMENTAL] + + (Optional) Source Specific Connector Options + """ + destination_table: VariableOrOptional[str] """ Optional. Destination table name. The pipeline fails if a table with that name already exists. If not set, the source table name is used. diff --git a/python/databricks/bundles/pipelines/_models/tik_tok_ads_options.py b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options.py new file mode 100644 index 00000000000..8c304eb5614 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options.py @@ -0,0 +1,136 @@ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrList, VariableOrOptional +from databricks.bundles.pipelines._models.tik_tok_ads_options_tik_tok_data_level import ( + TikTokAdsOptionsTikTokDataLevel, + TikTokAdsOptionsTikTokDataLevelParam, +) +from databricks.bundles.pipelines._models.tik_tok_ads_options_tik_tok_report_type import ( + TikTokAdsOptionsTikTokReportType, + TikTokAdsOptionsTikTokReportTypeParam, +) + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class TikTokAdsOptions: + """ + :meta private: [EXPERIMENTAL] + + TikTok Ads specific options for ingestion + """ + + data_level: VariableOrOptional[TikTokAdsOptionsTikTokDataLevel] = None + """ + (Optional) Data level for the report. + If not specified, defaults to AUCTION_CAMPAIGN. + """ + + dimensions: VariableOrList[str] = field(default_factory=list) + """ + (Optional) Dimensions to include in the report. + Examples: "campaign_id", "adgroup_id", "ad_id", "stat_time_day", "stat_time_hour" + If not specified, defaults to campaign_id. + """ + + lookback_window_days: VariableOrOptional[int] = None + """ + (Optional) Number of days to look back for report tables during incremental sync + to capture late-arriving conversions and attribution data. + If not specified, defaults to 7 days. + """ + + metrics: VariableOrList[str] = field(default_factory=list) + """ + (Optional) Metrics to include in the report. + Examples: "spend", "impressions", "clicks", "conversion", "cpc" + If not specified, defaults to basic metrics (spend, impressions, clicks, etc.) + """ + + query_lifetime: VariableOrOptional[bool] = None + """ + (Optional) Whether to request lifetime metrics (all-time aggregated data). + When true, the report returns all-time data. + If not specified, defaults to false. + """ + + report_type: VariableOrOptional[TikTokAdsOptionsTikTokReportType] = None + """ + (Optional) Report type for the TikTok Ads API. + If not specified, defaults to BASIC. + """ + + sync_start_date: VariableOrOptional[str] = None + """ + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 1 year of historical data for daily reports + and 30 days for hourly reports. + """ + + @classmethod + def from_dict(cls, value: "TikTokAdsOptionsDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "TikTokAdsOptionsDict": + return _transform_to_json_value(self) # type:ignore + + +class TikTokAdsOptionsDict(TypedDict, total=False): + """""" + + data_level: VariableOrOptional[TikTokAdsOptionsTikTokDataLevelParam] + """ + (Optional) Data level for the report. + If not specified, defaults to AUCTION_CAMPAIGN. + """ + + dimensions: VariableOrList[str] + """ + (Optional) Dimensions to include in the report. + Examples: "campaign_id", "adgroup_id", "ad_id", "stat_time_day", "stat_time_hour" + If not specified, defaults to campaign_id. + """ + + lookback_window_days: VariableOrOptional[int] + """ + (Optional) Number of days to look back for report tables during incremental sync + to capture late-arriving conversions and attribution data. + If not specified, defaults to 7 days. + """ + + metrics: VariableOrList[str] + """ + (Optional) Metrics to include in the report. + Examples: "spend", "impressions", "clicks", "conversion", "cpc" + If not specified, defaults to basic metrics (spend, impressions, clicks, etc.) + """ + + query_lifetime: VariableOrOptional[bool] + """ + (Optional) Whether to request lifetime metrics (all-time aggregated data). + When true, the report returns all-time data. + If not specified, defaults to false. + """ + + report_type: VariableOrOptional[TikTokAdsOptionsTikTokReportTypeParam] + """ + (Optional) Report type for the TikTok Ads API. + If not specified, defaults to BASIC. + """ + + sync_start_date: VariableOrOptional[str] + """ + (Optional) Start date for the initial sync of report tables in YYYY-MM-DD format. + This determines the earliest date from which to sync historical data. + If not specified, defaults to 1 year of historical data for daily reports + and 30 days for hourly reports. + """ + + +TikTokAdsOptionsParam = TikTokAdsOptionsDict | TikTokAdsOptions diff --git a/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_data_level.py b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_data_level.py new file mode 100644 index 00000000000..11f6159bcf8 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_data_level.py @@ -0,0 +1,21 @@ +from enum import Enum +from typing import Literal + + +class TikTokAdsOptionsTikTokDataLevel(Enum): + """ + :meta private: [EXPERIMENTAL] + + Data level for TikTok Ads report aggregation. + """ + + AUCTION_ADVERTISER = "AUCTION_ADVERTISER" + AUCTION_CAMPAIGN = "AUCTION_CAMPAIGN" + AUCTION_ADGROUP = "AUCTION_ADGROUP" + AUCTION_AD = "AUCTION_AD" + + +TikTokAdsOptionsTikTokDataLevelParam = ( + Literal["AUCTION_ADVERTISER", "AUCTION_CAMPAIGN", "AUCTION_ADGROUP", "AUCTION_AD"] + | TikTokAdsOptionsTikTokDataLevel +) diff --git a/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_report_type.py b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_report_type.py new file mode 100644 index 00000000000..272d36ff0c0 --- /dev/null +++ b/python/databricks/bundles/pipelines/_models/tik_tok_ads_options_tik_tok_report_type.py @@ -0,0 +1,23 @@ +from enum import Enum +from typing import Literal + + +class TikTokAdsOptionsTikTokReportType(Enum): + """ + :meta private: [EXPERIMENTAL] + + Report type for TikTok Ads API. + """ + + BASIC = "BASIC" + AUDIENCE = "AUDIENCE" + PLAYABLE_AD = "PLAYABLE_AD" + DSA = "DSA" + BUSINESS_CENTER = "BUSINESS_CENTER" + GMV_MAX = "GMV_MAX" + + +TikTokAdsOptionsTikTokReportTypeParam = ( + Literal["BASIC", "AUDIENCE", "PLAYABLE_AD", "DSA", "BUSINESS_CENTER", "GMV_MAX"] + | TikTokAdsOptionsTikTokReportType +) diff --git a/tools/post-generate.sh b/tools/post-generate.sh index cd3cbbe311b..4d65b70a35b 100755 --- a/tools/post-generate.sh +++ b/tools/post-generate.sh @@ -19,17 +19,21 @@ make generate-validation # Remove the next-changelog.yml workflow. rm .github/workflows/next-changelog.yml -# Move the tagging.py file to the internal/genkit/tagging.py file. We do this to avoid -# cluttering the root directory. +# Move the tagging.py file and its lock file to internal/genkit/. We do this to +# avoid cluttering the root directory. The lock file must stay next to tagging.py +# for `uv run --locked` to work in the tagging workflow. mv tagging.py internal/genkit/tagging.py +mv tagging.py.lock internal/genkit/tagging.py.lock # Update the tagging.yml workflow to use the new tagging.py file location. +# The genkit generates "uv run --locked tagging.py", we need to rewrite it +# to point at the moved location. if [[ "$(uname)" == "Darwin" ]]; then # macOS (BSD sed) requires empty string after -i - sed -i '' 's|python tagging.py|python internal/genkit/tagging.py|g' .github/workflows/tagging.yml + sed -i '' 's|tagging.py|internal/genkit/tagging.py|g' .github/workflows/tagging.yml else # Linux (GNU sed) - sed -i 's|python tagging.py|python internal/genkit/tagging.py|g' .github/workflows/tagging.yml + sed -i 's|tagging.py|internal/genkit/tagging.py|g' .github/workflows/tagging.yml fi go tool -modfile=tools/go.mod yamlfmt .github/workflows/tagging.yml