{
+ if (!this.sqlClient) {
+ try {
+ // Get the endpoint URL for the region
+ const endpoint = this.getSQLWorkbenchEndpoint(this.region)
+ this.logger.info(`Using SQL Workbench endpoint: ${endpoint}`)
+
+ if (this.connectionCredentialsProvider) {
+ // Create client with provided credentials
+ this.sqlClient = (await globals.sdkClientBuilder.createAwsService(
+ Service,
+ {
+ apiConfig: apiConfig,
+ region: this.region,
+ endpoint: endpoint,
+ credentialProvider: adaptConnectionCredentialsProvider(this.connectionCredentialsProvider),
+ } as ServiceConfigurationOptions,
+ undefined,
+ false
+ )) as SQLWorkbench
+ } else {
+ // Use the SDK client builder for default credentials
+ this.sqlClient = (await globals.sdkClientBuilder.createAwsService(
+ Service,
+ {
+ apiConfig: apiConfig,
+ region: this.region,
+ endpoint: endpoint,
+ } as ServiceConfigurationOptions,
+ undefined,
+ false
+ )) as SQLWorkbench
+ }
+
+ this.logger.debug('SQLWorkbenchClient: Successfully created SQL client')
+ } catch (err) {
+ this.logger.error('SQLWorkbenchClient: Failed to create SQL client: %s', err as Error)
+ throw err
+ }
+ }
+ return this.sqlClient
+ }
+}
diff --git a/packages/core/src/sagemakerunifiedstudio/shared/client/sqlworkbench.json b/packages/core/src/sagemakerunifiedstudio/shared/client/sqlworkbench.json
new file mode 100644
index 00000000000..e403ec34a88
--- /dev/null
+++ b/packages/core/src/sagemakerunifiedstudio/shared/client/sqlworkbench.json
@@ -0,0 +1,2102 @@
+{
+ "version": "2.0",
+ "metadata": {
+ "apiVersion": "2024-02-12",
+ "auth": ["aws.auth#sigv4"],
+ "endpointPrefix": "sqlworkbench",
+ "protocol": "rest-json",
+ "protocols": ["rest-json"],
+ "serviceFullName": "AmazonSQLWorkbench",
+ "serviceId": "SQLWorkbench",
+ "signatureVersion": "v4",
+ "signingName": "sqlworkbench",
+ "uid": "sqlworkbench-2024-02-12"
+ },
+ "operations": {
+ "CancelQueries": {
+ "name": "CancelQueries",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/cancelQueries",
+ "responseCode": 200
+ },
+ "input": { "shape": "CancelQueriesRequest" },
+ "output": { "shape": "CancelQueriesResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "CreateConnection": {
+ "name": "CreateConnection",
+ "http": {
+ "method": "PUT",
+ "requestUri": "/connections",
+ "responseCode": 200
+ },
+ "input": { "shape": "CreateConnectionRequest" },
+ "output": { "shape": "CreateConnectionResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "DeleteConnection": {
+ "name": "DeleteConnection",
+ "http": {
+ "method": "DELETE",
+ "requestUri": "/connections/{connectionId}",
+ "responseCode": 200
+ },
+ "input": { "shape": "DeleteConnectionRequest" },
+ "output": { "shape": "DeleteConnectionResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "ExecuteQuery": {
+ "name": "ExecuteQuery",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/executeQuery",
+ "responseCode": 200
+ },
+ "input": { "shape": "ExecuteQueryRequest" },
+ "output": { "shape": "ExecuteQueryResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "ExportQueryResults": {
+ "name": "ExportQueryResults",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/exportResults",
+ "responseCode": 200
+ },
+ "input": { "shape": "ExportQueryResultsRequest" },
+ "output": { "shape": "ExportQueryResultsResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetConnectableResources": {
+ "name": "GetConnectableResources",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/getConnectableResources",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetConnectableResourcesRequest" },
+ "output": { "shape": "GetConnectableResourcesResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetConnection": {
+ "name": "GetConnection",
+ "http": {
+ "method": "GET",
+ "requestUri": "/connections/{connectionId}",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetConnectionRequest" },
+ "output": { "shape": "GetConnectionResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetDatabaseConfigurations": {
+ "name": "GetDatabaseConfigurations",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/configurations",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetDatabaseConfigurationsRequest" },
+ "output": { "shape": "GetDatabaseConfigurationsResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetQueryExecutionHistory": {
+ "name": "GetQueryExecutionHistory",
+ "http": {
+ "method": "POST",
+ "requestUri": "/queryExecutionHistory/details",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetQueryExecutionHistoryRequest" },
+ "output": { "shape": "GetQueryExecutionHistoryResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetQueryResult": {
+ "name": "GetQueryResult",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/getQueryResults",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetQueryResultRequest" },
+ "output": { "shape": "GetQueryResultResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetResources": {
+ "name": "GetResources",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/getResources",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetResourcesRequest" },
+ "output": { "shape": "GetResourcesResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "GetTabStates": {
+ "name": "GetTabStates",
+ "http": {
+ "method": "POST",
+ "requestUri": "/tab/state",
+ "responseCode": 200
+ },
+ "input": { "shape": "GetTabStatesRequest" },
+ "output": { "shape": "GetTabStatesResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "ListQueryExecutionHistory": {
+ "name": "ListQueryExecutionHistory",
+ "http": {
+ "method": "POST",
+ "requestUri": "/queryExecutionHistory/list",
+ "responseCode": 200
+ },
+ "input": { "shape": "ListQueryExecutionHistoryRequest" },
+ "output": { "shape": "ListQueryExecutionHistoryResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "ListTagsForResource": {
+ "name": "ListTagsForResource",
+ "http": {
+ "method": "GET",
+ "requestUri": "/tags/{resourceArn}",
+ "responseCode": 200
+ },
+ "input": { "shape": "ListTagsForResourceRequest" },
+ "output": { "shape": "ListTagsForResourceResponse" },
+ "errors": [
+ { "shape": "BadRequestError" },
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "PollQueryExecutionEvents": {
+ "name": "PollQueryExecutionEvents",
+ "http": {
+ "method": "POST",
+ "requestUri": "/database/pollQueryExecutionEvents",
+ "responseCode": 200
+ },
+ "input": { "shape": "PollQueryExecutionEventsRequest" },
+ "output": { "shape": "PollQueryExecutionEventsResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "BadRequestError" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "TagResource": {
+ "name": "TagResource",
+ "http": {
+ "method": "POST",
+ "requestUri": "/tags/{resourceArn}",
+ "responseCode": 204
+ },
+ "input": { "shape": "TagResourceRequest" },
+ "output": { "shape": "TagResourceResponse" },
+ "errors": [
+ { "shape": "BadRequestError" },
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "UntagResource": {
+ "name": "UntagResource",
+ "http": {
+ "method": "DELETE",
+ "requestUri": "/tags/{resourceArn}",
+ "responseCode": 204
+ },
+ "input": { "shape": "UntagResourceRequest" },
+ "output": { "shape": "UntagResourceResponse" },
+ "errors": [
+ { "shape": "BadRequestError" },
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ],
+ "idempotent": true
+ },
+ "UpdateConnection": {
+ "name": "UpdateConnection",
+ "http": {
+ "method": "POST",
+ "requestUri": "/connections",
+ "responseCode": 200
+ },
+ "input": { "shape": "UpdateConnectionRequest" },
+ "output": { "shape": "UpdateConnectionResponse" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "ConflictException" },
+ { "shape": "InternalServerError" },
+ { "shape": "ValidationException" }
+ ]
+ },
+ "VerifyResourcesExistForTagris": {
+ "name": "VerifyResourcesExistForTagris",
+ "http": {
+ "method": "POST",
+ "requestUri": "/verifyResourcesExistForTagris",
+ "responseCode": 200
+ },
+ "input": { "shape": "TagrisVerifyResourcesExistInput" },
+ "output": { "shape": "TagrisVerifyResourcesExistOutput" },
+ "errors": [
+ { "shape": "ThrottlingException" },
+ { "shape": "InternalServerError" },
+ { "shape": "TagrisInvalidParameterException" },
+ { "shape": "TagrisAccessDeniedException" },
+ { "shape": "TagrisInvalidArnException" },
+ { "shape": "ResourceNotFoundException" },
+ { "shape": "TagrisInternalServiceException" },
+ { "shape": "ServiceQuotaExceededException" },
+ { "shape": "AccessDeniedException" },
+ { "shape": "TagrisPartialResourcesExistResultsException" },
+ { "shape": "TagrisThrottledException" },
+ { "shape": "ConflictException" },
+ { "shape": "ValidationException" }
+ ]
+ }
+ },
+ "shapes": {
+ "AccessDeniedException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 403,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "AckIds": {
+ "type": "list",
+ "member": { "shape": "AckIdsMemberString" }
+ },
+ "AckIdsMemberString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "Arn": {
+ "type": "string",
+ "max": 1011,
+ "min": 20
+ },
+ "AvailableConnectionConfigurationOptions": {
+ "type": "list",
+ "member": { "shape": "AvailableConnectionConfigurationOptionsMemberString" }
+ },
+ "AvailableConnectionConfigurationOptionsMemberString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "BadRequestError": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 400,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "Boolean": {
+ "type": "boolean",
+ "box": true
+ },
+ "CancelQueriesRequest": {
+ "type": "structure",
+ "required": ["queryExecutionIds", "databaseType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "queryExecutionIds": { "shape": "CancelQueriesRequestQueryExecutionIdsList" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ }
+ }
+ },
+ "CancelQueriesRequestQueryExecutionIdsList": {
+ "type": "list",
+ "member": { "shape": "CancelQueriesRequestQueryExecutionIdsListMemberString" },
+ "max": 100,
+ "min": 1
+ },
+ "CancelQueriesRequestQueryExecutionIdsListMemberString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "CancelQueriesResponse": {
+ "type": "structure",
+ "required": ["cancelQueryResponses"],
+ "members": {
+ "cancelQueryResponses": { "shape": "CancelQueryResponses" }
+ }
+ },
+ "CancelQueryResponse": {
+ "type": "structure",
+ "required": ["queryExecutionId"],
+ "members": {
+ "queryExecutionId": { "shape": "CancelQueryResponseQueryExecutionIdString" },
+ "queryCancellationStatus": { "shape": "QueryCancellationStatus" }
+ }
+ },
+ "CancelQueryResponseQueryExecutionIdString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CancelQueryResponses": {
+ "type": "list",
+ "member": { "shape": "CancelQueryResponse" }
+ },
+ "ChildObjectTypes": {
+ "type": "list",
+ "member": { "shape": "ChildObjectTypesMemberString" }
+ },
+ "ChildObjectTypesMemberString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "Columns": {
+ "type": "list",
+ "member": { "shape": "QueryResultCellValue" }
+ },
+ "ConflictException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 409,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "ConnectableResource": {
+ "type": "structure",
+ "required": ["displayName", "identifier", "childObjectTypes", "availableConnectionConfigurationOptions"],
+ "members": {
+ "displayName": { "shape": "ResourceDisplayName" },
+ "identifier": { "shape": "ResourceIdentifier" },
+ "type": { "shape": "ConnectableResourceTypeString" },
+ "unavailable": { "shape": "Boolean" },
+ "tooltipTranslationKey": { "shape": "ConnectableResourceTooltipTranslationKeyString" },
+ "childObjectTypes": { "shape": "ChildObjectTypes" },
+ "availableConnectionConfigurationOptions": { "shape": "AvailableConnectionConfigurationOptions" }
+ }
+ },
+ "ConnectableResourceTooltipTranslationKeyString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "ConnectableResourceTypeString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "ConnectableResourceTypes": {
+ "type": "list",
+ "member": { "shape": "ConnectableResourceTypesMemberString" }
+ },
+ "ConnectableResourceTypesMemberString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "ConnectableResources": {
+ "type": "list",
+ "member": { "shape": "ConnectableResource" }
+ },
+ "Connection": {
+ "type": "structure",
+ "members": {
+ "id": {
+ "shape": "String",
+ "documentation": "Id of the connection
"
+ },
+ "name": {
+ "shape": "ConnectionName",
+ "documentation": "Name of the connection
"
+ },
+ "authenticationType": {
+ "shape": "ConnectionAuthenticationTypes",
+ "documentation": "Number representing the type of authentication to use (2 = IAM, 3 = Username and Password). Today we only support the types 2 and 3
"
+ },
+ "secretArn": {
+ "shape": "String",
+ "documentation": "Secret that is linked to this connection
"
+ },
+ "databaseName": {
+ "shape": "DatabaseName",
+ "documentation": "Name of the database where the query is run
"
+ },
+ "clusterId": {
+ "shape": "String",
+ "documentation": "Id of the cluster of the connection
"
+ },
+ "dbUser": {
+ "shape": "DbUser",
+ "documentation": "User of the database
"
+ },
+ "isServerless": { "shape": "Boolean" },
+ "isProd": { "shape": "String" },
+ "isEnabled": { "shape": "String" },
+ "userSettings": { "shape": "UserSettings" },
+ "recordDate": { "shape": "String" },
+ "updatedDate": { "shape": "String" },
+ "tags": { "shape": "Tags" },
+ "databaseType": { "shape": "DatabaseType" },
+ "connectableResourceType": { "shape": "String" },
+ "connectableResourceIdentifier": { "shape": "ResourceIdentifier" }
+ }
+ },
+ "ConnectionAuthenticationTypes": {
+ "type": "string",
+ "enum": ["2", "3", "4", "5", "6", "7", "8"],
+ "sensitive": true
+ },
+ "ConnectionName": {
+ "type": "string",
+ "sensitive": true
+ },
+ "ConnectionProperties": {
+ "type": "map",
+ "key": { "shape": "ConnectionPropertyKey" },
+ "value": { "shape": "ConnectionPropertyValue" },
+ "max": 50,
+ "min": 1
+ },
+ "ConnectionPropertyKey": {
+ "type": "string",
+ "max": 1000,
+ "min": 1
+ },
+ "ConnectionPropertyValue": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionRequest": {
+ "type": "structure",
+ "required": ["name", "databaseName", "authenticationType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "name": {
+ "shape": "CreateConnectionRequestNameString",
+ "documentation": "Name of the connection
"
+ },
+ "databaseName": {
+ "shape": "CreateConnectionRequestDatabaseNameString",
+ "documentation": "Name of the database used for this connection
"
+ },
+ "authenticationType": {
+ "shape": "CreateConnectionRequestAuthenticationTypeEnum",
+ "documentation": "Number representing the type of authentication to use (2 = IAM, 3 = Username and Password, 4 = Federated connection)
"
+ },
+ "isProd": { "shape": "CreateConnectionRequestIsProdString" },
+ "userSettings": { "shape": "UserSettings" },
+ "secretArn": {
+ "shape": "CreateConnectionRequestSecretArnString",
+ "documentation": "secretArn for redshift cluster
"
+ },
+ "clusterId": {
+ "shape": "CreateConnectionRequestClusterIdString",
+ "documentation": "Id of the cluster used for this connection
"
+ },
+ "isServerless": {
+ "shape": "Boolean",
+ "documentation": "Is serverless connection
"
+ },
+ "dbUser": {
+ "shape": "DbUser",
+ "documentation": "User of the database used for this connection
"
+ },
+ "isStoreNewSecret": { "shape": "CreateConnectionRequestIsStoreNewSecretString" },
+ "username": {
+ "shape": "DbUser",
+ "documentation": "Username used in the Username_Password connection type
"
+ },
+ "password": {
+ "shape": "CreateConnectionRequestPasswordString",
+ "documentation": "Password of the user used for this connection
"
+ },
+ "tags": { "shape": "Tags" },
+ "host": {
+ "shape": "CreateConnectionRequestHostString",
+ "documentation": "Host address used for creating secret for Username_Password connection type
"
+ },
+ "secretName": { "shape": "CreateConnectionRequestSecretNameString" },
+ "description": { "shape": "CreateConnectionRequestDescriptionString" },
+ "databaseType": { "shape": "DatabaseType" },
+ "connectableResourceIdentifier": {
+ "shape": "CreateConnectionRequestConnectableResourceIdentifierString",
+ "documentation": "Id of the connectable resource used for this connection
"
+ },
+ "connectableResourceType": {
+ "shape": "CreateConnectionRequestConnectableResourceTypeString",
+ "documentation": "Type of the connectable resource used for this connection
"
+ }
+ }
+ },
+ "CreateConnectionRequestAuthenticationTypeEnum": {
+ "type": "string",
+ "enum": ["2", "3", "4", "5", "6", "7", "8"],
+ "max": 1,
+ "min": 1,
+ "sensitive": true
+ },
+ "CreateConnectionRequestClusterIdString": {
+ "type": "string",
+ "max": 63,
+ "min": 1
+ },
+ "CreateConnectionRequestConnectableResourceIdentifierString": {
+ "type": "string",
+ "max": 63,
+ "min": 1,
+ "sensitive": true
+ },
+ "CreateConnectionRequestConnectableResourceTypeString": {
+ "type": "string",
+ "max": 63,
+ "min": 1
+ },
+ "CreateConnectionRequestDatabaseNameString": {
+ "type": "string",
+ "max": 64,
+ "min": 1,
+ "sensitive": true
+ },
+ "CreateConnectionRequestDescriptionString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionRequestHostString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionRequestIsProdString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionRequestIsStoreNewSecretString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionRequestNameString": {
+ "type": "string",
+ "max": 512,
+ "min": 1,
+ "sensitive": true
+ },
+ "CreateConnectionRequestPasswordString": {
+ "type": "string",
+ "max": 64,
+ "min": 8,
+ "sensitive": true
+ },
+ "CreateConnectionRequestSecretArnString": {
+ "type": "string",
+ "max": 1000,
+ "min": 1
+ },
+ "CreateConnectionRequestSecretNameString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "CreateConnectionResponse": {
+ "type": "structure",
+ "members": {
+ "data": { "shape": "Connection" }
+ }
+ },
+ "DatabaseAuthenticationMethod": {
+ "type": "string",
+ "enum": ["USERNAME_PASSWORD", "TEMPORARY_CREDENTIALS_WITH_IAM"]
+ },
+ "DatabaseAuthenticationMethods": {
+ "type": "list",
+ "member": { "shape": "DatabaseAuthenticationMethod" }
+ },
+ "DatabaseAuthenticationOption": {
+ "type": "structure",
+ "required": ["connectableResourceType", "authenticationMethods"],
+ "members": {
+ "connectableResourceType": { "shape": "String" },
+ "authenticationMethods": { "shape": "DatabaseAuthenticationMethods" }
+ }
+ },
+ "DatabaseAuthenticationOptions": {
+ "type": "list",
+ "member": { "shape": "DatabaseAuthenticationOption" }
+ },
+ "DatabaseConfiguration": {
+ "type": "structure",
+ "required": [
+ "databaseType",
+ "authenticationOptions",
+ "connectableResourceTypes",
+ "sessionSupported",
+ "eventAcknowledgementSupported",
+ "appendingLimitToQuerySupported",
+ "queryStatsSupported"
+ ],
+ "members": {
+ "databaseType": { "shape": "DatabaseType" },
+ "authenticationOptions": { "shape": "DatabaseAuthenticationOptions" },
+ "connectableResourceTypes": { "shape": "ConnectableResourceTypes" },
+ "sessionSupported": { "shape": "Boolean" },
+ "eventAcknowledgementSupported": { "shape": "Boolean" },
+ "appendingLimitToQuerySupported": { "shape": "Boolean" },
+ "queryStatsSupported": { "shape": "Boolean" }
+ }
+ },
+ "DatabaseConfigurations": {
+ "type": "list",
+ "member": { "shape": "DatabaseConfiguration" }
+ },
+ "DatabaseConnectionAccountSettings": {
+ "type": "structure",
+ "members": {
+ "masterKeyArn": { "shape": "KmsKeyArn" }
+ }
+ },
+ "DatabaseConnectionConfiguration": {
+ "type": "structure",
+ "required": ["id", "type", "databaseType", "connectableResourceIdentifier", "connectableResourceType"],
+ "members": {
+ "id": { "shape": "DatabaseConnectionConfigurationIdString" },
+ "type": { "shape": "DatabaseIntegrationConnectionAuthenticationTypes" },
+ "auth": { "shape": "DatabaseConnectionConfigurationAuth" },
+ "databaseType": { "shape": "DatabaseType" },
+ "connectableResourceIdentifier": { "shape": "ResourceIdentifier" },
+ "connectableResourceType": { "shape": "DatabaseConnectionConfigurationConnectableResourceTypeString" },
+ "database": { "shape": "DatabaseName" }
+ }
+ },
+ "DatabaseConnectionConfigurationAuth": {
+ "type": "structure",
+ "members": {
+ "secretArn": { "shape": "SecretKeyArn" },
+ "username": { "shape": "DatabaseConnectionConfigurationAuthUsernameString" },
+ "password": { "shape": "DatabaseConnectionConfigurationAuthPasswordString" }
+ }
+ },
+ "DatabaseConnectionConfigurationAuthPasswordString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "sensitive": true
+ },
+ "DatabaseConnectionConfigurationAuthUsernameString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "sensitive": true
+ },
+ "DatabaseConnectionConfigurationConnectableResourceTypeString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "DatabaseConnectionConfigurationIdString": {
+ "type": "string",
+ "max": 2048,
+ "min": 32
+ },
+ "DatabaseIntegrationConnectionAuthenticationTypes": {
+ "type": "string",
+ "enum": ["4", "5", "6", "8"],
+ "sensitive": true
+ },
+ "DatabaseName": {
+ "type": "string",
+ "max": 150,
+ "min": 0,
+ "sensitive": true
+ },
+ "DatabaseType": {
+ "type": "string",
+ "enum": ["REDSHIFT", "ATHENA"]
+ },
+ "DbUser": {
+ "type": "string",
+ "max": 127,
+ "min": 1,
+ "pattern": "[a-zA-Z0-9_][a-zA-Z_0-9+.@$-]*",
+ "sensitive": true
+ },
+ "DeleteConnectionRequest": {
+ "type": "structure",
+ "required": ["connectionId"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "connectionId": {
+ "shape": "DeleteConnectionRequestConnectionIdString",
+ "documentation": "Id of connection to delete
",
+ "location": "uri",
+ "locationName": "connectionId"
+ }
+ }
+ },
+ "DeleteConnectionRequestConnectionIdString": {
+ "type": "string",
+ "max": 1000,
+ "min": 1
+ },
+ "DeleteConnectionResponse": {
+ "type": "structure",
+ "members": {}
+ },
+ "ErrorCode": {
+ "type": "string",
+ "enum": ["QUERY_EXECUTION_NOT_FOUND", "QUERY_EXECUTION_ACCESS_DENIED"]
+ },
+ "ExecuteQueryRequest": {
+ "type": "structure",
+ "required": ["query", "queryExecutionType", "queryResponseDeliveryType", "maxItems"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "connectionId": { "shape": "ExecuteQueryRequestConnectionIdString" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ },
+ "connection": { "shape": "DatabaseConnectionConfiguration" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "tabId": { "shape": "ExecuteQueryRequestTabIdString" },
+ "executionContext": { "shape": "ExecuteQueryRequestExecutionContextList" },
+ "query": { "shape": "ExecuteQueryRequestQueryString" },
+ "queryExecutionType": { "shape": "QueryExecutionType" },
+ "sessionId": { "shape": "ExecuteQueryRequestSessionIdString" },
+ "queryResponseDeliveryType": { "shape": "QueryResponseDeliveryType" },
+ "maxItems": { "shape": "ExecuteQueryRequestMaxItemsInteger" },
+ "limitQueryResults": { "shape": "ExecuteQueryRequestLimitQueryResultsInteger" },
+ "isExplain": { "shape": "Boolean" },
+ "ignoreHistory": { "shape": "Boolean" },
+ "timeoutMillis": { "shape": "ExecuteQueryRequestTimeoutMillisInteger" }
+ }
+ },
+ "ExecuteQueryRequestConnectionIdString": {
+ "type": "string",
+ "max": 2048,
+ "min": 32
+ },
+ "ExecuteQueryRequestExecutionContextList": {
+ "type": "list",
+ "member": { "shape": "ParentResource" },
+ "max": 100,
+ "min": 0
+ },
+ "ExecuteQueryRequestLimitQueryResultsInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 1000,
+ "min": 0
+ },
+ "ExecuteQueryRequestMaxItemsInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 100,
+ "min": 20
+ },
+ "ExecuteQueryRequestQueryString": {
+ "type": "string",
+ "max": 1000000,
+ "min": 0,
+ "sensitive": true
+ },
+ "ExecuteQueryRequestSessionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "ExecuteQueryRequestTabIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "ExecuteQueryRequestTimeoutMillisInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 120000,
+ "min": 0
+ },
+ "ExecuteQueryResponse": {
+ "type": "structure",
+ "required": ["queryExecutions"],
+ "members": {
+ "sessionId": { "shape": "ExecuteQueryResponseSessionIdString" },
+ "queryExecutions": { "shape": "QueryExecutions" },
+ "statusCode": {
+ "shape": "statusCode",
+ "location": "statusCode"
+ }
+ }
+ },
+ "ExecuteQueryResponseSessionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "ExportQueryResultsRequest": {
+ "type": "structure",
+ "required": ["queryExecutionId", "databaseType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "queryExecutionId": { "shape": "ExportQueryResultsRequestQueryExecutionIdString" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ },
+ "fileType": { "shape": "FileType" }
+ }
+ },
+ "ExportQueryResultsRequestQueryExecutionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "ExportQueryResultsResponse": {
+ "type": "structure",
+ "required": ["queryResult", "contentType", "fileName"],
+ "members": {
+ "queryResult": { "shape": "StreamingBlob" },
+ "contentType": {
+ "shape": "String",
+ "location": "header",
+ "locationName": "Content-Type"
+ },
+ "fileName": {
+ "shape": "String",
+ "location": "header",
+ "locationName": "Content-Disposition"
+ }
+ },
+ "payload": "queryResult"
+ },
+ "FileType": {
+ "type": "string",
+ "enum": ["JSON", "CSV"]
+ },
+ "FullQueryText": {
+ "type": "string",
+ "max": 1000000,
+ "min": 0,
+ "sensitive": true
+ },
+ "GetConnectableResourcesRequest": {
+ "type": "structure",
+ "required": ["type", "maxItems", "databaseType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "type": { "shape": "GetConnectableResourcesRequestTypeString" },
+ "maxItems": { "shape": "GetConnectableResourcesRequestMaxItemsInteger" },
+ "pageToken": { "shape": "PageToken" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ }
+ }
+ },
+ "GetConnectableResourcesRequestMaxItemsInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 50,
+ "min": 20
+ },
+ "GetConnectableResourcesRequestTypeString": {
+ "type": "string",
+ "max": 150,
+ "min": 0
+ },
+ "GetConnectableResourcesResponse": {
+ "type": "structure",
+ "required": ["connectableResources"],
+ "members": {
+ "connectableResources": { "shape": "ConnectableResources" },
+ "nextToken": { "shape": "String" }
+ }
+ },
+ "GetConnectionRequest": {
+ "type": "structure",
+ "required": ["connectionId"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "connectionId": {
+ "shape": "GetConnectionRequestConnectionIdString",
+ "documentation": "Id of connection to delete
",
+ "location": "uri",
+ "locationName": "connectionId"
+ }
+ }
+ },
+ "GetConnectionRequestConnectionIdString": {
+ "type": "string",
+ "max": 1000,
+ "min": 1
+ },
+ "GetConnectionResponse": {
+ "type": "structure",
+ "members": {
+ "data": { "shape": "Connection" }
+ }
+ },
+ "GetDatabaseConfigurationsRequest": {
+ "type": "structure",
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" }
+ }
+ },
+ "GetDatabaseConfigurationsResponse": {
+ "type": "structure",
+ "members": {
+ "configurations": { "shape": "DatabaseConfigurations" }
+ }
+ },
+ "GetQueryExecutionHistoryRequest": {
+ "type": "structure",
+ "required": ["queryExecutionId"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "queryExecutionId": { "shape": "GetQueryExecutionHistoryRequestQueryExecutionIdString" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" }
+ }
+ },
+ "GetQueryExecutionHistoryRequestQueryExecutionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "GetQueryExecutionHistoryResponse": {
+ "type": "structure",
+ "members": {
+ "id": { "shape": "String" },
+ "querySourceId": { "shape": "String" },
+ "queryStartTime": { "shape": "Long" },
+ "queryEndTime": { "shape": "Long" },
+ "status": { "shape": "QueryExecutionStatus" },
+ "queryText": { "shape": "FullQueryText" },
+ "serializedMetadata": { "shape": "SerializedMetadata" },
+ "serializedQueryStats": { "shape": "SerializedQueryStats" },
+ "databaseType": { "shape": "DatabaseType" }
+ }
+ },
+ "GetQueryResultRequest": {
+ "type": "structure",
+ "required": ["queryExecutionId", "databaseType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "queryExecutionId": { "shape": "GetQueryResultRequestQueryExecutionIdString" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "pageToken": { "shape": "PageToken" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ },
+ "pageSize": { "shape": "GetQueryResultRequestPageSizeInteger" }
+ }
+ },
+ "GetQueryResultRequestPageSizeInteger": {
+ "type": "integer",
+ "box": true,
+ "min": 0
+ },
+ "GetQueryResultRequestQueryExecutionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "GetQueryResultResponse": {
+ "type": "structure",
+ "members": {
+ "queryResult": { "shape": "QueryResult" },
+ "nextToken": { "shape": "String" },
+ "previousToken": { "shape": "String" }
+ }
+ },
+ "GetResourcesRequest": {
+ "type": "structure",
+ "required": ["parents", "type", "maxItems"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "connectionId": { "shape": "GetResourcesRequestConnectionIdString" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ },
+ "connection": { "shape": "DatabaseConnectionConfiguration" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "parents": { "shape": "ParentResources" },
+ "type": { "shape": "GetResourcesRequestTypeString" },
+ "maxItems": { "shape": "GetResourcesRequestMaxItemsInteger" },
+ "pageToken": { "shape": "PageToken" },
+ "forceRefresh": { "shape": "Boolean" },
+ "forceRefreshRecursive": { "shape": "Boolean" }
+ }
+ },
+ "GetResourcesRequestConnectionIdString": {
+ "type": "string",
+ "max": 2048,
+ "min": 32
+ },
+ "GetResourcesRequestMaxItemsInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 100,
+ "min": 20
+ },
+ "GetResourcesRequestTypeString": {
+ "type": "string",
+ "max": 150,
+ "min": 0
+ },
+ "GetResourcesResponse": {
+ "type": "structure",
+ "members": {
+ "resources": { "shape": "Resources" },
+ "nextToken": { "shape": "String" },
+ "statusCode": {
+ "shape": "statusCode",
+ "location": "statusCode"
+ },
+ "connectionProperties": { "shape": "ConnectionProperties" }
+ }
+ },
+ "GetTabStatesRequest": {
+ "type": "structure",
+ "required": ["tabId"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "tabId": { "shape": "String" }
+ }
+ },
+ "GetTabStatesResponse": {
+ "type": "structure",
+ "required": ["queryExecutionStates"],
+ "members": {
+ "queryExecutionStates": { "shape": "QueryExecutionStates" },
+ "sessionId": { "shape": "String" }
+ }
+ },
+ "Integer": {
+ "type": "integer",
+ "box": true
+ },
+ "InternalServerError": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": { "httpStatusCode": 500 },
+ "exception": true,
+ "fault": true
+ },
+ "KmsKeyArn": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "pattern": "arn:.*"
+ },
+ "ListQueryExecutionHistoryRequest": {
+ "type": "structure",
+ "required": ["maxItems"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "maxItems": { "shape": "ListQueryExecutionHistoryRequestMaxItemsInteger" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "pageToken": { "shape": "ListQueryExecutionHistoryRequestPageTokenString" },
+ "querySourceId": { "shape": "ListQueryExecutionHistoryRequestQuerySourceIdString" },
+ "databaseType": { "shape": "DatabaseType" },
+ "status": { "shape": "QueryExecutionStatus" },
+ "startTime": { "shape": "QueryHistoryTimestamp" },
+ "endTime": { "shape": "QueryHistoryTimestamp" },
+ "containsText": { "shape": "ListQueryExecutionHistoryRequestContainsTextString" }
+ }
+ },
+ "ListQueryExecutionHistoryRequestContainsTextString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "ListQueryExecutionHistoryRequestMaxItemsInteger": {
+ "type": "integer",
+ "box": true,
+ "max": 100,
+ "min": 1
+ },
+ "ListQueryExecutionHistoryRequestPageTokenString": {
+ "type": "string",
+ "max": 10000,
+ "min": 0
+ },
+ "ListQueryExecutionHistoryRequestQuerySourceIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "ListQueryExecutionHistoryResponse": {
+ "type": "structure",
+ "required": ["items"],
+ "members": {
+ "items": { "shape": "QueryExecutionHistoryPreviews" },
+ "nextToken": { "shape": "ListQueryExecutionHistoryResponseNextTokenString" }
+ }
+ },
+ "ListQueryExecutionHistoryResponseNextTokenString": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "ListTagsForResourceRequest": {
+ "type": "structure",
+ "required": ["resourceArn"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "resourceArn": {
+ "shape": "Arn",
+ "location": "uri",
+ "locationName": "resourceArn"
+ }
+ }
+ },
+ "ListTagsForResourceResponse": {
+ "type": "structure",
+ "required": ["tags"],
+ "members": {
+ "tags": { "shape": "Tags" }
+ }
+ },
+ "Long": {
+ "type": "long",
+ "box": true
+ },
+ "PageToken": {
+ "type": "string",
+ "max": 1000,
+ "min": 0
+ },
+ "ParentResource": {
+ "type": "structure",
+ "required": ["parentId", "parentType"],
+ "members": {
+ "parentId": { "shape": "ParentResourceParentIdString" },
+ "parentType": { "shape": "ParentResourceParentTypeString" }
+ }
+ },
+ "ParentResourceParentIdString": {
+ "type": "string",
+ "max": 1000,
+ "min": 1,
+ "sensitive": true
+ },
+ "ParentResourceParentTypeString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "ParentResources": {
+ "type": "list",
+ "member": { "shape": "ParentResource" }
+ },
+ "PollQueryExecutionEventsRequest": {
+ "type": "structure",
+ "required": ["queryExecutionIds", "databaseType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "queryExecutionIds": { "shape": "PollQueryExecutionEventsRequestQueryExecutionIdsList" },
+ "accountSettings": { "shape": "DatabaseConnectionAccountSettings" },
+ "databaseType": {
+ "shape": "DatabaseType",
+ "location": "querystring",
+ "locationName": "databaseType"
+ },
+ "ackIds": { "shape": "AckIds" }
+ }
+ },
+ "PollQueryExecutionEventsRequestQueryExecutionIdsList": {
+ "type": "list",
+ "member": { "shape": "PollQueryExecutionEventsRequestQueryExecutionIdsListMemberString" },
+ "max": 100,
+ "min": 1
+ },
+ "PollQueryExecutionEventsRequestQueryExecutionIdsListMemberString": {
+ "type": "string",
+ "max": 100,
+ "min": 1
+ },
+ "PollQueryExecutionEventsResponse": {
+ "type": "structure",
+ "members": {
+ "events": { "shape": "QueryExecutionEvents" }
+ }
+ },
+ "QueryCancellationStatus": {
+ "type": "string",
+ "enum": ["CANCELLED", "DOES_NOT_EXISTS", "ALREADY_FINISHED", "CANCELLATION_FAILED"]
+ },
+ "QueryExecution": {
+ "type": "structure",
+ "required": ["queryExecutionId"],
+ "members": {
+ "queryExecutionStatus": { "shape": "QueryExecutionStatus" },
+ "queryExecutionId": { "shape": "QueryExecutionQueryExecutionIdString" },
+ "queryResult": { "shape": "QueryResult" },
+ "queryText": { "shape": "QueryText" }
+ }
+ },
+ "QueryExecutionEvent": {
+ "type": "structure",
+ "required": ["queryExecutionEventType", "queryExecutionId"],
+ "members": {
+ "queryExecutionEventType": { "shape": "QueryExecutionEventType" },
+ "queryExecutionId": { "shape": "QueryExecutionEventQueryExecutionIdString" },
+ "queryExecutionStatus": { "shape": "QueryExecutionStatus" },
+ "queryResult": { "shape": "QueryResult" },
+ "nextToken": { "shape": "String" },
+ "ackId": { "shape": "String" }
+ }
+ },
+ "QueryExecutionEventQueryExecutionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "QueryExecutionEventType": {
+ "type": "string",
+ "enum": ["QUERY_EXECUTION_STATUS", "QUERY_EXECUTION_RESULT"]
+ },
+ "QueryExecutionEvents": {
+ "type": "list",
+ "member": { "shape": "QueryExecutionEvent" }
+ },
+ "QueryExecutionHistoryPreview": {
+ "type": "structure",
+ "members": {
+ "id": { "shape": "String" },
+ "querySourceId": { "shape": "String" },
+ "queryStartTime": { "shape": "Long" },
+ "queryEndTime": { "shape": "Long" },
+ "status": { "shape": "QueryExecutionStatus" },
+ "queryTextPreview": { "shape": "QueryTextPreview" },
+ "serializedMetadata": { "shape": "SerializedMetadata" },
+ "databaseType": { "shape": "DatabaseType" }
+ }
+ },
+ "QueryExecutionHistoryPreviews": {
+ "type": "list",
+ "member": { "shape": "QueryExecutionHistoryPreview" }
+ },
+ "QueryExecutionQueryExecutionIdString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "QueryExecutionState": {
+ "type": "structure",
+ "required": ["queryExecutionId", "status", "databaseType"],
+ "members": {
+ "queryExecutionId": { "shape": "String" },
+ "status": { "shape": "String" },
+ "databaseType": { "shape": "DatabaseType" }
+ }
+ },
+ "QueryExecutionStates": {
+ "type": "list",
+ "member": { "shape": "QueryExecutionState" }
+ },
+ "QueryExecutionStatus": {
+ "type": "string",
+ "enum": ["SCHEDULED", "RUNNING", "FAILED", "CANCELLED", "FINISHED"]
+ },
+ "QueryExecutionType": {
+ "type": "string",
+ "enum": ["PERSIST_SESSION", "NO_SESSION"]
+ },
+ "QueryExecutionWarning": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "QueryExecutionWarningMessage" },
+ "level": { "shape": "QueryExecutionWarningLevel" }
+ }
+ },
+ "QueryExecutionWarningLevel": {
+ "type": "string",
+ "enum": ["INFO", "WARNING"]
+ },
+ "QueryExecutionWarningMessage": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "sensitive": true
+ },
+ "QueryExecutionWarnings": {
+ "type": "list",
+ "member": { "shape": "QueryExecutionWarning" }
+ },
+ "QueryExecutions": {
+ "type": "list",
+ "member": { "shape": "QueryExecution" }
+ },
+ "QueryHistoryTimestamp": {
+ "type": "long",
+ "box": true
+ },
+ "QueryResponseDeliveryType": {
+ "type": "string",
+ "enum": ["SYNC", "ASYNC"]
+ },
+ "QueryResult": {
+ "type": "structure",
+ "members": {
+ "queryExecutionStatus": { "shape": "QueryExecutionStatus" },
+ "headers": { "shape": "QueryResultHeaders" },
+ "rows": { "shape": "Rows" },
+ "affectedRows": { "shape": "Integer" },
+ "totalRowCount": { "shape": "Integer" },
+ "elapsedTime": { "shape": "Long" },
+ "errorMessage": { "shape": "QueryResultErrorMessage" },
+ "errorPosition": { "shape": "Integer" },
+ "queryResultWarningCode": { "shape": "QueryResultQueryResultWarningCodeString" },
+ "warnings": { "shape": "QueryExecutionWarnings" },
+ "queryExecutionId": { "shape": "String" },
+ "sessionId": { "shape": "String" },
+ "queryText": { "shape": "QueryText" },
+ "statementType": { "shape": "StatementType" },
+ "serializedMetadata": { "shape": "SerializedMetadata" },
+ "connectionProperties": { "shape": "ConnectionProperties" }
+ }
+ },
+ "QueryResultCellType": {
+ "type": "string",
+ "enum": ["STRING", "BOOLEAN", "INTEGER", "BIG_INTEGER", "FLOAT", "BIG_DECIMAL", "DATE", "TIME", "DATETIME"]
+ },
+ "QueryResultCellValue": {
+ "type": "string",
+ "sensitive": true
+ },
+ "QueryResultErrorMessage": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "sensitive": true
+ },
+ "QueryResultHeader": {
+ "type": "structure",
+ "required": ["displayName", "type"],
+ "members": {
+ "displayName": { "shape": "QueryResultHeaderDisplayName" },
+ "type": { "shape": "QueryResultCellType" }
+ }
+ },
+ "QueryResultHeaderDisplayName": {
+ "type": "string",
+ "sensitive": true
+ },
+ "QueryResultHeaders": {
+ "type": "list",
+ "member": { "shape": "QueryResultHeader" }
+ },
+ "QueryResultQueryResultWarningCodeString": {
+ "type": "string",
+ "max": 100,
+ "min": 0
+ },
+ "QueryText": {
+ "type": "string",
+ "sensitive": true
+ },
+ "QueryTextPreview": {
+ "type": "string",
+ "max": 150,
+ "min": 0,
+ "sensitive": true
+ },
+ "Resource": {
+ "type": "structure",
+ "required": ["displayName", "identifier", "childObjectTypes"],
+ "members": {
+ "displayName": { "shape": "ResourceDisplayName" },
+ "identifier": { "shape": "ResourceIdentifier" },
+ "type": { "shape": "ResourceTypeString" },
+ "unavailable": { "shape": "Boolean" },
+ "tooltipTranslationKey": { "shape": "ResourceTooltipTranslationKeyString" },
+ "childObjectTypes": { "shape": "ChildObjectTypes" },
+ "allowedActions": { "shape": "ResourceActions" },
+ "resourceMetadata": { "shape": "ResourceMetadataItems" }
+ }
+ },
+ "ResourceAction": {
+ "type": "string",
+ "enum": ["Drop", "Truncate", "GenerateDefinition", "GenerateSelectQuery"]
+ },
+ "ResourceActions": {
+ "type": "list",
+ "member": { "shape": "ResourceAction" }
+ },
+ "ResourceDisplayName": {
+ "type": "string",
+ "max": 150,
+ "min": 0,
+ "sensitive": true
+ },
+ "ResourceIdentifier": {
+ "type": "string",
+ "max": 150,
+ "min": 0,
+ "sensitive": true
+ },
+ "ResourceMetadata": {
+ "type": "structure",
+ "members": {
+ "key": { "shape": "String" },
+ "value": { "shape": "String" }
+ }
+ },
+ "ResourceMetadataItems": {
+ "type": "list",
+ "member": { "shape": "ResourceMetadata" }
+ },
+ "ResourceNotFoundException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 404,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "ResourceTooltipTranslationKeyString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "ResourceTypeString": {
+ "type": "string",
+ "max": 50,
+ "min": 0
+ },
+ "Resources": {
+ "type": "list",
+ "member": { "shape": "Resource" }
+ },
+ "Row": {
+ "type": "structure",
+ "members": {
+ "row": { "shape": "Columns" }
+ }
+ },
+ "Rows": {
+ "type": "list",
+ "member": { "shape": "Row" }
+ },
+ "SecretKeyArn": {
+ "type": "string",
+ "max": 1000,
+ "min": 0,
+ "pattern": "arn:.*"
+ },
+ "SerializedMetadata": {
+ "type": "string",
+ "max": 1000000,
+ "min": 0,
+ "sensitive": true
+ },
+ "SerializedQueryStats": {
+ "type": "string",
+ "max": 1000000,
+ "min": 0,
+ "sensitive": true
+ },
+ "ServiceQuotaExceededException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 402,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "SqlworkbenchSource": {
+ "type": "string",
+ "enum": ["SUS", "RQEV2"]
+ },
+ "StatementType": {
+ "type": "string",
+ "enum": ["DQL", "DML", "DDL", "DCL", "Utility"]
+ },
+ "StreamingBlob": {
+ "type": "blob",
+ "streaming": true
+ },
+ "String": { "type": "string" },
+ "TagKey": {
+ "type": "string",
+ "max": 128,
+ "min": 1,
+ "pattern": "([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)"
+ },
+ "TagKeyList": {
+ "type": "list",
+ "member": { "shape": "TagKey" },
+ "max": 6500,
+ "min": 1
+ },
+ "TagResourceRequest": {
+ "type": "structure",
+ "required": ["resourceArn", "tags"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "resourceArn": {
+ "shape": "Arn",
+ "location": "uri",
+ "locationName": "resourceArn"
+ },
+ "tags": { "shape": "Tags" }
+ }
+ },
+ "TagResourceResponse": {
+ "type": "structure",
+ "members": {}
+ },
+ "TagValue": {
+ "type": "string",
+ "max": 256,
+ "min": 0,
+ "pattern": "([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)"
+ },
+ "TagrisAccessDeniedException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" }
+ },
+ "exception": true
+ },
+ "TagrisAccountId": {
+ "type": "string",
+ "max": 12,
+ "min": 12
+ },
+ "TagrisAmazonResourceName": {
+ "type": "string",
+ "max": 1011,
+ "min": 1
+ },
+ "TagrisExceptionMessage": {
+ "type": "string",
+ "max": 2048,
+ "min": 0
+ },
+ "TagrisInternalId": {
+ "type": "string",
+ "max": 64,
+ "min": 0
+ },
+ "TagrisInternalServiceException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" }
+ },
+ "exception": true,
+ "fault": true
+ },
+ "TagrisInvalidArnException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" },
+ "sweepListItem": { "shape": "TagrisSweepListItem" }
+ },
+ "exception": true
+ },
+ "TagrisInvalidParameterException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" }
+ },
+ "exception": true
+ },
+ "TagrisPartialResourcesExistResultsException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" },
+ "resourceExistenceInformation": { "shape": "TagrisSweepListResult" }
+ },
+ "exception": true
+ },
+ "TagrisStatus": {
+ "type": "string",
+ "enum": ["ACTIVE", "NOT_ACTIVE"]
+ },
+ "TagrisSweepList": {
+ "type": "list",
+ "member": { "shape": "TagrisSweepListItem" }
+ },
+ "TagrisSweepListItem": {
+ "type": "structure",
+ "members": {
+ "TagrisAccountId": { "shape": "TagrisAccountId" },
+ "TagrisAmazonResourceName": { "shape": "TagrisAmazonResourceName" },
+ "TagrisInternalId": { "shape": "TagrisInternalId" },
+ "TagrisVersion": { "shape": "TagrisVersion" }
+ }
+ },
+ "TagrisSweepListResult": {
+ "type": "map",
+ "key": { "shape": "TagrisAmazonResourceName" },
+ "value": { "shape": "TagrisStatus" }
+ },
+ "TagrisThrottledException": {
+ "type": "structure",
+ "members": {
+ "message": { "shape": "TagrisExceptionMessage" }
+ },
+ "exception": true
+ },
+ "TagrisVerifyResourcesExistInput": {
+ "type": "structure",
+ "required": ["TagrisSweepList"],
+ "members": {
+ "TagrisSweepList": { "shape": "TagrisSweepList" }
+ }
+ },
+ "TagrisVerifyResourcesExistOutput": {
+ "type": "structure",
+ "required": ["TagrisSweepListResult"],
+ "members": {
+ "TagrisSweepListResult": { "shape": "TagrisSweepListResult" }
+ }
+ },
+ "TagrisVersion": { "type": "long" },
+ "Tags": {
+ "type": "map",
+ "key": { "shape": "TagKey" },
+ "value": { "shape": "TagValue" },
+ "max": 50,
+ "min": 1
+ },
+ "ThrottlingException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 429,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "UntagResourceRequest": {
+ "type": "structure",
+ "required": ["resourceArn", "tagKeys"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "resourceArn": {
+ "shape": "Arn",
+ "location": "uri",
+ "locationName": "resourceArn"
+ },
+ "tagKeys": {
+ "shape": "TagKeyList",
+ "location": "querystring",
+ "locationName": "tagKeys"
+ }
+ }
+ },
+ "UntagResourceResponse": {
+ "type": "structure",
+ "members": {}
+ },
+ "UpdateConnectionRequest": {
+ "type": "structure",
+ "required": ["id", "authenticationType"],
+ "members": {
+ "sqlworkbenchSource": {
+ "shape": "SqlworkbenchSource",
+ "location": "header",
+ "locationName": "sqlworkbench-source"
+ },
+ "id": {
+ "shape": "UpdateConnectionRequestIdString",
+ "documentation": "Id of the connection to update
"
+ },
+ "name": {
+ "shape": "UpdateConnectionRequestNameString",
+ "documentation": "Name of the connection
"
+ },
+ "databaseName": {
+ "shape": "UpdateConnectionRequestDatabaseNameString",
+ "documentation": "Name of the database used for this connection
"
+ },
+ "authenticationType": {
+ "shape": "UpdateConnectionRequestAuthenticationTypeEnum",
+ "documentation": "Number representing the type of authentication to use (2 = IAM, 3 = Username and Password, 4 = Federated connection)
"
+ },
+ "secretArn": {
+ "shape": "UpdateConnectionRequestSecretArnString",
+ "documentation": "secretArn for redshift cluster
"
+ },
+ "clusterId": {
+ "shape": "UpdateConnectionRequestClusterIdString",
+ "documentation": "Id of the cluster used for this connection
"
+ },
+ "isServerless": {
+ "shape": "Boolean",
+ "documentation": "Is serverless connection
"
+ },
+ "dbUser": {
+ "shape": "DbUser",
+ "documentation": "User of the database used for this connection
"
+ },
+ "username": {
+ "shape": "DbUser",
+ "documentation": "Username used in the Username_Password connection type
"
+ },
+ "password": {
+ "shape": "UpdateConnectionRequestPasswordString",
+ "documentation": "Password of the user used for this connection
"
+ },
+ "host": {
+ "shape": "String",
+ "documentation": "Host address used for creating secret for Username_Password connection type
"
+ },
+ "databaseType": { "shape": "DatabaseType" },
+ "connectableResourceIdentifier": {
+ "shape": "UpdateConnectionRequestConnectableResourceIdentifierString",
+ "documentation": "Id of the connectable resource used for this connection
"
+ },
+ "connectableResourceType": {
+ "shape": "UpdateConnectionRequestConnectableResourceTypeString",
+ "documentation": "Type of the connectable resource used for this connection
"
+ }
+ }
+ },
+ "UpdateConnectionRequestAuthenticationTypeEnum": {
+ "type": "string",
+ "enum": ["2", "3", "4", "5", "6", "7", "8"],
+ "max": 1,
+ "min": 1,
+ "sensitive": true
+ },
+ "UpdateConnectionRequestClusterIdString": {
+ "type": "string",
+ "max": 63,
+ "min": 1
+ },
+ "UpdateConnectionRequestConnectableResourceIdentifierString": {
+ "type": "string",
+ "max": 63,
+ "min": 1,
+ "sensitive": true
+ },
+ "UpdateConnectionRequestConnectableResourceTypeString": {
+ "type": "string",
+ "max": 63,
+ "min": 1
+ },
+ "UpdateConnectionRequestDatabaseNameString": {
+ "type": "string",
+ "max": 64,
+ "min": 1,
+ "sensitive": true
+ },
+ "UpdateConnectionRequestIdString": {
+ "type": "string",
+ "max": 2048,
+ "min": 32
+ },
+ "UpdateConnectionRequestNameString": {
+ "type": "string",
+ "max": 512,
+ "min": 1,
+ "sensitive": true
+ },
+ "UpdateConnectionRequestPasswordString": {
+ "type": "string",
+ "max": 64,
+ "min": 8,
+ "sensitive": true
+ },
+ "UpdateConnectionRequestSecretArnString": {
+ "type": "string",
+ "max": 1000,
+ "min": 1
+ },
+ "UpdateConnectionResponse": {
+ "type": "structure",
+ "members": {
+ "data": { "shape": "Connection" }
+ }
+ },
+ "UserSettings": {
+ "type": "string",
+ "sensitive": true
+ },
+ "ValidationException": {
+ "type": "structure",
+ "required": ["message"],
+ "members": {
+ "message": { "shape": "String" },
+ "code": { "shape": "ErrorCode" }
+ },
+ "error": {
+ "httpStatusCode": 400,
+ "senderFault": true
+ },
+ "exception": true
+ },
+ "statusCode": {
+ "type": "integer",
+ "box": true,
+ "max": 500,
+ "min": 100
+ }
+ }
+}
diff --git a/packages/core/src/sagemakerunifiedstudio/shared/errors.ts b/packages/core/src/sagemakerunifiedstudio/shared/errors.ts
new file mode 100644
index 00000000000..1d582c22d74
--- /dev/null
+++ b/packages/core/src/sagemakerunifiedstudio/shared/errors.ts
@@ -0,0 +1,8 @@
+/*!
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const errorCode = {
+ failedAuthConnecton: 'FailedAuthConnecton',
+}
diff --git a/packages/core/src/sagemakerunifiedstudio/shared/smusUtils.ts b/packages/core/src/sagemakerunifiedstudio/shared/smusUtils.ts
new file mode 100644
index 00000000000..3fe1dd9b27b
--- /dev/null
+++ b/packages/core/src/sagemakerunifiedstudio/shared/smusUtils.ts
@@ -0,0 +1,353 @@
+/*!
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { getLogger } from '../../shared/logger/logger'
+import { ToolkitError } from '../../shared/errors'
+import { isSageMaker } from '../../shared/extensionUtilities'
+import { getResourceMetadata } from './utils/resourceMetadataUtils'
+import fetch from 'node-fetch'
+
+/**
+ * Represents SSO instance information retrieved from DataZone
+ */
+export interface SsoInstanceInfo {
+ issuerUrl: string
+ ssoInstanceId: string
+ clientId: string
+ region: string
+}
+
+/**
+ * Response from DataZone /sso/login endpoint
+ */
+interface DataZoneSsoLoginResponse {
+ redirectUrl: string
+}
+
+/**
+ * Credential expiry time constants for SMUS providers (in milliseconds)
+ */
+export const SmusCredentialExpiry = {
+ /** Domain Execution Role (DER) credentials expiry time: 10 minutes */
+ derExpiryMs: 10 * 60 * 1000,
+ /** Project Role credentials expiry time: 10 minutes */
+ projectExpiryMs: 10 * 60 * 1000,
+ /** Connection credentials expiry time: 10 minutes */
+ connectionExpiryMs: 10 * 60 * 1000,
+} as const
+
+/**
+ * Error codes for SMUS-related operations
+ */
+export const SmusErrorCodes = {
+ /** Error code for when no active SMUS connection is available */
+ NoActiveConnection: 'NoActiveConnection',
+ /** Error code for when API calls timeout */
+ ApiTimeout: 'ApiTimeout',
+ /** Error code for when SMUS login fails */
+ SmusLoginFailed: 'SmusLoginFailed',
+ /** Error code for when redeeming access token fails */
+ RedeemAccessTokenFailed: 'RedeemAccessTokenFailed',
+} as const
+
+/**
+ * Timeout constants for SMUS API calls (in milliseconds)
+ */
+export const SmusTimeouts = {
+ /** Default timeout for API calls: 10 seconds */
+ apiCallTimeoutMs: 10 * 1000,
+} as const
+
+/**
+ * Interface for AWS credential objects that need validation
+ */
+interface CredentialObject {
+ accessKeyId?: unknown
+ secretAccessKey?: unknown
+ sessionToken?: unknown
+ expiration?: unknown
+}
+
+/**
+ * Validates AWS credential fields and throws appropriate errors if invalid
+ * @param credentials The credential object to validate
+ * @param errorCode The error code to use in ToolkitError
+ * @param contextMessage The context message for error messages (e.g., "API response", "project credential response")
+ * @throws ToolkitError if any credential field is invalid
+ */
+export function validateCredentialFields(
+ credentials: CredentialObject,
+ errorCode: string,
+ contextMessage: string,
+ validateExpireTime: boolean = false
+): void {
+ if (!credentials.accessKeyId || typeof credentials.accessKeyId !== 'string') {
+ throw new ToolkitError(`Invalid accessKeyId in ${contextMessage}: ${typeof credentials.accessKeyId}`, {
+ code: errorCode,
+ })
+ }
+ if (!credentials.secretAccessKey || typeof credentials.secretAccessKey !== 'string') {
+ throw new ToolkitError(`Invalid secretAccessKey in ${contextMessage}: ${typeof credentials.secretAccessKey}`, {
+ code: errorCode,
+ })
+ }
+ if (!credentials.sessionToken || typeof credentials.sessionToken !== 'string') {
+ throw new ToolkitError(`Invalid sessionToken in ${contextMessage}: ${typeof credentials.sessionToken}`, {
+ code: errorCode,
+ })
+ }
+ if (validateExpireTime) {
+ if (!credentials.expiration || !(credentials.expiration instanceof Date)) {
+ throw new ToolkitError(`Invalid expireTime in ${contextMessage}: ${typeof credentials.expiration}`, {
+ code: errorCode,
+ })
+ }
+ }
+}
+
+/**
+ * Utility class for SageMaker Unified Studio domain URL parsing and validation
+ */
+export class SmusUtils {
+ private static readonly logger = getLogger()
+
+ /**
+ * Extracts the domain ID from a SageMaker Unified Studio domain URL
+ * @param domainUrl The SageMaker Unified Studio domain URL
+ * @returns The extracted domain ID or undefined if not found
+ */
+ public static extractDomainIdFromUrl(domainUrl: string): string | undefined {
+ try {
+ // Domain URL format: https://dzd_d3hr1nfjbtwui1.sagemaker.us-east-2.on.aws
+ const url = new URL(domainUrl)
+ const hostname = url.hostname
+
+ // Extract domain ID from hostname (dzd_d3hr1nfjbtwui1 or dzd-d3hr1nfjbtwui1)
+ const domainIdMatch = hostname.match(/^(dzd[-_][a-zA-Z0-9_-]{1,36})\./)
+ return domainIdMatch?.[1]
+ } catch (error) {
+ this.logger.error('Failed to extract domain ID from URL: %s', error as Error)
+ return undefined
+ }
+ }
+
+ /**
+ * Extracts the AWS region from a SageMaker Unified Studio domain URL
+ * @param domainUrl The SageMaker Unified Studio domain URL
+ * @param fallbackRegion Fallback region if extraction fails (default: 'us-east-1')
+ * @returns The extracted AWS region or the fallback region if not found
+ */
+ public static extractRegionFromUrl(domainUrl: string, fallbackRegion: string = 'us-east-1'): string {
+ try {
+ // Domain URL formats:
+ // - https://dzd_d3hr1nfjbtwui1.sagemaker.us-east-2.on.aws
+ // - https://dzd_4gickdfsxtoxg0.sagemaker-gamma.us-west-2.on.aws
+ const url = new URL(domainUrl)
+ const hostname = url.hostname
+
+ // Extract region from hostname, handling both prod and non-prod stages
+ // Pattern matches: .sagemaker[-stage].{region}.on.aws
+ const regionMatch = hostname.match(/\.sagemaker(?:-[a-z]+)?\.([a-z0-9-]+)\.on\.aws$/)
+ return regionMatch?.[1] || fallbackRegion
+ } catch (error) {
+ this.logger.error('Failed to extract region from URL: %s', error as Error)
+ return fallbackRegion
+ }
+ }
+
+ /**
+ * Extracts both domain ID and region from a SageMaker Unified Studio domain URL
+ * @param domainUrl The SageMaker Unified Studio domain URL
+ * @param fallbackRegion Fallback region if extraction fails (default: 'us-east-1')
+ * @returns Object containing domainId and region
+ */
+ public static extractDomainInfoFromUrl(
+ domainUrl: string,
+ fallbackRegion: string = 'us-east-1'
+ ): { domainId: string | undefined; region: string } {
+ return {
+ domainId: this.extractDomainIdFromUrl(domainUrl),
+ region: this.extractRegionFromUrl(domainUrl, fallbackRegion),
+ }
+ }
+
+ /**
+ * Validates the domain URL format for SageMaker Unified Studio
+ * @param value The URL to validate
+ * @returns Error message if invalid, undefined if valid
+ */
+ public static validateDomainUrl(value: string): string | undefined {
+ if (!value || value.trim() === '') {
+ return 'Domain URL is required'
+ }
+
+ const trimmedValue = value.trim()
+
+ // Check HTTPS requirement
+ if (!trimmedValue.startsWith('https://')) {
+ return 'Domain URL must use HTTPS (https://)'
+ }
+
+ // Check basic URL format
+ try {
+ const url = new URL(trimmedValue)
+
+ // Check if it looks like a SageMaker Unified Studio domain
+ if (!url.hostname.includes('sagemaker') || !url.hostname.includes('on.aws')) {
+ return 'URL must be a valid SageMaker Unified Studio domain (e.g., https://dzd_xxxxxxxxx.sagemaker.us-east-1.on.aws)'
+ }
+
+ // Extract domain ID to validate
+ const domainId = this.extractDomainIdFromUrl(trimmedValue)
+
+ if (!domainId) {
+ return 'URL must contain a valid domain ID (starting with dzd- or dzd_)'
+ }
+
+ return undefined // Valid
+ } catch (err) {
+ return 'Invalid URL format'
+ }
+ }
+
+ /**
+ * Makes HTTP call to DataZone /sso/login endpoint
+ * @param domainUrl The SageMaker Unified Studio domain URL
+ * @param domainId The extracted domain ID
+ * @returns Promise resolving to the login response
+ * @throws ToolkitError if the API call fails
+ */
+ private static async callDataZoneLogin(domainUrl: string, domainId: string): Promise {
+ const loginUrl = new URL('/sso/login', domainUrl)
+ const requestBody = {
+ domainId: domainId,
+ }
+
+ try {
+ const response = await fetch(loginUrl.toString(), {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Accept: 'application/json',
+ 'User-Agent': 'aws-toolkit-vscode',
+ },
+ body: JSON.stringify(requestBody),
+ timeout: SmusTimeouts.apiCallTimeoutMs,
+ })
+
+ if (!response.ok) {
+ throw new ToolkitError(`SMUS login failed: ${response.status} ${response.statusText}`, {
+ code: SmusErrorCodes.SmusLoginFailed,
+ })
+ }
+
+ return (await response.json()) as DataZoneSsoLoginResponse
+ } catch (error) {
+ // Handle timeout errors specifically
+ if (error instanceof Error && (error.name === 'AbortError' || error.message.includes('timeout'))) {
+ throw new ToolkitError(
+ `DataZone login request timed out after ${SmusTimeouts.apiCallTimeoutMs / 1000} seconds`,
+ {
+ code: SmusErrorCodes.ApiTimeout,
+ cause: error,
+ }
+ )
+ }
+ // Re-throw other errors as-is
+ throw error
+ }
+ }
+
+ /**
+ * Gets SSO instance information by calling DataZone /sso/login endpoint
+ * This extracts the proper SSO instance ID and issuer URL needed for OAuth client registration
+ *
+ * @param domainUrl The SageMaker Unified Studio domain URL
+ * @returns Promise resolving to SSO instance information
+ * @throws ToolkitError if the API call fails or response is invalid
+ */
+ public static async getSsoInstanceInfo(domainUrl: string): Promise {
+ try {
+ this.logger.info(`SMUS Auth: Getting SSO instance info from DataZone for domainurl: ${domainUrl}`)
+
+ // Extract domain ID from the domain URL
+ const domainId = this.extractDomainIdFromUrl(domainUrl)
+ if (!domainId) {
+ throw new ToolkitError('Invalid domain URL format', { code: 'InvalidDomainUrl' })
+ }
+
+ // Call DataZone /sso/login endpoint to get redirect URL with SSO instance info
+ const loginData = await this.callDataZoneLogin(domainUrl, domainId)
+ if (!loginData.redirectUrl) {
+ throw new ToolkitError('No redirect URL received from DataZone login', { code: 'InvalidLoginResponse' })
+ }
+
+ // Parse the redirect URL to extract SSO instance information
+ const redirectUrl = new URL(loginData.redirectUrl)
+ const clientIdParam = redirectUrl.searchParams.get('client_id')
+ if (!clientIdParam) {
+ throw new ToolkitError('No client_id found in DataZone redirect URL', { code: 'InvalidRedirectUrl' })
+ }
+
+ // Decode the client_id ARN: arn:aws:sso::785498918019:application/ssoins-6684636af7e1a207/apl-5f60548b7f5677a2
+ const decodedClientId = decodeURIComponent(clientIdParam)
+ const arnParts = decodedClientId.split('/')
+ if (arnParts.length < 2) {
+ throw new ToolkitError('Invalid client_id ARN format', { code: 'InvalidArnFormat' })
+ }
+
+ const ssoInstanceId = arnParts[1] // Extract ssoins-6684636af7e1a207
+ const issuerUrl = `https://identitycenter.amazonaws.com/${ssoInstanceId}`
+
+ // Extract region from domain URL
+ const region = this.extractRegionFromUrl(domainUrl)
+
+ this.logger.info('SMUS Auth: Extracted SSO instance info: %s', ssoInstanceId)
+
+ return {
+ issuerUrl,
+ ssoInstanceId,
+ clientId: decodedClientId,
+ region,
+ }
+ } catch (error) {
+ const errorMsg = error instanceof Error ? error.message : 'Unknown error'
+ this.logger.error('SMUS Auth: Failed to get SSO instance info: %s', errorMsg)
+
+ if (error instanceof ToolkitError) {
+ throw error
+ }
+
+ throw new ToolkitError(`Failed to get SSO instance info: ${errorMsg}`, {
+ code: 'SsoInstanceInfoFailed',
+ cause: error instanceof Error ? error : undefined,
+ })
+ }
+ }
+ /**
+ * Extracts SSO ID from a user ID in the format "user-"
+ * @param userId The user ID to extract SSO ID from
+ * @returns The extracted SSO ID
+ * @throws Error if the userId format is invalid
+ */
+ public static extractSSOIdFromUserId(userId: string): string {
+ const match = userId.match(/user-(.+)$/)
+ if (!match) {
+ this.logger.error(`Invalid UserId format: ${userId}`)
+ throw new Error(`Invalid UserId format: ${userId}`)
+ }
+ return match[1]
+ }
+
+ /**
+ * Checks if we're in SMUS space environment (should hide certain UI elements)
+ * @returns True if in SMUS space environment with DataZone domain ID
+ */
+ public static isInSmusSpaceEnvironment(): boolean {
+ const isSMUSspace = isSageMaker('SMUS') || isSageMaker('SMUS-SPACE-REMOTE-ACCESS')
+ const resourceMetadata = getResourceMetadata()
+ return isSMUSspace && !!resourceMetadata?.AdditionalMetadata?.DataZoneDomainId
+ }
+}
diff --git a/packages/core/src/sagemakerunifiedstudio/shared/utils/resourceMetadataUtils.ts b/packages/core/src/sagemakerunifiedstudio/shared/utils/resourceMetadataUtils.ts
new file mode 100644
index 00000000000..61ce0430ecd
--- /dev/null
+++ b/packages/core/src/sagemakerunifiedstudio/shared/utils/resourceMetadataUtils.ts
@@ -0,0 +1,93 @@
+/*!
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fs } from '../../../shared/fs/fs'
+import { getLogger } from '../../../shared/logger/logger'
+import { isSageMaker } from '../../../shared/extensionUtilities'
+
+/**
+ * Resource metadata schema used by `resource-metadata.json` in SageMaker Unified Studio spaces
+ */
+export type ResourceMetadata = {
+ AppType?: string
+ DomainId?: string
+ SpaceName?: string
+ UserProfileName?: string
+ ExecutionRoleArn?: string
+ ResourceArn?: string
+ ResourceName?: string
+ AppImageVersion?: string
+ AdditionalMetadata?: {
+ DataZoneDomainId?: string
+ DataZoneDomainRegion?: string
+ DataZoneEndpoint?: string
+ DataZoneEnvironmentId?: string
+ DataZoneProjectId?: string
+ DataZoneScopeName?: string
+ DataZoneStage?: string
+ DataZoneUserId?: string
+ PrivateSubnets?: string
+ ProjectS3Path?: string
+ SecurityGroup?: string
+ }
+ ResourceArnCaseSensitive?: string
+ IpAddressType?: string
+} & Record
+
+const resourceMetadataPath = '/opt/ml/metadata/resource-metadata.json'
+let resourceMetadata: ResourceMetadata | undefined = undefined
+
+/**
+ * Gets the cached resource metadata (must be initialized with `initializeResourceMetadata()` first)
+ * @returns ResourceMetadata object or undefined if not yet initialized
+ */
+export function getResourceMetadata(): ResourceMetadata | undefined {
+ return resourceMetadata
+}
+
+/**
+ * Initializes resource metadata by reading and parsing the resource-metadata.json file
+ */
+export async function initializeResourceMetadata(): Promise {
+ const logger = getLogger()
+
+ if (!isSageMaker('SMUS') && !isSageMaker('SMUS-SPACE-REMOTE-ACCESS')) {
+ logger.debug(`Not in SageMaker Unified Studio space, skipping initialization of resource metadata`)
+ return
+ }
+
+ try {
+ if (!(await resourceMetadataFileExists())) {
+ logger.debug(`Resource metadata file not found at: ${resourceMetadataPath}`)
+ }
+
+ const fileContent = await fs.readFileText(resourceMetadataPath)
+ resourceMetadata = JSON.parse(fileContent) as ResourceMetadata
+ logger.debug(`Successfully read resource metadata from: ${resourceMetadataPath}`)
+ } catch (error) {
+ logger.error(`Failed to read or parse resource metadata file: ${error as Error}`)
+ }
+}
+
+/**
+ * Checks if the resource-metadata.json file exists
+ * @returns True if the file exists, false otherwise
+ */
+export async function resourceMetadataFileExists(): Promise {
+ try {
+ return await fs.existsFile(resourceMetadataPath)
+ } catch (error) {
+ const logger = getLogger()
+ logger.error(`Failed to check if resource metadata file exists: ${error as Error}`)
+ return false
+ }
+}
+
+/**
+ * Resets the cached resource metadata
+ */
+export function resetResourceMetadata(): void {
+ resourceMetadata = undefined
+}
diff --git a/packages/core/src/shared/awsClientBuilder.ts b/packages/core/src/shared/awsClientBuilder.ts
index bdec40957cb..b6464317a3e 100644
--- a/packages/core/src/shared/awsClientBuilder.ts
+++ b/packages/core/src/shared/awsClientBuilder.ts
@@ -82,8 +82,11 @@ export class DefaultAWSClientBuilder implements AWSClientBuilder {
const listeners = Array.isArray(onRequest) ? onRequest : [onRequest]
const opt = { ...options }
delete opt.onRequestSetup
+ if (opt.credentialProvider) {
+ opt.credentials = await opt.credentialProvider.resolvePromise()
+ }
- if (!opt.credentials && !opt.token) {
+ if (!opt.credentials && !opt.token && !opt.credentialProvider) {
const shim = this.awsContext.credentialsShim
if (!shim) {
diff --git a/packages/core/src/shared/clients/clientWrapper.ts b/packages/core/src/shared/clients/clientWrapper.ts
index a90d009eb18..beb117a9bf6 100644
--- a/packages/core/src/shared/clients/clientWrapper.ts
+++ b/packages/core/src/shared/clients/clientWrapper.ts
@@ -19,22 +19,13 @@ export abstract class ClientWrapper implements vscode.Dispo
public constructor(
public readonly regionCode: string,
- private readonly clientType: AwsClientConstructor,
- private readonly isSageMaker: boolean = false
+ private readonly clientType: AwsClientConstructor
) {}
protected getClient(ignoreCache: boolean = false) {
const args = {
serviceClient: this.clientType,
region: this.regionCode,
- ...(this.isSageMaker
- ? {
- clientOptions: {
- endpoint: `https://sagemaker.${this.regionCode}.amazonaws.com`,
- region: this.regionCode,
- },
- }
- : {}),
}
return ignoreCache
? globals.sdkClientBuilderV3.createAwsService(args)
diff --git a/packages/core/src/shared/clients/sagemaker.ts b/packages/core/src/shared/clients/sagemaker.ts
index 8a8e138dd85..ff086ed1d9e 100644
--- a/packages/core/src/shared/clients/sagemaker.ts
+++ b/packages/core/src/shared/clients/sagemaker.ts
@@ -6,6 +6,7 @@
import * as vscode from 'vscode'
import {
AppDetails,
+ AppType,
CreateAppCommand,
CreateAppCommandInput,
CreateAppCommandOutput,
@@ -48,14 +49,42 @@ import { getDomainSpaceKey } from '../../awsService/sagemaker/utils'
import { getLogger } from '../logger/logger'
import { ToolkitError } from '../errors'
import { yes, no, continueText, cancel } from '../localizedText'
+import { AwsCredentialIdentity } from '@aws-sdk/types'
+import globals from '../extensionGlobals'
export interface SagemakerSpaceApp extends SpaceDetails {
App?: AppDetails
DomainSpaceKey: string
}
+
export class SagemakerClient extends ClientWrapper {
- public constructor(public override readonly regionCode: string) {
- super(regionCode, SageMakerClient, true)
+ public constructor(
+ public override readonly regionCode: string,
+ private readonly credentialsProvider?: () => Promise
+ ) {
+ super(regionCode, SageMakerClient)
+ }
+
+ protected override getClient(ignoreCache: boolean = false) {
+ if (!this.client || ignoreCache) {
+ const args = {
+ serviceClient: SageMakerClient,
+ region: this.regionCode,
+ clientOptions: {
+ endpoint: `https://sagemaker.${this.regionCode}.amazonaws.com`,
+ region: this.regionCode,
+ ...(this.credentialsProvider && { credentials: this.credentialsProvider }),
+ },
+ }
+ this.client = globals.sdkClientBuilderV3.createAwsService(args)
+ }
+ return this.client
+ }
+
+ public override dispose() {
+ getLogger().debug('SagemakerClient: Disposing client %O', this.client)
+ this.client?.destroy()
+ this.client = undefined
}
public listSpaces(request: ListSpacesCommandInput = {}): AsyncCollection {
@@ -200,27 +229,37 @@ export class SagemakerClient extends ClientWrapper {
}
}
- public async fetchSpaceAppsAndDomains(): Promise<
- [Map, Map]
- > {
- try {
- const appMap: Map = await this.listApps()
- .flatten()
- .filter((app) => !!app.DomainId && !!app.SpaceName)
- .filter((app) => app.AppType === 'JupyterLab' || app.AppType === 'CodeEditor')
- .toMap((app) => getDomainSpaceKey(app.DomainId || '', app.SpaceName || ''))
-
- const spaceApps: Map = await this.listSpaces()
- .flatten()
- .filter((space) => !!space.DomainId && !!space.SpaceName)
- .map((space) => {
- const key = getDomainSpaceKey(space.DomainId || '', space.SpaceName || '')
- return { ...space, App: appMap.get(key), DomainSpaceKey: key }
- })
- .toMap((space) => getDomainSpaceKey(space.DomainId || '', space.SpaceName || ''))
+ public async listSpaceApps(domainId?: string): Promise