diff --git a/packages/cli/src/Queue.ts b/packages/cli/src/Queue.ts index 1bd7fb5fcf4c0..e0fda6288559a 100644 --- a/packages/cli/src/Queue.ts +++ b/packages/cli/src/Queue.ts @@ -2,6 +2,7 @@ import type Bull from 'bull'; import type { RedisOptions } from 'ioredis'; import { Service } from 'typedi'; import type { IExecuteResponsePromiseData } from 'n8n-workflow'; +import fs from 'fs'; import config from '@/config'; import { ActiveExecutions } from '@/ActiveExecutions'; import * as WebhookHelpers from '@/WebhookHelpers'; @@ -24,6 +25,18 @@ export interface WebhookResponse { response: IExecuteResponsePromiseData; } +interface SecureRedisConfig { + secure: boolean; + tls?: { + cert?: string | Buffer; + cert_file?: string; + key?: string | Buffer; + key_file?: string; + ca?: string | Buffer; + ca_file?: string; + }; +} + @Service() export class Queue { private jobQueue: JobQueue; @@ -32,7 +45,27 @@ export class Queue { async init() { const prefix = config.getEnv('queue.bull.prefix'); - const redisOptions: RedisOptions = config.getEnv('queue.bull.redis'); + const redisOptions = config.getEnv('queue.bull.redis') as SecureRedisConfig; + if (!redisOptions.secure) { + delete redisOptions.tls; + } else { + if (!redisOptions.tls) redisOptions.tls = {}; + if (!redisOptions.tls.ca) { + if (redisOptions.tls.ca_file) { + redisOptions.tls.ca = fs.readFileSync(redisOptions.tls.ca_file); + } + } + if (!redisOptions.tls?.key) { + if (redisOptions.tls?.key_file) { + redisOptions.tls.key = fs.readFileSync(redisOptions.tls.key_file); + } + } + if (!redisOptions.tls?.cert) { + if (redisOptions.tls?.cert_file) { + redisOptions.tls.cert = fs.readFileSync(redisOptions.tls.cert_file); + } + } + } // eslint-disable-next-line @typescript-eslint/naming-convention const { default: Bull } = await import('bull'); diff --git a/packages/cli/src/config/schema.ts b/packages/cli/src/config/schema.ts index 5d9cb40045740..b0b3dc94447b1 100644 --- a/packages/cli/src/config/schema.ts +++ b/packages/cli/src/config/schema.ts @@ -396,6 +396,56 @@ export const schema = { default: '', env: 'QUEUE_BULL_REDIS_USERNAME', }, + secure: { + doc: 'Redis secure (TLS) flag', + format: Boolean, + default: false, + env: 'QUEUE_BULL_REDIS_SECURE', + }, + tls: { + rejectUnauthorized: { + doc: 'Reject uanathorized certificate', + format: Boolean, + default: true, + env: 'QUEUE_BULL_REDIS_TLS_REJECTANUTHORIZEDT', + }, + cert: { + doc: 'Cert in PEM format', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_CERT', + }, + cert_file: { + doc: 'Cert file in PEM format, used only if "cert" value is not specified', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_CERT_FILE', + }, + key: { + doc: 'Private key', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_KEY', + }, + key_file: { + doc: 'Private key file', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_KEY_FILE', + }, + ca: { + doc: 'Trusted CA certificates', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_CA', + }, + ca_file: { + doc: 'Trusted CA certificates', + format: String, + default: '', + env: 'QUEUE_BULL_REDIS_TLS_CA_FILE', + }, + }, }, queueRecoveryInterval: { doc: 'If > 0 enables an active polling to the queue that can recover for Redis crashes. Given in seconds; 0 is disabled. May increase Redis traffic significantly.',