mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-10 19:52:53 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a16771898c | ||
|
|
65de6f581f | ||
|
|
360a2e434d | ||
|
|
c8318305f9 | ||
|
|
4133ff36b7 | ||
|
|
25e506f54d | ||
|
|
cbbcc2e5e4 | ||
|
|
3f030fd50f | ||
|
|
5f77877bb4 | ||
|
|
6aea21e81f | ||
|
|
2982c8598e | ||
|
|
0486d733a1 | ||
|
|
8c49c31760 | ||
|
|
8ec8fb3386 | ||
|
|
f432d57004 | ||
|
|
26a4e6dcf1 | ||
|
|
54dc63d848 | ||
|
|
949063eff8 | ||
|
|
9832b0395a |
@@ -21,6 +21,12 @@ unit:
|
|||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- npm test
|
- npm test
|
||||||
|
coverage: '/Statements[^:]*\:[^:]*\s+([\d\.]+)%/'
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: coverage/cobertura-coverage.xml
|
||||||
|
|
||||||
audit:
|
audit:
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|||||||
42
CHANGELOG.md
42
CHANGELOG.md
@@ -1,3 +1,45 @@
|
|||||||
|
# [1.5.0](https://gitlab.com/openstapps/proxy/compare/v1.4.1...v1.5.0) (2022-11-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* SVGs treated as plain texts ([25e506f](https://gitlab.com/openstapps/proxy/commit/25e506f54d56f49bf5201b76076bc167fafce290)), closes [#14](https://gitlab.com/openstapps/proxy/issues/14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.4.1](https://gitlab.com/openstapps/proxy/compare/v1.4.0...v1.4.1) (2022-11-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* include uri path in json log verbatim ([5f77877](https://gitlab.com/openstapps/proxy/commit/5f77877bb4239a437ff3f2eea1c0dfd51c7d4818))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.4.0](https://gitlab.com/openstapps/proxy/compare/v1.3.0...v1.4.0) (2022-11-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add support for log aggregators ([8c49c31](https://gitlab.com/openstapps/proxy/commit/8c49c317603b1a2964708ed377a5a7c687f829cd))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.3.0](https://gitlab.com/openstapps/proxy/compare/v1.2.0...v1.3.0) (2022-08-22)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.2.0](https://gitlab.com/openstapps/proxy/compare/v1.1.0...v1.2.0) (2022-06-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* added prometheus metrics support ([5522ac5](https://gitlab.com/openstapps/proxy/commit/5522ac55ac00d4b809d942d0a8c58d15b0432fb8))
|
||||||
|
* reload nginx on proxyconfig change ([1fcf734](https://gitlab.com/openstapps/proxy/commit/1fcf7340d49bde993b3acc7bdc90e6a637a05321))
|
||||||
|
* support docker swarm deployments ([4bb46d8](https://gitlab.com/openstapps/proxy/commit/4bb46d8a06ff7829b6908bd03c1cf4240767fcc2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.1.0](https://gitlab.com/openstapps/proxy/compare/v1.0.1...v1.1.0) (2022-03-10)
|
# [1.1.0](https://gitlab.com/openstapps/proxy/compare/v1.0.1...v1.1.0) (2022-03-10)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {ConfigFile} from '../src/common';
|
|||||||
const config: ConfigFile = {
|
const config: ConfigFile = {
|
||||||
activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'],
|
activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'],
|
||||||
hiddenRoutes: ['/bulk'],
|
hiddenRoutes: ['/bulk'],
|
||||||
|
logFormat: 'default',
|
||||||
metrics: false,
|
metrics: false,
|
||||||
outdatedVersions: ['0\\.8\\.\\d+', '0\\.5\\.\\d+', '0\\.6\\.\\d+', '0\\.7\\.\\d+'],
|
outdatedVersions: ['0\\.8\\.\\d+', '0\\.5\\.\\d+', '0\\.6\\.\\d+', '0\\.7\\.\\d+'],
|
||||||
output: '/etc/nginx/http.d/default.conf',
|
output: '/etc/nginx/http.d/default.conf',
|
||||||
|
|||||||
@@ -3,4 +3,3 @@ add_header 'Access-Control-Allow-Credentials' 'true';
|
|||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-StApps-Version';
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-StApps-Version';
|
||||||
add_header 'Access-Control-Max-Age' 1728000;
|
add_header 'Access-Control-Max-Age' 1728000;
|
||||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
|
||||||
|
|||||||
33
fixtures/logFormatters.template
Normal file
33
fixtures/logFormatters.template
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
map $time_iso8601 $time_iso8601_dateTime {
|
||||||
|
~([^+]+) $1;
|
||||||
|
}
|
||||||
|
map $time_iso8601 $time_iso8601_TZ {
|
||||||
|
~\+([0-9:]+)$ $1;
|
||||||
|
}
|
||||||
|
map $msec $millisec {
|
||||||
|
~\.([0-9]+)$ $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_format json escape=json '{ "nginx_timestamp": "$time_iso8601_dateTime.$millisec+$time_iso8601_TZ", '
|
||||||
|
'"remote_addr": "$remote_addr", '
|
||||||
|
'"connection": "$connection", '
|
||||||
|
'"connection_requests": $connection_requests, '
|
||||||
|
'"pipe": "$pipe", '
|
||||||
|
'"body_bytes_sent": $body_bytes_sent, '
|
||||||
|
'"request_length": $request_length, '
|
||||||
|
'"request_time": $request_time, '
|
||||||
|
'"response_status": $status, '
|
||||||
|
'"request_uri": "$request_uri", '
|
||||||
|
'"request_method": "$request_method", '
|
||||||
|
'"host": "$host", '
|
||||||
|
'"upstream_cache_status": "$upstream_cache_status", '
|
||||||
|
'"upstream_addr": "$upstream_addr", '
|
||||||
|
'"http_x_stapps_version": "$http_x_stapps_version", '
|
||||||
|
'"http_x_forwarded_for": "$http_x_forwarded_for", '
|
||||||
|
'"http_referrer": "$http_referer", '
|
||||||
|
'"http_user_agent": "$http_user_agent", '
|
||||||
|
'"http_version": "$server_protocol", '
|
||||||
|
'"remote_user": "$remote_user", '
|
||||||
|
'"http_x_forwarded_proto": "$http_x_forwarded_proto", '
|
||||||
|
'"upstream_response_time": "$upstream_response_time", '
|
||||||
|
'"nginx_access": true }';
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
|
map $status $omitOKs {
|
||||||
|
default 1;
|
||||||
|
~^[2][0][0] 0;
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 8080;
|
listen 8080;
|
||||||
|
error_log stderr;
|
||||||
|
access_log /dev/stdout {{{ logFormat }}} if=$omitOKs;
|
||||||
location /metrics {
|
location /metrics {
|
||||||
vhost_traffic_status_display;
|
vhost_traffic_status_display;
|
||||||
vhost_traffic_status_display_format prometheus;
|
vhost_traffic_status_display_format prometheus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
{{{ logFormatters }}}
|
||||||
|
|
||||||
{{{ metrics }}}
|
{{{ metrics }}}
|
||||||
|
|
||||||
{{{ dockerVersionMap }}}
|
{{{ dockerVersionMap }}}
|
||||||
@@ -19,6 +21,10 @@ map $isRateLimited $rateLimit {
|
|||||||
limit_req_zone $rateLimit zone=customstappslimit:10m rate=20r/s;
|
limit_req_zone $rateLimit zone=customstappslimit:10m rate=20r/s;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
charset utf-8;
|
||||||
|
error_log stderr;
|
||||||
|
access_log /dev/stdout {{{ logFormat }}};
|
||||||
|
|
||||||
{{{ listener }}}
|
{{{ listener }}}
|
||||||
|
|
||||||
{{{ visibleRoutes }}}
|
{{{ visibleRoutes }}}
|
||||||
|
|||||||
1034
package-lock.json
generated
1034
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@@ -1,47 +1,47 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/proxy",
|
"name": "@openstapps/proxy",
|
||||||
"version": "1.2.0",
|
"version": "1.5.1",
|
||||||
"description": "NGINX proxy that is dynamically configured by a Node.js script",
|
"description": "NGINX proxy that is dynamically configured by a Node.js script",
|
||||||
"main": "./lib/cli.js",
|
"main": "./lib/cli.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openstapps/logger": "0.8.1",
|
"@openstapps/logger": "1.1.1",
|
||||||
"@types/config": "0.0.41",
|
"@types/config": "3.3.0",
|
||||||
"@types/dockerode": "3.3.9",
|
"@types/dockerode": "3.3.14",
|
||||||
"@types/node": "14.18.16",
|
"@types/node": "14.18.36",
|
||||||
"@types/sha1": "1.1.3",
|
"@types/sha1": "1.1.3",
|
||||||
"config": "3.3.7",
|
"config": "3.3.8",
|
||||||
"dockerode": "3.3.2",
|
"dockerode": "3.3.4",
|
||||||
"is-cidr": "4.0.2",
|
"is-cidr": "4.0.2",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"node-port-scanner": "3.0.1",
|
"node-port-scanner": "3.0.1",
|
||||||
"semver": "7.3.7"
|
"semver": "7.3.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.31.0",
|
"@openstapps/configuration": "0.33.0",
|
||||||
"@openstapps/eslint-config": "1.0.0",
|
"@openstapps/eslint-config": "1.1.0",
|
||||||
"@testdeck/mocha": "0.2.0",
|
"@testdeck/mocha": "0.3.3",
|
||||||
"@types/chai": "4.3.1",
|
"@types/chai": "4.3.4",
|
||||||
"@types/chai-spies": "1.0.3",
|
"@types/chai-spies": "1.0.3",
|
||||||
"@types/mustache": "4.1.3",
|
"@types/mustache": "4.2.2",
|
||||||
"@types/proxyquire": "1.3.28",
|
"@types/proxyquire": "1.3.28",
|
||||||
"@typescript-eslint/eslint-plugin": "5.27.1",
|
"@typescript-eslint/eslint-plugin": "5.42.1",
|
||||||
"@typescript-eslint/parser": "5.27.1",
|
"@typescript-eslint/parser": "5.42.1",
|
||||||
"chai": "4.3.6",
|
"chai": "4.3.7",
|
||||||
"chai-spies": "1.0.0",
|
"chai-spies": "1.0.0",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"eslint": "8.17.0",
|
"eslint": "8.31.0",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": "39.3.2",
|
"eslint-plugin-jsdoc": "39.6.4",
|
||||||
"eslint-plugin-prettier": "4.0.0",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "42.0.0",
|
"eslint-plugin-unicorn": "44.0.2",
|
||||||
"mocha": "9.2.2",
|
"mocha": "10.2.0",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"prepend-file-cli": "1.0.6",
|
"prepend-file-cli": "1.0.6",
|
||||||
"prettier": "2.6.2",
|
"prettier": "2.8.2",
|
||||||
"proxyquire": "2.1.3",
|
"proxyquire": "2.1.3",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"ts-node": "10.8.1",
|
"ts-node": "10.9.1",
|
||||||
"typedoc": "0.22.17",
|
"typedoc": "0.22.18",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -94,6 +94,7 @@
|
|||||||
"lines": 95,
|
"lines": 95,
|
||||||
"per-file": true,
|
"per-file": true,
|
||||||
"reporter": [
|
"reporter": [
|
||||||
|
"cobertura",
|
||||||
"html",
|
"html",
|
||||||
"text-summary"
|
"text-summary"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -79,4 +79,5 @@ async function updateNginxConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start the process that checks the docker socket periodically
|
// start the process that checks the docker socket periodically
|
||||||
|
// eslint-disable-next-line unicorn/prefer-top-level-await
|
||||||
updateNginxConfig();
|
updateNginxConfig();
|
||||||
|
|||||||
@@ -47,6 +47,20 @@ export interface SSLFilePaths {
|
|||||||
dhparam: string;
|
dhparam: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported log formats for config
|
||||||
|
*/
|
||||||
|
type SupportedLogFormatsKeys = 'default' | 'combined' | 'json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map supported formats to stings used in template view
|
||||||
|
*/
|
||||||
|
export const SupportedLogFormats: {[key in SupportedLogFormatsKeys]: string} = {
|
||||||
|
default: 'combined',
|
||||||
|
combined: 'combined',
|
||||||
|
json: 'json',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of the config file
|
* A representation of the config file
|
||||||
*/
|
*/
|
||||||
@@ -59,10 +73,14 @@ export interface ConfigFile {
|
|||||||
* List of hidden routes
|
* List of hidden routes
|
||||||
*/
|
*/
|
||||||
hiddenRoutes: string[];
|
hiddenRoutes: string[];
|
||||||
|
/**
|
||||||
|
* Sets log format (default or json)
|
||||||
|
*/
|
||||||
|
logFormat: SupportedLogFormatsKeys;
|
||||||
/**
|
/**
|
||||||
* Enables metrics on /metrics route
|
* Enables metrics on /metrics route
|
||||||
*/
|
*/
|
||||||
metrics: boolean;
|
metrics?: boolean;
|
||||||
/**
|
/**
|
||||||
* List of outdated versions
|
* List of outdated versions
|
||||||
*/
|
*/
|
||||||
@@ -97,6 +115,14 @@ export interface TemplateView {
|
|||||||
* Listener
|
* Listener
|
||||||
*/
|
*/
|
||||||
listener: string;
|
listener: string;
|
||||||
|
/**
|
||||||
|
* Log format to use
|
||||||
|
*/
|
||||||
|
logFormat: string;
|
||||||
|
/**
|
||||||
|
* Custom Log formatters
|
||||||
|
*/
|
||||||
|
logFormatters: string;
|
||||||
/**
|
/**
|
||||||
* Local server with listener for /metrics route
|
* Local server with listener for /metrics route
|
||||||
*/
|
*/
|
||||||
|
|||||||
19
src/main.ts
19
src/main.ts
@@ -26,6 +26,7 @@ import {
|
|||||||
protocolHardeningParameters,
|
protocolHardeningParameters,
|
||||||
SSLFilePaths,
|
SSLFilePaths,
|
||||||
sslHardeningParameters,
|
sslHardeningParameters,
|
||||||
|
SupportedLogFormats,
|
||||||
TemplateView,
|
TemplateView,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
|
||||||
@@ -244,11 +245,14 @@ ${protocolHardeningParameters}
|
|||||||
/**
|
/**
|
||||||
* Reads predefined server entry with metrics location
|
* Reads predefined server entry with metrics location
|
||||||
*/
|
*/
|
||||||
export async function generateMetricsServer(enableMetrics: boolean): Promise<string> {
|
export async function generateMetricsServer(logFormat: string, enableMetrics?: boolean): Promise<string> {
|
||||||
if (!enableMetrics) {
|
if (!enableMetrics) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return asyncReadFile('./fixtures/metrics.template', 'utf8');
|
|
||||||
|
return renderTemplate(path.join('fixtures', 'metrics.template'), {
|
||||||
|
logFormat: logFormat,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,6 +306,13 @@ export async function getTemplateView(containers: Dockerode.ContainerInfo[]): Pr
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const logFormattingPromise = renderTemplate(path.join('fixtures', 'logFormatters.template'), {});
|
||||||
|
|
||||||
|
const logFormat =
|
||||||
|
configFile.logFormat in SupportedLogFormats
|
||||||
|
? SupportedLogFormats[configFile.logFormat]
|
||||||
|
: SupportedLogFormats.default;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dockerVersionMap: await generateUpstreamMap(
|
dockerVersionMap: await generateUpstreamMap(
|
||||||
configFile.activeVersions,
|
configFile.activeVersions,
|
||||||
@@ -310,7 +321,9 @@ export async function getTemplateView(containers: Dockerode.ContainerInfo[]): Pr
|
|||||||
),
|
),
|
||||||
hiddenRoutes: (await Promise.all(hiddenRoutesPromises)).join(''),
|
hiddenRoutes: (await Promise.all(hiddenRoutesPromises)).join(''),
|
||||||
listener: generateListener(configFile.sslFilePaths),
|
listener: generateListener(configFile.sslFilePaths),
|
||||||
metrics: await generateMetricsServer(configFile.metrics),
|
logFormat: logFormat,
|
||||||
|
logFormatters: await logFormattingPromise,
|
||||||
|
metrics: await generateMetricsServer(logFormat, configFile.metrics),
|
||||||
rateLimitAllowList: generateRateLimitAllowList(configFile.rateLimitAllowList),
|
rateLimitAllowList: generateRateLimitAllowList(configFile.rateLimitAllowList),
|
||||||
staticRoute: await renderTemplate(path.join('fixtures', 'staticRoute.template'), {cors}),
|
staticRoute: await renderTemplate(path.join('fixtures', 'staticRoute.template'), {cors}),
|
||||||
visibleRoutes: (await Promise.all(visibleRoutesPromises)).join(''),
|
visibleRoutes: (await Promise.all(visibleRoutesPromises)).join(''),
|
||||||
|
|||||||
@@ -402,12 +402,12 @@ Please check if docker is running and Node.js can access the docker socket (/var
|
|||||||
|
|
||||||
@test
|
@test
|
||||||
async 'include metrics config'() {
|
async 'include metrics config'() {
|
||||||
expect(await generateMetricsServer(true)).length.to.be.greaterThan(1);
|
expect(await generateMetricsServer('test', true)).length.to.be.greaterThan(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@test
|
@test
|
||||||
async 'omit metrics config'() {
|
async 'omit metrics config'() {
|
||||||
expect(await generateMetricsServer(false)).to.equal('');
|
expect(await generateMetricsServer('test', false)).to.equal('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@test
|
@test
|
||||||
|
|||||||
Reference in New Issue
Block a user