first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
# Syslog Manual Testing
|
||||
|
||||
Please note: You will need an enterprise licence in n8n to configure this.
|
||||
|
||||
## With TCP
|
||||
|
||||
### Step 1 - Configure and start syslog-ng
|
||||
|
||||
Create a new directory to contain your syslog config (doesn't have to be the home dir):
|
||||
|
||||
```sh
|
||||
mkdir -p ~/syslog-tcp-test && cd ~/syslog-tcp-test
|
||||
```
|
||||
|
||||
Create a file `syslog-ng.conf` and paste the following content:
|
||||
|
||||
```
|
||||
@version: 4.10
|
||||
@include "scl.conf"
|
||||
|
||||
source s_tcp {
|
||||
network(
|
||||
transport("tcp")
|
||||
port(514)
|
||||
flags(no-parse)
|
||||
);
|
||||
};
|
||||
|
||||
destination d_console {
|
||||
file("/proc/1/fd/1" template("RECEIVED: $MSG\n"));
|
||||
};
|
||||
|
||||
log {
|
||||
source(s_tcp);
|
||||
destination(d_console);
|
||||
flags(flow-control);
|
||||
};
|
||||
```
|
||||
|
||||
Start a local instance with docker and validate it is working
|
||||
|
||||
```shell
|
||||
docker run -d \
|
||||
--name syslog-ng-tcp \
|
||||
-p 514:514 \
|
||||
-v $(pwd)/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro \
|
||||
balabit/syslog-ng:latest
|
||||
|
||||
# In one window
|
||||
docker logs -f syslog-ng-tcp
|
||||
|
||||
# In another window
|
||||
echo "test message" | nc -v localhost 514
|
||||
|
||||
# You should see the message in the window tailing the logs
|
||||
```
|
||||
|
||||
### Step 2 - Configure log streaming in n8n
|
||||
Head to n8n log streaming settings and enter the following:
|
||||
```
|
||||
Host: localhost
|
||||
Port: 514
|
||||
Protocol: TCP
|
||||
Facility: Local0
|
||||
App Name: n8n
|
||||
```
|
||||
Once saved you can send a test message and validate it is received using the `docker logs syslog-ng-tcp` command.
|
||||
|
||||
## With TLS
|
||||
|
||||
These instructions will help you setup a syslog server that will accept TLS connections. They will be useful if you need
|
||||
to manually validate anything specific around TLS & syslog configuration.
|
||||
|
||||
### Step 1 - Setup Test Certs
|
||||
```shell
|
||||
mkdir -p ~/syslog-tls-test && cd ~/syslog-tls-test
|
||||
|
||||
# CA certificate
|
||||
openssl req -x509 -newkey rsa:4096 \
|
||||
-keyout ca-key.pem \
|
||||
-out ca-cert.pem \
|
||||
-days 365 -nodes \
|
||||
-subj "/CN=Test CA/O=Test Org"
|
||||
|
||||
# Server key
|
||||
openssl genrsa -out server-key.pem 4096
|
||||
|
||||
# Server certificate signing request
|
||||
openssl req -new \
|
||||
-key server-key.pem \
|
||||
-out server-csr.pem \
|
||||
-subj "/CN=localhost/O=Test Server"
|
||||
|
||||
# Sign server certificate using CA
|
||||
openssl x509 -req \
|
||||
-in server-csr.pem \
|
||||
-CA ca-cert.pem \
|
||||
-CAkey ca-key.pem \
|
||||
-CAcreateserial \
|
||||
-out server-cert.pem \
|
||||
-days 365 \
|
||||
-sha256
|
||||
```
|
||||
|
||||
### Step 2 - Configure and start syslog-ng
|
||||
Create a file `syslog-ng.conf` and paste the following content:
|
||||
|
||||
```
|
||||
@version: 4.10
|
||||
@include "scl.conf"
|
||||
|
||||
source s_tls {
|
||||
network(
|
||||
transport("tls")
|
||||
port(6514)
|
||||
flags(no-parse)
|
||||
tls(
|
||||
key-file("/certs/server-key.pem")
|
||||
cert-file("/certs/server-cert.pem")
|
||||
peer-verify(optional-untrusted)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
destination d_console {
|
||||
file("/proc/1/fd/1" template("RECEIVED: $MSG\n"));
|
||||
};
|
||||
|
||||
log {
|
||||
source(s_tls);
|
||||
destination(d_console);
|
||||
flags(flow-control);
|
||||
};
|
||||
```
|
||||
|
||||
Start a local instance with docker and validate it is working
|
||||
|
||||
```shell
|
||||
docker run -d \
|
||||
--name syslog-ng-tls \
|
||||
-p 6514:6514 \
|
||||
-v $(pwd)/ca-cert.pem:/certs/ca-cert.pem:ro \
|
||||
-v $(pwd)/server-cert.pem:/certs/server-cert.pem:ro \
|
||||
-v $(pwd)/server-key.pem:/certs/server-key.pem:ro \
|
||||
-v $(pwd)/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro \
|
||||
balabit/syslog-ng:latest
|
||||
|
||||
# In one window
|
||||
docker logs -f syslog-ng-tls
|
||||
|
||||
# In another window
|
||||
echo 'TEST MESSAGE' | \
|
||||
openssl s_client -connect localhost:6514 -CAfile ca-cert.pem -ign_eof 2>&1
|
||||
|
||||
# You should see the message in the window tailing the logs
|
||||
```
|
||||
|
||||
### Step 3 - Configure log streaming in n8n
|
||||
Head to n8n log streaming settings and enter the following:
|
||||
```
|
||||
Host: localhost // This is important as the certificate CN=localhost
|
||||
Port: 6514
|
||||
Protocol: TLS
|
||||
TlsCa: Paste the contents of ca-cert.pem created in step 1
|
||||
Facility: Local0
|
||||
App Name: n8n
|
||||
```
|
||||
Once saved you can send a test message and validate it is received using the `docker logs syslog-ng-tls` command.
|
||||
|
||||
Most problems result in a log in the n8n system - error feedback will hopefully be improved in
|
||||
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDfzCCAmegAwIBAgIUEo4pU1hgsKHlV01QIN3hhDaQ6ggwDQYJKoZIhvcNAQEL
|
||||
BQAwTjELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3Qx
|
||||
DTALBgNVBAoMBFRlc3QxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yNjAxMDUyMDQ1
|
||||
NDhaGA8yMDUzMDUyMzIwNDU0OFowTjELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRl
|
||||
c3QxDTALBgNVBAcMBFRlc3QxDTALBgNVBAoMBFRlc3QxEjAQBgNVBAMMCWxvY2Fs
|
||||
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzoP33jcgWYJ/mS
|
||||
A8NQm9gABgeOVHlc4lEqHsMo9gZy3GfmanI/XFpTr3Nxeb2AMqJ1B9EgXOtJLBDP
|
||||
J+Z+k3jN9Sv2ZRSClf6ZZUUPFKcjQ6TNYXG/Jgmjoku7k0I9cJluXE8VwlC9mzty
|
||||
iHbZGo/tRtU4LkbaedmL2eTctcBukX4g99uVMJVKot5l8PWxZ1seVZ6T4IiRcaRo
|
||||
NcQqL67xspm3KmlrVx/WzlM41BfGj2k+L4Bgenm/bIg1RPQ+MoETViVFGeKgKjkp
|
||||
kTOjCsZqeK2STCIj1+XI4tLMCxV0B95fw7bcFfEtbnL9XyEjyn+3A33625EJMoiq
|
||||
OX6bb9MCAwEAAaNTMFEwHQYDVR0OBBYEFEB7f6J6nW90lXS8i4gOR/6rya7qMB8G
|
||||
A1UdIwQYMBaAFEB7f6J6nW90lXS8i4gOR/6rya7qMA8GA1UdEwEB/wQFMAMBAf8w
|
||||
DQYJKoZIhvcNAQELBQADggEBAIXoFrV9saNREtlDkMp5O66IO+UFhr1NcLYmXvhs
|
||||
n3H+OFpg/Uo+/p++vHgf5UKNTdx24pO/88FyPujIcq1mfemrAIgcd8t++aclzSlf
|
||||
G49bZvhYyxsE+qoyl7XWtmYLPydCpYKkL7krLwUVzSeC/f6f/GWEn0vvwWPht5ky
|
||||
dR/Uze7pg/Ux12gztSLPV77n9gBua6lj5HKhXYGoIFuZSw9n1tWqndT28OQ3VwI7
|
||||
ZSpFFJmDyevspC2F18NaTE5VmXv9gckeUmqx8nr0zOmWWREVnFt+d4NNvrNLEChj
|
||||
IJFfkzynUHYTe+1oQkv8Evr0GHU5ocHsqOQ4NqW5gx0XXRA=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDfTCCAmWgAwIBAgIUfC52wMYMzcoL9c/GY3Ks0beSH2kwDQYJKoZIhvcNAQEL
|
||||
BQAwTTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVdyb25nMQ4wDAYDVQQHDAVXcm9u
|
||||
ZzEOMAwGA1UECgwFV3JvbmcxDjAMBgNVBAMMBXdyb25nMCAXDTI2MDEwNTIwNDU0
|
||||
OFoYDzIwNTMwNTIzMjA0NTQ4WjBNMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFV3Jv
|
||||
bmcxDjAMBgNVBAcMBVdyb25nMQ4wDAYDVQQKDAVXcm9uZzEOMAwGA1UEAwwFd3Jv
|
||||
bmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj1725lupt3pTvMf2O
|
||||
o931s2l4ObA5qTC6ihlWJX+A7R4RkHrQTlwahEwIgMNSzNURtXOwu3ePyqZE3Luk
|
||||
pVWGMFdgedNuU+4zNUXXamIyIJfsMuEmw6xrWLpdWqawo0G50Y2RxB4MN6/127PL
|
||||
EqogXC+0PHdgBUWtso/sJcGRrdQvGpmH9ZXavVNhER4G3q6f/Tcp1eu0xry1UwGV
|
||||
WN/DghkE5R/9mLm830Lr7gLpEQ6JKUUTnPKaZQW9m9G8gjr6oEXR9QaTcTariHgx
|
||||
HT0wkGRKO54CC3RdBxqwucdkvgUI7OkaGl8tS46QMI4DwQHcUFLkqx29wXHY/Zhu
|
||||
mHxDAgMBAAGjUzBRMB0GA1UdDgQWBBT8E+hqfJTcai2AlqT27R4KL/nGNTAfBgNV
|
||||
HSMEGDAWgBT8E+hqfJTcai2AlqT27R4KL/nGNTAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQCf38uZYe6+cW7/juw2wCoLObSBoomRuJicwpRbDJpo
|
||||
kzKzlBm4KbAwrz0+2kugZCrqrY1pLZPozQiqqf7UOImNcBi/wCbNk6iksdD9WRpv
|
||||
tooKb2UHY9Z+1VJ7FqBhEekUJnxAoOlmOnSwPW3qDQNaP+niWZEZjgK+m+3/ZI5d
|
||||
oW8lU1UGYJs/pZrZDwPUGHRnPj7Sa6q0S5OCVFx4BN+YMKN9ynvVG0z0pkO3QpA3
|
||||
wOYu/WxINCuFb6Iu469Ov/FoSfnqZRcqZ+PlMDWHr0NCj0DNBP/eGq8VWy6VRabQ
|
||||
SyRRjByPFe8fK1PAbrwIh8w6QIWz28OQZjAz0TsHnK7D
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDM6D9943IFmCf5
|
||||
kgPDUJvYAAYHjlR5XOJRKh7DKPYGctxn5mpyP1xaU69zcXm9gDKidQfRIFzrSSwQ
|
||||
zyfmfpN4zfUr9mUUgpX+mWVFDxSnI0OkzWFxvyYJo6JLu5NCPXCZblxPFcJQvZs7
|
||||
coh22RqP7UbVOC5G2nnZi9nk3LXAbpF+IPfblTCVSqLeZfD1sWdbHlWek+CIkXGk
|
||||
aDXEKi+u8bKZtyppa1cf1s5TONQXxo9pPi+AYHp5v2yINUT0PjKBE1YlRRnioCo5
|
||||
KZEzowrGanitkkwiI9flyOLSzAsVdAfeX8O23BXxLW5y/V8hI8p/twN9+tuRCTKI
|
||||
qjl+m2/TAgMBAAECggEARqkwe/EbOOKnpmC7+3aox2v6qFBkwRVO1j54LUTK0p55
|
||||
czr6Kju/VUbWkjDnknnK/ErvTyah5GFvWLyXPd0YbehYS7jEUrZVk17ClXYF4T0/
|
||||
7m0E1XzdWSWcqhEdTxJw6fgszPjr8XvxNCbi+FkV19wzOQQOsVBWBLc9hLa31ous
|
||||
CCMmpmJD+KaaN1D7VKDyLOtMQDPM7xft9VcWTU0qATN86HzvTxRF3+wWi1Z8ChV+
|
||||
miMfu4yb4Ip/tFSZfCJQqWupxdXYxw+p6HbcYRxSFa8ux4oZoQwvSVIi3pGKFXij
|
||||
/0oBhx2N1Y0T5LnuUZvne6CjwSyRSCmN68FnUKiogQKBgQD5UuHXcMZiDyZSskpj
|
||||
6rj//Hc3I9eRvB2CIvxVbDecRoCat3r9SZmZJ+DFxyH9Voy0ClrQnjSjPsXR5T89
|
||||
Ya+dFELl0zg7scHMw9VVSBsIjPrBhCnqPII1tfZj5ZzKI0oM1P8DwsoBOMotZIjl
|
||||
eHsUsd3Qw5sogbrwJ5d0cuDcaQKBgQDSZOPLwuEtAc7qyu1lSbifCMYwM4ISac3F
|
||||
2f116BV43/9L8eQv41XmVl1ELmwebahQdIbTtP5bNGDRHLRyIfbsSWxzBamQkKX9
|
||||
INzsiaeCENMTEHo4oSXX89DoZkr50iT62y9DKF5TkzNkA+CMvUuKfkh8YZAnLizA
|
||||
dhrM0NOS2wKBgQD3nJ/ctgzgEEmwMY994fxvhw3i/j62ZswrlZFjSQGFu+M3ROfp
|
||||
q3HXUGqEIbuY/Z7po6sDq0t9oPcX+QQwctbVOu0hkP81Edn2AbvaYa0vdcwH6rkx
|
||||
/3wV2axlFAH+IsQFMHhABPFX+02XfVQUCe6649b24X0z4nuEzN028mxtmQKBgC7q
|
||||
XHmVbUzx+EgXFDTf6ZFdDYS2F60vdrlF0OU36YHYwT8YI4AiO4dvfsCzcVyfq0a1
|
||||
lVMkKwv/dA9tTTeeJ0etX8eOXa9k8f6uE1WTpIy2X7sCk56JIL01G0KXfOSUXbaq
|
||||
pbFeERql2nHVA3+evneVjWhfARwbidMpAvTlJCi9AoGAQxFKi/dKzjZQFkikv9xU
|
||||
QpvtrfjZvYHU56HMDkKA4yIjBpONPWc6TAir5eOroKIKxAF0K+5s/bcQqZagShfZ
|
||||
WhZSdUid4J+gPCYL2v5F8symu9dxP54xRw1886uJUuqyb7tHhdFCOHRclD5wlLg3
|
||||
OrfEUwhYRn7d21UZoGDAvYU=
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,136 @@
|
||||
import { Logger } from '@n8n/backend-common';
|
||||
import { GLOBAL_OWNER_ROLE } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import type TestAgent from 'supertest/lib/agent';
|
||||
|
||||
import { EventMessageGeneric } from '@/eventbus/event-message-classes/event-message-generic';
|
||||
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
|
||||
import { LogStreamingDestinationService } from '@/modules/log-streaming.ee/log-streaming-destination.service';
|
||||
|
||||
import { TlsSyslogServer } from './tls-server';
|
||||
import { createUser } from '../shared/db/users';
|
||||
import * as utils from '../shared/utils';
|
||||
|
||||
jest.unmock('@/eventbus/message-event-bus/message-event-bus');
|
||||
|
||||
const tlsServer = new TlsSyslogServer();
|
||||
let serverPort: number;
|
||||
let eventBus: MessageEventBus;
|
||||
let destinationService: LogStreamingDestinationService;
|
||||
let authOwnerAgent: TestAgent;
|
||||
let logger: Logger;
|
||||
|
||||
const testServer = utils.setupTestServer({
|
||||
endpointGroups: ['eventBus'],
|
||||
enabledFeatures: ['feat:logStreaming'],
|
||||
modules: ['log-streaming'],
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await eventBus?.close();
|
||||
// Undo the "unmock" from above
|
||||
jest.mock('@/eventbus/message-event-bus/message-event-bus');
|
||||
await tlsServer.stop();
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
serverPort = await tlsServer.start();
|
||||
|
||||
const owner = await createUser({ role: GLOBAL_OWNER_ROLE });
|
||||
authOwnerAgent = testServer.authAgentFor(owner);
|
||||
|
||||
eventBus = Container.get(MessageEventBus);
|
||||
logger = Container.get(Logger);
|
||||
await eventBus.initialize();
|
||||
|
||||
destinationService = Container.get(LogStreamingDestinationService);
|
||||
await destinationService.initialize();
|
||||
});
|
||||
|
||||
describe('TLS Syslog E2E', () => {
|
||||
const destinationId = 'e2e-tls-test';
|
||||
const subscribedEvent = 'n8n.workflow.failed';
|
||||
|
||||
beforeEach(() => {
|
||||
tlsServer.clearMessages();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
const destinations = await destinationService.findDestination();
|
||||
for (const destination of destinations) {
|
||||
if (destination.id) {
|
||||
await destinationService.removeDestination(destination.id, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('should send message over real TLS connection', async () => {
|
||||
const certificate = fs.readFileSync(path.join(__dirname, 'support', 'certificate.pem'), 'utf8');
|
||||
|
||||
await authOwnerAgent.post('/eventbus/destination').send({
|
||||
__type: '$$MessageEventBusDestinationSyslog',
|
||||
id: destinationId,
|
||||
protocol: 'tls',
|
||||
host: 'localhost',
|
||||
port: serverPort,
|
||||
label: 'E2E TLS Syslog',
|
||||
enabled: true,
|
||||
subscribedEvents: [subscribedEvent],
|
||||
tlsCa: certificate,
|
||||
});
|
||||
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: subscribedEvent,
|
||||
id: 'test-message-1',
|
||||
});
|
||||
|
||||
await eventBus.send(testMessage);
|
||||
|
||||
// Wait for message to arrive at real server
|
||||
const receivedMessage = await tlsServer.waitForMessage(5000);
|
||||
|
||||
expect(receivedMessage).toBeTruthy();
|
||||
expect(receivedMessage).toContain('n8n.workflow.failed');
|
||||
expect(receivedMessage).toContain('test-message-1');
|
||||
});
|
||||
|
||||
test('should log an error when the certificate is invalid - but not break the application', async () => {
|
||||
const loggerErrorSpy = jest.spyOn(logger, 'error');
|
||||
|
||||
const incorrectCertificate = fs.readFileSync(
|
||||
path.join(__dirname, 'support', 'incorrect-certificate.pem'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
const authOwnerAgent = testServer.authAgentFor(await createUser({ role: GLOBAL_OWNER_ROLE }));
|
||||
|
||||
await authOwnerAgent.post('/eventbus/destination').send({
|
||||
__type: '$$MessageEventBusDestinationSyslog',
|
||||
id: destinationId,
|
||||
protocol: 'tls',
|
||||
host: 'localhost',
|
||||
port: serverPort,
|
||||
label: 'Invalid TLS',
|
||||
enabled: true,
|
||||
subscribedEvents: [subscribedEvent],
|
||||
tlsCa: incorrectCertificate,
|
||||
});
|
||||
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: subscribedEvent,
|
||||
id: 'test-invalid',
|
||||
});
|
||||
|
||||
await eventBus.send(testMessage);
|
||||
|
||||
// Should NOT receive message (cert validation failed)
|
||||
await expect(tlsServer.waitForMessage(2000)).rejects.toThrow('Timeout');
|
||||
|
||||
// Should output an error log message.
|
||||
expect(loggerErrorSpy).toHaveBeenCalledWith('Transport error');
|
||||
|
||||
loggerErrorSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import * as tls from 'tls';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as readline from 'readline';
|
||||
|
||||
export class TlsSyslogServer {
|
||||
private server: tls.Server | null = null;
|
||||
private messages: string[] = [];
|
||||
port: number = 0;
|
||||
|
||||
async start(): Promise<number> {
|
||||
const key = fs.readFileSync(path.join(__dirname, 'support', 'key.pem'), 'utf8');
|
||||
const cert = fs.readFileSync(path.join(__dirname, 'support', 'certificate.pem'), 'utf8');
|
||||
|
||||
return await new Promise((resolve) => {
|
||||
this.server = tls.createServer({ key, cert, secureProtocol: 'TLSv1_2_method' }, (socket) => {
|
||||
const lines = readline.createInterface({ input: socket });
|
||||
lines.on('line', (line) => {
|
||||
this.messages.push(line);
|
||||
console.log('Received:', line);
|
||||
});
|
||||
});
|
||||
|
||||
this.server.listen(0, () => {
|
||||
const address = this.server!.address();
|
||||
this.port = address && typeof address === 'object' ? address.port : 0;
|
||||
console.log(`TLS Syslog server listening on port ${this.port}`);
|
||||
resolve(this.port);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
return await new Promise((resolve) => {
|
||||
this.server?.close();
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
getMessages(): string[] {
|
||||
return [...this.messages];
|
||||
}
|
||||
|
||||
clearMessages(): void {
|
||||
this.messages = [];
|
||||
}
|
||||
|
||||
async waitForMessage(timeout = 5000): Promise<string> {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
if (this.messages.length > 0) {
|
||||
return this.messages.shift()!;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
throw new Error('Timeout waiting for message');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user