From 6b4c8e58b56dd908feec7fe23eec35508b3965a2 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Wed, 19 Nov 2025 16:26:00 +0800 Subject: [PATCH 1/6] init --- runtime/drivers/azure/azure.go | 25 +++++-------------- .../src/features/sources/modal/constants.ts | 2 +- .../src/features/sources/modal/yupSchemas.ts | 6 ++--- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/runtime/drivers/azure/azure.go b/runtime/drivers/azure/azure.go index dbfd51ffd90..7eb8a160f23 100644 --- a/runtime/drivers/azure/azure.go +++ b/runtime/drivers/azure/azure.go @@ -24,27 +24,14 @@ var spec = drivers.Spec{ DocsURL: "https://docs.rilldata.com/build/connectors/data-source/azure", ConfigProperties: []*drivers.PropertySpec{ { - Key: "azure_storage_account", - Type: drivers.StringPropertyType, - Secret: true, - }, - { - Key: "azure_storage_key", - Type: drivers.StringPropertyType, - Secret: true, - }, - { - Key: "azure_storage_sas_token", - Type: drivers.StringPropertyType, - Secret: true, - }, - { - Key: "azure_storage_connection_string", - Type: drivers.StringPropertyType, - Secret: true, + Key: "azure_storage_connection_string", + Type: drivers.StringPropertyType, + DisplayName: "Azure Connection String", + Description: "Azure connection string for storage account", + Placeholder: "Paste your Azure connection string here", + Secret: true, }, }, - // Important: Any edits to the below properties must be accompanied by changes to the client-side form validation schemas. SourceProperties: []*drivers.PropertySpec{ { Key: "path", diff --git a/web-common/src/features/sources/modal/constants.ts b/web-common/src/features/sources/modal/constants.ts index 4bffc52825d..dcd62119d8f 100644 --- a/web-common/src/features/sources/modal/constants.ts +++ b/web-common/src/features/sources/modal/constants.ts @@ -67,7 +67,7 @@ export const OLAP_ENGINES = [ export const ALL_CONNECTORS = [...SOURCES, ...OLAP_ENGINES]; // Connectors that support multi-step forms (connector -> source) -export const MULTI_STEP_CONNECTORS = ["gcs"]; +export const MULTI_STEP_CONNECTORS = ["gcs", "azure"]; export const FORM_HEIGHT_TALL = "max-h-[38.5rem] min-h-[38.5rem]"; export const FORM_HEIGHT_DEFAULT = "max-h-[34.5rem] min-h-[34.5rem]"; diff --git a/web-common/src/features/sources/modal/yupSchemas.ts b/web-common/src/features/sources/modal/yupSchemas.ts index b12ec332eae..f4e20e7f104 100644 --- a/web-common/src/features/sources/modal/yupSchemas.ts +++ b/web-common/src/features/sources/modal/yupSchemas.ts @@ -66,18 +66,18 @@ export const getYupSchema = { }), azure: yup.object().shape({ + azure_storage_connection_string: yup.string(), path: yup .string() .matches( /^azure:\/\//, "Must be an Azure URI (e.g. azure://container/path)", ) - .required("Path is required"), - azure_storage_account: yup.string(), + .optional(), name: yup .string() .matches(VALID_NAME_PATTERN, INVALID_NAME_MESSAGE) - .required("Source name is required"), + .optional(), }), postgres: yup.object().shape({ From c8bdebaedc5edf70b151276e9eb1a55554d8922d Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Wed, 19 Nov 2025 23:43:31 +0800 Subject: [PATCH 2/6] fix multi step, always use config props --- .../features/sources/modal/AddDataForm.svelte | 24 +++++++++++++------ .../sources/modal/AddDataFormManager.ts | 12 +++++++--- .../sources/modal/AddDataModal.svelte | 2 ++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/web-common/src/features/sources/modal/AddDataForm.svelte b/web-common/src/features/sources/modal/AddDataForm.svelte index 697c5def71e..d23275608e9 100644 --- a/web-common/src/features/sources/modal/AddDataForm.svelte +++ b/web-common/src/features/sources/modal/AddDataForm.svelte @@ -383,13 +383,23 @@ enhance={paramsEnhance} onSubmit={paramsSubmit} > - + {#if connector.name === "gcs"} + + {:else} + + {/if} {:else} diff --git a/web-common/src/features/sources/modal/AddDataFormManager.ts b/web-common/src/features/sources/modal/AddDataFormManager.ts index c81956ffeaa..a82adadd1a7 100644 --- a/web-common/src/features/sources/modal/AddDataFormManager.ts +++ b/web-common/src/features/sources/modal/AddDataFormManager.ts @@ -89,12 +89,18 @@ export class AddDataFormManager { const isSourceForm = formType === "source"; const isConnectorForm = formType === "connector"; + const isMultiStep = MULTI_STEP_CONNECTORS.includes(connector.name ?? ""); // Base properties + // For multi-step connectors (e.g., gcs, azure), step 1 always configures the connector, + // even when the overall formType is "source". So prefer configProperties here. this.properties = - (isSourceForm - ? connector.sourceProperties - : connector.configProperties?.filter((p) => p.key !== "dsn")) ?? []; + (isMultiStep + ? connector.configProperties + : isSourceForm + ? connector.sourceProperties + : connector.configProperties + )?.filter((p) => p.key !== "dsn") ?? []; // Filter properties based on connector type this.filteredParamsProperties = (() => { diff --git a/web-common/src/features/sources/modal/AddDataModal.svelte b/web-common/src/features/sources/modal/AddDataModal.svelte index 42c8289d1b1..968edca0183 100644 --- a/web-common/src/features/sources/modal/AddDataModal.svelte +++ b/web-common/src/features/sources/modal/AddDataModal.svelte @@ -71,6 +71,8 @@ }); function goToConnectorForm(connector: V1ConnectorDriver) { + // Ensure multi-step connectors always start on the connector step + resetConnectorStep(); const state = { step: 2, selectedConnector: connector, From 09582d147666c60a692621d4310a89d117819909 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Tue, 25 Nov 2025 04:52:44 +0800 Subject: [PATCH 3/6] re-add keys --- runtime/drivers/azure/azure.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/runtime/drivers/azure/azure.go b/runtime/drivers/azure/azure.go index 7eb8a160f23..9ec149214ce 100644 --- a/runtime/drivers/azure/azure.go +++ b/runtime/drivers/azure/azure.go @@ -31,6 +31,21 @@ var spec = drivers.Spec{ Placeholder: "Paste your Azure connection string here", Secret: true, }, + { + Key: "azure_storage_account", + Type: drivers.StringPropertyType, + Secret: true, + }, + { + Key: "azure_storage_key", + Type: drivers.StringPropertyType, + Secret: true, + }, + { + Key: "azure_storage_sas_token", + Type: drivers.StringPropertyType, + Secret: true, + }, }, SourceProperties: []*drivers.PropertySpec{ { From 5d3f7c58f641f26853fa595d1f1c22aab530960f Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Tue, 25 Nov 2025 15:56:53 +0800 Subject: [PATCH 4/6] azure multi step form --- .../features/sources/modal/AddDataForm.svelte | 8 + .../sources/modal/AzureMultiStepForm.svelte | 178 ++++++++++++++++++ .../src/features/sources/modal/constants.ts | 33 ++++ 3 files changed, 219 insertions(+) create mode 100644 web-common/src/features/sources/modal/AzureMultiStepForm.svelte diff --git a/web-common/src/features/sources/modal/AddDataForm.svelte b/web-common/src/features/sources/modal/AddDataForm.svelte index d23275608e9..15bdd9b8b7f 100644 --- a/web-common/src/features/sources/modal/AddDataForm.svelte +++ b/web-common/src/features/sources/modal/AddDataForm.svelte @@ -22,6 +22,7 @@ import { connectorStepStore } from "./connectorStepStore"; import FormRenderer from "./FormRenderer.svelte"; import YamlPreview from "./YamlPreview.svelte"; + import AzureMultiStepForm from "./AzureMultiStepForm.svelte"; import GCSMultiStepForm from "./GCSMultiStepForm.svelte"; import { AddDataFormManager } from "./AddDataFormManager"; import { hasOnlyDsn } from "./utils"; @@ -391,6 +392,13 @@ {onStringInputChange} {handleFileUpload} /> + {:else if connector.name === "azure"} + {:else} + import Input from "@rilldata/web-common/components/forms/Input.svelte"; + import Checkbox from "@rilldata/web-common/components/forms/Checkbox.svelte"; + import InformationalField from "@rilldata/web-common/components/forms/InformationalField.svelte"; + import Radio from "@rilldata/web-common/components/forms/Radio.svelte"; + import { ConnectorDriverPropertyType } from "@rilldata/web-common/runtime-client"; + import { normalizeErrors } from "./utils"; + import { + AZURE_AUTH_OPTIONS, + type AzureAuthMethod, + } from "./constants"; + + export let properties: any[] = []; + export let paramsForm: any; + export let paramsErrors: Record; + export let onStringInputChange: (e: Event) => void; + + let azureAuthMethod: AzureAuthMethod = "connection_string"; + + const filteredParamsProperties = properties; + + function clearFields(keys: string[]) { + paramsForm.update( + ($form) => { + for (const key of keys) { + $form[key] = ""; + } + return $form; + }, + { taint: false }, + ); + } + + $: if (azureAuthMethod === "connection_string") { + clearFields([ + "azure_storage_account", + "azure_storage_key", + "azure_storage_sas_token", + ]); + } else if (azureAuthMethod === "storage_key") { + clearFields(["azure_storage_connection_string", "azure_storage_sas_token"]); + } else if (azureAuthMethod === "sas_token") { + clearFields(["azure_storage_connection_string", "azure_storage_key"]); + } else if (azureAuthMethod === "public") { + clearFields([ + "azure_storage_connection_string", + "azure_storage_account", + "azure_storage_key", + "azure_storage_sas_token", + ]); + } + + +
+
+
Authentication
+ + + {#if option.value === "connection_string"} + + {:else if option.value === "storage_key"} +
+ + +
+ {:else if option.value === "sas_token"} +
+ + +
+ {:else if option.value === "public"} + + {/if} +
+
+
+ + {#each filteredParamsProperties as property (property.key)} + {@const propertyKey = property.key ?? ""} + {#if propertyKey !== "path" && + propertyKey !== "azure_storage_connection_string" && + propertyKey !== "azure_storage_account" && + propertyKey !== "azure_storage_key" && + propertyKey !== "azure_storage_sas_token"} +
+ {#if property.type === ConnectorDriverPropertyType.TYPE_STRING || + property.type === ConnectorDriverPropertyType.TYPE_NUMBER} + onStringInputChange(e)} + alwaysShowError + /> + {:else if property.type === ConnectorDriverPropertyType.TYPE_BOOLEAN} + + {:else if property.type === ConnectorDriverPropertyType.TYPE_INFORMATIONAL} + + {/if} +
+ {/if} + {/each} +
+ diff --git a/web-common/src/features/sources/modal/constants.ts b/web-common/src/features/sources/modal/constants.ts index dcd62119d8f..37bd5f01102 100644 --- a/web-common/src/features/sources/modal/constants.ts +++ b/web-common/src/features/sources/modal/constants.ts @@ -18,6 +18,11 @@ export const CONNECTION_TAB_OPTIONS: { value: string; label: string }[] = [ ]; export type GCSAuthMethod = "credentials" | "hmac"; +export type AzureAuthMethod = + | "connection_string" + | "storage_key" + | "sas_token" + | "public"; export const GCS_AUTH_OPTIONS: { value: GCSAuthMethod; @@ -39,6 +44,34 @@ export const GCS_AUTH_OPTIONS: { }, ]; +export const AZURE_AUTH_OPTIONS: { + value: AzureAuthMethod; + label: string; + description: string; + hint?: string; +}[] = [ + { + value: "connection_string", + label: "Connection String", + description: "Alternative for cloud deployment", + }, + { + value: "storage_key", + label: "Storage Account Key", + description: "Recommended for cloud deployment", + }, + { + value: "sas_token", + label: "Shared Access Signature (SAS) Token", + description: "Most secure, fine-grained control", + }, + { + value: "public", + label: "Public", + description: "Use Azure CLI or anonymous access (local only)", + }, +]; + // pre-defined order for sources export const SOURCES = [ "athena", From aafcbf6571e2f75fae4014cf88c04cb3269dae23 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Tue, 25 Nov 2025 16:08:21 +0800 Subject: [PATCH 5/6] remove public --- .../sources/modal/AzureMultiStepForm.svelte | 20 +++---------------- .../src/features/sources/modal/constants.ts | 5 ----- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/web-common/src/features/sources/modal/AzureMultiStepForm.svelte b/web-common/src/features/sources/modal/AzureMultiStepForm.svelte index 03c7d8852bd..06c04baef85 100644 --- a/web-common/src/features/sources/modal/AzureMultiStepForm.svelte +++ b/web-common/src/features/sources/modal/AzureMultiStepForm.svelte @@ -5,10 +5,7 @@ import Radio from "@rilldata/web-common/components/forms/Radio.svelte"; import { ConnectorDriverPropertyType } from "@rilldata/web-common/runtime-client"; import { normalizeErrors } from "./utils"; - import { - AZURE_AUTH_OPTIONS, - type AzureAuthMethod, - } from "./constants"; + import { AZURE_AUTH_OPTIONS, type AzureAuthMethod } from "./constants"; export let properties: any[] = []; export let paramsForm: any; @@ -124,11 +121,6 @@ alwaysShowError /> - {:else if option.value === "public"} - {/if} @@ -136,14 +128,9 @@ {#each filteredParamsProperties as property (property.key)} {@const propertyKey = property.key ?? ""} - {#if propertyKey !== "path" && - propertyKey !== "azure_storage_connection_string" && - propertyKey !== "azure_storage_account" && - propertyKey !== "azure_storage_key" && - propertyKey !== "azure_storage_sas_token"} + {#if propertyKey !== "path" && propertyKey !== "azure_storage_connection_string" && propertyKey !== "azure_storage_account" && propertyKey !== "azure_storage_key" && propertyKey !== "azure_storage_sas_token"}
- {#if property.type === ConnectorDriverPropertyType.TYPE_STRING || - property.type === ConnectorDriverPropertyType.TYPE_NUMBER} + {#if property.type === ConnectorDriverPropertyType.TYPE_STRING || property.type === ConnectorDriverPropertyType.TYPE_NUMBER} - diff --git a/web-common/src/features/sources/modal/constants.ts b/web-common/src/features/sources/modal/constants.ts index 37bd5f01102..36871354e42 100644 --- a/web-common/src/features/sources/modal/constants.ts +++ b/web-common/src/features/sources/modal/constants.ts @@ -65,11 +65,6 @@ export const AZURE_AUTH_OPTIONS: { label: "Shared Access Signature (SAS) Token", description: "Most secure, fine-grained control", }, - { - value: "public", - label: "Public", - description: "Use Azure CLI or anonymous access (local only)", - }, ]; // pre-defined order for sources From 435bcdf68bfda62aa0aaa7ab08c04d01b81d0b7b Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Tue, 25 Nov 2025 17:13:28 +0800 Subject: [PATCH 6/6] yupschema --- web-common/src/features/sources/modal/yupSchemas.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web-common/src/features/sources/modal/yupSchemas.ts b/web-common/src/features/sources/modal/yupSchemas.ts index f4e20e7f104..091459dcf0f 100644 --- a/web-common/src/features/sources/modal/yupSchemas.ts +++ b/web-common/src/features/sources/modal/yupSchemas.ts @@ -67,6 +67,9 @@ export const getYupSchema = { azure: yup.object().shape({ azure_storage_connection_string: yup.string(), + azure_storage_account: yup.string(), + azure_storage_key: yup.string(), + azure_storage_sas_token: yup.string(), path: yup .string() .matches(