* s3 proxy works with get (no auth yet) * nit * support s3:// syntax * Support s3:// syntax and fix vite api proxy normalizing double slashes in URI * s3 checks authed * nit * PUT works * delete file works * Derive the JWT signature from the backend * Authorize s3 correctly (JWT signature is never sent in cleartext) * convert object store error to wmill error for correct status code * stash * fix * POST first request proxy works * s3 put for duckdb * factor out direct proxy code * Fix Issue with backend proxy and wrong signature due to Host header mismatch * Add _default_ syntax to solve URI normalization issues with signing * restricted to user paths toggle * user path restriction works ! * change restriction to allow * fix * factor out code * better permissions UX in object storage settings * Revert to restrict_to_user_paths * check permissions in old s3 api * DuckDB now uses S3 Proxy and no longer needs LFS query * implement todo * fix hardcoded w_id * s3 proxy size limit * s3_proxy is ee * nit * add Google Cloud Storage as option to secondary storage * GCS secret in duckdb * fix toolchain compile * Remove user permissions for v0 * fix ci 2 * fix CI OSS * fix missing feature flag * fix unused warning * integration test fails bc rustc 1.85.0 * ee ref * fix ci ... * update ee ref
114 lines
4.2 KiB
TypeScript
114 lines
4.2 KiB
TypeScript
import type { GetSettingsResponse, LargeFileStorage } from './gen'
|
|
import { emptyString } from './utils'
|
|
|
|
// Extended type to include GCS support until backend types are regenerated
|
|
|
|
type s3type = 's3' | 'azure_blob' | 's3_aws_oidc' | 'azure_workload_identity' | 'gcloud_storage'
|
|
type s3ResourceSettingsItem = {
|
|
resourceType: s3type
|
|
resourcePath: string | undefined
|
|
publicResource: boolean | undefined
|
|
}
|
|
export type S3ResourceSettings = s3ResourceSettingsItem & {
|
|
secondaryStorage: [string, s3ResourceSettingsItem][] | undefined
|
|
}
|
|
export function convertBackendSettingsToFrontendSettings(
|
|
large_file_storage: GetSettingsResponse['large_file_storage']
|
|
): S3ResourceSettings {
|
|
let settings: Partial<S3ResourceSettings> =
|
|
convertBackendSettingsToFrontendSettingsItem(large_file_storage)
|
|
settings.secondaryStorage = Object.entries(large_file_storage?.secondary_storage ?? {}).map(
|
|
([key, value]) => [key, convertBackendSettingsToFrontendSettingsItem(value)]
|
|
)
|
|
|
|
return settings as S3ResourceSettings
|
|
}
|
|
|
|
export function convertBackendSettingsToFrontendSettingsItem(
|
|
large_file_storage: GetSettingsResponse['large_file_storage']
|
|
): s3ResourceSettingsItem {
|
|
if (large_file_storage?.type === 'S3Storage') {
|
|
return {
|
|
resourceType: 's3',
|
|
resourcePath: large_file_storage?.s3_resource_path?.replace('$res:', ''),
|
|
publicResource: large_file_storage?.public_resource
|
|
}
|
|
} else if (large_file_storage?.type === 'AzureBlobStorage') {
|
|
return {
|
|
resourceType: 'azure_blob',
|
|
resourcePath: large_file_storage?.azure_blob_resource_path?.replace('$res:', ''),
|
|
publicResource: large_file_storage?.public_resource
|
|
}
|
|
} else if (large_file_storage?.type === 'AzureWorkloadIdentity') {
|
|
return {
|
|
resourceType: 'azure_workload_identity',
|
|
resourcePath: large_file_storage?.azure_blob_resource_path?.replace('$res:', ''),
|
|
publicResource: large_file_storage?.public_resource
|
|
}
|
|
} else if (large_file_storage?.type === 'S3AwsOidc') {
|
|
return {
|
|
resourceType: 's3_aws_oidc',
|
|
resourcePath: large_file_storage?.s3_resource_path?.replace('$res:', ''),
|
|
publicResource: large_file_storage?.public_resource
|
|
}
|
|
} else if (large_file_storage?.type === 'GoogleCloudStorage') {
|
|
return {
|
|
resourceType: 'gcloud_storage',
|
|
resourcePath: large_file_storage?.gcs_resource_path?.replace('$res:', ''),
|
|
publicResource: large_file_storage?.public_resource
|
|
}
|
|
} else {
|
|
return {
|
|
resourceType: 's3',
|
|
resourcePath: undefined,
|
|
publicResource: undefined
|
|
}
|
|
}
|
|
}
|
|
|
|
export function convertFrontendToBackendSetting(
|
|
s3ResourceSettings: S3ResourceSettings
|
|
): LargeFileStorage | undefined {
|
|
let settings = convertFrontendToBackendettingsItem(s3ResourceSettings)
|
|
if (settings) {
|
|
settings.secondary_storage = Object.fromEntries(
|
|
(s3ResourceSettings.secondaryStorage ?? [])
|
|
.map(([key, value]) => [key, convertFrontendToBackendettingsItem(value)])
|
|
.filter(([, value]) => value !== undefined)
|
|
)
|
|
}
|
|
return settings
|
|
}
|
|
export function convertFrontendToBackendettingsItem(
|
|
s3ResourceSettings: s3ResourceSettingsItem
|
|
): LargeFileStorage | undefined {
|
|
if (!emptyString(s3ResourceSettings.resourcePath)) {
|
|
let resourcePathWithPrefix = `$res:${s3ResourceSettings.resourcePath}`
|
|
let params = {
|
|
public_resource: s3ResourceSettings.publicResource
|
|
}
|
|
if (s3ResourceSettings.resourceType === 'azure_blob') {
|
|
let typ: LargeFileStorage['type'] = 'AzureBlobStorage'
|
|
params['type'] = typ
|
|
params['azure_blob_resource_path'] = resourcePathWithPrefix
|
|
} else if (s3ResourceSettings.resourceType === 'azure_workload_identity') {
|
|
let typ: LargeFileStorage['type'] = 'AzureWorkloadIdentity'
|
|
params['type'] = typ
|
|
params['azure_blob_resource_path'] = resourcePathWithPrefix
|
|
} else if (s3ResourceSettings.resourceType === 's3_aws_oidc') {
|
|
let typ: LargeFileStorage['type'] = 'S3AwsOidc'
|
|
params['type'] = typ
|
|
params['s3_resource_path'] = resourcePathWithPrefix
|
|
} else if (s3ResourceSettings.resourceType === 'gcloud_storage') {
|
|
let typ: LargeFileStorage['type'] = 'GoogleCloudStorage'
|
|
params['type'] = typ
|
|
params['gcs_resource_path'] = resourcePathWithPrefix
|
|
} else {
|
|
let typ: LargeFileStorage['type'] = 'S3Storage'
|
|
params['type'] = typ
|
|
params['s3_resource_path'] = resourcePathWithPrefix
|
|
}
|
|
return params
|
|
}
|
|
}
|