mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 17:42:57 +00:00
feat: support docker swarm deployments
This commit is contained in:
56
package-lock.json
generated
56
package-lock.json
generated
@@ -649,6 +649,12 @@
|
|||||||
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
|
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/proxyquire": {
|
||||||
|
"version": "1.3.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz",
|
||||||
|
"integrity": "sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/semver": {
|
"@types/semver": {
|
||||||
"version": "7.3.9",
|
"version": "7.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
|
||||||
@@ -1101,9 +1107,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001338",
|
"version": "1.0.30001339",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001338.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001339.tgz",
|
||||||
"integrity": "sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ==",
|
"integrity": "sha512-Es8PiVqCe+uXdms0Gu5xP5PF2bxLR7OBp3wUzUnuO7OHzhOfCyg3hdiGWVPVxhiuniOzng+hTc1u3fEQ0TlkSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chai": {
|
"chai": {
|
||||||
@@ -2061,6 +2067,16 @@
|
|||||||
"flat-cache": "^3.0.4"
|
"flat-cache": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fill-keys": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-object": "~1.0.1",
|
||||||
|
"merge-descriptors": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
@@ -2571,6 +2587,12 @@
|
|||||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
|
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-object": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-plain-obj": {
|
"is-plain-obj": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
|
||||||
@@ -3016,6 +3038,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"merge2": {
|
"merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
@@ -3229,6 +3257,12 @@
|
|||||||
"integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
|
"integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"module-not-found-error": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.29.1",
|
"version": "2.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||||
@@ -3268,6 +3302,11 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node-port-scanner": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-port-scanner/-/node-port-scanner-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-TuFGEWfye+1atB74v0Vm6myEjpq0L5Jo3UaOG9xgtYHxnFZN0fF9CnwCxp7ENWDerGbI1UXAgdRMIPz8TM73Hg=="
|
||||||
|
},
|
||||||
"node-preload": {
|
"node-preload": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
|
||||||
@@ -3624,6 +3663,17 @@
|
|||||||
"fromentries": "^1.2.0"
|
"fromentries": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"proxyquire": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fill-keys": "^1.0.2",
|
||||||
|
"module-not-found-error": "^1.0.1",
|
||||||
|
"resolve": "^1.11.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"pump": {
|
"pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"dockerode": "3.3.1",
|
"dockerode": "3.3.1",
|
||||||
"is-cidr": "4.0.2",
|
"is-cidr": "4.0.2",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
|
"node-port-scanner": "3.0.1",
|
||||||
"semver": "7.3.7"
|
"semver": "7.3.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
"@types/chai": "4.3.1",
|
"@types/chai": "4.3.1",
|
||||||
"@types/chai-spies": "1.0.3",
|
"@types/chai-spies": "1.0.3",
|
||||||
"@types/mustache": "4.1.2",
|
"@types/mustache": "4.1.2",
|
||||||
|
"@types/proxyquire": "1.3.28",
|
||||||
"@typescript-eslint/eslint-plugin": "5.22.0",
|
"@typescript-eslint/eslint-plugin": "5.22.0",
|
||||||
"@typescript-eslint/parser": "5.22.0",
|
"@typescript-eslint/parser": "5.22.0",
|
||||||
"chai": "4.3.6",
|
"chai": "4.3.6",
|
||||||
@@ -36,6 +38,7 @@
|
|||||||
"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.6.2",
|
||||||
|
"proxyquire": "2.1.3",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"ts-node": "10.7.0",
|
"ts-node": "10.7.0",
|
||||||
"typedoc": "0.22.15",
|
"typedoc": "0.22.15",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ process.on('unhandledRejection', async error => {
|
|||||||
|
|
||||||
let containerHashCache = '';
|
let containerHashCache = '';
|
||||||
let configHashCache = '';
|
let configHashCache = '';
|
||||||
|
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the container information from the docker socket and updates the nginx config if necessary
|
* Reads the container information from the docker socket and updates the nginx config if necessary
|
||||||
@@ -51,6 +52,8 @@ async function updateNginxConfig() {
|
|||||||
// if containers changed -> write config file, reload nginx
|
// if containers changed -> write config file, reload nginx
|
||||||
if (containerHash !== containerHashCache || configHash !== configHashCache) {
|
if (containerHash !== containerHashCache || configHash !== configHashCache) {
|
||||||
Logger.log('Generating new NGINX configuration');
|
Logger.log('Generating new NGINX configuration');
|
||||||
|
Logger.log('Waiting for Docker network to settle...');
|
||||||
|
await delay(10_000);
|
||||||
|
|
||||||
// render nginx config file
|
// render nginx config file
|
||||||
const nginxConfig = render(
|
const nginxConfig = render(
|
||||||
|
|||||||
49
src/main.ts
49
src/main.ts
@@ -32,6 +32,9 @@ import {
|
|||||||
/* eslint-disable unicorn/prefer-module */
|
/* eslint-disable unicorn/prefer-module */
|
||||||
/* eslint-disable unicorn/no-await-expression-member */
|
/* eslint-disable unicorn/no-await-expression-member */
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const nodePortScanner = require('node-port-scanner');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a ContainerInfo matches a name and version regex
|
* Checks if a ContainerInfo matches a name and version regex
|
||||||
*
|
*
|
||||||
@@ -47,8 +50,11 @@ export function containerMatchesRegex(
|
|||||||
return (
|
return (
|
||||||
typeof container.Labels['stapps.version'] === 'string' &&
|
typeof container.Labels['stapps.version'] === 'string' &&
|
||||||
container.Labels['stapps.version'].match(versionRegex) !== null &&
|
container.Labels['stapps.version'].match(versionRegex) !== null &&
|
||||||
typeof container.Labels['com.docker.compose.service'] === 'string' &&
|
((typeof container.Labels['com.docker.compose.service'] === 'string' &&
|
||||||
container.Labels['com.docker.compose.service'] === name
|
container.Labels['com.docker.compose.service'] === name) ||
|
||||||
|
(typeof container.Labels['com.docker.stack.namespace'] === 'string' &&
|
||||||
|
container.Labels['com.docker.swarm.service.name'] ===
|
||||||
|
`${container.Labels['com.docker.stack.namespace']}_${name}`))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,14 +68,43 @@ export function containerMatchesRegex(
|
|||||||
*/
|
*/
|
||||||
export async function getGatewayOfStAppsBackend(container: Dockerode.ContainerInfo): Promise<string> {
|
export async function getGatewayOfStAppsBackend(container: Dockerode.ContainerInfo): Promise<string> {
|
||||||
if (container.Ports.length === 0) {
|
if (container.Ports.length === 0) {
|
||||||
await Logger.error(`Container ${container.Id} does not advertise any port.
|
await Logger.error(`Container ${container.Names[0]} does not advertise any port.
|
||||||
Please expose a port if the container should be accessible by NGINX.`);
|
Please expose a port if the container should be accessible by NGINX.`);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Basic Docker network
|
||||||
|
if (typeof container.Ports[0].IP !== 'undefined' && typeof container.Ports[0].PublicPort !== 'undefined') {
|
||||||
// ip:port
|
// ip:port
|
||||||
return `${container.Ports[0].IP}:${container.Ports[0].PublicPort}`;
|
return `${container.Ports[0].IP}:${container.Ports[0].PublicPort}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Docker Swarm network
|
||||||
|
if (
|
||||||
|
typeof container.NetworkSettings?.Networks?.ingress?.IPAddress !== 'undefined' &&
|
||||||
|
typeof container.Ports[0].PrivatePort !== 'undefined'
|
||||||
|
) {
|
||||||
|
const port = container.Ports[0].PrivatePort;
|
||||||
|
|
||||||
|
// Get a routable network connection
|
||||||
|
for (const network in container.NetworkSettings.Networks) {
|
||||||
|
const scan = await nodePortScanner(container.NetworkSettings.Networks[network].IPAddress, [port]);
|
||||||
|
|
||||||
|
if ((scan.ports.open as Array<number>).includes(port)) {
|
||||||
|
Logger.info(
|
||||||
|
`${container.Names[0]} reachable via ${container.NetworkSettings.Networks[network].IPAddress}:${port}`,
|
||||||
|
);
|
||||||
|
return `${container.NetworkSettings.Networks[network].IPAddress}:${port}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Logger.error(
|
||||||
|
`Couldn't infer ${container.Names[0]} network reachability. It's possible your current Docker network setup isn't supported yet.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +126,10 @@ export async function generateUpstreamMap(
|
|||||||
|
|
||||||
let foundMatchingContainer = false;
|
let foundMatchingContainer = false;
|
||||||
|
|
||||||
|
// const backendContainer = containers.filter(container => container.Image.includes('backend'));
|
||||||
|
// // eslint-disable-next-line no-console
|
||||||
|
//console.log(JSON.stringify(backendContainer, undefined, 2));
|
||||||
|
|
||||||
// active versions
|
// active versions
|
||||||
result += (
|
result += (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -137,7 +176,7 @@ export async function generateUpstreamMap(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Logger.error('No backend for version', activeVersionRegex, 'found');
|
Logger.warn('No backend for version', activeVersionRegex, 'found');
|
||||||
|
|
||||||
return ` \"~${activeVersionRegex}\" unavailable;\n`;
|
return ` \"~${activeVersionRegex}\" unavailable;\n`;
|
||||||
}),
|
}),
|
||||||
@@ -149,7 +188,7 @@ export async function generateUpstreamMap(
|
|||||||
.map(outdatedVersionRegex => {
|
.map(outdatedVersionRegex => {
|
||||||
return ` \"~${outdatedVersionRegex}\" outdated;`;
|
return ` \"~${outdatedVersionRegex}\" outdated;`;
|
||||||
})
|
})
|
||||||
.join('');
|
.join('\n');
|
||||||
|
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
result += '\n\}';
|
result += '\n\}';
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ import {
|
|||||||
} from '../src/main';
|
} from '../src/main';
|
||||||
import {resolve} from 'path';
|
import {resolve} from 'path';
|
||||||
import {mkdirSync, writeFileSync, unlinkSync, rmdirSync} from 'fs';
|
import {mkdirSync, writeFileSync, unlinkSync, rmdirSync} from 'fs';
|
||||||
|
import proxyquire from 'proxyquire';
|
||||||
|
|
||||||
|
proxyquire.callThru().preserveCache();
|
||||||
|
|
||||||
process.on('unhandledRejection', async error => {
|
process.on('unhandledRejection', async error => {
|
||||||
await Logger.error(error);
|
await Logger.error(error);
|
||||||
@@ -139,6 +142,56 @@ export class MainSpec {
|
|||||||
Status: 'Up 3 minutes',
|
Status: 'Up 3 minutes',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static swarmBackendContainerWithExposedPorts: ContainerInfo = {
|
||||||
|
Command: 'node ./bin/www',
|
||||||
|
Created: 1524669882,
|
||||||
|
HostConfig: {
|
||||||
|
NetworkMode: 'deployment_default',
|
||||||
|
},
|
||||||
|
Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7',
|
||||||
|
Image: 'registry.gitlab.com/openstapps/backend/b-tu-typescript-refactor-for-new-tslint-config',
|
||||||
|
ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9',
|
||||||
|
Labels: {
|
||||||
|
'com.docker.compose.config-hash': '91c6e0cebad15951824162c93392b6880b69599692f07798ae8de659c1616a03',
|
||||||
|
'com.docker.compose.container-number': '1',
|
||||||
|
'com.docker.compose.oneoff': 'False',
|
||||||
|
'com.docker.compose.project': 'deployment',
|
||||||
|
'com.docker.compose.service': 'backend',
|
||||||
|
'com.docker.compose.version': '1.21.0',
|
||||||
|
'stapps.version': '1.0.0',
|
||||||
|
},
|
||||||
|
Mounts: [],
|
||||||
|
Names: ['/deployment_backend_1'],
|
||||||
|
NetworkSettings: {
|
||||||
|
Networks: {
|
||||||
|
ingress: {
|
||||||
|
Aliases: null,
|
||||||
|
EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14',
|
||||||
|
Gateway: '172.18.0.1',
|
||||||
|
GlobalIPv6Address: '',
|
||||||
|
GlobalIPv6PrefixLen: 0,
|
||||||
|
IPAMConfig: null,
|
||||||
|
IPAddress: '172.18.0.3',
|
||||||
|
IPPrefixLen: 16,
|
||||||
|
IPv6Gateway: '',
|
||||||
|
Links: null,
|
||||||
|
MacAddress: '03:41:ac:11:00:23',
|
||||||
|
NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Ports: [
|
||||||
|
{
|
||||||
|
IP: 'delete me',
|
||||||
|
PrivatePort: 3000,
|
||||||
|
PublicPort: 3000,
|
||||||
|
Type: 'tcp',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
State: 'running',
|
||||||
|
Status: 'Up 3 minutes',
|
||||||
|
};
|
||||||
|
|
||||||
static sandbox = chai.spy.sandbox();
|
static sandbox = chai.spy.sandbox();
|
||||||
|
|
||||||
before() {
|
before() {
|
||||||
@@ -199,15 +252,54 @@ export class MainSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@test
|
@test
|
||||||
async 'upstream map calls logger error when no matching container is found'() {
|
async 'get gateway of backend container within docker swarm'() {
|
||||||
const spy = MainSpec.sandbox.on(console, 'warn', () => {
|
const backendContainer = MainSpec.swarmBackendContainerWithExposedPorts as any;
|
||||||
|
delete backendContainer.Ports[0].IP;
|
||||||
|
|
||||||
|
const main = proxyquire('../src/main', {
|
||||||
|
'node-port-scanner': (_host: unknown, _ports: unknown) => {
|
||||||
|
return new Promise((resolve, _reject) => {
|
||||||
|
resolve({
|
||||||
|
ports: {
|
||||||
|
open: [3000],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(await main.getGatewayOfStAppsBackend(backendContainer)).to.be.equal('172.18.0.3:3000');
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
async 'fail to get gateway of backend container if unreachable'() {
|
||||||
|
const backendContainer = MainSpec.swarmBackendContainerWithExposedPorts as any;
|
||||||
|
delete backendContainer.Ports[0].IP;
|
||||||
|
delete backendContainer.Ports[0].PublicPort;
|
||||||
|
delete backendContainer.Ports[0].PrivatePort;
|
||||||
|
|
||||||
|
const spy = MainSpec.sandbox.on(console, 'error', () => {
|
||||||
|
// noop
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(await generateUpstreamMap(
|
expect(await getGatewayOfStAppsBackend(MainSpec.swarmBackendContainerWithExposedPorts)).to.be.equal('');
|
||||||
|
expect(spy.__spy.calls[0][0]).to.contain(
|
||||||
|
"It's possible your current Docker network setup isn't supported yet.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
async 'upstream map calls logger error when no matching container is found'() {
|
||||||
|
const spy = MainSpec.sandbox.on(console, 'warn', () => {
|
||||||
|
// noop
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await generateUpstreamMap(
|
||||||
['0\\.8\\.\\d+'],
|
['0\\.8\\.\\d+'],
|
||||||
['1\\.1\\.\\d+'],
|
['1\\.1\\.\\d+'],
|
||||||
[MainSpec.backendContainerWithExposedPorts],
|
[MainSpec.backendContainerWithExposedPorts],
|
||||||
)).to.be.equal(`map $http_x_stapps_version $proxyurl {
|
),
|
||||||
|
).to.be.equal(`map $http_x_stapps_version $proxyurl {
|
||||||
default unsupported;
|
default unsupported;
|
||||||
"~0\\.8\\.\\d+" unavailable;
|
"~0\\.8\\.\\d+" unavailable;
|
||||||
"~1\\.1\\.\\d+" outdated;
|
"~1\\.1\\.\\d+" outdated;
|
||||||
|
|||||||
Reference in New Issue
Block a user