import { EditorLanguage, FormComponentType, InputDataType, Plugin, PluginResponseType, PluginType, FormItem, IntegrationAuthType } from '../../types/index.js'; import { PARAMETERIZED_SQL_DESCRIPTION, SQL_INITIAL_TEXT, PUBLIC_INTEGRATIONS_LOGO_URL, DOCS_BASE_URL } from './constants.js'; import { makeDropdownItem } from './shared/db.js'; import { BASE_SUBJECT_TOKEN_SOURCE, BASE_TOKEN_URL, BASE_CLIENT_ID, BASE_CLIENT_SECRET, BASE_AUDIENCE, BASE_SCOPE, BASE_SUBJECT_TOKEN_STATIC_TOKEN } from './shared/index.js'; const SnowflakePluginVersions = { V1: '0.0.1', V2: '0.0.2', V6: '0.0.6', V7: '0.0.7', V8: '0.0.8', V9: '0.0.9', V10: '0.0.10', V11: '0.0.11' }; const CONNECTION_TYPE_FIELD = 'connectionType'; const CONNECTION_METHODS_AND_DISPLAY_NAMES_V7 = { fields: 'Password-based authentication', okta: 'Native SSO' }; const CONNECTION_METHODS_AND_DISPLAY_NAMES_V8 = { ...CONNECTION_METHODS_AND_DISPLAY_NAMES_V7, 'key-pair': 'Key-pair authentication' }; const CONNECTION_METHODS_AND_DISPLAY_NAMES_V10 = { ...CONNECTION_METHODS_AND_DISPLAY_NAMES_V8, [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE]: 'External OAuth' }; const BASE_DATABASE_ACCOUNT = { label: 'Account identifier', name: 'authentication.custom.account.value', componentType: FormComponentType.INPUT_TEXT, placeholder: 'xyz12345.us-east-1', rules: [{ required: true, message: 'Account identifier is required' }], tooltip: { markdownText: 'Use the [Account Identifier](https://docs.snowflake.com/en/user-guide/admin-account-identifier#non-vps-account-locator-formats-by-cloud-platform-and-region) based on your cloud platform and region.' } }; const BASE_USERNAME = { label: 'Username', name: 'authentication.username', componentType: FormComponentType.INPUT_TEXT, rules: [{ required: true, message: 'Username is required' }] }; const BASE_PASSWORD = { label: 'Password', name: 'authentication.password', componentType: FormComponentType.INPUT_TEXT, dataType: InputDataType.PASSWORD, rules: [{ required: true, message: 'Password is required' }] }; const BASE_DATABASE_NAME = { name: 'authentication.custom.databaseName.value', componentType: FormComponentType.INPUT_TEXT, tooltip: { markdownText: 'The default database to use for the session after connecting.' } }; const BASE_DATABASE_WAREHOUSE = { label: 'Default warehouse (optional)', name: 'authentication.custom.warehouse.value', componentType: FormComponentType.INPUT_TEXT, tooltip: { markdownText: 'The default virtual warehouse to use for the session after connecting. Used for performing queries, loading data, etc.' } }; const BASE_DATABASE_SCHEMA = { label: 'Default schema (optional)', name: 'authentication.custom.schema.value', componentType: FormComponentType.INPUT_TEXT, tooltip: { markdownText: 'The default schema to use for the session after connecting.' }, placeholder: 'PUBLIC' }; const BASE_ROLE = { label: 'Default role (optional)', name: 'authentication.custom.role.value', componentType: FormComponentType.INPUT_TEXT, tooltip: { markdownText: 'The default security role to use for the session after connecting.' }, placeholder: 'ACCOUNTADMIN' }; const BASE_CONNECTION_METHOD = { label: 'Connection method', name: CONNECTION_TYPE_FIELD, componentType: FormComponentType.DROPDOWN, initialValue: 'fields', rules: [{ required: true }] }; export const SnowflakePlugin: Plugin = { id: 'snowflake', name: 'Snowflake Warehouse', moduleName: 'SnowflakePlugin', modulePath: 'plugins/snowflake/SnowflakePlugin', iconLocation: `${PUBLIC_INTEGRATIONS_LOGO_URL}/snowflake.png`, docsUrl: `${DOCS_BASE_URL}/snowflake`, type: PluginType.DB, responseType: PluginResponseType.TABLE, hasRawRequest: true, hasMetadata: true, rawRequestName: 'Executed SQL', datasourceTemplate: { sections: [ { name: 'main', items: [ { label: 'Display name', name: 'name', startVersion: SnowflakePluginVersions.V1, componentType: FormComponentType.INPUT_TEXT, placeholder: 'Snowflake Prod', rules: [{ required: true, message: 'Display name is required' }] }, // NOTE: (joeyagreco) // this is a field that will always be hidden to users. // this exists to tell the agent WHERE to look on the datasource configuration for the authType // for more info, see addTokenIfNeeded.go in the orchestrator { label: '', name: 'authTypeField', hidden: true, initialValue: CONNECTION_TYPE_FIELD, componentType: FormComponentType.INPUT_TEXT, rules: [{ required: false }], startVersion: SnowflakePluginVersions.V10 }, // CONNECTION METHOD { ...BASE_CONNECTION_METHOD, startVersion: SnowflakePluginVersions.V7, endVersion: SnowflakePluginVersions.V7, options: Object.entries(CONNECTION_METHODS_AND_DISPLAY_NAMES_V7).map(([value, displayName]) => makeDropdownItem(value, displayName) ) } as FormItem, { ...BASE_CONNECTION_METHOD, startVersion: SnowflakePluginVersions.V8, endVersion: SnowflakePluginVersions.V9, options: Object.entries(CONNECTION_METHODS_AND_DISPLAY_NAMES_V8).map(([value, displayName]) => makeDropdownItem(value, displayName) ) } as FormItem, { ...BASE_CONNECTION_METHOD, startVersion: SnowflakePluginVersions.V10, options: Object.entries(CONNECTION_METHODS_AND_DISPLAY_NAMES_V10).map(([value, displayName]) => makeDropdownItem(value, displayName) ) } as FormItem, // DATABASE ACCOUNT { ...BASE_DATABASE_ACCOUNT, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V6 } as FormItem, { ...BASE_DATABASE_ACCOUNT, startVersion: SnowflakePluginVersions.V7, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'okta', 'key-pair', IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, // USERNAME { ...BASE_USERNAME, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V6 } as FormItem, { ...BASE_USERNAME, startVersion: SnowflakePluginVersions.V7, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'key-pair'] } } } as FormItem, { label: 'Okta username', name: 'authentication.username', componentType: FormComponentType.INPUT_TEXT, rules: [{ required: true, message: 'Okta username is required' }], startVersion: SnowflakePluginVersions.V7, display: { show: { [CONNECTION_TYPE_FIELD]: ['okta'] } } }, // PASSWORD { ...BASE_PASSWORD, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V6 } as FormItem, { ...BASE_PASSWORD, startVersion: SnowflakePluginVersions.V7, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields'] } } } as FormItem, { label: 'Okta password', name: 'authentication.password', componentType: FormComponentType.INPUT_TEXT, startVersion: SnowflakePluginVersions.V7, dataType: InputDataType.PASSWORD, rules: [{ required: true, message: 'Okta password is required' }], display: { show: { [CONNECTION_TYPE_FIELD]: ['okta'] } } }, { label: 'Authenticator URL', name: 'okta.authenticatorUrl', componentType: FormComponentType.INPUT_TEXT, startVersion: SnowflakePluginVersions.V7, rules: [{ required: true, message: 'Authenticator URL is required' }], placeholder: 'https://myaccount.okta.com', display: { show: { [CONNECTION_TYPE_FIELD]: ['okta'] } } }, { label: '', messageTemplate: 'SSO that requires 2FA is not supported at this time.', name: 'oauth-binding-alert', startVersion: SnowflakePluginVersions.V7, componentType: FormComponentType.ALERT, type: 'warning', display: { show: { [CONNECTION_TYPE_FIELD]: ['okta'] } } }, { label: 'Private key', name: 'keyPair.privateKey', componentType: FormComponentType.CODE_EDITOR, language: EditorLanguage.TEXT, startVersion: SnowflakePluginVersions.V8, rules: [{ required: true, message: 'Private key is required' }], placeholder: '-----BEGIN PRIVATE KEY-----\n' + 'am9leSBpcyB0aGUgYmVzdCBlbmdpbmVlciBpbiB0aGUgd29ybGQgISEhIHhE\n' + '...\n' + '-----END PRIVATE KEY-----', display: { show: { [CONNECTION_TYPE_FIELD]: ['key-pair'] } }, tooltip: { markdownText: 'Private key in PKCS #8 format.' } }, { label: 'Passphrase (optional)', name: 'keyPair.password', componentType: FormComponentType.INPUT_TEXT, dataType: InputDataType.PASSWORD, startVersion: SnowflakePluginVersions.V8, rules: [{ required: false }], display: { show: { [CONNECTION_TYPE_FIELD]: ['key-pair'] } }, tooltip: { markdownText: 'Passphrase for the given private key, if encrypted.' } }, // OAUTH2 { ...BASE_SUBJECT_TOKEN_SOURCE, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, { ...BASE_SUBJECT_TOKEN_STATIC_TOKEN, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE], 'authConfig.subjectTokenSource': ['SUBJECT_TOKEN_SOURCE_STATIC_TOKEN'] } } } as FormItem, { ...BASE_TOKEN_URL, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, { ...BASE_CLIENT_ID, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, { ...BASE_CLIENT_SECRET, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, { ...BASE_AUDIENCE, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, { ...BASE_SCOPE, startVersion: SnowflakePluginVersions.V10, display: { show: { [CONNECTION_TYPE_FIELD]: [IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, // DATABASE NAME { ...BASE_DATABASE_NAME, label: 'Database name', rules: [{ required: true, message: 'Database name is required' }], startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V7 } as FormItem, { ...BASE_DATABASE_NAME, label: 'Database', rules: [{ required: true, message: 'Database is required' }], startVersion: SnowflakePluginVersions.V7, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'key-pair', 'okta', IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, // DATABASE WAREHOUSE { ...BASE_DATABASE_WAREHOUSE, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V7 } as FormItem, { ...BASE_DATABASE_WAREHOUSE, startVersion: SnowflakePluginVersions.V7, endVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields'] } } } as FormItem, { ...BASE_DATABASE_WAREHOUSE, startVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'key-pair', 'okta', IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, // DATABASE SCHEMA { ...BASE_DATABASE_SCHEMA, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V7 } as FormItem, { ...BASE_DATABASE_SCHEMA, startVersion: SnowflakePluginVersions.V7, endVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields'] } } } as FormItem, { ...BASE_DATABASE_SCHEMA, startVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'key-pair', 'okta', IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem, // ROLE { ...BASE_ROLE, startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V7 } as FormItem, { ...BASE_ROLE, startVersion: SnowflakePluginVersions.V7, endVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields'] } } } as FormItem, { ...BASE_ROLE, startVersion: SnowflakePluginVersions.V9, display: { show: { [CONNECTION_TYPE_FIELD]: ['fields', 'key-pair', 'okta', IntegrationAuthType.OAUTH2_TOKEN_EXCHANGE] } } } as FormItem ] } ] }, actionTemplate: { sections: [ { name: 'main', items: [ { label: 'Parameters (?, ?, ...)', name: 'parameters', startVersion: SnowflakePluginVersions.V11, ldFlag: 'clark.parameterized-apis.v2.enabled', componentType: FormComponentType.DYNAMIC_INPUT_TEXT, placeholder: '[param1, param2, ...]', tooltip: { markdownText: 'JavaScript expression that evaluates to an array of parameter values. Use `?` placeholders in your SQL query to reference these parameters.' } }, { label: '', // Query name: 'body', startVersion: SnowflakePluginVersions.V1, endVersion: SnowflakePluginVersions.V10, componentType: FormComponentType.CODE_EDITOR, language: EditorLanguage.SQL, initialValue: SQL_INITIAL_TEXT }, { label: '', // Query name: 'body', startVersion: SnowflakePluginVersions.V11, componentType: FormComponentType.CODE_EDITOR, language: EditorLanguage.SQL, initialValue: SQL_INITIAL_TEXT } ] }, { name: 'advanced:main', items: [ { label: 'Use parameterized SQL', name: 'usePreparedSql', startVersion: SnowflakePluginVersions.V6, endVersion: SnowflakePluginVersions.V10, componentType: FormComponentType.SWITCH, initialValue: true, tooltip: { markdownText: PARAMETERIZED_SQL_DESCRIPTION } }, { label: 'Use parameterized SQL', name: 'usePreparedSql', startVersion: SnowflakePluginVersions.V11, componentType: FormComponentType.SWITCH, initialValue: true, tooltip: { markdownText: PARAMETERIZED_SQL_DESCRIPTION }, display: { show: { parameters: ['undefined'] } } } ] } ] } };