Skip to content

Commit cc8a07e

Browse files
committed
feat: add http server module
1 parent 3031024 commit cc8a07e

File tree

4 files changed

+133
-42
lines changed

4 files changed

+133
-42
lines changed

lib/http-server/index.ts

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import fastify from 'fastify';
2+
3+
// @ts-expect-error it's a js library
4+
import cfLogs from 'cf-logs';
5+
6+
import { saveServerAddress } from '../helpers';
7+
import deprecatedImagesCollector from '../metric/deprecated-images/deprecated-images.collector';
8+
9+
const logger = cfLogs.Logger('codefresh:containerLogger');
10+
11+
export class HttpServer {
12+
13+
private readonly host;
14+
private readonly port;
15+
private readonly server;
16+
17+
constructor(private taskLogger: any) {
18+
try {
19+
this.host = process.env.HOST || '0.0.0.0';
20+
this.port = +(process.env.PORT || 8080);
21+
this.server = fastify();
22+
23+
this.initSecrets();
24+
this.initDeprecatedImages();
25+
} catch (error) {
26+
logger.error(`could not initialize server for engine's requests due to error: ${error}`);
27+
throw error;
28+
}
29+
}
30+
31+
private initSecrets() {
32+
const secretsOptions = {
33+
schema: {
34+
body: {
35+
type: 'object',
36+
required: ['key', 'value'],
37+
properties: {
38+
key: { type: 'string' },
39+
value: { type: 'string' },
40+
},
41+
},
42+
},
43+
};
44+
45+
this.server.post('/secrets', secretsOptions, async (request, reply) => {
46+
try {
47+
const { body }: { body: any } = request;
48+
const { secret } = body;
49+
logger.info(`got request to add new mask: ${secret.key}`);
50+
this.taskLogger.addNewMask(secret);
51+
reply.code(201);
52+
return 'secret added';
53+
} catch (err) {
54+
logger.info(`could not create new mask for due to error: ${err}`);
55+
reply.code(500);
56+
throw err;
57+
}
58+
});
59+
}
60+
61+
private initDeprecatedImages() {
62+
this.server.get('/deprecated-images', async () => {
63+
logger.info(`got request to retrieve deprecated images`);
64+
return deprecatedImagesCollector.consumeAll();
65+
});
66+
67+
this.server.post<{ Body: { count: number } }>('/deprecated-images/ack', async (request, reply) => {
68+
const { count } = request.body;
69+
70+
if (typeof count !== 'number' || count < 1) {
71+
return reply.status(400).send({ error: 'You must provide a valid count (positive integer).' });
72+
}
73+
74+
deprecatedImagesCollector.destroyConsumed(count);
75+
76+
return reply.status(200).send({ count });
77+
});
78+
}
79+
80+
async start() {
81+
let address: string;
82+
try {
83+
address = await this.server.listen({
84+
host: this.host,
85+
port: this.port,
86+
});
87+
88+
logger.info(`listening for engine's requests on ${address}`);
89+
} catch (error) {
90+
logger.error(`could not start server for engine updates due to error: ${error}`);
91+
throw error;
92+
}
93+
94+
try {
95+
await saveServerAddress(address);
96+
} catch (error) {
97+
logger.error(`could not save server address due to error: ${error}`);
98+
throw error;
99+
}
100+
}
101+
102+
}

lib/logger.js

+8-42
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ const DockerEvents = require('docker-events');
66
const CFError = require('cf-errors');
77
const logger = require('cf-logs').Logger('codefresh:containerLogger');
88
const { TaskLogger } = require('@codefresh-io/task-logger');
9-
const fastify = require('fastify');
109
const { ContainerStatus } = require('./enums');
1110
const { LoggerStrategy } = require('./enums');
1211
const { ContainerHandlingStatus } = require('./enums');
1312
const ContainerLogger = require('./ContainerLogger');
14-
const { getPromiseWithResolvers, saveServerAddress } = require('./helpers');
13+
const { getPromiseWithResolvers } = require('./helpers');
14+
15+
// eslint-disable-next-line import/no-unresolved,import/extensions
16+
const { HttpServer } = require('./http-server');
1517

1618
const initialState = {
1719
pid: process.pid, status: 'init', lastLogsDate: new Date(), failedHealthChecks: [], restartCounter: 0, containers: {}
@@ -38,6 +40,7 @@ class Logger {
3840
this.finishedContainers = 0;
3941
this.finishedContainersEmitter = new EventEmitter();
4042
this.showProgress = showProgress;
43+
this.httpServer = new HttpServer();
4144

4245
let dockerSockPath;
4346
if (process.platform === 'win32') {
@@ -123,7 +126,7 @@ class Logger {
123126

124127
});
125128

126-
await this._listenForEngineUpdates();
129+
await this._listenForEngineRequests();
127130
}
128131

129132
_readState() {
@@ -351,45 +354,8 @@ class Logger {
351354
});
352355
}
353356

354-
async _listenForEngineUpdates() {
355-
try {
356-
const port = +(process.env.PORT || 8080);
357-
const host = process.env.HOST || '0.0.0.0';
358-
359-
const server = fastify();
360-
const secretsOptions = {
361-
schema: {
362-
body: {
363-
type: 'object',
364-
required: ['key', 'value'],
365-
properties: {
366-
key: { type: 'string' },
367-
value: { type: 'string' },
368-
},
369-
},
370-
},
371-
};
372-
server.post('/secrets', secretsOptions, async (request, reply) => {
373-
try {
374-
const { body: secret } = request;
375-
logger.info(`got request to add new mask: ${secret.key}`);
376-
this.taskLogger.addNewMask(secret);
377-
reply.code(201);
378-
return 'secret added';
379-
} catch (err) {
380-
logger.info(`could not create new mask for due to error: ${err}`);
381-
reply.code(500);
382-
throw err;
383-
}
384-
});
385-
386-
const address = await server.listen({ host, port });
387-
await saveServerAddress(address);
388-
logger.info(`listening for engine updates on ${address}`);
389-
} catch (error) {
390-
logger.error(`could not start server for engine updates due to error: ${error}`);
391-
throw error;
392-
}
357+
async _listenForEngineRequests() {
358+
await this.httpServer.start();
393359
}
394360

395361
_handleContainerStreamEnd(containerId) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface DeprecatedImageDto {
2+
image: string;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { DeprecatedImageDto } from './deprecated-image.dto';
2+
3+
class DeprecatedImagesCollector {
4+
5+
private list: DeprecatedImageDto[] = [];
6+
7+
push(deprecatedImageDto: DeprecatedImageDto) {
8+
this.list.push(deprecatedImageDto);
9+
}
10+
11+
consumeAll() {
12+
return this.list;
13+
}
14+
15+
destroyConsumed(consumedNumber: number) {
16+
this.list = this.list.slice(consumedNumber);
17+
}
18+
}
19+
20+
export default new DeprecatedImagesCollector();

0 commit comments

Comments
 (0)