refactor(core): Make launcher auth easier to debug (#11768)

Co-authored-by: Tomi Turtiainen <10324676+tomi@users.noreply.github.com>
This commit is contained in:
Iván Ovejero 2024-11-19 09:32:19 +01:00 committed by GitHub
parent 6cd9b996af
commit 4880d1a92a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 5 deletions

View file

@ -0,0 +1,7 @@
export class MissingAuthTokenError extends Error {
constructor() {
super(
'Missing auth token. When `N8N_RUNNERS_MODE` is `external`, it is required to set `N8N_RUNNERS_AUTH_TOKEN`. Its value should be a shared secret between the main instance and the launcher.',
);
}
}

View file

@ -4,6 +4,7 @@ import Container, { Service } from 'typedi';
import type { TaskRunnerProcess } from '@/runners/task-runner-process';
import { MissingAuthTokenError } from './errors/missing-auth-token.error';
import { TaskRunnerWsServer } from './runner-ws-server';
import type { LocalTaskManager } from './task-managers/local-task-manager';
import type { TaskRunnerServer } from './task-runner-server';
@ -28,13 +29,14 @@ export class TaskRunnerModule {
async start() {
a.ok(this.runnerConfig.enabled, 'Task runner is disabled');
const { mode, authToken } = this.runnerConfig;
if (mode === 'external' && !authToken) throw new MissingAuthTokenError();
await this.loadTaskManager();
await this.loadTaskRunnerServer();
if (
this.runnerConfig.mode === 'internal_childprocess' ||
this.runnerConfig.mode === 'internal_launcher'
) {
if (mode === 'internal_childprocess' || mode === 'internal_launcher') {
await this.startInternalTaskRunner();
}
}

View file

@ -181,7 +181,10 @@ export class TaskRunnerServer {
const response = new ServerResponse(request);
response.writeHead = (statusCode) => {
if (statusCode > 200) ws.close();
if (statusCode > 200) {
this.logger.error(`Task runner connection attempt failed with status code ${statusCode}`);
ws.close();
}
return response;
};

View file

@ -1,6 +1,7 @@
import { TaskRunnersConfig } from '@n8n/config';
import Container from 'typedi';
import { MissingAuthTokenError } from '@/runners/errors/missing-auth-token.error';
import { TaskRunnerModule } from '@/runners/task-runner-module';
import { DefaultTaskRunnerDisconnectAnalyzer } from '../../../src/runners/default-task-runner-disconnect-analyzer';
@ -10,6 +11,7 @@ describe('TaskRunnerModule in external mode', () => {
const runnerConfig = Container.get(TaskRunnersConfig);
runnerConfig.mode = 'external';
runnerConfig.port = 0;
runnerConfig.authToken = 'test';
const module = Container.get(TaskRunnerModule);
afterEach(async () => {
@ -24,6 +26,17 @@ describe('TaskRunnerModule in external mode', () => {
await expect(module.start()).rejects.toThrow('Task runner is disabled');
});
it('should throw if auth token is missing', async () => {
const runnerConfig = new TaskRunnersConfig();
runnerConfig.mode = 'external';
runnerConfig.enabled = true;
runnerConfig.authToken = '';
const module = new TaskRunnerModule(runnerConfig);
await expect(module.start()).rejects.toThrowError(MissingAuthTokenError);
});
it('should start the task runner', async () => {
runnerConfig.enabled = true;