@kapeta/local-cluster-service 0.6.1 → 0.7.1

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 (192) hide show
  1. package/.eslintrc.cjs +17 -0
  2. package/.github/workflows/main.yml +22 -22
  3. package/.prettierignore +4 -0
  4. package/.vscode/launch.json +2 -4
  5. package/CHANGELOG.md +14 -0
  6. package/definitions.d.ts +17 -35
  7. package/dist/cjs/index.d.ts +27 -0
  8. package/dist/cjs/index.js +126 -0
  9. package/dist/cjs/package.json +1 -0
  10. package/dist/cjs/src/assetManager.d.ts +31 -0
  11. package/dist/cjs/src/assetManager.js +153 -0
  12. package/dist/cjs/src/assets/routes.d.ts +3 -0
  13. package/dist/cjs/src/assets/routes.js +117 -0
  14. package/dist/cjs/src/clusterService.d.ts +40 -0
  15. package/dist/cjs/src/clusterService.js +114 -0
  16. package/dist/cjs/src/codeGeneratorManager.d.ts +8 -0
  17. package/dist/cjs/src/codeGeneratorManager.js +53 -0
  18. package/dist/cjs/src/config/routes.d.ts +3 -0
  19. package/dist/cjs/src/config/routes.js +126 -0
  20. package/dist/cjs/src/configManager.d.ts +36 -0
  21. package/dist/cjs/src/configManager.js +110 -0
  22. package/dist/cjs/src/containerManager.d.ts +89 -0
  23. package/dist/cjs/src/containerManager.js +365 -0
  24. package/dist/cjs/src/filesystem/routes.d.ts +3 -0
  25. package/dist/cjs/src/filesystem/routes.js +69 -0
  26. package/dist/cjs/src/filesystemManager.d.ts +15 -0
  27. package/dist/cjs/src/filesystemManager.js +87 -0
  28. package/dist/cjs/src/identities/routes.d.ts +3 -0
  29. package/dist/cjs/src/identities/routes.js +18 -0
  30. package/dist/cjs/src/instanceManager.d.ts +56 -0
  31. package/dist/cjs/src/instanceManager.js +424 -0
  32. package/dist/cjs/src/instances/routes.d.ts +3 -0
  33. package/dist/cjs/src/instances/routes.js +134 -0
  34. package/dist/cjs/src/middleware/cors.d.ts +2 -0
  35. package/dist/cjs/src/middleware/cors.js +10 -0
  36. package/dist/cjs/src/middleware/kapeta.d.ts +11 -0
  37. package/dist/cjs/src/middleware/kapeta.js +17 -0
  38. package/dist/cjs/src/middleware/stringBody.d.ts +5 -0
  39. package/dist/cjs/src/middleware/stringBody.js +14 -0
  40. package/dist/cjs/src/networkManager.d.ts +32 -0
  41. package/dist/cjs/src/networkManager.js +109 -0
  42. package/dist/cjs/src/operatorManager.d.ts +36 -0
  43. package/dist/cjs/src/operatorManager.js +165 -0
  44. package/dist/cjs/src/progressListener.d.ts +20 -0
  45. package/dist/cjs/src/progressListener.js +91 -0
  46. package/dist/cjs/src/providerManager.d.ts +9 -0
  47. package/dist/cjs/src/providerManager.js +51 -0
  48. package/dist/cjs/src/providers/routes.d.ts +3 -0
  49. package/dist/cjs/src/providers/routes.js +42 -0
  50. package/dist/cjs/src/proxy/routes.d.ts +3 -0
  51. package/dist/cjs/src/proxy/routes.js +111 -0
  52. package/dist/cjs/src/proxy/types/rest.d.ts +4 -0
  53. package/dist/cjs/src/proxy/types/rest.js +114 -0
  54. package/dist/cjs/src/proxy/types/web.d.ts +4 -0
  55. package/dist/cjs/src/proxy/types/web.js +53 -0
  56. package/dist/cjs/src/repositoryManager.d.ts +17 -0
  57. package/dist/cjs/src/repositoryManager.js +218 -0
  58. package/dist/cjs/src/serviceManager.d.ts +29 -0
  59. package/dist/cjs/src/serviceManager.js +99 -0
  60. package/dist/cjs/src/socketManager.d.ts +14 -0
  61. package/dist/cjs/src/socketManager.js +53 -0
  62. package/dist/cjs/src/storageService.d.ts +17 -0
  63. package/dist/cjs/src/storageService.js +74 -0
  64. package/dist/cjs/src/traffic/routes.d.ts +3 -0
  65. package/dist/cjs/src/traffic/routes.js +18 -0
  66. package/dist/cjs/src/types.d.ts +88 -0
  67. package/dist/cjs/src/types.js +2 -0
  68. package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +29 -0
  69. package/dist/cjs/src/utils/BlockInstanceRunner.js +468 -0
  70. package/dist/cjs/src/utils/LogData.d.ts +19 -0
  71. package/dist/cjs/src/utils/LogData.js +43 -0
  72. package/dist/cjs/src/utils/pathTemplateParser.d.ts +26 -0
  73. package/dist/cjs/src/utils/pathTemplateParser.js +121 -0
  74. package/dist/cjs/src/utils/utils.d.ts +1 -0
  75. package/dist/cjs/src/utils/utils.js +18 -0
  76. package/dist/cjs/start.d.ts +1 -0
  77. package/dist/cjs/start.js +12 -0
  78. package/dist/esm/index.d.ts +27 -0
  79. package/dist/esm/index.js +121 -0
  80. package/dist/esm/package.json +1 -0
  81. package/dist/esm/src/assetManager.d.ts +31 -0
  82. package/{src → dist/esm/src}/assetManager.js +22 -60
  83. package/dist/esm/src/assets/routes.d.ts +3 -0
  84. package/{src → dist/esm/src}/assets/routes.js +21 -36
  85. package/dist/esm/src/clusterService.d.ts +40 -0
  86. package/{src → dist/esm/src}/clusterService.js +14 -37
  87. package/dist/esm/src/codeGeneratorManager.d.ts +8 -0
  88. package/{src → dist/esm/src}/codeGeneratorManager.js +15 -24
  89. package/dist/esm/src/config/routes.d.ts +3 -0
  90. package/{src → dist/esm/src}/config/routes.js +40 -89
  91. package/dist/esm/src/configManager.d.ts +36 -0
  92. package/{src → dist/esm/src}/configManager.js +11 -40
  93. package/dist/esm/src/containerManager.d.ts +89 -0
  94. package/{src → dist/esm/src}/containerManager.js +81 -182
  95. package/dist/esm/src/filesystem/routes.d.ts +3 -0
  96. package/dist/esm/src/filesystem/routes.js +64 -0
  97. package/dist/esm/src/filesystemManager.d.ts +15 -0
  98. package/{src → dist/esm/src}/filesystemManager.js +20 -28
  99. package/dist/esm/src/identities/routes.d.ts +3 -0
  100. package/dist/esm/src/identities/routes.js +13 -0
  101. package/dist/esm/src/instanceManager.d.ts +56 -0
  102. package/{src → dist/esm/src}/instanceManager.js +88 -179
  103. package/dist/esm/src/instances/routes.d.ts +3 -0
  104. package/{src → dist/esm/src}/instances/routes.js +31 -70
  105. package/dist/esm/src/middleware/cors.d.ts +2 -0
  106. package/{src → dist/esm/src}/middleware/cors.js +2 -3
  107. package/dist/esm/src/middleware/kapeta.d.ts +11 -0
  108. package/{src → dist/esm/src}/middleware/kapeta.js +3 -7
  109. package/dist/esm/src/middleware/stringBody.d.ts +5 -0
  110. package/{src → dist/esm/src}/middleware/stringBody.js +2 -3
  111. package/dist/esm/src/networkManager.d.ts +32 -0
  112. package/{src → dist/esm/src}/networkManager.js +16 -33
  113. package/dist/esm/src/operatorManager.d.ts +36 -0
  114. package/{src → dist/esm/src}/operatorManager.js +35 -91
  115. package/dist/esm/src/progressListener.d.ts +20 -0
  116. package/dist/esm/src/progressListener.js +88 -0
  117. package/dist/esm/src/providerManager.d.ts +9 -0
  118. package/dist/esm/src/providerManager.js +45 -0
  119. package/dist/esm/src/providers/routes.d.ts +3 -0
  120. package/{src → dist/esm/src}/providers/routes.js +10 -16
  121. package/dist/esm/src/proxy/routes.d.ts +3 -0
  122. package/dist/esm/src/proxy/routes.js +106 -0
  123. package/dist/esm/src/proxy/types/rest.d.ts +4 -0
  124. package/dist/esm/src/proxy/types/rest.js +107 -0
  125. package/dist/esm/src/proxy/types/web.d.ts +4 -0
  126. package/{src → dist/esm/src}/proxy/types/web.js +13 -35
  127. package/dist/esm/src/repositoryManager.d.ts +17 -0
  128. package/dist/esm/src/repositoryManager.js +212 -0
  129. package/dist/esm/src/serviceManager.d.ts +29 -0
  130. package/{src → dist/esm/src}/serviceManager.js +12 -42
  131. package/dist/esm/src/socketManager.d.ts +14 -0
  132. package/{src → dist/esm/src}/socketManager.js +19 -23
  133. package/dist/esm/src/storageService.d.ts +17 -0
  134. package/{src → dist/esm/src}/storageService.js +8 -27
  135. package/dist/esm/src/traffic/routes.d.ts +3 -0
  136. package/{src → dist/esm/src}/traffic/routes.js +4 -9
  137. package/dist/esm/src/types.d.ts +88 -0
  138. package/dist/esm/src/types.js +1 -0
  139. package/dist/esm/src/utils/BlockInstanceRunner.d.ts +29 -0
  140. package/{src → dist/esm/src}/utils/BlockInstanceRunner.js +137 -256
  141. package/dist/esm/src/utils/LogData.d.ts +19 -0
  142. package/{src → dist/esm/src}/utils/LogData.js +11 -22
  143. package/dist/esm/src/utils/pathTemplateParser.d.ts +26 -0
  144. package/{src → dist/esm/src}/utils/pathTemplateParser.js +21 -40
  145. package/dist/esm/src/utils/utils.d.ts +1 -0
  146. package/dist/esm/src/utils/utils.js +11 -0
  147. package/dist/esm/start.d.ts +1 -0
  148. package/dist/esm/start.js +7 -0
  149. package/index.ts +147 -0
  150. package/package.json +106 -74
  151. package/src/assetManager.ts +191 -0
  152. package/src/assets/routes.ts +132 -0
  153. package/src/clusterService.ts +134 -0
  154. package/src/codeGeneratorManager.ts +57 -0
  155. package/src/config/routes.ts +159 -0
  156. package/src/configManager.ts +148 -0
  157. package/src/containerManager.ts +466 -0
  158. package/src/filesystem/routes.ts +74 -0
  159. package/src/filesystemManager.ts +93 -0
  160. package/src/identities/routes.ts +20 -0
  161. package/src/instanceManager.ts +503 -0
  162. package/src/instances/routes.ts +164 -0
  163. package/src/middleware/cors.ts +9 -0
  164. package/src/middleware/kapeta.ts +27 -0
  165. package/src/middleware/stringBody.ts +16 -0
  166. package/src/networkManager.ts +137 -0
  167. package/src/operatorManager.ts +221 -0
  168. package/src/progressListener.ts +102 -0
  169. package/src/{providerManager.js → providerManager.ts} +15 -31
  170. package/src/providers/routes.ts +46 -0
  171. package/src/proxy/routes.ts +148 -0
  172. package/src/proxy/types/{rest.js → rest.ts} +30 -30
  173. package/src/proxy/types/web.ts +60 -0
  174. package/src/{repositoryManager.js → repositoryManager.ts} +49 -73
  175. package/src/serviceManager.ts +120 -0
  176. package/src/socketManager.ts +57 -0
  177. package/src/storageService.ts +88 -0
  178. package/src/traffic/routes.ts +18 -0
  179. package/src/types.ts +97 -0
  180. package/src/utils/BlockInstanceRunner.ts +555 -0
  181. package/src/utils/LogData.ts +47 -0
  182. package/src/utils/pathTemplateParser.ts +138 -0
  183. package/src/utils/utils.ts +12 -0
  184. package/start.ts +8 -0
  185. package/tsconfig.json +13 -0
  186. package/index.js +0 -127
  187. package/src/filesystem/routes.js +0 -74
  188. package/src/identities/routes.js +0 -19
  189. package/src/progressListener.js +0 -82
  190. package/src/proxy/routes.js +0 -126
  191. package/src/utils/utils.js +0 -13
  192. package/start.js +0 -7
@@ -1,41 +1,33 @@
1
- const ClusterConfiguration = require('@kapeta/local-cluster-config').default;
2
- const serviceManager = require('./serviceManager');
3
- const storageService = require('./storageService');
4
- const containerManager = require('./containerManager');
5
- const _ = require('lodash');
6
- const mkdirp = require('mkdirp');
7
- const Path = require('path');
8
- const md5 = require('md5');
9
- const {parseKapetaUri} = require("@kapeta/nodejs-utils");
10
-
1
+ import ClusterConfiguration from '@kapeta/local-cluster-config';
2
+ import Path from 'path';
3
+ import md5 from 'md5';
4
+ import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
+ import { serviceManager } from './serviceManager';
6
+ import { storageService } from './storageService';
7
+ import { containerManager } from './containerManager';
8
+ import FSExtra from 'fs-extra';
11
9
  const KIND_OPERATOR = 'core/resource-type-operator';
12
-
13
10
  class Operator {
11
+ _data;
14
12
  constructor(data) {
15
13
  this._data = data;
16
14
  }
17
-
18
15
  getData() {
19
16
  return this._data;
20
17
  }
21
-
22
18
  getCredentials() {
23
19
  return this._data.credentials;
24
20
  }
25
21
  }
26
-
27
22
  class OperatorManager {
28
-
23
+ _mountDir;
29
24
  constructor() {
30
25
  this._mountDir = Path.join(storageService.getKapetaBasedir(), 'mounts');
31
-
32
- mkdirp.sync(this._mountDir);
26
+ FSExtra.mkdirpSync(this._mountDir);
33
27
  }
34
-
35
28
  _getMountPoint(operatorType, mountName) {
36
29
  return Path.join(this._mountDir, operatorType, mountName);
37
30
  }
38
-
39
31
  /**
40
32
  * Get operator definition for resource type
41
33
  *
@@ -45,89 +37,62 @@ class OperatorManager {
45
37
  */
46
38
  getOperator(resourceType, version) {
47
39
  const operators = ClusterConfiguration.getDefinitions(KIND_OPERATOR);
48
-
49
- const operator = _.find(operators, (operator) => operator.definition &&
40
+ const operator = operators.find((operator) => operator.definition &&
50
41
  operator.definition.metadata &&
51
42
  operator.definition.metadata.name &&
52
43
  operator.definition.metadata.name.toLowerCase() === resourceType.toLowerCase() &&
53
44
  operator.version === version);
54
-
55
45
  if (!operator) {
56
46
  throw new Error(`Unknown resource type: ${resourceType}:${version}`);
57
47
  }
58
-
59
- if (!operator.definition.spec ||
60
- !operator.definition.spec.local) {
48
+ if (!operator.definition.spec || !operator.definition.spec.local) {
61
49
  throw new Error(`Operator missing local definition: ${resourceType}:${version}`);
62
50
  }
63
-
64
51
  return new Operator(operator.definition.spec.local);
65
52
  }
66
-
67
53
  /**
68
54
  * Get information about a specific consumed resource
69
- *
70
- * @param {string} systemId
71
- * @param {string} fromServiceId
72
- * @param {string} resourceType
73
- * @param {string} portType
74
- * @param {string} name
75
- * @returns {Promise<{host: string, port: (*|string), type: *, protocol: *, credentials: *}>}
76
55
  */
77
56
  async getConsumerResourceInfo(systemId, fromServiceId, resourceType, portType, name, environment) {
78
-
79
57
  const plans = ClusterConfiguration.getDefinitions('core/plan');
80
-
81
58
  const planUri = parseKapetaUri(systemId);
82
- const currentPlan = plans.find(plan => plan.definition.metadata.name === planUri.fullName && plan.version === planUri.version);
59
+ const currentPlan = plans.find((plan) => plan.definition.metadata.name === planUri.fullName && plan.version === planUri.version);
83
60
  if (!currentPlan) {
84
61
  throw new Error(`Unknown plan: ${systemId}`);
85
62
  }
86
-
87
- const currentInstance = currentPlan.definition.spec.blocks?.find(instance => instance.id === fromServiceId);
63
+ const currentInstance = currentPlan.definition.spec.blocks?.find((instance) => instance.id === fromServiceId);
88
64
  if (!currentInstance) {
89
65
  throw new Error(`Unknown instance: ${fromServiceId} in plan ${systemId}`);
90
66
  }
91
-
92
67
  const blockUri = parseKapetaUri(currentInstance.block.ref);
93
- const blockDefinition = ClusterConfiguration.getDefinitions().find(definition =>
94
- definition.version === blockUri.version &&
95
- definition.definition.metadata.name === blockUri.fullName
96
- );
97
-
68
+ const blockDefinition = ClusterConfiguration.getDefinitions().find((definition) => definition.version === blockUri.version && definition.definition.metadata.name === blockUri.fullName);
98
69
  if (!blockDefinition) {
99
70
  throw new Error(`Unknown block: ${currentInstance.block.ref} in plan ${systemId}`);
100
71
  }
101
-
102
- const blockResource = blockDefinition.definition.spec?.consumers?.find(resource => resource.metadata.name === name);
72
+ const blockResource = blockDefinition.definition.spec?.consumers?.find((resource) => resource.metadata.name === name);
103
73
  if (!blockResource) {
104
74
  throw new Error(`Unknown resource: ${name} in block ${currentInstance.block.ref} in plan ${systemId}`);
105
75
  }
106
-
107
76
  const kindUri = parseKapetaUri(blockResource.kind);
108
77
  const operator = this.getOperator(resourceType, kindUri.version);
109
78
  const credentials = operator.getCredentials();
110
79
  const container = await this.ensureResource(systemId, resourceType, kindUri.version);
111
80
  const portInfo = await container.getPort(portType);
112
-
113
81
  if (!portInfo) {
114
82
  throw new Error('Unknown resource port type : ' + resourceType + '#' + portType);
115
83
  }
116
-
117
84
  const dbName = name + '_' + fromServiceId.replace(/[^a-z0-9]/gi, '');
118
-
119
85
  return {
120
86
  host: environment === 'docker' ? 'host.docker.internal' : '127.0.0.1',
121
87
  port: portInfo.hostPort,
122
88
  type: portType,
123
89
  protocol: portInfo.protocol,
124
90
  options: {
125
- dbName
91
+ dbName,
126
92
  },
127
- credentials
93
+ credentials,
128
94
  };
129
95
  }
130
-
131
96
  /**
132
97
  * Ensure we have a running operator of given type
133
98
  *
@@ -138,78 +103,57 @@ class OperatorManager {
138
103
  */
139
104
  async ensureResource(systemId, resourceType, version) {
140
105
  const operator = this.getOperator(resourceType, version);
141
-
142
106
  const operatorData = operator.getData();
143
-
144
107
  const portTypes = Object.keys(operatorData.ports);
145
-
146
108
  portTypes.sort();
147
-
148
109
  const containerBaseName = 'kapeta-resource';
149
-
150
110
  const nameParts = [resourceType.toLowerCase()];
151
-
152
111
  const ports = {};
153
-
154
- for(let i = 0 ; i < portTypes.length; i++) {
112
+ for (let i = 0; i < portTypes.length; i++) {
155
113
  const portType = portTypes[i];
156
114
  let containerPortInfo = operatorData.ports[portType];
157
115
  const hostPort = await serviceManager.ensureServicePort(resourceType, portType);
158
-
159
- if (typeof containerPortInfo === 'number' ||
160
- typeof containerPortInfo === 'string') {
161
- containerPortInfo = {port: containerPortInfo, type: 'tcp'};
116
+ if (typeof containerPortInfo === 'number' || typeof containerPortInfo === 'string') {
117
+ containerPortInfo = { port: containerPortInfo, type: 'tcp' };
162
118
  }
163
-
164
119
  if (!containerPortInfo.type) {
165
120
  containerPortInfo.type = 'tcp';
166
121
  }
167
-
168
122
  const portId = containerPortInfo.port + '/' + containerPortInfo.type;
169
123
  nameParts.push(portType + '-' + portId + '-' + hostPort);
170
-
171
124
  ports[portId] = {
172
125
  type: portType,
173
- hostPort
126
+ hostPort,
174
127
  };
175
128
  }
176
-
177
129
  const mounts = containerManager.createMounts(resourceType, operatorData.mounts);
178
-
179
130
  const containerName = containerBaseName + '-' + md5(nameParts.join('_'));
180
131
  let container = await containerManager.get(containerName);
181
-
182
132
  const isRunning = container ? await container.isRunning() : false;
183
133
  if (container && !isRunning) {
184
134
  await container.start();
185
135
  }
186
-
187
136
  if (!container) {
188
-
189
- container = await containerManager.run(
190
- operatorData.image,
191
- containerName,
192
- {
193
- mounts,
194
- ports,
195
- health: operatorData.health,
196
- env: operatorData.env,
197
- cmd: operatorData.cmd
198
- });
137
+ container = await containerManager.run(operatorData.image, containerName, {
138
+ mounts,
139
+ ports,
140
+ health: operatorData.health,
141
+ env: operatorData.env,
142
+ cmd: operatorData.cmd,
143
+ });
199
144
  }
200
-
201
145
  try {
202
146
  if (operatorData.health) {
203
147
  await containerManager.waitForHealthy(container.native);
204
- } else {
148
+ }
149
+ else {
205
150
  await containerManager.waitForReady(container.native);
206
151
  }
207
- } catch (e) {
152
+ }
153
+ catch (e) {
208
154
  console.error(e.message);
209
155
  }
210
-
211
156
  return container;
212
157
  }
213
158
  }
214
-
215
- module.exports = new OperatorManager();
159
+ export const operatorManager = new OperatorManager();
@@ -0,0 +1,20 @@
1
+ /// <reference types="node" />
2
+ import { SocketManager } from './socketManager';
3
+ declare class ProgressListener {
4
+ private socketManager;
5
+ constructor(socketManager: SocketManager);
6
+ run(command: string, directory?: string): Promise<{
7
+ exit: number;
8
+ signal: NodeJS.Signals | null;
9
+ }>;
10
+ progress(label: string, callback: () => void | Promise<void>): Promise<void>;
11
+ check(message: string, ok: boolean | Promise<boolean> | (() => Promise<boolean>)): Promise<void>;
12
+ start(label: string): void;
13
+ showValue(label: string, value: any): void;
14
+ error(msg: string, ...args: any[]): void;
15
+ warn(msg: string, ...args: any[]): void;
16
+ info(msg: string, ...args: any[]): void;
17
+ debug(msg: string, ...args: any[]): void;
18
+ }
19
+ export declare const progressListener: ProgressListener;
20
+ export {};
@@ -0,0 +1,88 @@
1
+ import { spawn } from 'child_process';
2
+ import { socketManager } from './socketManager';
3
+ class ProgressListener {
4
+ socketManager;
5
+ constructor(socketManager) {
6
+ this.socketManager = socketManager;
7
+ }
8
+ run(command, directory) {
9
+ this.socketManager.emit(`install`, 'install:log', {
10
+ type: 'info',
11
+ message: `Running command "${command}"`,
12
+ });
13
+ return new Promise((resolve, reject) => {
14
+ const child = spawn(command, {
15
+ cwd: directory ? directory : process.cwd(),
16
+ detached: true,
17
+ shell: true,
18
+ });
19
+ child.stdout.on('data', (data) => {
20
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: data.toString() });
21
+ });
22
+ child.stderr.on('data', (data) => {
23
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: data.toString() });
24
+ });
25
+ child.on('exit', (exit, signal) => {
26
+ if (exit !== 0) {
27
+ this.socketManager.emit(`install`, 'install:log', {
28
+ type: 'info',
29
+ message: `"${command}" failed: "${exit}"`,
30
+ });
31
+ reject(new Error(`Command "${command}" exited with code ${exit}`));
32
+ }
33
+ else {
34
+ this.socketManager.emit(`install`, 'install:log', {
35
+ type: 'info',
36
+ message: `Command OK: "${command}"`,
37
+ });
38
+ resolve({ exit, signal });
39
+ }
40
+ });
41
+ child.on('error', (err) => {
42
+ this.socketManager.emit(`install`, 'install:log', {
43
+ type: 'info',
44
+ message: `"${command}" failed: "${err.message}"`,
45
+ });
46
+ reject(err);
47
+ });
48
+ });
49
+ }
50
+ async progress(label, callback) {
51
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: `${label}: started` });
52
+ try {
53
+ const result = await callback();
54
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: `${label}: done` });
55
+ return result;
56
+ }
57
+ catch (e) {
58
+ this.socketManager.emit(`install`, 'install:log', {
59
+ type: 'info',
60
+ message: `${label}: failed. ${e.message}`,
61
+ });
62
+ throw e;
63
+ }
64
+ }
65
+ async check(message, ok) {
66
+ const wasOk = await ok;
67
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: `${message}: ${wasOk}` });
68
+ }
69
+ start(label) {
70
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: label });
71
+ }
72
+ showValue(label, value) {
73
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: `${label}: ${value}` });
74
+ }
75
+ error(msg, ...args) {
76
+ this.socketManager.emit(`install`, 'install:log', { type: 'error', message: msg });
77
+ }
78
+ warn(msg, ...args) {
79
+ this.socketManager.emit(`install`, 'install:log', { type: 'warn', message: msg });
80
+ }
81
+ info(msg, ...args) {
82
+ this.socketManager.emit(`install`, 'install:log', { type: 'info', message: msg });
83
+ }
84
+ debug(msg, ...args) {
85
+ this.socketManager.emit(`install`, 'install:log', { type: 'debug', message: msg });
86
+ }
87
+ }
88
+ export const progressListener = new ProgressListener(socketManager);
@@ -0,0 +1,9 @@
1
+ /// <reference types="node" />
2
+ declare class ProviderManager {
3
+ private _webAssetCache;
4
+ constructor();
5
+ getWebProviders(): import("@kapeta/local-cluster-config").DefinitionInfo[];
6
+ getAsset(handle: string, name: string, version: string, sourceMap?: boolean): Promise<string | Buffer | null>;
7
+ }
8
+ export declare const providerManager: ProviderManager;
9
+ export {};
@@ -0,0 +1,45 @@
1
+ import Path from 'path';
2
+ import FSExtra from 'fs-extra';
3
+ import { repositoryManager } from './repositoryManager';
4
+ import ClusterConfiguration from '@kapeta/local-cluster-config';
5
+ class ProviderManager {
6
+ _webAssetCache;
7
+ constructor() {
8
+ this._webAssetCache = {};
9
+ }
10
+ getWebProviders() {
11
+ return ClusterConfiguration.getProviderDefinitions().filter((providerDefinition) => providerDefinition.hasWeb);
12
+ }
13
+ async getAsset(handle, name, version, sourceMap = false) {
14
+ const fullName = `${handle}/${name}`;
15
+ const id = `${handle}/${name}/${version}/web.js${sourceMap ? '.map' : ''}`;
16
+ if (this._webAssetCache[id] && (await FSExtra.pathExists(this._webAssetCache[id]))) {
17
+ return FSExtra.readFile(this._webAssetCache[id], 'utf8');
18
+ }
19
+ await repositoryManager.ensureAsset(handle, name, version);
20
+ const installedProvider = this.getWebProviders().find((providerDefinition) => {
21
+ return providerDefinition.definition.metadata.name === fullName && providerDefinition.version === version;
22
+ });
23
+ if (installedProvider) {
24
+ //Check locally installed providers
25
+ const path = Path.join(installedProvider.path, 'web', handle, `${name}.js${sourceMap ? '.map' : ''}`);
26
+ if (await FSExtra.pathExists(path)) {
27
+ this._webAssetCache[id] = path;
28
+ return FSExtra.readFile(path);
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ }
34
+ const providerDefinitions = ClusterConfiguration.getProviderDefinitions();
35
+ if (providerDefinitions.length > 0) {
36
+ console.log('## Loaded the following providers ##');
37
+ providerDefinitions.forEach((providerDefinition) => {
38
+ console.log(' - %s[%s:%s]', providerDefinition.definition.kind, providerDefinition.definition.metadata.name, providerDefinition.version);
39
+ console.log(' from %s', providerDefinition.path);
40
+ });
41
+ }
42
+ else {
43
+ console.log('## No providers found ##');
44
+ }
45
+ export const providerManager = new ProviderManager();
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -1,37 +1,32 @@
1
- const Router = require('express-promise-router').default;
2
- const providerManager = require('../providerManager');
3
-
4
- const router = new Router();
5
-
6
- router.use('/', require('../middleware/cors'));
7
-
1
+ import Router from 'express-promise-router';
2
+ import { providerManager } from '../providerManager';
3
+ import { corsHandler } from '../middleware/cors';
4
+ const router = Router();
5
+ router.use('/', corsHandler);
8
6
  router.get('/', async (req, res) => {
9
7
  const result = await providerManager.getWebProviders();
10
-
11
8
  res.send(result);
12
9
  });
13
-
14
10
  router.get('/asset/:handle/:name/:version/web.js', async (req, res) => {
15
11
  const { handle, name, version } = req.params;
16
12
  let result = await providerManager.getAsset(handle, name, version);
17
-
18
13
  if (!result) {
19
14
  res.status(404).send('');
20
- } else {
15
+ }
16
+ else {
21
17
  if (version !== 'local') {
22
18
  res.setHeader('Cache-Control', 'max-age=31536000, immutable');
23
19
  }
24
20
  res.send(result.toString().replace(`${name}.js.map`, 'web.js.map'));
25
21
  }
26
22
  });
27
-
28
23
  router.get('/asset/:handle/:name/:version/web.js.map', async (req, res) => {
29
24
  const { handle, name, version } = req.params;
30
25
  const result = await providerManager.getAsset(handle, name, version, true);
31
-
32
26
  if (!result) {
33
27
  res.status(404).send('');
34
- } else {
28
+ }
29
+ else {
35
30
  // Only cache successful requests
36
31
  if (version !== 'local') {
37
32
  res.setHeader('Cache-Control', 'max-age=31536000, immutable');
@@ -39,5 +34,4 @@ router.get('/asset/:handle/:name/:version/web.js.map', async (req, res) => {
39
34
  res.send(result);
40
35
  }
41
36
  });
42
-
43
- module.exports = router;
37
+ export default router;
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -0,0 +1,106 @@
1
+ import Router from 'express-promise-router';
2
+ import { proxyRestRequest } from './types/rest';
3
+ import { proxyWebRequest } from './types/web';
4
+ import { stringBody } from '../middleware/stringBody';
5
+ import { serviceManager } from '../serviceManager';
6
+ import { clusterService } from '../clusterService';
7
+ import { assetManager } from '../assetManager';
8
+ import _ from 'lodash';
9
+ const router = Router();
10
+ /**
11
+ * @var {{[key:string]:ProxyRequestHandler}}
12
+ */
13
+ const TYPE_HANDLERS = {
14
+ rest: proxyRestRequest,
15
+ web: proxyWebRequest,
16
+ };
17
+ function getResource(resources, resourceName) {
18
+ return resources.find((resource) => {
19
+ return resource.metadata.name.toLowerCase() === resourceName.toLowerCase();
20
+ });
21
+ }
22
+ router.use('/:systemId/:consumerInstanceId/:consumerResourceName', stringBody);
23
+ router.all('/:systemId/:consumerInstanceId/:consumerResourceName/:type/*', async (req, res) => {
24
+ try {
25
+ const typeHandler = TYPE_HANDLERS[req.params.type.toLowerCase()];
26
+ if (!typeHandler) {
27
+ res.status(401).send({ error: 'Unknown connection type: ' + req.params.type });
28
+ return;
29
+ }
30
+ const plan = await assetManager.getPlan(req.params.systemId);
31
+ // We can find the connection by the consumer information alone since
32
+ // only 1 provider can be connected to a consumer resource at a time
33
+ const connection = _.find(plan.spec.connections, (connection) => {
34
+ return (connection.consumer.blockId.toLowerCase() === req.params.consumerInstanceId.toLowerCase() &&
35
+ connection.consumer.resourceName.toLowerCase() === req.params.consumerResourceName.toLowerCase());
36
+ });
37
+ if (!connection) {
38
+ res.status(401).send({
39
+ error: `No connection found for consumer "${req.params.consumerInstanceId}::${req.params.consumerResourceName}"`,
40
+ });
41
+ return;
42
+ }
43
+ const toBlockInstance = _.find(plan.spec.blocks, (blockInstance) => {
44
+ return blockInstance.id.toLowerCase() === connection.consumer.blockId.toLowerCase();
45
+ });
46
+ if (!toBlockInstance) {
47
+ res.status(401).send({ error: `Block instance not found "${req.params.consumerInstanceId}` });
48
+ return;
49
+ }
50
+ const toBlockAsset = await assetManager.getAsset(toBlockInstance.block.ref);
51
+ if (!toBlockAsset) {
52
+ res.status(401).send({ error: `Block asset not found "${toBlockInstance.block.ref}` });
53
+ return;
54
+ }
55
+ const consumerResource = getResource(toBlockAsset.data.spec.consumers, req.params.consumerResourceName);
56
+ if (!consumerResource) {
57
+ res.status(401).send({
58
+ error: `Block resource not found "${req.params.consumerInstanceId}::${req.params.consumerResourceName}`,
59
+ });
60
+ return;
61
+ }
62
+ const basePath = clusterService.getProxyPath(req.params.systemId, req.params.consumerInstanceId, req.params.consumerResourceName, req.params.type);
63
+ const fromBlockInstance = _.find(plan.spec.blocks, (blockInstance) => {
64
+ return blockInstance.id.toLowerCase() === connection.provider.blockId.toLowerCase();
65
+ });
66
+ if (!fromBlockInstance) {
67
+ res.status(401).send({ error: `Block instance not found "${connection.provider.blockId}` });
68
+ return;
69
+ }
70
+ const fromBlockAsset = await assetManager.getAsset(fromBlockInstance.block.ref);
71
+ if (!fromBlockAsset) {
72
+ res.status(401).send({ error: `Block asset not found "${fromBlockInstance.block.ref}` });
73
+ return;
74
+ }
75
+ const providerResource = getResource(fromBlockAsset.data.spec.providers, connection.provider.resourceName);
76
+ if (!providerResource) {
77
+ res.status(401).send({
78
+ error: `Block resource not found "${connection.provider.blockId}::${connection.provider.resourceName}`,
79
+ });
80
+ return;
81
+ }
82
+ //Get target address
83
+ let address = await serviceManager.getProviderAddress(req.params.systemId, connection.provider.blockId, req.params.type);
84
+ while (address.endsWith('/')) {
85
+ address = address.substring(0, address.length - 1);
86
+ }
87
+ /*
88
+ Get the path the consumer requested.
89
+ Note that this might not match the path the destination is expecting so we need to identify the method
90
+ that is being called and identify the destination path from the connection.
91
+ */
92
+ const consumerPath = req.originalUrl.substring(basePath.length - 1);
93
+ typeHandler(req, res, {
94
+ consumerPath,
95
+ address,
96
+ consumerResource,
97
+ providerResource,
98
+ connection,
99
+ });
100
+ }
101
+ catch (err) {
102
+ console.warn('Failed to process proxy request', err);
103
+ res.status(400).send({ error: err.message });
104
+ }
105
+ });
106
+ export default router;
@@ -0,0 +1,4 @@
1
+ import { Response } from 'express';
2
+ import { ProxyRequestInfo } from '../../types';
3
+ import { StringBodyRequest } from '../../middleware/stringBody';
4
+ export declare function proxyRestRequest(req: StringBodyRequest, res: Response, opts: ProxyRequestInfo): void;