diff --git a/packages/@n8n/config/src/configs/external-storage.ts b/packages/@n8n/config/src/configs/external-storage.ts new file mode 100644 index 0000000000..c876e0ee34 --- /dev/null +++ b/packages/@n8n/config/src/configs/external-storage.ts @@ -0,0 +1,42 @@ +import { Config, Env, Nested } from '../decorators'; + +@Config +class S3BucketConfig { + /** Name of the n8n bucket in S3-compatible external storage */ + @Env('N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME') + readonly name: string = ''; + + /** Region of the n8n bucket in S3-compatible external storage @example "us-east-1" */ + @Env('N8N_EXTERNAL_STORAGE_S3_BUCKET_REGION') + readonly region: string = ''; +} + +@Config +class S3CredentialsConfig { + /** Access key in S3-compatible external storage */ + @Env('N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY') + readonly accessKey: string = ''; + + /** Access secret in S3-compatible external storage */ + @Env('N8N_EXTERNAL_STORAGE_S3_ACCESS_SECRET') + readonly accessSecret: string = ''; +} + +@Config +class S3Config { + /** Host of the n8n bucket in S3-compatible external storage @example "s3.us-east-1.amazonaws.com" */ + @Env('N8N_EXTERNAL_STORAGE_S3_HOST') + readonly host: string = ''; + + @Nested + readonly bucket: S3BucketConfig; + + @Nested + readonly credentials: S3CredentialsConfig; +} + +@Config +export class ExternalStorageConfig { + @Nested + readonly s3: S3Config; +} diff --git a/packages/@n8n/config/src/index.ts b/packages/@n8n/config/src/index.ts index 46a35989d7..33856fffc4 100644 --- a/packages/@n8n/config/src/index.ts +++ b/packages/@n8n/config/src/index.ts @@ -8,6 +8,7 @@ import { ExternalSecretsConfig } from './configs/external-secrets'; import { TemplatesConfig } from './configs/templates'; import { EventBusConfig } from './configs/event-bus'; import { NodesConfig } from './configs/nodes'; +import { ExternalStorageConfig } from './configs/external-storage'; @Config class UserManagementConfig { @@ -18,29 +19,32 @@ class UserManagementConfig { @Config export class GlobalConfig { @Nested - database: DatabaseConfig; + readonly database: DatabaseConfig; @Nested - credentials: CredentialsConfig; + readonly credentials: CredentialsConfig; @Nested - userManagement: UserManagementConfig; + readonly userManagement: UserManagementConfig; @Nested - versionNotifications: VersionNotificationsConfig; + readonly versionNotifications: VersionNotificationsConfig; @Nested - publicApi: PublicApiConfig; + readonly publicApi: PublicApiConfig; @Nested - externalSecrets: ExternalSecretsConfig; + readonly externalSecrets: ExternalSecretsConfig; @Nested - templates: TemplatesConfig; + readonly templates: TemplatesConfig; @Nested - eventBus: EventBusConfig; + readonly eventBus: EventBusConfig; @Nested readonly nodes: NodesConfig; + + @Nested + readonly externalStorage: ExternalStorageConfig; } diff --git a/packages/@n8n/config/test/config.test.ts b/packages/@n8n/config/test/config.test.ts index 2e77b093b9..68f49dfb09 100644 --- a/packages/@n8n/config/test/config.test.ts +++ b/packages/@n8n/config/test/config.test.ts @@ -122,6 +122,19 @@ describe('GlobalConfig', () => { endpoint: 'https://api.n8n.io/api/versions/', infoUrl: 'https://docs.n8n.io/hosting/installation/updating/', }, + externalStorage: { + s3: { + host: '', + bucket: { + name: '', + region: '', + }, + credentials: { + accessKey: '', + accessSecret: '', + }, + }, + }, }; it('should use all default values when no env variables are defined', () => { diff --git a/packages/cli/src/commands/BaseCommand.ts b/packages/cli/src/commands/BaseCommand.ts index a1fa342413..b00d314b91 100644 --- a/packages/cli/src/commands/BaseCommand.ts +++ b/packages/cli/src/commands/BaseCommand.ts @@ -44,6 +44,8 @@ export abstract class BaseCommand extends Command { protected license: License; + private globalConfig = Container.get(GlobalConfig); + /** * How long to wait for graceful shutdown before force killing the process. */ @@ -79,8 +81,7 @@ export abstract class BaseCommand extends Command { await this.exitWithCrash('There was an error running database migrations', error), ); - const globalConfig = Container.get(GlobalConfig); - const { type: dbType } = globalConfig.database; + const { type: dbType } = this.globalConfig.database; if (['mysqldb', 'mariadb'].includes(dbType)) { this.logger.warn( @@ -199,7 +200,7 @@ export abstract class BaseCommand extends Command { private async _initObjectStoreService(options = { isReadOnly: false }) { const objectStoreService = Container.get(ObjectStoreService); - const host = config.getEnv('externalStorage.s3.host'); + const { host, bucket, credentials } = this.globalConfig.externalStorage.s3; if (host === '') { throw new ApplicationError( @@ -207,11 +208,6 @@ export abstract class BaseCommand extends Command { ); } - const bucket = { - name: config.getEnv('externalStorage.s3.bucket.name'), - region: config.getEnv('externalStorage.s3.bucket.region'), - }; - if (bucket.name === '') { throw new ApplicationError( 'External storage bucket name not configured. Please set `N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME`.', @@ -224,11 +220,6 @@ export abstract class BaseCommand extends Command { ); } - const credentials = { - accessKey: config.getEnv('externalStorage.s3.credentials.accessKey'), - accessSecret: config.getEnv('externalStorage.s3.credentials.accessSecret'), - }; - if (credentials.accessKey === '') { throw new ApplicationError( 'External storage access key not configured. Please set `N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY`.', diff --git a/packages/cli/src/config/schema.ts b/packages/cli/src/config/schema.ts index 5df1900a95..ebf32fe4d1 100644 --- a/packages/cli/src/config/schema.ts +++ b/packages/cli/src/config/schema.ts @@ -671,45 +671,6 @@ export const schema = { }, }, - externalStorage: { - s3: { - host: { - format: String, - default: '', - env: 'N8N_EXTERNAL_STORAGE_S3_HOST', - doc: 'Host of the n8n bucket in S3-compatible external storage, e.g. `s3.us-east-1.amazonaws.com`', - }, - bucket: { - name: { - format: String, - default: '', - env: 'N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME', - doc: 'Name of the n8n bucket in S3-compatible external storage', - }, - region: { - format: String, - default: '', - env: 'N8N_EXTERNAL_STORAGE_S3_BUCKET_REGION', - doc: 'Region of the n8n bucket in S3-compatible external storage, e.g. `us-east-1`', - }, - }, - credentials: { - accessKey: { - format: String, - default: '', - env: 'N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY', - doc: 'Access key in S3-compatible external storage', - }, - accessSecret: { - format: String, - default: '', - env: 'N8N_EXTERNAL_STORAGE_S3_ACCESS_SECRET', - doc: 'Access secret in S3-compatible external storage', - }, - }, - }, - }, - deployment: { type: { format: String,