windmill-components 1.695.1 → 1.699.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +2 -0
- package/dist/sharedUtils/base.d.ts +1 -0
- package/dist/sharedUtils/cloud.d.ts +1 -0
- package/dist/sharedUtils/common.d.ts +111 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +13 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +11 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +95 -0
- package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +6 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +33 -0
- package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +10 -0
- package/dist/sharedUtils/components/apps/editor/component/components.d.ts +5371 -0
- package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/index.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +3 -0
- package/dist/sharedUtils/components/apps/gridUtils.d.ts +14 -0
- package/dist/sharedUtils/components/apps/inputType.d.ts +178 -0
- package/dist/sharedUtils/components/apps/rx.d.ts +29 -0
- package/dist/sharedUtils/components/apps/sharedTypes.d.ts +21 -0
- package/dist/sharedUtils/components/apps/types.d.ts +274 -0
- package/dist/sharedUtils/components/assets/lib.d.ts +25 -0
- package/dist/sharedUtils/components/common/alert/model.d.ts +2 -0
- package/dist/sharedUtils/components/common/badge/model.d.ts +8 -0
- package/dist/sharedUtils/components/common/button/model.d.ts +45 -0
- package/dist/sharedUtils/components/common/fileInput/model.d.ts +1 -0
- package/dist/sharedUtils/components/common/index.d.ts +24 -0
- package/dist/sharedUtils/components/common/skeleton/model.d.ts +21 -0
- package/dist/sharedUtils/components/dbTypes.d.ts +14 -0
- package/dist/sharedUtils/components/diff_drawer.d.ts +26 -0
- package/dist/sharedUtils/components/ducklake.d.ts +1 -0
- package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +7 -0
- package/dist/sharedUtils/components/icons/index.d.ts +101 -0
- package/dist/sharedUtils/components/random_positive_adjetive.d.ts +1 -0
- package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +10 -0
- package/dist/sharedUtils/components/raw_apps/utils.d.ts +15 -0
- package/dist/sharedUtils/components/triggers/email/utils.d.ts +4 -0
- package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/http/utils.d.ts +11 -0
- package/dist/sharedUtils/components/triggers/kafka/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/nats/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +8 -0
- package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +32 -0
- package/dist/sharedUtils/components/triggers/utils.d.ts +80 -0
- package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers.d.ts +20 -0
- package/dist/sharedUtils/gen/core/ApiError.d.ts +10 -0
- package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +13 -0
- package/dist/sharedUtils/gen/core/ApiResult.d.ts +7 -0
- package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +26 -0
- package/dist/sharedUtils/gen/core/OpenAPI.d.ts +27 -0
- package/dist/sharedUtils/gen/core/request.d.ts +29 -0
- package/dist/sharedUtils/gen/index.d.ts +6 -0
- package/dist/sharedUtils/gen/schemas.gen.d.ts +7036 -0
- package/dist/sharedUtils/gen/services.gen.d.ts +6047 -0
- package/dist/sharedUtils/gen/types.gen.d.ts +21881 -0
- package/dist/sharedUtils/history.svelte.d.ts +9 -0
- package/dist/sharedUtils/hub.d.ts +49 -0
- package/dist/sharedUtils/jsr.json +6 -0
- package/dist/sharedUtils/lib.d.ts +5 -0
- package/dist/sharedUtils/lib.es.js +1588 -0
- package/dist/sharedUtils/package.json +12 -0
- package/dist/sharedUtils/schema.d.ts +3 -0
- package/dist/sharedUtils/stores.d.ts +97 -0
- package/dist/sharedUtils/svelte5Utils.svelte.d.ts +80 -0
- package/dist/sharedUtils/toast.d.ts +8 -0
- package/dist/sharedUtils/utils.d.ts +265 -0
- package/package/components/AppConnectInner.svelte +38 -5
- package/package/components/CompareWorkspaces.svelte +142 -486
- package/package/components/DisplayResult.svelte +39 -19
- package/package/components/Editor.svelte +5 -4
- package/package/components/Editor.svelte.d.ts +1 -0
- package/package/components/FilterSearchbar.svelte +3 -1
- package/package/components/FilterSearchbar.svelte.d.ts +1 -0
- package/package/components/FlowStatusViewerInner.svelte +23 -9
- package/package/components/ForkWorkspaceBanner.svelte +16 -0
- package/package/components/HistoricInputs.svelte +2 -1
- package/package/components/InstanceSetting.svelte +47 -5
- package/package/components/LogViewer.svelte +101 -71
- package/package/components/OnBehalfOfSelector.svelte +10 -7
- package/package/components/ParqetCsvTableRenderer.svelte +9 -4
- package/package/components/Path.svelte +10 -0
- package/package/components/ResourceEditor.svelte +198 -311
- package/package/components/ResourceEditor.svelte.d.ts +3 -3
- package/package/components/ResourceEditorDrawer.svelte +17 -6
- package/package/components/ResourceForm.svelte +235 -0
- package/package/components/ResourceForm.svelte.d.ts +25 -0
- package/package/components/RunsPage.svelte +1 -0
- package/package/components/S3FilePickerInner.svelte +22 -8
- package/package/components/ScriptBuilder.svelte +1 -0
- package/package/components/ScriptEditor.svelte +44 -7
- package/package/components/ScriptEditor.svelte.d.ts +1 -0
- package/package/components/ShareModal.svelte.d.ts +1 -1
- package/package/components/TaggedTextInput.svelte +4 -1
- package/package/components/TaggedTextInput.svelte.d.ts +2 -0
- package/package/components/VariableEditor.svelte +177 -199
- package/package/components/VariableEditor.svelte.d.ts +1 -2
- package/package/components/VariableForm.svelte +133 -0
- package/package/components/VariableForm.svelte.d.ts +22 -0
- package/package/components/WsSpecificVersions.svelte +39 -0
- package/package/components/WsSpecificVersions.svelte.d.ts +9 -0
- package/package/components/apps/editor/AppEditorHeaderDeploy.svelte.d.ts +1 -1
- package/package/components/common/fileDownload/FileDownload.svelte +16 -6
- package/package/components/common/table/AppRow.svelte +2 -1
- package/package/components/common/table/AppRow.svelte.d.ts +1 -0
- package/package/components/common/table/FlowRow.svelte +2 -1
- package/package/components/common/table/FlowRow.svelte.d.ts +1 -0
- package/package/components/common/table/RawAppRow.svelte +2 -1
- package/package/components/common/table/RawAppRow.svelte.d.ts +1 -0
- package/package/components/common/table/Row.svelte +11 -3
- package/package/components/common/table/Row.svelte.d.ts +2 -1
- package/package/components/common/table/RowIcon.svelte +18 -2
- package/package/components/common/table/RowIcon.svelte.d.ts +1 -1
- package/package/components/common/table/ScriptRow.svelte +2 -1
- package/package/components/common/table/ScriptRow.svelte.d.ts +1 -0
- package/package/components/copilot/autocomplete/Autocompletor.d.ts +3 -1
- package/package/components/copilot/autocomplete/Autocompletor.js +5 -2
- package/package/components/copilot/autocomplete/request.d.ts +1 -0
- package/package/components/copilot/autocomplete/request.js +1 -1
- package/package/components/copilot/chat/AIChatManager.svelte.js +14 -4
- package/package/components/copilot/chat/AiChatLayout.svelte +2 -0
- package/package/components/copilot/chat/ContextManager.svelte.d.ts +1 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte +129 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte.d.ts +4 -0
- package/package/components/copilot/chat/ToolExecutionDisplay.svelte +14 -6
- package/package/components/copilot/chat/ToolMessageActions.svelte +73 -0
- package/package/components/copilot/chat/ToolMessageActions.svelte.d.ts +7 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.d.ts +6 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.js +29 -0
- package/package/components/copilot/chat/script/core.d.ts +6 -2
- package/package/components/copilot/chat/script/core.js +13 -7
- package/package/components/copilot/chat/script/wacPrompt.test.d.ts +1 -0
- package/package/components/copilot/chat/script/wacPrompt.test.js +25 -0
- package/package/components/copilot/chat/shared.d.ts +12 -0
- package/package/components/copilot/chat/shared.test.js +23 -2
- package/package/components/copilot/chat/workspaceTools.js +34 -4
- package/package/components/flows/content/ScriptEditorDrawer.svelte +1 -0
- package/package/components/flows/idUtils.js +4 -1
- package/package/components/flows/stepsInputArgs.svelte.js +6 -1
- package/package/components/graph/wacToFlow.js +1 -1
- package/package/components/graph/wacToFlow.test.d.ts +1 -0
- package/package/components/graph/wacToFlow.test.js +17 -0
- package/package/components/home/Item.svelte +5 -1
- package/package/components/home/Item.svelte.d.ts +1 -0
- package/package/components/home/ItemsList.svelte +260 -3
- package/package/components/instanceSettings/SecretBackendConfig.svelte +492 -98
- package/package/components/propertyPicker/ObjectViewer.svelte +10 -4
- package/package/components/runs/runsFilter.d.ts +1 -1
- package/package/components/runs/useJobsLoader.svelte.d.ts +1 -0
- package/package/components/runs/useJobsLoader.svelte.js +8 -12
- package/package/components/scriptEditor/LogPanel.svelte +4 -1
- package/package/components/scriptEditor/LogPanel.svelte.d.ts +1 -0
- package/package/components/settings/WorkspaceOperatorSettings.svelte +1 -1
- package/package/components/sidebar/SidebarContent.svelte +40 -2
- package/package/components/sidebar/WorkspaceMenu.svelte +19 -5
- package/package/externalDomain.d.ts +2 -0
- package/package/externalDomain.js +16 -0
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/schemas.gen.d.ts +33 -4
- package/package/gen/schemas.gen.js +33 -4
- package/package/gen/services.gen.d.ts +20 -1
- package/package/gen/services.gen.js +40 -0
- package/package/gen/types.gen.d.ts +70 -3
- package/package/hubPaths.json +2 -2
- package/package/system_prompts/index.d.ts +1 -1
- package/package/system_prompts/index.js +22 -3
- package/package/system_prompts/prompts.d.ts +2 -2
- package/package/system_prompts/prompts.js +7 -4
- package/package/utils/downloadFile.d.ts +11 -0
- package/package/utils/downloadFile.js +48 -0
- package/package/utils_deployable.d.ts +162 -638
- package/package/utils_deployable.js +75 -143
- package/package/utils_workspace_deploy.d.ts +10 -4
- package/package/utils_workspace_deploy.js +167 -42
- package/package.json +7 -3
|
@@ -42,7 +42,8 @@ let vaultDisabled = $derived(!$enterpriseLicense);
|
|
|
42
42
|
function setBackendType(type) {
|
|
43
43
|
if (!type)
|
|
44
44
|
return;
|
|
45
|
-
if ((type === 'HashiCorpVault' || type === 'AzureKeyVault' || type === 'AwsSecretsManager') &&
|
|
45
|
+
if ((type === 'HashiCorpVault' || type === 'AzureKeyVault' || type === 'AwsSecretsManager') &&
|
|
46
|
+
vaultDisabled)
|
|
46
47
|
return;
|
|
47
48
|
if (type === 'Database') {
|
|
48
49
|
$values['secret_backend'] = { type: 'Database' };
|
|
@@ -53,6 +54,7 @@ function setBackendType(type) {
|
|
|
53
54
|
address: $values['secret_backend']?.address ?? '',
|
|
54
55
|
mount_path: $values['secret_backend']?.mount_path ?? 'windmill',
|
|
55
56
|
jwt_role: $values['secret_backend']?.jwt_role ?? 'windmill-secrets',
|
|
57
|
+
jwt_mount_path: $values['secret_backend']?.jwt_mount_path ?? null,
|
|
56
58
|
namespace: $values['secret_backend']?.namespace ?? null,
|
|
57
59
|
token: $values['secret_backend']?.token ?? null,
|
|
58
60
|
skip_ssl_verify: $values['secret_backend']?.skip_ssl_verify ?? false
|
|
@@ -80,13 +82,23 @@ function setBackendType(type) {
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
function setAuthMethod(method) {
|
|
83
|
-
if (!method ||
|
|
85
|
+
if (!method ||
|
|
86
|
+
!$values['secret_backend'] ||
|
|
87
|
+
$values['secret_backend'].type !== 'HashiCorpVault')
|
|
84
88
|
return;
|
|
85
89
|
if (method === 'token') {
|
|
86
|
-
$values['secret_backend'] = {
|
|
90
|
+
$values['secret_backend'] = {
|
|
91
|
+
...$values['secret_backend'],
|
|
92
|
+
jwt_role: null,
|
|
93
|
+
token: $values['secret_backend'].token ?? ''
|
|
94
|
+
};
|
|
87
95
|
}
|
|
88
96
|
else if (method === 'jwt') {
|
|
89
|
-
$values['secret_backend'] = {
|
|
97
|
+
$values['secret_backend'] = {
|
|
98
|
+
...$values['secret_backend'],
|
|
99
|
+
token: null,
|
|
100
|
+
jwt_role: $values['secret_backend'].jwt_role ?? 'windmill-secrets'
|
|
101
|
+
};
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
function getVaultSettings() {
|
|
@@ -94,6 +106,7 @@ function getVaultSettings() {
|
|
|
94
106
|
address: $values['secret_backend'].address,
|
|
95
107
|
mount_path: $values['secret_backend'].mount_path,
|
|
96
108
|
jwt_role: $values['secret_backend'].jwt_role,
|
|
109
|
+
jwt_mount_path: $values['secret_backend'].jwt_mount_path || undefined,
|
|
97
110
|
namespace: $values['secret_backend'].namespace || undefined,
|
|
98
111
|
token: $values['secret_backend'].token || undefined,
|
|
99
112
|
skip_ssl_verify: $values['secret_backend'].skip_ssl_verify || undefined
|
|
@@ -138,7 +151,9 @@ async function migrateSecretsToDatabase() {
|
|
|
138
151
|
return;
|
|
139
152
|
migratingToDatabase = true;
|
|
140
153
|
try {
|
|
141
|
-
const report = await SettingService.migrateSecretsToDatabase({
|
|
154
|
+
const report = await SettingService.migrateSecretsToDatabase({
|
|
155
|
+
requestBody: getVaultSettings()
|
|
156
|
+
});
|
|
142
157
|
if (report.failed_count > 0)
|
|
143
158
|
sendUserToast(`Migration: ${report.migrated_count}/${report.total_secrets} migrated, ${report.failed_count} failed`, true);
|
|
144
159
|
else
|
|
@@ -190,7 +205,9 @@ async function migrateSecretsToAzureKv() {
|
|
|
190
205
|
return;
|
|
191
206
|
migratingToAzureKv = true;
|
|
192
207
|
try {
|
|
193
|
-
const report = await SettingService.migrateSecretsToAzureKv({
|
|
208
|
+
const report = await SettingService.migrateSecretsToAzureKv({
|
|
209
|
+
requestBody: getAzureKvSettings()
|
|
210
|
+
});
|
|
194
211
|
if (report.failed_count > 0)
|
|
195
212
|
sendUserToast(`Migration: ${report.migrated_count}/${report.total_secrets} migrated, ${report.failed_count} failed`, true);
|
|
196
213
|
else
|
|
@@ -209,7 +226,9 @@ async function migrateSecretsFromAzureKv() {
|
|
|
209
226
|
return;
|
|
210
227
|
migratingFromAzureKv = true;
|
|
211
228
|
try {
|
|
212
|
-
const report = await SettingService.migrateSecretsFromAzureKv({
|
|
229
|
+
const report = await SettingService.migrateSecretsFromAzureKv({
|
|
230
|
+
requestBody: getAzureKvSettings()
|
|
231
|
+
});
|
|
213
232
|
if (report.failed_count > 0)
|
|
214
233
|
sendUserToast(`Migration: ${report.migrated_count}/${report.total_secrets} migrated, ${report.failed_count} failed`, true);
|
|
215
234
|
else
|
|
@@ -228,8 +247,7 @@ function isAzureKvConfigValid() {
|
|
|
228
247
|
return false;
|
|
229
248
|
return ($values['secret_backend'].vault_url?.trim() !== '' &&
|
|
230
249
|
$values['secret_backend'].tenant_id?.trim() !== '' &&
|
|
231
|
-
$values['secret_backend'].client_id?.trim() !== ''
|
|
232
|
-
(!!$values['secret_backend'].client_secret?.trim() || !!$values['secret_backend'].token?.trim()));
|
|
250
|
+
$values['secret_backend'].client_id?.trim() !== '');
|
|
233
251
|
}
|
|
234
252
|
function getAwsSmSettings() {
|
|
235
253
|
return {
|
|
@@ -279,7 +297,9 @@ async function migrateSecretsFromAwsSm() {
|
|
|
279
297
|
return;
|
|
280
298
|
migratingFromAwsSm = true;
|
|
281
299
|
try {
|
|
282
|
-
const report = await SettingService.migrateSecretsFromAwsSm({
|
|
300
|
+
const report = await SettingService.migrateSecretsFromAwsSm({
|
|
301
|
+
requestBody: getAwsSmSettings()
|
|
302
|
+
});
|
|
283
303
|
if (report.failed_count > 0)
|
|
284
304
|
sendUserToast(`Migration: ${report.migrated_count}/${report.total_secrets} migrated, ${report.failed_count} failed`, true);
|
|
285
305
|
else
|
|
@@ -299,16 +319,47 @@ function isAwsSmConfigValid() {
|
|
|
299
319
|
return $values['secret_backend'].region?.trim() !== '';
|
|
300
320
|
}
|
|
301
321
|
let baseUrl = $derived($values['base_url'] ?? 'https://your-windmill-instance.com');
|
|
322
|
+
let jwtMount = $derived(($values['secret_backend']?.jwt_mount_path?.trim() || 'jwt'));
|
|
323
|
+
let vaultAudience = $derived(($values['secret_backend']?.address?.trim() || 'https://vault.example.com:8200'));
|
|
302
324
|
</script>
|
|
303
325
|
|
|
304
326
|
<div class="space-y-6">
|
|
305
327
|
<div class="flex flex-col gap-2 mt-1">
|
|
306
328
|
<ToggleButtonGroup selected={selectedType} onSelected={(v) => setBackendType(v)}>
|
|
307
329
|
{#snippet children({ item: toggleButton })}
|
|
308
|
-
<ToggleButton
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
330
|
+
<ToggleButton
|
|
331
|
+
value="Database"
|
|
332
|
+
label="Database"
|
|
333
|
+
tooltip="Store secrets encrypted in the database (default)"
|
|
334
|
+
item={toggleButton}
|
|
335
|
+
/>
|
|
336
|
+
<ToggleButton
|
|
337
|
+
value="HashiCorpVault"
|
|
338
|
+
label="HashiCorp Vault (Beta)"
|
|
339
|
+
tooltip={vaultDisabled
|
|
340
|
+
? 'Requires Enterprise Edition'
|
|
341
|
+
: 'Store secrets in HashiCorp Vault'}
|
|
342
|
+
item={toggleButton}
|
|
343
|
+
disabled={vaultDisabled}
|
|
344
|
+
/>
|
|
345
|
+
<ToggleButton
|
|
346
|
+
value="AzureKeyVault"
|
|
347
|
+
label="Azure Key Vault"
|
|
348
|
+
tooltip={vaultDisabled
|
|
349
|
+
? 'Requires Enterprise Edition'
|
|
350
|
+
: 'Store secrets in Azure Key Vault'}
|
|
351
|
+
item={toggleButton}
|
|
352
|
+
disabled={vaultDisabled}
|
|
353
|
+
/>
|
|
354
|
+
<ToggleButton
|
|
355
|
+
value="AwsSecretsManager"
|
|
356
|
+
label="AWS Secrets Manager (Beta)"
|
|
357
|
+
tooltip={vaultDisabled
|
|
358
|
+
? 'Requires Enterprise Edition'
|
|
359
|
+
: 'Store secrets in AWS Secrets Manager'}
|
|
360
|
+
item={toggleButton}
|
|
361
|
+
disabled={vaultDisabled}
|
|
362
|
+
/>
|
|
312
363
|
{/snippet}
|
|
313
364
|
</ToggleButtonGroup>
|
|
314
365
|
{#if vaultDisabled}
|
|
@@ -323,7 +374,10 @@ let baseUrl = $derived($values['base_url'] ?? 'https://your-windmill-instance.co
|
|
|
323
374
|
<Database class="text-primary" size={20} />
|
|
324
375
|
<div>
|
|
325
376
|
<p class="text-sm font-medium text-emphasis">Database Storage (Default)</p>
|
|
326
|
-
<p class="text-xs text-secondary"
|
|
377
|
+
<p class="text-xs text-secondary"
|
|
378
|
+
>Secrets are encrypted using workspace-specific keys and stored in the PostgreSQL
|
|
379
|
+
database.</p
|
|
380
|
+
>
|
|
327
381
|
</div>
|
|
328
382
|
</div>
|
|
329
383
|
{:else if selectedType === 'HashiCorpVault'}
|
|
@@ -331,100 +385,221 @@ let baseUrl = $derived($values['base_url'] ?? 'https://your-windmill-instance.co
|
|
|
331
385
|
<div class="flex items-center gap-2 mb-4">
|
|
332
386
|
<Lock class="text-primary" size={20} />
|
|
333
387
|
<div>
|
|
334
|
-
<p class="text-sm font-medium text-emphasis"
|
|
335
|
-
|
|
388
|
+
<p class="text-sm font-medium text-emphasis"
|
|
389
|
+
>HashiCorp Vault Configuration <span
|
|
390
|
+
class="ml-2 px-1.5 py-0.5 text-2xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 rounded"
|
|
391
|
+
>Beta</span
|
|
392
|
+
></p
|
|
393
|
+
>
|
|
394
|
+
<p class="text-xs text-secondary"
|
|
395
|
+
>Store secrets in an external HashiCorp Vault instance.</p
|
|
396
|
+
>
|
|
336
397
|
</div>
|
|
337
398
|
</div>
|
|
338
399
|
<div class="grid grid-cols-1 gap-4">
|
|
339
400
|
<div class="flex flex-col gap-1">
|
|
340
|
-
<label for="vault_address" class="block text-xs font-semibold text-emphasis"
|
|
341
|
-
|
|
401
|
+
<label for="vault_address" class="block text-xs font-semibold text-emphasis"
|
|
402
|
+
>Vault Address</label
|
|
403
|
+
>
|
|
404
|
+
<TextInput
|
|
405
|
+
inputProps={{
|
|
406
|
+
type: 'text',
|
|
407
|
+
id: 'vault_address',
|
|
408
|
+
placeholder: 'https://vault.company.com:8200',
|
|
409
|
+
disabled
|
|
410
|
+
}}
|
|
411
|
+
bind:value={$values['secret_backend'].address}
|
|
412
|
+
/>
|
|
342
413
|
</div>
|
|
343
414
|
<div class="flex flex-col gap-1">
|
|
344
|
-
<label for="vault_mount_path" class="block text-xs font-semibold text-emphasis"
|
|
415
|
+
<label for="vault_mount_path" class="block text-xs font-semibold text-emphasis"
|
|
416
|
+
>KV Mount Path</label
|
|
417
|
+
>
|
|
345
418
|
<span class="text-2xs text-secondary">The KV v2 secrets engine mount path in Vault</span>
|
|
346
|
-
<TextInput
|
|
419
|
+
<TextInput
|
|
420
|
+
inputProps={{ type: 'text', id: 'vault_mount_path', placeholder: 'windmill', disabled }}
|
|
421
|
+
bind:value={$values['secret_backend'].mount_path}
|
|
422
|
+
/>
|
|
347
423
|
</div>
|
|
348
424
|
<div class="flex flex-col gap-2">
|
|
349
425
|
<span class="block text-xs font-semibold text-emphasis">Authentication Method</span>
|
|
350
426
|
<ToggleButtonGroup selected={authMethod} onSelected={(v) => setAuthMethod(v)}>
|
|
351
427
|
{#snippet children({ item: toggleButton })}
|
|
352
|
-
<ToggleButton
|
|
353
|
-
|
|
428
|
+
<ToggleButton
|
|
429
|
+
value="jwt"
|
|
430
|
+
label="JWT Auth"
|
|
431
|
+
tooltip="Authenticate using Windmill-signed JWTs"
|
|
432
|
+
item={toggleButton}
|
|
433
|
+
{disabled}
|
|
434
|
+
/>
|
|
435
|
+
<ToggleButton
|
|
436
|
+
value="token"
|
|
437
|
+
label="Static Token"
|
|
438
|
+
tooltip="Use a static Vault token"
|
|
439
|
+
item={toggleButton}
|
|
440
|
+
{disabled}
|
|
441
|
+
/>
|
|
354
442
|
{/snippet}
|
|
355
443
|
</ToggleButtonGroup>
|
|
356
444
|
</div>
|
|
357
445
|
{#if authMethod === 'token'}
|
|
358
446
|
<div class="flex flex-col gap-1 p-3 bg-surface-secondary rounded-lg">
|
|
359
|
-
<label for="vault_token" class="block text-xs font-semibold text-emphasis"
|
|
360
|
-
|
|
447
|
+
<label for="vault_token" class="block text-xs font-semibold text-emphasis"
|
|
448
|
+
>Vault Token</label
|
|
449
|
+
>
|
|
450
|
+
<span class="text-2xs text-secondary"
|
|
451
|
+
>Static token. Recommended only for testing/development.</span
|
|
452
|
+
>
|
|
361
453
|
<Password bind:password={$values['secret_backend'].token} small {disabled} />
|
|
362
454
|
</div>
|
|
363
455
|
{:else}
|
|
364
456
|
<div class="flex flex-col gap-2 p-3 bg-surface-secondary rounded-lg">
|
|
365
|
-
<label for="vault_jwt_role" class="block text-xs font-semibold text-emphasis"
|
|
366
|
-
|
|
367
|
-
|
|
457
|
+
<label for="vault_jwt_role" class="block text-xs font-semibold text-emphasis"
|
|
458
|
+
>JWT Auth Role</label
|
|
459
|
+
>
|
|
460
|
+
<span class="text-2xs text-secondary"
|
|
461
|
+
>The JWT authentication role configured in Vault.</span
|
|
462
|
+
>
|
|
463
|
+
<TextInput
|
|
464
|
+
inputProps={{
|
|
465
|
+
type: 'text',
|
|
466
|
+
id: 'vault_jwt_role',
|
|
467
|
+
placeholder: 'windmill-secrets',
|
|
468
|
+
disabled
|
|
469
|
+
}}
|
|
470
|
+
bind:value={$values['secret_backend'].jwt_role}
|
|
471
|
+
/>
|
|
472
|
+
<label for="vault_jwt_mount_path" class="block text-xs font-semibold text-emphasis"
|
|
473
|
+
>JWT Auth Mount Path (optional)</label
|
|
474
|
+
>
|
|
475
|
+
<span class="text-2xs text-secondary"
|
|
476
|
+
>Mount path of the JWT auth method in Vault. Defaults to <code>jwt</code>. Set this
|
|
477
|
+
only if you mounted the JWT auth method at a non-default path (<code
|
|
478
|
+
>vault auth enable -path=<mount> jwt</code
|
|
479
|
+
>).</span
|
|
480
|
+
>
|
|
481
|
+
<TextInput
|
|
482
|
+
inputProps={{
|
|
483
|
+
type: 'text',
|
|
484
|
+
id: 'vault_jwt_mount_path',
|
|
485
|
+
placeholder: 'jwt',
|
|
486
|
+
disabled
|
|
487
|
+
}}
|
|
488
|
+
bind:value={$values['secret_backend'].jwt_mount_path}
|
|
489
|
+
/>
|
|
368
490
|
<details class="mt-2">
|
|
369
|
-
<summary class="text-xs font-medium text-secondary cursor-pointer hover:text-primary"
|
|
491
|
+
<summary class="text-xs font-medium text-secondary cursor-pointer hover:text-primary"
|
|
492
|
+
>Vault JWT Setup Instructions</summary
|
|
493
|
+
>
|
|
370
494
|
<div class="mt-2 p-2 bg-surface rounded text-2xs text-secondary space-y-2">
|
|
371
495
|
<p>Configure Vault to accept JWTs from Windmill:</p>
|
|
372
|
-
<div
|
|
373
|
-
|
|
374
|
-
|
|
496
|
+
<div
|
|
497
|
+
class="bg-gray-100 dark:bg-gray-800 p-2 rounded font-mono text-2xs overflow-x-auto"
|
|
498
|
+
>
|
|
499
|
+
<pre
|
|
500
|
+
># Enable JWT auth method{jwtMount === 'jwt'
|
|
501
|
+
? ''
|
|
502
|
+
: ` at custom mount '${jwtMount}'`}
|
|
503
|
+
vault auth enable {jwtMount === 'jwt' ? 'jwt' : `-path=${jwtMount} jwt`}
|
|
375
504
|
|
|
376
505
|
# Configure JWT auth with Windmill's JWKS endpoint
|
|
377
|
-
vault write auth/
|
|
378
|
-
jwks_url="{baseUrl}
|
|
379
|
-
bound_issuer="{baseUrl}"
|
|
506
|
+
vault write auth/{jwtMount}/config \
|
|
507
|
+
jwks_url="{baseUrl}/api/oidc/jwks" \
|
|
508
|
+
bound_issuer="{baseUrl}/api/oidc/"
|
|
380
509
|
|
|
381
510
|
# Create a policy for Windmill secrets
|
|
382
511
|
vault policy write windmill-secrets - <<EOF
|
|
383
|
-
path "windmill/data/*" {
|
|
512
|
+
path "{$values['secret_backend']?.mount_path ?? 'windmill'}/data/*" {
|
|
384
513
|
capabilities = ["create", "read", "update", "delete"]
|
|
385
514
|
}
|
|
386
|
-
path "windmill/metadata/*" {
|
|
515
|
+
path "{$values['secret_backend']?.mount_path ?? 'windmill'}/metadata/*" {
|
|
387
516
|
capabilities = ["list", "delete"]
|
|
388
517
|
}
|
|
389
518
|
EOF
|
|
390
519
|
|
|
391
|
-
# Create the JWT role
|
|
392
|
-
|
|
520
|
+
# Create the JWT role. bound_audiences must match the Vault server
|
|
521
|
+
# address — Windmill signs the JWT with `aud` = your Vault address.
|
|
522
|
+
vault write auth/{jwtMount}/role/{$values['secret_backend']?.jwt_role || 'windmill-secrets'} \
|
|
393
523
|
role_type="jwt" \
|
|
394
|
-
bound_audiences="{
|
|
395
|
-
user_claim="
|
|
524
|
+
bound_audiences="{vaultAudience}" \
|
|
525
|
+
user_claim="sub" \
|
|
396
526
|
policies="windmill-secrets" \
|
|
397
|
-
ttl="1h"</pre
|
|
527
|
+
ttl="1h"</pre
|
|
528
|
+
>
|
|
398
529
|
</div>
|
|
399
530
|
</div>
|
|
400
531
|
</details>
|
|
401
532
|
</div>
|
|
402
533
|
{/if}
|
|
403
534
|
<div class="flex flex-col gap-1">
|
|
404
|
-
<label for="vault_namespace" class="block text-xs font-semibold text-emphasis"
|
|
535
|
+
<label for="vault_namespace" class="block text-xs font-semibold text-emphasis"
|
|
536
|
+
>Namespace (optional)</label
|
|
537
|
+
>
|
|
405
538
|
<span class="text-2xs text-secondary">Vault Enterprise namespace</span>
|
|
406
|
-
<TextInput
|
|
539
|
+
<TextInput
|
|
540
|
+
inputProps={{
|
|
541
|
+
type: 'text',
|
|
542
|
+
id: 'vault_namespace',
|
|
543
|
+
placeholder: 'admin/my-namespace',
|
|
544
|
+
disabled
|
|
545
|
+
}}
|
|
546
|
+
bind:value={$values['secret_backend'].namespace}
|
|
547
|
+
/>
|
|
407
548
|
</div>
|
|
408
549
|
<div class="flex flex-col gap-1">
|
|
409
|
-
<Toggle
|
|
410
|
-
|
|
550
|
+
<Toggle
|
|
551
|
+
id="vault_skip_ssl_verify"
|
|
552
|
+
{disabled}
|
|
553
|
+
bind:checked={$values['secret_backend'].skip_ssl_verify}
|
|
554
|
+
size="xs"
|
|
555
|
+
options={{ right: 'Skip TLS certificate verification' }}
|
|
556
|
+
/>
|
|
557
|
+
<span class="text-2xs text-secondary"
|
|
558
|
+
>Disables TLS verification when connecting to Vault. Only enable for self-signed
|
|
559
|
+
certificates in development.</span
|
|
560
|
+
>
|
|
411
561
|
</div>
|
|
412
562
|
</div>
|
|
413
563
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
414
|
-
<Button
|
|
564
|
+
<Button
|
|
565
|
+
unifiedSize="md"
|
|
566
|
+
variant="accent"
|
|
567
|
+
onclick={testVaultConnection}
|
|
568
|
+
disabled={disabled || !isVaultConfigValid() || testingConnection}
|
|
569
|
+
loading={testingConnection}
|
|
570
|
+
startIcon={{ icon: Server }}>Test Connection</Button
|
|
571
|
+
>
|
|
415
572
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
416
573
|
<span class="block text-xs font-semibold text-emphasis">Secret Migration</span>
|
|
417
|
-
<span class="text-2xs text-secondary"
|
|
574
|
+
<span class="text-2xs text-secondary"
|
|
575
|
+
>Original values are NOT deleted to allow for rollback.</span
|
|
576
|
+
>
|
|
418
577
|
<div class="flex gap-4">
|
|
419
578
|
<div class="flex-1 p-3 border rounded-lg">
|
|
420
|
-
<div class="flex items-center gap-2 mb-2"
|
|
579
|
+
<div class="flex items-center gap-2 mb-2"
|
|
580
|
+
><Database size={16} /><ArrowRight size={16} /><Lock size={16} /></div
|
|
581
|
+
>
|
|
421
582
|
<p class="text-xs font-medium mb-2">Database → Vault</p>
|
|
422
|
-
<Button
|
|
583
|
+
<Button
|
|
584
|
+
unifiedSize="sm"
|
|
585
|
+
variant="default"
|
|
586
|
+
onclick={() => (migrateToVaultModalOpen = true)}
|
|
587
|
+
disabled={disabled || !isVaultConfigValid() || migratingToVault}
|
|
588
|
+
startIcon={{ icon: ArrowRight }}>Migrate to Vault</Button
|
|
589
|
+
>
|
|
423
590
|
</div>
|
|
424
591
|
<div class="flex-1 p-3 border rounded-lg">
|
|
425
|
-
<div class="flex items-center gap-2 mb-2"
|
|
592
|
+
<div class="flex items-center gap-2 mb-2"
|
|
593
|
+
><Lock size={16} /><ArrowLeft size={16} /><Database size={16} /></div
|
|
594
|
+
>
|
|
426
595
|
<p class="text-xs font-medium mb-2">Vault → Database</p>
|
|
427
|
-
<Button
|
|
596
|
+
<Button
|
|
597
|
+
unifiedSize="sm"
|
|
598
|
+
variant="default"
|
|
599
|
+
onclick={() => (migrateToDatabaseModalOpen = true)}
|
|
600
|
+
disabled={disabled || !isVaultConfigValid() || migratingToDatabase}
|
|
601
|
+
startIcon={{ icon: ArrowLeft }}>Migrate to Database</Button
|
|
602
|
+
>
|
|
428
603
|
</div>
|
|
429
604
|
</div>
|
|
430
605
|
</div>
|
|
@@ -441,42 +616,109 @@ vault write auth/jwt/role/windmill-secrets \
|
|
|
441
616
|
</div>
|
|
442
617
|
<div class="grid grid-cols-1 gap-4">
|
|
443
618
|
<div class="flex flex-col gap-1">
|
|
444
|
-
<label for="azure_vault_url" class="block text-xs font-semibold text-emphasis"
|
|
445
|
-
|
|
619
|
+
<label for="azure_vault_url" class="block text-xs font-semibold text-emphasis"
|
|
620
|
+
>Vault URL</label
|
|
621
|
+
>
|
|
622
|
+
<TextInput
|
|
623
|
+
inputProps={{
|
|
624
|
+
type: 'text',
|
|
625
|
+
id: 'azure_vault_url',
|
|
626
|
+
placeholder: 'https://my-vault.vault.azure.net',
|
|
627
|
+
disabled
|
|
628
|
+
}}
|
|
629
|
+
bind:value={$values['secret_backend'].vault_url}
|
|
630
|
+
/>
|
|
446
631
|
</div>
|
|
447
632
|
<div class="flex flex-col gap-1">
|
|
448
|
-
<label for="azure_tenant_id" class="block text-xs font-semibold text-emphasis"
|
|
449
|
-
|
|
633
|
+
<label for="azure_tenant_id" class="block text-xs font-semibold text-emphasis"
|
|
634
|
+
>Tenant ID</label
|
|
635
|
+
>
|
|
636
|
+
<TextInput
|
|
637
|
+
inputProps={{
|
|
638
|
+
type: 'text',
|
|
639
|
+
id: 'azure_tenant_id',
|
|
640
|
+
placeholder: '00000000-0000-0000-0000-000000000000',
|
|
641
|
+
disabled
|
|
642
|
+
}}
|
|
643
|
+
bind:value={$values['secret_backend'].tenant_id}
|
|
644
|
+
/>
|
|
450
645
|
</div>
|
|
451
646
|
<div class="flex flex-col gap-1">
|
|
452
|
-
<label for="azure_client_id" class="block text-xs font-semibold text-emphasis"
|
|
453
|
-
|
|
647
|
+
<label for="azure_client_id" class="block text-xs font-semibold text-emphasis"
|
|
648
|
+
>Client ID</label
|
|
649
|
+
>
|
|
650
|
+
<TextInput
|
|
651
|
+
inputProps={{
|
|
652
|
+
type: 'text',
|
|
653
|
+
id: 'azure_client_id',
|
|
654
|
+
placeholder: '00000000-0000-0000-0000-000000000000',
|
|
655
|
+
disabled
|
|
656
|
+
}}
|
|
657
|
+
bind:value={$values['secret_backend'].client_id}
|
|
658
|
+
/>
|
|
454
659
|
</div>
|
|
455
660
|
<div class="flex flex-col gap-1 p-3 bg-surface-secondary rounded-lg">
|
|
456
|
-
<label for="azure_client_secret" class="block text-xs font-semibold text-emphasis"
|
|
661
|
+
<label for="azure_client_secret" class="block text-xs font-semibold text-emphasis"
|
|
662
|
+
>Client Secret <span class="text-2xs font-normal text-secondary">(optional)</span
|
|
663
|
+
></label
|
|
664
|
+
>
|
|
665
|
+
<span class="text-2xs text-secondary"
|
|
666
|
+
>Leave blank to use Azure Workload Identity. Requires
|
|
667
|
+
<code>AZURE_FEDERATED_TOKEN_FILE</code> on the Windmill process (auto-injected on AKS by
|
|
668
|
+
the workload-identity webhook; set manually on other Kubernetes clusters).</span
|
|
669
|
+
>
|
|
457
670
|
<Password bind:password={$values['secret_backend'].client_secret} small {disabled} />
|
|
458
671
|
</div>
|
|
459
672
|
<div class="flex flex-col gap-1 p-3 bg-surface-secondary rounded-lg">
|
|
460
|
-
<label for="azure_token" class="block text-xs font-semibold text-emphasis"
|
|
461
|
-
|
|
673
|
+
<label for="azure_token" class="block text-xs font-semibold text-emphasis"
|
|
674
|
+
>Token (optional)</label
|
|
675
|
+
>
|
|
676
|
+
<span class="text-2xs text-secondary"
|
|
677
|
+
>Static Bearer token for testing. If provided, OAuth2 is skipped.</span
|
|
678
|
+
>
|
|
462
679
|
<Password bind:password={$values['secret_backend'].token} small {disabled} />
|
|
463
680
|
</div>
|
|
464
681
|
</div>
|
|
465
682
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
466
|
-
<Button
|
|
683
|
+
<Button
|
|
684
|
+
unifiedSize="md"
|
|
685
|
+
variant="accent"
|
|
686
|
+
onclick={testAzureKvConnection}
|
|
687
|
+
disabled={disabled || !isAzureKvConfigValid() || testingAzureKvConnection}
|
|
688
|
+
loading={testingAzureKvConnection}
|
|
689
|
+
startIcon={{ icon: Server }}>Test Connection</Button
|
|
690
|
+
>
|
|
467
691
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
468
692
|
<span class="block text-xs font-semibold text-emphasis">Secret Migration</span>
|
|
469
|
-
<span class="text-2xs text-secondary"
|
|
693
|
+
<span class="text-2xs text-secondary"
|
|
694
|
+
>Original values are NOT deleted to allow for rollback.</span
|
|
695
|
+
>
|
|
470
696
|
<div class="flex gap-4">
|
|
471
697
|
<div class="flex-1 p-3 border rounded-lg">
|
|
472
|
-
<div class="flex items-center gap-2 mb-2"
|
|
698
|
+
<div class="flex items-center gap-2 mb-2"
|
|
699
|
+
><Database size={16} /><ArrowRight size={16} /><Cloud size={16} /></div
|
|
700
|
+
>
|
|
473
701
|
<p class="text-xs font-medium mb-2">Database → Azure Key Vault</p>
|
|
474
|
-
<Button
|
|
702
|
+
<Button
|
|
703
|
+
unifiedSize="sm"
|
|
704
|
+
variant="default"
|
|
705
|
+
onclick={() => (migrateToAzureKvModalOpen = true)}
|
|
706
|
+
disabled={disabled || !isAzureKvConfigValid() || migratingToAzureKv}
|
|
707
|
+
startIcon={{ icon: ArrowRight }}>Migrate to Azure KV</Button
|
|
708
|
+
>
|
|
475
709
|
</div>
|
|
476
710
|
<div class="flex-1 p-3 border rounded-lg">
|
|
477
|
-
<div class="flex items-center gap-2 mb-2"
|
|
711
|
+
<div class="flex items-center gap-2 mb-2"
|
|
712
|
+
><Cloud size={16} /><ArrowLeft size={16} /><Database size={16} /></div
|
|
713
|
+
>
|
|
478
714
|
<p class="text-xs font-medium mb-2">Azure Key Vault → Database</p>
|
|
479
|
-
<Button
|
|
715
|
+
<Button
|
|
716
|
+
unifiedSize="sm"
|
|
717
|
+
variant="default"
|
|
718
|
+
onclick={() => (migrateFromAzureKvModalOpen = true)}
|
|
719
|
+
disabled={disabled || !isAzureKvConfigValid() || migratingFromAzureKv}
|
|
720
|
+
startIcon={{ icon: ArrowLeft }}>Migrate to Database</Button
|
|
721
|
+
>
|
|
480
722
|
</div>
|
|
481
723
|
</div>
|
|
482
724
|
</div>
|
|
@@ -487,50 +729,118 @@ vault write auth/jwt/role/windmill-secrets \
|
|
|
487
729
|
<div class="flex items-center gap-2 mb-4">
|
|
488
730
|
<Cloud class="text-primary" size={20} />
|
|
489
731
|
<div>
|
|
490
|
-
<p class="text-sm font-medium text-emphasis"
|
|
732
|
+
<p class="text-sm font-medium text-emphasis"
|
|
733
|
+
>AWS Secrets Manager Configuration <span
|
|
734
|
+
class="ml-2 px-1.5 py-0.5 text-2xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 rounded"
|
|
735
|
+
>Beta</span
|
|
736
|
+
></p
|
|
737
|
+
>
|
|
491
738
|
<p class="text-xs text-secondary">Store secrets in AWS Secrets Manager.</p>
|
|
492
739
|
</div>
|
|
493
740
|
</div>
|
|
494
741
|
<div class="grid grid-cols-1 gap-4">
|
|
495
742
|
<div class="flex flex-col gap-1">
|
|
496
|
-
<label for="aws_sm_region" class="block text-xs font-semibold text-emphasis">Region</label
|
|
497
|
-
|
|
743
|
+
<label for="aws_sm_region" class="block text-xs font-semibold text-emphasis">Region</label
|
|
744
|
+
>
|
|
745
|
+
<TextInput
|
|
746
|
+
inputProps={{ type: 'text', id: 'aws_sm_region', placeholder: 'us-east-1', disabled }}
|
|
747
|
+
bind:value={$values['secret_backend'].region}
|
|
748
|
+
/>
|
|
498
749
|
</div>
|
|
499
750
|
<div class="flex flex-col gap-1">
|
|
500
|
-
<label for="aws_sm_access_key_id" class="block text-xs font-semibold text-emphasis"
|
|
501
|
-
|
|
502
|
-
|
|
751
|
+
<label for="aws_sm_access_key_id" class="block text-xs font-semibold text-emphasis"
|
|
752
|
+
>Access Key ID (optional)</label
|
|
753
|
+
>
|
|
754
|
+
<span class="text-2xs text-secondary"
|
|
755
|
+
>If not provided, the default AWS credential chain is used (env vars, instance profile,
|
|
756
|
+
EKS pod identity)</span
|
|
757
|
+
>
|
|
758
|
+
<TextInput
|
|
759
|
+
inputProps={{
|
|
760
|
+
type: 'text',
|
|
761
|
+
id: 'aws_sm_access_key_id',
|
|
762
|
+
placeholder: 'AKIA...',
|
|
763
|
+
disabled
|
|
764
|
+
}}
|
|
765
|
+
bind:value={$values['secret_backend'].access_key_id}
|
|
766
|
+
/>
|
|
503
767
|
</div>
|
|
504
768
|
<div class="flex flex-col gap-1 p-3 bg-surface-secondary rounded-lg">
|
|
505
|
-
<label for="aws_sm_secret_access_key" class="block text-xs font-semibold text-emphasis"
|
|
769
|
+
<label for="aws_sm_secret_access_key" class="block text-xs font-semibold text-emphasis"
|
|
770
|
+
>Secret Access Key (optional)</label
|
|
771
|
+
>
|
|
506
772
|
<Password bind:password={$values['secret_backend'].secret_access_key} small {disabled} />
|
|
507
773
|
</div>
|
|
508
774
|
<div class="flex flex-col gap-1">
|
|
509
|
-
<label for="aws_sm_prefix" class="block text-xs font-semibold text-emphasis"
|
|
510
|
-
|
|
511
|
-
|
|
775
|
+
<label for="aws_sm_prefix" class="block text-xs font-semibold text-emphasis"
|
|
776
|
+
>Secret Name Prefix (optional)</label
|
|
777
|
+
>
|
|
778
|
+
<span class="text-2xs text-secondary"
|
|
779
|
+
>Prefix for secret names in AWS Secrets Manager (default: windmill/)</span
|
|
780
|
+
>
|
|
781
|
+
<TextInput
|
|
782
|
+
inputProps={{ type: 'text', id: 'aws_sm_prefix', placeholder: 'windmill/', disabled }}
|
|
783
|
+
bind:value={$values['secret_backend'].prefix}
|
|
784
|
+
/>
|
|
512
785
|
</div>
|
|
513
786
|
<div class="flex flex-col gap-1">
|
|
514
|
-
<label for="aws_sm_endpoint_url" class="block text-xs font-semibold text-emphasis"
|
|
515
|
-
|
|
516
|
-
|
|
787
|
+
<label for="aws_sm_endpoint_url" class="block text-xs font-semibold text-emphasis"
|
|
788
|
+
>Endpoint URL (optional)</label
|
|
789
|
+
>
|
|
790
|
+
<span class="text-2xs text-secondary"
|
|
791
|
+
>Custom endpoint for LocalStack or other compatible services</span
|
|
792
|
+
>
|
|
793
|
+
<TextInput
|
|
794
|
+
inputProps={{
|
|
795
|
+
type: 'text',
|
|
796
|
+
id: 'aws_sm_endpoint_url',
|
|
797
|
+
placeholder: 'http://localhost:4566',
|
|
798
|
+
disabled
|
|
799
|
+
}}
|
|
800
|
+
bind:value={$values['secret_backend'].endpoint_url}
|
|
801
|
+
/>
|
|
517
802
|
</div>
|
|
518
803
|
</div>
|
|
519
804
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
520
|
-
<Button
|
|
805
|
+
<Button
|
|
806
|
+
unifiedSize="md"
|
|
807
|
+
variant="accent"
|
|
808
|
+
onclick={testAwsSmConnection}
|
|
809
|
+
disabled={disabled || !isAwsSmConfigValid() || testingAwsSmConnection}
|
|
810
|
+
loading={testingAwsSmConnection}
|
|
811
|
+
startIcon={{ icon: Server }}>Test Connection</Button
|
|
812
|
+
>
|
|
521
813
|
<div class="flex flex-col gap-4 pt-4 border-t">
|
|
522
814
|
<span class="block text-xs font-semibold text-emphasis">Secret Migration</span>
|
|
523
|
-
<span class="text-2xs text-secondary"
|
|
815
|
+
<span class="text-2xs text-secondary"
|
|
816
|
+
>Original values are NOT deleted to allow for rollback.</span
|
|
817
|
+
>
|
|
524
818
|
<div class="flex gap-4">
|
|
525
819
|
<div class="flex-1 p-3 border rounded-lg">
|
|
526
|
-
<div class="flex items-center gap-2 mb-2"
|
|
820
|
+
<div class="flex items-center gap-2 mb-2"
|
|
821
|
+
><Database size={16} /><ArrowRight size={16} /><Cloud size={16} /></div
|
|
822
|
+
>
|
|
527
823
|
<p class="text-xs font-medium mb-2">Database → AWS Secrets Manager</p>
|
|
528
|
-
<Button
|
|
824
|
+
<Button
|
|
825
|
+
unifiedSize="sm"
|
|
826
|
+
variant="default"
|
|
827
|
+
onclick={() => (migrateToAwsSmModalOpen = true)}
|
|
828
|
+
disabled={disabled || !isAwsSmConfigValid() || migratingToAwsSm}
|
|
829
|
+
startIcon={{ icon: ArrowRight }}>Migrate to AWS SM</Button
|
|
830
|
+
>
|
|
529
831
|
</div>
|
|
530
832
|
<div class="flex-1 p-3 border rounded-lg">
|
|
531
|
-
<div class="flex items-center gap-2 mb-2"
|
|
833
|
+
<div class="flex items-center gap-2 mb-2"
|
|
834
|
+
><Cloud size={16} /><ArrowLeft size={16} /><Database size={16} /></div
|
|
835
|
+
>
|
|
532
836
|
<p class="text-xs font-medium mb-2">AWS Secrets Manager → Database</p>
|
|
533
|
-
<Button
|
|
837
|
+
<Button
|
|
838
|
+
unifiedSize="sm"
|
|
839
|
+
variant="default"
|
|
840
|
+
onclick={() => (migrateFromAwsSmModalOpen = true)}
|
|
841
|
+
disabled={disabled || !isAwsSmConfigValid() || migratingFromAwsSm}
|
|
842
|
+
startIcon={{ icon: ArrowLeft }}>Migrate to Database</Button
|
|
843
|
+
>
|
|
534
844
|
</div>
|
|
535
845
|
</div>
|
|
536
846
|
</div>
|
|
@@ -539,21 +849,105 @@ vault write auth/jwt/role/windmill-secrets \
|
|
|
539
849
|
{/if}
|
|
540
850
|
</div>
|
|
541
851
|
|
|
542
|
-
<ConfirmationModal
|
|
543
|
-
|
|
852
|
+
<ConfirmationModal
|
|
853
|
+
title="Migrate to AWS Secrets Manager"
|
|
854
|
+
confirmationText="Migrate"
|
|
855
|
+
open={migrateToAwsSmModalOpen}
|
|
856
|
+
loading={migratingToAwsSm}
|
|
857
|
+
type="reload"
|
|
858
|
+
onCanceled={() => {
|
|
859
|
+
migrateToAwsSmModalOpen = false
|
|
860
|
+
}}
|
|
861
|
+
onConfirmed={migrateSecretsToAwsSm}
|
|
862
|
+
>
|
|
863
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
864
|
+
><p>This will copy all secrets from the database to AWS Secrets Manager.</p><p
|
|
865
|
+
class="text-yellow-600 dark:text-yellow-400 text-sm"
|
|
866
|
+
>Database values are NOT deleted automatically.</p
|
|
867
|
+
></div
|
|
868
|
+
>{/snippet}
|
|
544
869
|
</ConfirmationModal>
|
|
545
|
-
<ConfirmationModal
|
|
546
|
-
|
|
870
|
+
<ConfirmationModal
|
|
871
|
+
title="Migrate to Database"
|
|
872
|
+
confirmationText="Migrate"
|
|
873
|
+
open={migrateFromAwsSmModalOpen}
|
|
874
|
+
loading={migratingFromAwsSm}
|
|
875
|
+
type="reload"
|
|
876
|
+
onCanceled={() => {
|
|
877
|
+
migrateFromAwsSmModalOpen = false
|
|
878
|
+
}}
|
|
879
|
+
onConfirmed={migrateSecretsFromAwsSm}
|
|
880
|
+
>
|
|
881
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
882
|
+
><p>This will copy all secrets from AWS Secrets Manager back to the database.</p><p
|
|
883
|
+
class="text-yellow-600 dark:text-yellow-400 text-sm"
|
|
884
|
+
>AWS Secrets Manager values are NOT deleted automatically.</p
|
|
885
|
+
></div
|
|
886
|
+
>{/snippet}
|
|
547
887
|
</ConfirmationModal>
|
|
548
|
-
<ConfirmationModal
|
|
549
|
-
|
|
888
|
+
<ConfirmationModal
|
|
889
|
+
title="Migrate to Azure Key Vault"
|
|
890
|
+
confirmationText="Migrate"
|
|
891
|
+
open={migrateToAzureKvModalOpen}
|
|
892
|
+
loading={migratingToAzureKv}
|
|
893
|
+
type="reload"
|
|
894
|
+
onCanceled={() => {
|
|
895
|
+
migrateToAzureKvModalOpen = false
|
|
896
|
+
}}
|
|
897
|
+
onConfirmed={migrateSecretsToAzureKv}
|
|
898
|
+
>
|
|
899
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
900
|
+
><p>This will copy all secrets to Azure Key Vault.</p><p
|
|
901
|
+
class="text-yellow-600 dark:text-yellow-400 text-sm"
|
|
902
|
+
>Database values are NOT deleted automatically.</p
|
|
903
|
+
></div
|
|
904
|
+
>{/snippet}
|
|
550
905
|
</ConfirmationModal>
|
|
551
|
-
<ConfirmationModal
|
|
552
|
-
|
|
906
|
+
<ConfirmationModal
|
|
907
|
+
title="Migrate to Database"
|
|
908
|
+
confirmationText="Migrate"
|
|
909
|
+
open={migrateFromAzureKvModalOpen}
|
|
910
|
+
loading={migratingFromAzureKv}
|
|
911
|
+
type="reload"
|
|
912
|
+
onCanceled={() => {
|
|
913
|
+
migrateFromAzureKvModalOpen = false
|
|
914
|
+
}}
|
|
915
|
+
onConfirmed={migrateSecretsFromAzureKv}
|
|
916
|
+
>
|
|
917
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
918
|
+
><p>This will copy all secrets from Azure Key Vault back to the database.</p></div
|
|
919
|
+
>{/snippet}
|
|
553
920
|
</ConfirmationModal>
|
|
554
|
-
<ConfirmationModal
|
|
555
|
-
|
|
921
|
+
<ConfirmationModal
|
|
922
|
+
title="Migrate to Vault"
|
|
923
|
+
confirmationText="Migrate"
|
|
924
|
+
open={migrateToVaultModalOpen}
|
|
925
|
+
loading={migratingToVault}
|
|
926
|
+
type="reload"
|
|
927
|
+
onCanceled={() => {
|
|
928
|
+
migrateToVaultModalOpen = false
|
|
929
|
+
}}
|
|
930
|
+
onConfirmed={migrateSecretsToVault}
|
|
931
|
+
>
|
|
932
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
933
|
+
><p>This will copy all secrets to HashiCorp Vault.</p><p
|
|
934
|
+
class="text-yellow-600 dark:text-yellow-400 text-sm"
|
|
935
|
+
>Database values are NOT deleted automatically.</p
|
|
936
|
+
></div
|
|
937
|
+
>{/snippet}
|
|
556
938
|
</ConfirmationModal>
|
|
557
|
-
<ConfirmationModal
|
|
558
|
-
|
|
939
|
+
<ConfirmationModal
|
|
940
|
+
title="Migrate to Database"
|
|
941
|
+
confirmationText="Migrate"
|
|
942
|
+
open={migrateToDatabaseModalOpen}
|
|
943
|
+
loading={migratingToDatabase}
|
|
944
|
+
type="reload"
|
|
945
|
+
onCanceled={() => {
|
|
946
|
+
migrateToDatabaseModalOpen = false
|
|
947
|
+
}}
|
|
948
|
+
onConfirmed={migrateSecretsToDatabase}
|
|
949
|
+
>
|
|
950
|
+
{#snippet children()}<div class="flex flex-col gap-2"
|
|
951
|
+
><p>This will copy all secrets from Vault back to the database.</p></div
|
|
952
|
+
>{/snippet}
|
|
559
953
|
</ConfirmationModal>
|