navy 7.0.0-alpha.3 → 7.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__tests__/http-proxy.js +210 -0
- package/lib/cli/__tests__/program.js +109 -0
- package/lib/http-proxy.js +44 -0
- package/package.json +1 -1
|
@@ -62,6 +62,185 @@ describe('resolveProxyImage', function () {
|
|
|
62
62
|
(0, _chai.expect)((0, _httpProxy.resolveProxyImage)()).to.equal('navycloud/navy-proxy');
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
|
+
describe('resolveProxyEnvFromNavyFile', function () {
|
|
66
|
+
it('should return an empty object when no navyFile is provided', function () {
|
|
67
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)()).to.eql({});
|
|
68
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)(null)).to.eql({});
|
|
69
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)(undefined)).to.eql({});
|
|
70
|
+
});
|
|
71
|
+
it('should return an empty object when navyFile has no httpProxyEnv', function () {
|
|
72
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)({})).to.eql({});
|
|
73
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)({
|
|
74
|
+
plugins: []
|
|
75
|
+
})).to.eql({});
|
|
76
|
+
});
|
|
77
|
+
it('should return the httpProxyEnv map from navyFile', function () {
|
|
78
|
+
const navyFile = {
|
|
79
|
+
httpProxyEnv: {
|
|
80
|
+
FOO: 'bar',
|
|
81
|
+
BAZ: 'qux'
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)(navyFile)).to.eql({
|
|
85
|
+
FOO: 'bar',
|
|
86
|
+
BAZ: 'qux'
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
it('should drop entries with empty string, null, or undefined values', function () {
|
|
90
|
+
const navyFile = {
|
|
91
|
+
httpProxyEnv: {
|
|
92
|
+
EMPTY: '',
|
|
93
|
+
NULL: null,
|
|
94
|
+
UNDEF: undefined,
|
|
95
|
+
KEEP: 'value'
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)(navyFile)).to.eql({
|
|
99
|
+
KEEP: 'value'
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it('should coerce numeric values to strings', function () {
|
|
103
|
+
const navyFile = {
|
|
104
|
+
httpProxyEnv: {
|
|
105
|
+
PORT: 8080,
|
|
106
|
+
ZERO: 0
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)(navyFile)).to.eql({
|
|
110
|
+
PORT: '8080',
|
|
111
|
+
ZERO: '0'
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it('should return an empty object when httpProxyEnv is a string', function () {
|
|
115
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)({
|
|
116
|
+
httpProxyEnv: 'FOO=bar'
|
|
117
|
+
})).to.eql({});
|
|
118
|
+
});
|
|
119
|
+
it('should return an empty object when httpProxyEnv is an array', function () {
|
|
120
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvFromNavyFile)({
|
|
121
|
+
httpProxyEnv: ['FOO=bar']
|
|
122
|
+
})).to.eql({});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('resolveProxyEnvAllowlist', function () {
|
|
126
|
+
const namesSetDuringTest = [];
|
|
127
|
+
function setEnv(name, value) {
|
|
128
|
+
namesSetDuringTest.push(name);
|
|
129
|
+
process.env[name] = value;
|
|
130
|
+
}
|
|
131
|
+
afterEach(function () {
|
|
132
|
+
delete process.env.NAVY_HTTP_PROXY_ENV;
|
|
133
|
+
while (namesSetDuringTest.length > 0) {
|
|
134
|
+
delete process.env[namesSetDuringTest.pop()];
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
it('should return an empty object when NAVY_HTTP_PROXY_ENV is unset', function () {
|
|
138
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({});
|
|
139
|
+
});
|
|
140
|
+
it('should return an empty object when NAVY_HTTP_PROXY_ENV is empty', function () {
|
|
141
|
+
process.env.NAVY_HTTP_PROXY_ENV = '';
|
|
142
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({});
|
|
143
|
+
});
|
|
144
|
+
it('should forward a single name whose value is present in process.env', function () {
|
|
145
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'FORWARD_ME';
|
|
146
|
+
setEnv('FORWARD_ME', 'hello');
|
|
147
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({
|
|
148
|
+
FORWARD_ME: 'hello'
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
it('should trim whitespace from comma-separated names', function () {
|
|
152
|
+
process.env.NAVY_HTTP_PROXY_ENV = ' FOO , BAR ';
|
|
153
|
+
setEnv('FOO', 'one');
|
|
154
|
+
setEnv('BAR', 'two');
|
|
155
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({
|
|
156
|
+
FOO: 'one',
|
|
157
|
+
BAR: 'two'
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
it('should deduplicate repeated names', function () {
|
|
161
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'FOO,FOO,BAR,FOO';
|
|
162
|
+
setEnv('FOO', 'one');
|
|
163
|
+
setEnv('BAR', 'two');
|
|
164
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({
|
|
165
|
+
FOO: 'one',
|
|
166
|
+
BAR: 'two'
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
it('should drop names whose value is empty or unset', function () {
|
|
170
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'PRESENT,EMPTY,MISSING';
|
|
171
|
+
setEnv('PRESENT', 'value');
|
|
172
|
+
setEnv('EMPTY', '');
|
|
173
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({
|
|
174
|
+
PRESENT: 'value'
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
it('should ignore empty entries produced by trailing or repeated commas', function () {
|
|
178
|
+
process.env.NAVY_HTTP_PROXY_ENV = ',FOO,,';
|
|
179
|
+
setEnv('FOO', 'value');
|
|
180
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnvAllowlist)()).to.eql({
|
|
181
|
+
FOO: 'value'
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe('resolveProxyEnv', function () {
|
|
186
|
+
const namesSetDuringTest = [];
|
|
187
|
+
function setEnv(name, value) {
|
|
188
|
+
namesSetDuringTest.push(name);
|
|
189
|
+
process.env[name] = value;
|
|
190
|
+
}
|
|
191
|
+
afterEach(function () {
|
|
192
|
+
delete process.env.NAVY_HTTP_PROXY_ENV;
|
|
193
|
+
while (namesSetDuringTest.length > 0) {
|
|
194
|
+
delete process.env[namesSetDuringTest.pop()];
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
it('should return null when both sources are empty', function () {
|
|
198
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)()).to.equal(null);
|
|
199
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)({})).to.equal(null);
|
|
200
|
+
});
|
|
201
|
+
it('should return only the navyFile entries when no allowlist is set', function () {
|
|
202
|
+
const navyFile = {
|
|
203
|
+
httpProxyEnv: {
|
|
204
|
+
FOO: 'bar'
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)(navyFile)).to.eql({
|
|
208
|
+
FOO: 'bar'
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
it('should return only the allowlisted entries when navyFile has none', function () {
|
|
212
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'FORWARD_ME';
|
|
213
|
+
setEnv('FORWARD_ME', 'hello');
|
|
214
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)()).to.eql({
|
|
215
|
+
FORWARD_ME: 'hello'
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
it('should merge entries from both sources', function () {
|
|
219
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'FROM_ENV';
|
|
220
|
+
setEnv('FROM_ENV', 'env-value');
|
|
221
|
+
const navyFile = {
|
|
222
|
+
httpProxyEnv: {
|
|
223
|
+
FROM_FILE: 'file-value'
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)(navyFile)).to.eql({
|
|
227
|
+
FROM_FILE: 'file-value',
|
|
228
|
+
FROM_ENV: 'env-value'
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
it('should give the allowlist precedence on key collisions', function () {
|
|
232
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'SHARED';
|
|
233
|
+
setEnv('SHARED', 'env-value');
|
|
234
|
+
const navyFile = {
|
|
235
|
+
httpProxyEnv: {
|
|
236
|
+
SHARED: 'file-value'
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
(0, _chai.expect)((0, _httpProxy.resolveProxyEnv)(navyFile)).to.eql({
|
|
240
|
+
SHARED: 'env-value'
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
65
244
|
describe('resolveDockerSocketPath', function () {
|
|
66
245
|
let originalDockerHost;
|
|
67
246
|
beforeEach(function () {
|
|
@@ -211,4 +390,35 @@ describe('reconfigureHTTPProxy', function () {
|
|
|
211
390
|
const rmCall = execStub.getCalls().find(c => Array.isArray(c.args[1]) && c.args[1].includes('rm'));
|
|
212
391
|
(0, _chai.expect)(rmCall).to.equal(undefined);
|
|
213
392
|
});
|
|
393
|
+
it('should omit the environment block from the proxy compose service when no env config is provided', async function () {
|
|
394
|
+
listNetworksStub.resolves([]);
|
|
395
|
+
await (0, _httpProxy.reconfigureHTTPProxy)({
|
|
396
|
+
navies: []
|
|
397
|
+
});
|
|
398
|
+
const written = _jsYaml.default.load(writeFileSyncStub.firstCall.args[1]);
|
|
399
|
+
(0, _chai.expect)(written.services['nginx-proxy']).to.not.have.property('environment');
|
|
400
|
+
});
|
|
401
|
+
it('should include the merged environment block on the proxy compose service when httpProxyEnv or NAVY_HTTP_PROXY_ENV is set', async function () {
|
|
402
|
+
listNetworksStub.resolves([]);
|
|
403
|
+
process.env.NAVY_HTTP_PROXY_ENV = 'FROM_ENV';
|
|
404
|
+
process.env.FROM_ENV = 'env-value';
|
|
405
|
+
try {
|
|
406
|
+
await (0, _httpProxy.reconfigureHTTPProxy)({
|
|
407
|
+
navies: [],
|
|
408
|
+
navyFile: {
|
|
409
|
+
httpProxyEnv: {
|
|
410
|
+
FROM_FILE: 'file-value'
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
const written = _jsYaml.default.load(writeFileSyncStub.firstCall.args[1]);
|
|
415
|
+
(0, _chai.expect)(written.services['nginx-proxy'].environment).to.eql({
|
|
416
|
+
FROM_FILE: 'file-value',
|
|
417
|
+
FROM_ENV: 'env-value'
|
|
418
|
+
});
|
|
419
|
+
} finally {
|
|
420
|
+
delete process.env.NAVY_HTTP_PROXY_ENV;
|
|
421
|
+
delete process.env.FROM_ENV;
|
|
422
|
+
}
|
|
423
|
+
});
|
|
214
424
|
});
|
|
@@ -329,6 +329,103 @@ describe('cli/program', function () {
|
|
|
329
329
|
// exercised in practice. We do not test it because asserting that
|
|
330
330
|
// behaviour would lock in a latent bug.
|
|
331
331
|
});
|
|
332
|
+
describe('normaliseLazyRequireArgs (via lazyRequire wrapped action)', function () {
|
|
333
|
+
let importSpy;
|
|
334
|
+
function loadWithImportSpy() {
|
|
335
|
+
importSpy = sandbox.stub().resolves('imported');
|
|
336
|
+
return _proxyquire.default.noCallThru()('../program', {
|
|
337
|
+
commander: {
|
|
338
|
+
program: createCapturingProgram()
|
|
339
|
+
},
|
|
340
|
+
'../errors': {
|
|
341
|
+
NavyError: _errors.NavyError
|
|
342
|
+
},
|
|
343
|
+
'../config': {
|
|
344
|
+
getConfig: getConfigStub
|
|
345
|
+
},
|
|
346
|
+
'../driver-logging': {
|
|
347
|
+
startDriverLogging: startDriverLoggingStub,
|
|
348
|
+
stopDriverLogging: stopDriverLoggingStub
|
|
349
|
+
},
|
|
350
|
+
'../config-provider': {
|
|
351
|
+
getImportCommandLineOptions: getImportCommandLineOptionsStub
|
|
352
|
+
},
|
|
353
|
+
'../navy': {
|
|
354
|
+
getNavy: getNavyStub
|
|
355
|
+
},
|
|
356
|
+
'./import': importSpy,
|
|
357
|
+
'./launch': () => Promise.resolve(),
|
|
358
|
+
'./ps': () => Promise.resolve(),
|
|
359
|
+
'./updates': () => Promise.resolve(),
|
|
360
|
+
'./logs': () => Promise.resolve(),
|
|
361
|
+
'./health': () => Promise.resolve(),
|
|
362
|
+
'./wait-for-healthy': () => Promise.resolve(),
|
|
363
|
+
'./https': () => Promise.resolve(),
|
|
364
|
+
'./open': () => Promise.resolve(),
|
|
365
|
+
'./develop': () => Promise.resolve(),
|
|
366
|
+
'./live': () => Promise.resolve(),
|
|
367
|
+
'./run': () => Promise.resolve(),
|
|
368
|
+
'./refresh-config': () => Promise.resolve(),
|
|
369
|
+
'./status': () => Promise.resolve(),
|
|
370
|
+
'./doctor': () => Promise.resolve(),
|
|
371
|
+
'./config/wrapper': () => Promise.resolve(),
|
|
372
|
+
'./external-ip': () => Promise.resolve(),
|
|
373
|
+
'./lan-ip': () => Promise.resolve(),
|
|
374
|
+
'./local-ip': () => Promise.resolve()
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
it('should pass through unchanged when invoked with no arguments at all', async function () {
|
|
378
|
+
loadWithImportSpy();
|
|
379
|
+
capturedActions.import();
|
|
380
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
381
|
+
(0, _chai.expect)(importSpy.calledOnce).to.equal(true);
|
|
382
|
+
(0, _chai.expect)(importSpy.firstCall.args).to.eql([]);
|
|
383
|
+
});
|
|
384
|
+
it('should strip the trailing Command instance when no other args were supplied', async function () {
|
|
385
|
+
loadWithImportSpy();
|
|
386
|
+
const fakeCommand = {
|
|
387
|
+
optsWithGlobals: () => ({
|
|
388
|
+
navy: 'global'
|
|
389
|
+
})
|
|
390
|
+
};
|
|
391
|
+
capturedActions.import(fakeCommand);
|
|
392
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
393
|
+
(0, _chai.expect)(importSpy.calledOnce).to.equal(true);
|
|
394
|
+
(0, _chai.expect)(importSpy.firstCall.args).to.eql([]);
|
|
395
|
+
});
|
|
396
|
+
it('should merge inherited globals into the trailing options object before forwarding', async function () {
|
|
397
|
+
loadWithImportSpy();
|
|
398
|
+
const fakeCommand = {
|
|
399
|
+
optsWithGlobals: () => ({
|
|
400
|
+
navy: 'from-global',
|
|
401
|
+
extra: 1
|
|
402
|
+
}),
|
|
403
|
+
getOptionValueSource: () => 'default'
|
|
404
|
+
};
|
|
405
|
+
capturedActions.import({
|
|
406
|
+
navy: 'subcommand-default'
|
|
407
|
+
}, fakeCommand);
|
|
408
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
409
|
+
(0, _chai.expect)(importSpy.calledOnce).to.equal(true);
|
|
410
|
+
(0, _chai.expect)(importSpy.firstCall.args).to.have.lengthOf(1);
|
|
411
|
+
(0, _chai.expect)(importSpy.firstCall.args[0]).to.eql({
|
|
412
|
+
navy: 'from-global',
|
|
413
|
+
extra: 1
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
it('should leave non-object trailing arguments untouched when stripping the command', async function () {
|
|
417
|
+
loadWithImportSpy();
|
|
418
|
+
const fakeCommand = {
|
|
419
|
+
optsWithGlobals: () => ({
|
|
420
|
+
navy: 'global'
|
|
421
|
+
})
|
|
422
|
+
};
|
|
423
|
+
capturedActions.import(['web', 'api'], fakeCommand);
|
|
424
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
425
|
+
(0, _chai.expect)(importSpy.calledOnce).to.equal(true);
|
|
426
|
+
(0, _chai.expect)(importSpy.firstCall.args).to.eql([['web', 'api']]);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
332
429
|
describe('basicCliWrapper action', function () {
|
|
333
430
|
beforeEach(function () {
|
|
334
431
|
loadModule();
|
|
@@ -354,6 +451,18 @@ describe('cli/program', function () {
|
|
|
354
451
|
}, fakeCommand);
|
|
355
452
|
(0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('from-global');
|
|
356
453
|
});
|
|
454
|
+
it('should fall back to maybeServices as opts when only an opts object and command are passed', async function () {
|
|
455
|
+
navyStub.getAvailableServiceNames = sandbox.stub().resolves([]);
|
|
456
|
+
const fakeCommand = {
|
|
457
|
+
optsWithGlobals: () => ({
|
|
458
|
+
navy: 'from-global'
|
|
459
|
+
})
|
|
460
|
+
};
|
|
461
|
+
await actionsByCommand['available-services']({
|
|
462
|
+
navy: 'subcommand-default'
|
|
463
|
+
}, fakeCommand);
|
|
464
|
+
(0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('from-global');
|
|
465
|
+
});
|
|
357
466
|
it('should pass undefined when called with an empty service list', async function () {
|
|
358
467
|
navyStub.start = sandbox.stub().resolves();
|
|
359
468
|
await actionsByCommand.start([], {
|
package/lib/http-proxy.js
CHANGED
|
@@ -6,6 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.reconfigureHTTPProxy = reconfigureHTTPProxy;
|
|
8
8
|
exports.resolveDockerSocketPath = resolveDockerSocketPath;
|
|
9
|
+
exports.resolveProxyEnv = resolveProxyEnv;
|
|
10
|
+
exports.resolveProxyEnvAllowlist = resolveProxyEnvAllowlist;
|
|
11
|
+
exports.resolveProxyEnvFromNavyFile = resolveProxyEnvFromNavyFile;
|
|
9
12
|
exports.resolveProxyImage = resolveProxyImage;
|
|
10
13
|
var _os = _interopRequireDefault(require("os"));
|
|
11
14
|
var _path = _interopRequireDefault(require("path"));
|
|
@@ -21,6 +24,43 @@ const DEFAULT_DOCKER_SOCKET = '/var/run/docker.sock';
|
|
|
21
24
|
function resolveProxyImage(navyFile) {
|
|
22
25
|
return process.env.NAVY_HTTP_PROXY_IMAGE || navyFile && navyFile.httpProxyImage || DEFAULT_PROXY_IMAGE;
|
|
23
26
|
}
|
|
27
|
+
function resolveProxyEnvFromNavyFile(navyFile) {
|
|
28
|
+
if (!navyFile) return {};
|
|
29
|
+
const raw = navyFile.httpProxyEnv;
|
|
30
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const key of Object.keys(raw)) {
|
|
33
|
+
const value = raw[key];
|
|
34
|
+
if (value === null || value === undefined) continue;
|
|
35
|
+
const coerced = String(value);
|
|
36
|
+
if (coerced === '') continue;
|
|
37
|
+
result[key] = coerced;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function resolveProxyEnvAllowlist() {
|
|
42
|
+
const allowlist = process.env.NAVY_HTTP_PROXY_ENV;
|
|
43
|
+
if (!allowlist) return {};
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
const result = {};
|
|
46
|
+
for (const rawName of allowlist.split(',')) {
|
|
47
|
+
const name = rawName.trim();
|
|
48
|
+
if (!name || seen.has(name)) continue;
|
|
49
|
+
seen.add(name);
|
|
50
|
+
const value = process.env[name];
|
|
51
|
+
if (typeof value !== 'string' || value === '') continue;
|
|
52
|
+
result[name] = value;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
function resolveProxyEnv(navyFile) {
|
|
57
|
+
const merged = {
|
|
58
|
+
...resolveProxyEnvFromNavyFile(navyFile),
|
|
59
|
+
...resolveProxyEnvAllowlist()
|
|
60
|
+
};
|
|
61
|
+
if (Object.keys(merged).length === 0) return null;
|
|
62
|
+
return merged;
|
|
63
|
+
}
|
|
24
64
|
|
|
25
65
|
// Resolve the host path to the Docker socket. The proxy container needs to
|
|
26
66
|
// read events from the same daemon as the rest of navy, so we honour
|
|
@@ -61,6 +101,7 @@ async function updateComposeConfig(navies, navyFile) {
|
|
|
61
101
|
volumes.push(`${certsPath}:/etc/nginx/certs`);
|
|
62
102
|
volumes.push(`${certsPath}:/etc/nginx/dhparam`); // to persist DH params
|
|
63
103
|
}
|
|
104
|
+
const proxyEnv = resolveProxyEnv(navyFile);
|
|
64
105
|
const config = {
|
|
65
106
|
version: '2',
|
|
66
107
|
services: {
|
|
@@ -69,6 +110,9 @@ async function updateComposeConfig(navies, navyFile) {
|
|
|
69
110
|
ports,
|
|
70
111
|
networks: networks.map(net => net.Name),
|
|
71
112
|
volumes,
|
|
113
|
+
...(proxyEnv ? {
|
|
114
|
+
environment: proxyEnv
|
|
115
|
+
} : {}),
|
|
72
116
|
restart: 'always'
|
|
73
117
|
}
|
|
74
118
|
},
|