navy 6.0.0 → 7.0.0-alpha.2

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.
Files changed (149) hide show
  1. package/lib/__tests__/config-provider.js +75 -0
  2. package/lib/__tests__/config.js +130 -0
  3. package/lib/__tests__/driver-logging.js +148 -0
  4. package/lib/__tests__/driver.js +19 -0
  5. package/lib/__tests__/errors.js +49 -0
  6. package/lib/__tests__/http-proxy.js +214 -0
  7. package/lib/__tests__/index.js +25 -0
  8. package/lib/__tests__/service.js +16 -0
  9. package/lib/cli/__tests__/develop.js +239 -0
  10. package/lib/cli/__tests__/external-ip.js +68 -0
  11. package/lib/cli/__tests__/health.js +257 -0
  12. package/lib/cli/__tests__/https.js +210 -0
  13. package/lib/cli/__tests__/import.js +110 -0
  14. package/lib/cli/__tests__/index.js +118 -0
  15. package/lib/cli/__tests__/lan-ip.js +90 -0
  16. package/lib/cli/__tests__/launch.js +179 -0
  17. package/lib/cli/__tests__/live.js +155 -0
  18. package/lib/cli/__tests__/local-ip.js +72 -0
  19. package/lib/cli/__tests__/logs.js +52 -0
  20. package/lib/cli/__tests__/open.js +65 -0
  21. package/lib/cli/__tests__/program.js +472 -0
  22. package/lib/cli/__tests__/ps.js +345 -0
  23. package/lib/cli/__tests__/refresh-config.js +95 -0
  24. package/lib/cli/__tests__/run.js +54 -0
  25. package/lib/cli/__tests__/status.js +204 -0
  26. package/lib/cli/__tests__/updates.js +243 -0
  27. package/lib/cli/__tests__/wait-for-healthy.js +134 -0
  28. package/lib/cli/config/__tests__/index.js +275 -0
  29. package/lib/cli/config/__tests__/wrapper.js +53 -0
  30. package/lib/cli/config/index.js +19 -37
  31. package/lib/cli/config/wrapper.js +0 -6
  32. package/lib/cli/develop.js +7 -21
  33. package/lib/cli/doctor/__tests__/clean-compose-files.js +78 -0
  34. package/lib/cli/doctor/__tests__/index.js +67 -0
  35. package/lib/cli/doctor/__tests__/invalid-compose-config.js +103 -0
  36. package/lib/cli/doctor/__tests__/invalid-state.js +83 -0
  37. package/lib/cli/doctor/__tests__/util.js +91 -0
  38. package/lib/cli/doctor/clean-compose-files.js +5 -13
  39. package/lib/cli/doctor/index.js +0 -12
  40. package/lib/cli/doctor/invalid-compose-config.js +0 -4
  41. package/lib/cli/doctor/invalid-state.js +0 -6
  42. package/lib/cli/doctor/util.js +0 -10
  43. package/lib/cli/external-ip.js +0 -4
  44. package/lib/cli/health.js +0 -12
  45. package/lib/cli/https.js +9 -25
  46. package/lib/cli/import.js +0 -12
  47. package/lib/cli/index.js +0 -9
  48. package/lib/cli/lan-ip.js +2 -8
  49. package/lib/cli/launch.js +0 -9
  50. package/lib/cli/live.js +6 -16
  51. package/lib/cli/local-ip.js +2 -7
  52. package/lib/cli/logs.js +0 -3
  53. package/lib/cli/open.js +2 -7
  54. package/lib/cli/program.js +73 -101
  55. package/lib/cli/ps.js +1 -21
  56. package/lib/cli/refresh-config.js +0 -7
  57. package/lib/cli/run.js +0 -3
  58. package/lib/cli/status.js +0 -11
  59. package/lib/cli/updates.js +0 -22
  60. package/lib/cli/util/__tests__/get-or-initialise-navy.js +66 -0
  61. package/lib/cli/util/__tests__/import.js +123 -0
  62. package/lib/cli/util/__tests__/index.js +17 -0
  63. package/lib/cli/util/__tests__/merge-action-options.js +47 -0
  64. package/lib/cli/util/__tests__/reconfigure.js +78 -0
  65. package/lib/cli/util/get-or-initialise-navy.js +0 -7
  66. package/lib/cli/util/import.js +0 -9
  67. package/lib/cli/util/index.js +0 -2
  68. package/lib/cli/util/merge-action-options.js +20 -0
  69. package/lib/cli/util/reconfigure.js +0 -4
  70. package/lib/cli/wait-for-healthy.js +0 -21
  71. package/lib/client/registry/__tests__/get-credentials.js +62 -0
  72. package/lib/client/registry/__tests__/get-endpoint.js +124 -0
  73. package/lib/client/registry/__tests__/get-fat-manifest.js +67 -0
  74. package/lib/client/registry/__tests__/get-token.js +66 -0
  75. package/lib/client/registry/__tests__/helpers.js +26 -0
  76. package/lib/client/registry/get-credentials.js +3 -9
  77. package/lib/client/registry/get-endpoint.js +29 -63
  78. package/lib/client/registry/get-fat-manifest.js +2 -9
  79. package/lib/client/registry/get-token.js +2 -13
  80. package/lib/client/registry/helpers.js +0 -4
  81. package/lib/config-provider.js +0 -12
  82. package/lib/config-providers/filesystem/__tests__/index.js +176 -0
  83. package/lib/config-providers/filesystem/index.js +5 -23
  84. package/lib/config-providers/npm/__tests__/index.js +226 -0
  85. package/lib/config-providers/npm/__tests__/util.js +1 -2
  86. package/lib/config-providers/npm/index.js +12 -35
  87. package/lib/config-providers/npm/util.js +0 -3
  88. package/lib/config.js +4 -19
  89. package/lib/domain/__tests__/container-image.js +81 -0
  90. package/lib/domain/__tests__/oci-api-specification.js +23 -0
  91. package/lib/domain/container-image.js +8 -21
  92. package/lib/domain/oci-api-specification.js +3 -5
  93. package/lib/driver-logging.js +0 -19
  94. package/lib/driver.js +0 -4
  95. package/lib/drivers/docker-compose/__tests__/client.js +249 -0
  96. package/lib/drivers/docker-compose/__tests__/index.js +430 -0
  97. package/lib/drivers/docker-compose/client.js +0 -16
  98. package/lib/drivers/docker-compose/index.js +7 -49
  99. package/lib/errors.js +0 -10
  100. package/lib/http-proxy.js +28 -23
  101. package/lib/index.js +1 -9
  102. package/lib/middleware/__tests__/add-service-proxy-config.js +258 -0
  103. package/lib/middleware/__tests__/develop.js +120 -0
  104. package/lib/middleware/__tests__/helpers.js +154 -0
  105. package/lib/middleware/__tests__/port-override.js +125 -0
  106. package/lib/middleware/__tests__/set-env-vars.js +94 -0
  107. package/lib/middleware/__tests__/set-image.js +76 -0
  108. package/lib/middleware/__tests__/set-logging-driver.js +94 -0
  109. package/lib/middleware/__tests__/tag-override.js +92 -0
  110. package/lib/middleware/add-service-proxy-config.js +8 -16
  111. package/lib/middleware/develop.js +2 -5
  112. package/lib/middleware/helpers.js +6 -12
  113. package/lib/middleware/port-override.js +5 -8
  114. package/lib/middleware/set-env-vars.js +6 -6
  115. package/lib/middleware/set-image.js +4 -5
  116. package/lib/middleware/set-logging-driver.js +6 -6
  117. package/lib/middleware/tag-override.js +4 -6
  118. package/lib/navy/__tests__/default-middleware.js +40 -0
  119. package/lib/navy/__tests__/index.js +1612 -0
  120. package/lib/navy/__tests__/middleware.js +71 -0
  121. package/lib/navy/__tests__/plugin-interface.js +121 -0
  122. package/lib/navy/__tests__/state.js +103 -0
  123. package/lib/navy/__tests__/util.js +24 -0
  124. package/lib/navy/default-middleware.js +0 -10
  125. package/lib/navy/index.js +83 -138
  126. package/lib/navy/middleware.js +0 -6
  127. package/lib/navy/plugin-interface.js +2 -10
  128. package/lib/navy/state.js +12 -24
  129. package/lib/navy/util.js +0 -1
  130. package/lib/service.js +2 -3
  131. package/lib/util/__tests__/exec-async.js +83 -0
  132. package/lib/util/__tests__/external-ip.js +97 -2
  133. package/lib/util/__tests__/get-lan-ip.js +46 -0
  134. package/lib/util/__tests__/has-update.js +136 -0
  135. package/lib/util/__tests__/https.js +301 -0
  136. package/lib/util/__tests__/navyrc.js +45 -0
  137. package/lib/util/__tests__/service-host.js +63 -5
  138. package/lib/util/__tests__/table.js +44 -0
  139. package/lib/util/docker-client.js +2 -10
  140. package/lib/util/exec-async.js +0 -4
  141. package/lib/util/external-ip.js +8 -12
  142. package/lib/util/fs.js +1 -6
  143. package/lib/util/get-lan-ip.js +0 -5
  144. package/lib/util/has-update.js +2 -14
  145. package/lib/util/https.js +11 -55
  146. package/lib/util/navyrc.js +0 -5
  147. package/lib/util/service-host.js +0 -17
  148. package/lib/util/table.js +0 -6
  149. package/package.json +14 -13
package/lib/errors.js CHANGED
@@ -1,19 +1,15 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.NavyNotInitialisedError = exports.NavyError = void 0;
9
-
10
8
  var _chalk = _interopRequireDefault(require("chalk"));
11
-
12
9
  class NavyError {
13
10
  constructor(message) {
14
11
  this.message = message;
15
12
  }
16
-
17
13
  prettyPrint() {
18
14
  console.log();
19
15
  console.log(_chalk.default.bgRed(_chalk.default.bold(' ERROR ')));
@@ -21,22 +17,16 @@ class NavyError {
21
17
  console.log(' ' + this.message);
22
18
  console.log();
23
19
  }
24
-
25
20
  }
26
-
27
21
  exports.NavyError = NavyError;
28
-
29
22
  class NavyNotInitialisedError extends NavyError {
30
23
  constructor(navyName) {
31
24
  super('Navy "' + navyName + '" not imported');
32
25
  }
33
-
34
26
  prettyPrint() {
35
27
  super.prettyPrint();
36
28
  console.log(' Make sure you\'ve imported the navy with ' + _chalk.default.bold('navy import'));
37
29
  console.log();
38
30
  }
39
-
40
31
  }
41
-
42
32
  exports.NavyNotInitialisedError = NavyNotInitialisedError;
package/lib/http-proxy.js CHANGED
@@ -1,39 +1,49 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.reconfigureHTTPProxy = reconfigureHTTPProxy;
9
-
8
+ exports.resolveDockerSocketPath = resolveDockerSocketPath;
9
+ exports.resolveProxyImage = resolveProxyImage;
10
10
  var _os = _interopRequireDefault(require("os"));
11
-
12
11
  var _path = _interopRequireDefault(require("path"));
13
-
14
12
  var _jsYaml = _interopRequireDefault(require("js-yaml"));
15
-
16
13
  var _dockerClient = _interopRequireDefault(require("./util/docker-client"));
17
-
18
14
  var _fs = _interopRequireDefault(require("fs"));
19
-
20
15
  var _https = require("./util/https");
21
-
22
16
  var _execAsync = require("./util/exec-async");
23
-
24
17
  var _driverLogging = require("./driver-logging");
25
-
26
18
  var _navy = require("./navy");
19
+ const DEFAULT_PROXY_IMAGE = 'navycloud/navy-proxy';
20
+ const DEFAULT_DOCKER_SOCKET = '/var/run/docker.sock';
21
+ function resolveProxyImage(navyFile) {
22
+ return process.env.NAVY_HTTP_PROXY_IMAGE || navyFile && navyFile.httpProxyImage || DEFAULT_PROXY_IMAGE;
23
+ }
27
24
 
28
- async function updateComposeConfig(navies) {
29
- const networks = await _dockerClient.default.listNetworks().filter(net => net.Name.indexOf('_') !== -1) // is docker-compose network?
25
+ // Resolve the host path to the Docker socket. The proxy container needs to
26
+ // read events from the same daemon as the rest of navy, so we honour
27
+ // DOCKER_HOST when it points at a unix socket (e.g. on CI where
28
+ // `docker/setup-docker-action` puts the daemon on a custom path) and fall
29
+ // back to the conventional `/var/run/docker.sock` otherwise.
30
+ function resolveDockerSocketPath() {
31
+ const dockerHost = process.env.DOCKER_HOST;
32
+ if (dockerHost && dockerHost.indexOf('unix://') === 0) {
33
+ const socketPath = dockerHost.slice('unix://'.length);
34
+ if (socketPath) return socketPath;
35
+ }
36
+ return DEFAULT_DOCKER_SOCKET;
37
+ }
38
+ async function updateComposeConfig(navies, navyFile) {
39
+ const allNetworks = await _dockerClient.default.listNetworks();
40
+ const networks = allNetworks.filter(net => net.Name.indexOf('_') !== -1) // is docker-compose network?
30
41
  .filter(net => {
31
42
  for (const navy of navies) {
32
43
  if (net.Name.indexOf(navy + '_') === 0) {
33
44
  return true;
34
45
  }
35
46
  }
36
-
37
47
  return false;
38
48
  });
39
49
  const networksConfig = {};
@@ -41,22 +51,21 @@ async function updateComposeConfig(navies) {
41
51
  external: true
42
52
  });
43
53
  const ports = ['80:80'];
44
- const volumes = ['/var/run/docker.sock:/tmp/docker.sock:ro']; // Enable HTTPS for services that
45
- // match crt file names in tlsRootCaDir
54
+ const volumes = [`${resolveDockerSocketPath()}:/tmp/docker.sock:ro`];
46
55
 
56
+ // Enable HTTPS for services that
57
+ // match crt file names in tlsRootCaDir
47
58
  const certsPath = await (0, _https.getCertsPath)(true);
48
-
49
59
  if (certsPath) {
50
60
  ports.push('443:443');
51
61
  volumes.push(`${certsPath}:/etc/nginx/certs`);
52
62
  volumes.push(`${certsPath}:/etc/nginx/dhparam`); // to persist DH params
53
63
  }
54
-
55
64
  const config = {
56
65
  version: '2',
57
66
  services: {
58
67
  'nginx-proxy': {
59
- image: 'navycloud/navy-proxy',
68
+ image: resolveProxyImage(navyFile),
60
69
  ports,
61
70
  networks: networks.map(net => net.Name),
62
71
  volumes,
@@ -65,13 +74,10 @@ async function updateComposeConfig(navies) {
65
74
  },
66
75
  networks: networksConfig
67
76
  };
68
-
69
77
  _fs.default.writeFileSync(_path.default.join(_os.default.tmpdir(), 'navyinternaldockercompose.yml'), _jsYaml.default.dump(config));
70
78
  }
71
-
72
79
  async function reconfigureHTTPProxy(opts = {}) {
73
80
  const navyInternalYamlFile = _path.default.join(_os.default.tmpdir(), 'navyinternaldockercompose.yml');
74
-
75
81
  if (opts.restart) {
76
82
  // proxy needs to be recreated to detect changes (deletes) in /etc/nginx/certs
77
83
  if (_fs.default.existsSync(navyInternalYamlFile)) {
@@ -79,9 +85,8 @@ async function reconfigureHTTPProxy(opts = {}) {
79
85
  await (0, _execAsync.execAsync)('docker compose', ['-f', navyInternalYamlFile, '-p', 'navyinternal', 'rm', '-s', '-f', 'nginx-proxy']);
80
86
  }
81
87
  }
82
-
83
88
  if (!opts.navies) opts.navies = await (0, _navy.getLaunchedNavyNames)();
84
- await updateComposeConfig(opts.navies);
89
+ await updateComposeConfig(opts.navies, opts.navyFile);
85
90
  (0, _driverLogging.log)('Configuring HTTP proxy...');
86
91
  await (0, _execAsync.execAsync)('docker compose', ['-f', navyInternalYamlFile, '-p', 'navyinternal', 'up', '-d']);
87
92
  }
package/lib/index.js CHANGED
@@ -40,17 +40,9 @@ Object.defineProperty(exports, "middlewareHelpers", {
40
40
  return _helpers.middlewareHelpers;
41
41
  }
42
42
  });
43
-
44
43
  var _navy = require("./navy");
45
-
46
44
  var _Service = _interopRequireWildcard(require("./service"));
47
-
48
45
  exports.Service = _Service;
49
-
50
46
  var _errors = require("./errors");
51
-
52
47
  var _helpers = require("./middleware/helpers");
53
-
54
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
55
-
56
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
48
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var serviceHostModule = _interopRequireWildcard(require("../../util/service-host"));
7
+ var httpsModule = _interopRequireWildcard(require("../../util/https"));
8
+ var _addServiceProxyConfig = _interopRequireDefault(require("../add-service-proxy-config"));
9
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
+ /* eslint-env mocha */
11
+
12
+ function makeNavy({
13
+ navyFile = null,
14
+ externalIP = '10.0.0.1'
15
+ } = {}) {
16
+ return {
17
+ name: 'env',
18
+ normalisedName: 'env',
19
+ getNavyFile: _sinon.default.stub().resolves(navyFile),
20
+ externalIP: _sinon.default.stub().resolves(externalIP)
21
+ };
22
+ }
23
+ describe('add-service-proxy-config middleware', function () {
24
+ let sandbox;
25
+ let createCertStub;
26
+ let createHostStub;
27
+ beforeEach(function () {
28
+ sandbox = _sinon.default.createSandbox();
29
+ createCertStub = sandbox.stub(httpsModule, 'createCert').resolves();
30
+ createHostStub = sandbox.stub(serviceHostModule, 'createHostForService').callsFake(async (svc, navyName) => `${svc}.${navyName}.test.local`);
31
+ });
32
+ afterEach(function () {
33
+ sandbox.restore();
34
+ });
35
+ describe('factory', function () {
36
+ it('should return an async middleware function when invoked with a navy', function () {
37
+ const fn = (0, _addServiceProxyConfig.default)(makeNavy());
38
+ (0, _chai.expect)(fn).to.be.a('function');
39
+ });
40
+ });
41
+ describe('auto-proxy of port 80', function () {
42
+ it('should add VIRTUAL_HOST/VIRTUAL_PORT for services exposing port 80 by default', async function () {
43
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
44
+ const config = {
45
+ services: {
46
+ web: {
47
+ ports: ['80:80']
48
+ }
49
+ }
50
+ };
51
+ const result = await middleware(config, {});
52
+ (0, _chai.expect)(result.services.web.environment.VIRTUAL_HOST).to.equal('web.env.test.local');
53
+ (0, _chai.expect)(result.services.web.environment.VIRTUAL_PORT).to.equal(80);
54
+ });
55
+ it('should not auto-proxy services that do not expose port 80', async function () {
56
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
57
+ const config = {
58
+ services: {
59
+ worker: {
60
+ ports: ['8080:8080']
61
+ }
62
+ }
63
+ };
64
+ const result = await middleware(config, {});
65
+ (0, _chai.expect)(result.services.worker).to.eql({
66
+ ports: ['8080:8080']
67
+ });
68
+ });
69
+ it('should not auto-proxy services that have no ports declared', async function () {
70
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
71
+ const config = {
72
+ services: {
73
+ worker: {}
74
+ }
75
+ };
76
+ const result = await middleware(config, {});
77
+ (0, _chai.expect)(result.services.worker).to.eql({});
78
+ });
79
+ });
80
+ describe('explicit httpProxy config in navyFile', function () {
81
+ it('should use the explicit httpProxy config to set VIRTUAL_HOST and VIRTUAL_PORT', async function () {
82
+ const navy = makeNavy({
83
+ navyFile: {
84
+ httpProxy: {
85
+ api: {
86
+ port: 3000
87
+ }
88
+ }
89
+ }
90
+ });
91
+ const middleware = (0, _addServiceProxyConfig.default)(navy);
92
+ const result = await middleware({
93
+ services: {
94
+ api: {
95
+ ports: ['3000:3000']
96
+ }
97
+ }
98
+ }, {});
99
+ (0, _chai.expect)(result.services.api.environment.VIRTUAL_PORT).to.equal(3000);
100
+ (0, _chai.expect)(result.services.api.environment.VIRTUAL_HOST).to.equal('api.env.test.local');
101
+ });
102
+ it('should issue a TLS cert when proxyConfig.enableHttps is set', async function () {
103
+ const navy = makeNavy({
104
+ navyFile: {
105
+ httpProxy: {
106
+ api: {
107
+ port: 3000,
108
+ enableHttps: true
109
+ }
110
+ }
111
+ }
112
+ });
113
+ const middleware = (0, _addServiceProxyConfig.default)(navy);
114
+ await middleware({
115
+ services: {
116
+ api: {}
117
+ }
118
+ }, {});
119
+ (0, _chai.expect)(createCertStub.calledOnce).to.equal(true);
120
+ (0, _chai.expect)(createCertStub.firstCall.args[0]).to.eql({
121
+ hostName: 'api.env.test.local'
122
+ });
123
+ });
124
+ it('should not issue a TLS cert when proxyConfig is implicit (no enableHttps)', async function () {
125
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
126
+ await middleware({
127
+ services: {
128
+ web: {
129
+ ports: ['80:80']
130
+ }
131
+ }
132
+ }, {});
133
+ (0, _chai.expect)(createCertStub.called).to.equal(false);
134
+ });
135
+ });
136
+ describe('httpProxyAutoPorts navyFile config', function () {
137
+ it('should auto-proxy a different port when configured via httpProxyAutoPorts', async function () {
138
+ const navy = makeNavy({
139
+ navyFile: {
140
+ httpProxyAutoPorts: ['3000']
141
+ }
142
+ });
143
+ const middleware = (0, _addServiceProxyConfig.default)(navy);
144
+ const result = await middleware({
145
+ services: {
146
+ api: {
147
+ ports: ['3000:3000']
148
+ }
149
+ }
150
+ }, {});
151
+ (0, _chai.expect)(result.services.api.environment.VIRTUAL_PORT).to.equal(3000);
152
+ });
153
+ it('should fall back to ["80"] when httpProxyAutoPorts is not an array', async function () {
154
+ const navy = makeNavy({
155
+ navyFile: {
156
+ httpProxyAutoPorts: 'not-an-array'
157
+ }
158
+ });
159
+ const middleware = (0, _addServiceProxyConfig.default)(navy);
160
+ const result = await middleware({
161
+ services: {
162
+ web: {
163
+ ports: ['80:80']
164
+ }
165
+ }
166
+ }, {});
167
+ (0, _chai.expect)(result.services.web.environment.VIRTUAL_PORT).to.equal(80);
168
+ });
169
+ });
170
+ describe('port matching forms', function () {
171
+ it('should match a numeric port equal to the auto port', async function () {
172
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
173
+ const result = await middleware({
174
+ services: {
175
+ web: {
176
+ ports: [80]
177
+ }
178
+ }
179
+ }, {});
180
+ // eslint-disable-next-line no-unused-expressions
181
+ (0, _chai.expect)(result.services.web.environment).to.exist;
182
+ });
183
+ it('should match a "80/tcp" protocol-suffixed port', async function () {
184
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
185
+ const result = await middleware({
186
+ services: {
187
+ web: {
188
+ ports: ['80/tcp']
189
+ }
190
+ }
191
+ }, {});
192
+ // eslint-disable-next-line no-unused-expressions
193
+ (0, _chai.expect)(result.services.web.environment).to.exist;
194
+ });
195
+ it('should match a port object with a target field equal to the auto port', async function () {
196
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
197
+ const result = await middleware({
198
+ services: {
199
+ web: {
200
+ ports: [{
201
+ target: 80,
202
+ published: 8080
203
+ }]
204
+ }
205
+ }
206
+ }, {});
207
+ // eslint-disable-next-line no-unused-expressions
208
+ (0, _chai.expect)(result.services.web.environment).to.exist;
209
+ });
210
+ });
211
+ describe('environment merge', function () {
212
+ it('should not overwrite existing env vars with VIRTUAL_HOST/VIRTUAL_PORT', async function () {
213
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
214
+ const result = await middleware({
215
+ services: {
216
+ web: {
217
+ ports: ['80:80'],
218
+ environment: {
219
+ VIRTUAL_HOST: 'preset.host',
220
+ OTHER: 'x'
221
+ }
222
+ }
223
+ }
224
+ }, {});
225
+ (0, _chai.expect)(result.services.web.environment.VIRTUAL_HOST).to.equal('preset.host');
226
+ (0, _chai.expect)(result.services.web.environment.OTHER).to.equal('x');
227
+ });
228
+ });
229
+ it('should preserve other top-level config keys', async function () {
230
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
231
+ const result = await middleware({
232
+ version: '3.7',
233
+ services: {
234
+ web: {
235
+ ports: ['80:80']
236
+ }
237
+ },
238
+ networks: {
239
+ default: {}
240
+ }
241
+ }, {});
242
+ (0, _chai.expect)(result.version).to.equal('3.7');
243
+ (0, _chai.expect)(result.networks).to.eql({
244
+ default: {}
245
+ });
246
+ });
247
+ it('should not call externalIP/createHostForService for services without proxy config', async function () {
248
+ const middleware = (0, _addServiceProxyConfig.default)(makeNavy());
249
+ await middleware({
250
+ services: {
251
+ worker: {
252
+ ports: ['9000:9000']
253
+ }
254
+ }
255
+ }, {});
256
+ (0, _chai.expect)(createHostStub.called).to.equal(false);
257
+ });
258
+ });
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _develop = _interopRequireDefault(require("../develop"));
6
+ /* eslint-env mocha */
7
+
8
+ describe('develop middleware', function () {
9
+ it('should return the service unchanged when no service state exists', function () {
10
+ const config = {
11
+ services: {
12
+ api: {
13
+ image: 'api',
14
+ command: 'npm start'
15
+ }
16
+ }
17
+ };
18
+ const state = {
19
+ services: {}
20
+ };
21
+ const result = (0, _develop.default)(config, state);
22
+ (0, _chai.expect)(result.services.api).to.eql({
23
+ image: 'api',
24
+ command: 'npm start'
25
+ });
26
+ });
27
+ it('should return the service unchanged when state has no _develop entry', function () {
28
+ const config = {
29
+ services: {
30
+ api: {
31
+ image: 'api',
32
+ command: 'npm start'
33
+ }
34
+ }
35
+ };
36
+ const state = {
37
+ services: {
38
+ api: {
39
+ unrelated: true
40
+ }
41
+ }
42
+ };
43
+ const result = (0, _develop.default)(config, state);
44
+ (0, _chai.expect)(result.services.api).to.eql({
45
+ image: 'api',
46
+ command: 'npm start'
47
+ });
48
+ });
49
+ it('should set stdin_open and append _develop.mounts as volumes', function () {
50
+ const config = {
51
+ services: {
52
+ api: {
53
+ image: 'api',
54
+ volumes: ['./preexisting:/preexisting'],
55
+ command: 'npm start'
56
+ }
57
+ }
58
+ };
59
+ const state = {
60
+ services: {
61
+ api: {
62
+ _develop: {
63
+ mounts: {
64
+ './local': '/app',
65
+ './node_modules': '/app/node_modules'
66
+ }
67
+ }
68
+ }
69
+ }
70
+ };
71
+ const result = (0, _develop.default)(config, state);
72
+ (0, _chai.expect)(result.services.api.stdin_open).to.equal(true);
73
+ (0, _chai.expect)(result.services.api.volumes).to.include('./preexisting:/preexisting');
74
+ (0, _chai.expect)(result.services.api.volumes).to.include('./local:/app');
75
+ (0, _chai.expect)(result.services.api.volumes).to.include('./node_modules:/app/node_modules');
76
+ });
77
+ it('should override the command when _develop.command is set', function () {
78
+ const config = {
79
+ services: {
80
+ api: {
81
+ image: 'api',
82
+ command: 'npm start'
83
+ }
84
+ }
85
+ };
86
+ const state = {
87
+ services: {
88
+ api: {
89
+ _develop: {
90
+ mounts: {},
91
+ command: 'npm run dev'
92
+ }
93
+ }
94
+ }
95
+ };
96
+ const result = (0, _develop.default)(config, state);
97
+ (0, _chai.expect)(result.services.api.command).to.equal('npm run dev');
98
+ });
99
+ it('should keep the existing command when _develop.command is not set', function () {
100
+ const config = {
101
+ services: {
102
+ api: {
103
+ image: 'api',
104
+ command: 'npm start'
105
+ }
106
+ }
107
+ };
108
+ const state = {
109
+ services: {
110
+ api: {
111
+ _develop: {
112
+ mounts: {}
113
+ }
114
+ }
115
+ }
116
+ };
117
+ const result = (0, _develop.default)(config, state);
118
+ (0, _chai.expect)(result.services.api.command).to.equal('npm start');
119
+ });
120
+ });