@kapeta/local-cluster-service 0.16.8 → 0.18.0
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/CHANGELOG.md +20 -0
- package/dist/cjs/index.js +6 -2
- package/dist/cjs/src/assetManager.d.ts +2 -2
- package/dist/cjs/src/assetManager.js +16 -16
- package/dist/cjs/src/assets/routes.js +2 -2
- package/dist/cjs/src/authManager.d.ts +12 -0
- package/dist/cjs/src/authManager.js +60 -0
- package/dist/cjs/src/codeGeneratorManager.d.ts +1 -1
- package/dist/cjs/src/codeGeneratorManager.js +3 -3
- package/dist/cjs/src/configManager.js +2 -2
- package/dist/cjs/src/definitionsManager.d.ts +7 -6
- package/dist/cjs/src/definitionsManager.js +102 -18
- package/dist/cjs/src/instanceManager.d.ts +1 -1
- package/dist/cjs/src/instanceManager.js +4 -4
- package/dist/cjs/src/instances/routes.js +2 -2
- package/dist/cjs/src/operatorManager.d.ts +1 -1
- package/dist/cjs/src/operatorManager.js +7 -9
- package/dist/cjs/src/providerManager.d.ts +2 -1
- package/dist/cjs/src/providerManager.js +23 -15
- package/dist/cjs/src/repositoryManager.d.ts +2 -2
- package/dist/cjs/src/repositoryManager.js +8 -9
- package/dist/cjs/src/socketManager.js +6 -0
- package/dist/cjs/src/utils/BlockInstanceRunner.js +6 -8
- package/dist/cjs/src/utils/DefaultProviderInstaller.d.ts +11 -0
- package/dist/cjs/src/utils/DefaultProviderInstaller.js +129 -0
- package/dist/esm/index.js +67 -58
- package/dist/esm/src/RepositoryWatcher.js +40 -33
- package/dist/esm/src/api.js +14 -9
- package/dist/esm/src/assetManager.d.ts +2 -2
- package/dist/esm/src/assetManager.js +73 -67
- package/dist/esm/src/assets/routes.js +23 -18
- package/dist/esm/src/attachments/routes.js +14 -9
- package/dist/esm/src/authManager.d.ts +12 -0
- package/dist/esm/src/authManager.js +60 -0
- package/dist/esm/src/cacheManager.js +13 -5
- package/dist/esm/src/clusterService.js +6 -3
- package/dist/esm/src/codeGeneratorManager.d.ts +1 -1
- package/dist/esm/src/codeGeneratorManager.js +20 -14
- package/dist/esm/src/config/routes.js +30 -25
- package/dist/esm/src/configManager.js +29 -26
- package/dist/esm/src/containerManager.js +48 -39
- package/dist/esm/src/definitionsManager.d.ts +7 -6
- package/dist/esm/src/definitionsManager.js +114 -24
- package/dist/esm/src/filesystem/routes.js +21 -16
- package/dist/esm/src/filesystemManager.js +23 -17
- package/dist/esm/src/identities/routes.js +13 -8
- package/dist/esm/src/instanceManager.d.ts +1 -1
- package/dist/esm/src/instanceManager.js +165 -158
- package/dist/esm/src/instances/routes.js +39 -34
- package/dist/esm/src/middleware/cors.js +5 -1
- package/dist/esm/src/middleware/kapeta.js +8 -4
- package/dist/esm/src/middleware/stringBody.js +5 -1
- package/dist/esm/src/networkManager.js +15 -9
- package/dist/esm/src/operatorManager.d.ts +1 -1
- package/dist/esm/src/operatorManager.js +48 -44
- package/dist/esm/src/progressListener.js +16 -12
- package/dist/esm/src/providerManager.d.ts +2 -1
- package/dist/esm/src/providerManager.js +43 -29
- package/dist/esm/src/providers/routes.js +14 -9
- package/dist/esm/src/proxy/routes.js +26 -21
- package/dist/esm/src/proxy/types/rest.js +29 -22
- package/dist/esm/src/proxy/types/web.js +18 -11
- package/dist/esm/src/repositoryManager.d.ts +2 -2
- package/dist/esm/src/repositoryManager.js +33 -28
- package/dist/esm/src/serviceManager.js +25 -19
- package/dist/esm/src/socketManager.js +31 -18
- package/dist/esm/src/storageService.js +18 -12
- package/dist/esm/src/taskManager.js +12 -8
- package/dist/esm/src/tasks/routes.js +14 -9
- package/dist/esm/src/traffic/routes.js +12 -7
- package/dist/esm/src/types.js +11 -8
- package/dist/esm/src/utils/BlockInstanceRunner.js +60 -55
- package/dist/esm/src/utils/DefaultProviderInstaller.d.ts +11 -0
- package/dist/esm/src/utils/DefaultProviderInstaller.js +129 -0
- package/dist/esm/src/utils/LogData.js +5 -1
- package/dist/esm/src/utils/commandLineUtils.js +12 -7
- package/dist/esm/src/utils/pathTemplateParser.js +7 -2
- package/dist/esm/src/utils/utils.js +30 -17
- package/dist/esm/start.js +7 -2
- package/index.ts +7 -2
- package/package.json +10 -4
- package/src/assetManager.ts +18 -16
- package/src/assets/routes.ts +2 -2
- package/src/authManager.ts +62 -0
- package/src/codeGeneratorManager.ts +3 -3
- package/src/configManager.ts +2 -2
- package/src/definitionsManager.ts +132 -17
- package/src/instanceManager.ts +5 -5
- package/src/instances/routes.ts +2 -2
- package/src/operatorManager.ts +7 -12
- package/src/providerManager.ts +27 -19
- package/src/repositoryManager.ts +8 -11
- package/src/socketManager.ts +6 -0
- package/src/utils/BlockInstanceRunner.ts +6 -8
- package/src/utils/DefaultProviderInstaller.ts +141 -0
- package/tsconfig.json +3 -2
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@kapeta/local-cluster-service",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.18.0",
|
4
4
|
"description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
|
5
5
|
"type": "commonjs",
|
6
6
|
"exports": {
|
@@ -34,8 +34,8 @@
|
|
34
34
|
"dev": "nodemon -e js,ts,json ./start.ts",
|
35
35
|
"test": "echo its fine",
|
36
36
|
"clean": "rm -rf ./dist",
|
37
|
-
"build:esm": "tsc --module
|
38
|
-
"build:cjs": "tsc
|
37
|
+
"build:esm": "tsc --module nodenext --moduleResolution nodenext --outDir ./dist/esm && echo '{\"type\":\"module\"}' > ./dist/esm/package.json",
|
38
|
+
"build:cjs": "tsc --outDir ./dist/cjs && echo '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
|
39
39
|
"build": "npm run clean && npm run build:esm && npm run build:cjs",
|
40
40
|
"format": "prettier --write .",
|
41
41
|
"lint": "tsc --noEmit && eslint src/**/*.ts",
|
@@ -57,7 +57,8 @@
|
|
57
57
|
"express": "4.17.1",
|
58
58
|
"express-promise-router": "^4.1.1",
|
59
59
|
"fs-extra": "^11.1.0",
|
60
|
-
"glob": "7.1.6",
|
60
|
+
"glob": "^7.1.6",
|
61
|
+
"gunzip-maybe": "^1.4.2",
|
61
62
|
"lodash": "^4.17.15",
|
62
63
|
"md5": "2.2.1",
|
63
64
|
"node-cache": "^5.1.2",
|
@@ -66,6 +67,7 @@
|
|
66
67
|
"request": "2.88.2",
|
67
68
|
"request-promise": "4.2.6",
|
68
69
|
"socket.io": "^4.5.2",
|
70
|
+
"tar-stream": "^3.1.6",
|
69
71
|
"typescript": "^5.1.6",
|
70
72
|
"yaml": "^1.6.0"
|
71
73
|
},
|
@@ -76,10 +78,14 @@
|
|
76
78
|
"@types/async-lock": "^1.4.0",
|
77
79
|
"@types/express": "^4.17.17",
|
78
80
|
"@types/fs-extra": "^11.0.1",
|
81
|
+
"@types/glob": "^8.1.0",
|
82
|
+
"@types/gunzip-maybe": "^1.4.0",
|
79
83
|
"@types/lodash": "^4.14.195",
|
80
84
|
"@types/md5": "^2.3.2",
|
85
|
+
"@types/node": "^20.5.8",
|
81
86
|
"@types/node-uuid": "^0.0.29",
|
82
87
|
"@types/request": "^2.48.8",
|
88
|
+
"@types/tar-stream": "^2.2.2",
|
83
89
|
"eslint": "^8.42.0",
|
84
90
|
"eslint-config-prettier": "^8.8.0",
|
85
91
|
"nodemon": "^2.0.2",
|
package/src/assetManager.ts
CHANGED
@@ -64,9 +64,9 @@ class AssetManager {
|
|
64
64
|
* @param {string[]} [assetKinds]
|
65
65
|
* @returns {{path: *, ref: string, data: *, editable: boolean, kind: *, exists: boolean}[]}
|
66
66
|
*/
|
67
|
-
getAssets(assetKinds?: string[]): EnrichedAsset[] {
|
67
|
+
async getAssets(assetKinds?: string[]): Promise<EnrichedAsset[]> {
|
68
68
|
if (!assetKinds) {
|
69
|
-
const blockTypeProviders = definitionsManager.getDefinitions([
|
69
|
+
const blockTypeProviders = await definitionsManager.getDefinitions([
|
70
70
|
'core/block-type',
|
71
71
|
'core/block-type-operator',
|
72
72
|
]);
|
@@ -76,12 +76,12 @@ class AssetManager {
|
|
76
76
|
assetKinds.push('core/plan');
|
77
77
|
}
|
78
78
|
|
79
|
-
const assets = definitionsManager.getDefinitions(assetKinds);
|
79
|
+
const assets = await definitionsManager.getDefinitions(assetKinds);
|
80
80
|
|
81
81
|
return assets.map(enrichAsset);
|
82
82
|
}
|
83
83
|
|
84
|
-
getPlans(): EnrichedAsset[] {
|
84
|
+
async getPlans(): Promise<EnrichedAsset[]> {
|
85
85
|
return this.getAssets(['core/plan']);
|
86
86
|
}
|
87
87
|
|
@@ -110,18 +110,18 @@ class AssetManager {
|
|
110
110
|
await repositoryManager.ensureAsset(uri.handle, uri.name, uri.version, true);
|
111
111
|
}
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
.map(enrichAsset)
|
116
|
-
.find((a) => parseKapetaUri(a.ref).equals(uri));
|
117
|
-
if (autoFetch && !asset) {
|
113
|
+
const definitionInfo = await definitionsManager.getDefinition(ref);
|
114
|
+
if (autoFetch && !definitionInfo) {
|
118
115
|
throw new Error('Asset not found: ' + ref);
|
119
116
|
}
|
120
|
-
|
117
|
+
|
118
|
+
if (definitionInfo) {
|
119
|
+
const asset = enrichAsset(definitionInfo);
|
121
120
|
cacheManager.set(cacheKey, asset, CACHE_TTL);
|
121
|
+
return asset;
|
122
122
|
}
|
123
123
|
|
124
|
-
return
|
124
|
+
return undefined;
|
125
125
|
}
|
126
126
|
|
127
127
|
async createAsset(
|
@@ -151,7 +151,7 @@ class AssetManager {
|
|
151
151
|
|
152
152
|
const ref = `kapeta://${yaml.metadata.name}:local`;
|
153
153
|
|
154
|
-
this.maybeGenerateCode(ref, path, yaml);
|
154
|
+
await this.maybeGenerateCode(ref, path, yaml);
|
155
155
|
|
156
156
|
return asset;
|
157
157
|
}
|
@@ -178,7 +178,7 @@ class AssetManager {
|
|
178
178
|
cacheManager.remove(toKey(ref));
|
179
179
|
definitionsManager.clearCache();
|
180
180
|
|
181
|
-
this.maybeGenerateCode(asset.ref, asset.ymlPath, yaml);
|
181
|
+
await this.maybeGenerateCode(asset.ref, asset.ymlPath, yaml);
|
182
182
|
}
|
183
183
|
|
184
184
|
async importFile(filePath: string) {
|
@@ -206,7 +206,9 @@ class AssetManager {
|
|
206
206
|
|
207
207
|
definitionsManager.clearCache();
|
208
208
|
|
209
|
-
|
209
|
+
const assets = await this.getAssets();
|
210
|
+
|
211
|
+
return assets.filter((a) => refs.some((ref) => compareRefs(ref, a.ref)));
|
210
212
|
}
|
211
213
|
|
212
214
|
async unregisterAsset(ref: string) {
|
@@ -236,9 +238,9 @@ class AssetManager {
|
|
236
238
|
return await repositoryManager.ensureAsset(uri.handle, uri.name, uri.version, false);
|
237
239
|
}
|
238
240
|
|
239
|
-
private maybeGenerateCode(ref: string, ymlPath: string, block: BlockDefinition) {
|
241
|
+
private async maybeGenerateCode(ref: string, ymlPath: string, block: BlockDefinition) {
|
240
242
|
ref = normalizeKapetaUri(ref);
|
241
|
-
if (codeGeneratorManager.canGenerateCode(block)) {
|
243
|
+
if (await codeGeneratorManager.canGenerateCode(block)) {
|
242
244
|
const assetTitle = block.metadata.title ? block.metadata.title : parseKapetaUri(block.metadata.name).name;
|
243
245
|
taskManager.add(
|
244
246
|
`codegen:${ref}`,
|
package/src/assets/routes.ts
CHANGED
@@ -31,8 +31,8 @@ router.use('/', stringBody);
|
|
31
31
|
/**
|
32
32
|
* Get all local assets available
|
33
33
|
*/
|
34
|
-
router.get('/', (req: Request, res: Response) => {
|
35
|
-
res.send(assetManager.getAssets([]));
|
34
|
+
router.get('/', async (req: Request, res: Response) => {
|
35
|
+
res.send(await assetManager.getAssets([]));
|
36
36
|
});
|
37
37
|
|
38
38
|
/**
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
2
|
+
import Path from 'node:path';
|
3
|
+
import chokidar, { FSWatcher } from 'chokidar';
|
4
|
+
import ClusterConfiguration from '@kapeta/local-cluster-config';
|
5
|
+
import { WatchEventName } from './types';
|
6
|
+
import { definitionsManager } from './definitionsManager';
|
7
|
+
import { KapetaAPI } from '@kapeta/nodejs-api-client';
|
8
|
+
import { socketManager } from './socketManager';
|
9
|
+
|
10
|
+
class AuthManager extends EventEmitter {
|
11
|
+
private watcher?: FSWatcher;
|
12
|
+
|
13
|
+
private hadToken: boolean;
|
14
|
+
|
15
|
+
constructor() {
|
16
|
+
super();
|
17
|
+
this.hadToken = this.hasToken();
|
18
|
+
}
|
19
|
+
|
20
|
+
public listenForChanges() {
|
21
|
+
const parentDir = Path.dirname(ClusterConfiguration.getKapetaBasedir());
|
22
|
+
//We watch the parent dir to catch changes to the base dir itself
|
23
|
+
this.watcher = chokidar.watch(parentDir, {
|
24
|
+
followSymlinks: false,
|
25
|
+
ignorePermissionErrors: true,
|
26
|
+
disableGlobbing: true,
|
27
|
+
persistent: true,
|
28
|
+
ignoreInitial: true,
|
29
|
+
depth: 1,
|
30
|
+
ignored: (path) => {
|
31
|
+
return !path.startsWith(ClusterConfiguration.getKapetaBasedir());
|
32
|
+
},
|
33
|
+
});
|
34
|
+
this.watcher.add(ClusterConfiguration.getKapetaBasedir());
|
35
|
+
this.watcher.on('all', this.handleFileChange.bind(this));
|
36
|
+
this.watcher.on('error', (error) => {
|
37
|
+
console.log('Error watching repository', error);
|
38
|
+
});
|
39
|
+
this.watcher.on('ready', () => {
|
40
|
+
console.log('Watching for auth changes: %s', ClusterConfiguration.getKapetaBasedir());
|
41
|
+
});
|
42
|
+
}
|
43
|
+
|
44
|
+
private hasToken() {
|
45
|
+
const api = new KapetaAPI();
|
46
|
+
return api.hasToken();
|
47
|
+
}
|
48
|
+
|
49
|
+
private async handleFileChange(eventName: WatchEventName, path: string) {
|
50
|
+
const hasTokenNow = this.hasToken();
|
51
|
+
if (this.hadToken !== hasTokenNow) {
|
52
|
+
socketManager.emitGlobal('auth-change', {});
|
53
|
+
if (hasTokenNow) {
|
54
|
+
// Clear the cache in case we need to rewrite the sample plan
|
55
|
+
definitionsManager.clearCache();
|
56
|
+
}
|
57
|
+
this.hadToken = hasTokenNow;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
export const authManager = new AuthManager();
|
@@ -10,7 +10,7 @@ const BLOCK_TYPE_KIND = 'core/block-type';
|
|
10
10
|
class CodeGeneratorManager {
|
11
11
|
async reload() {
|
12
12
|
Targets.reset();
|
13
|
-
const languageTargets = definitionsManager.getDefinitions(TARGET_KIND);
|
13
|
+
const languageTargets = await definitionsManager.getDefinitions(TARGET_KIND);
|
14
14
|
for (const languageTarget of languageTargets) {
|
15
15
|
const key = `${languageTarget.definition.metadata.name}:${languageTarget.version}`;
|
16
16
|
try {
|
@@ -26,13 +26,13 @@ class CodeGeneratorManager {
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
|
29
|
-
canGenerateCode(yamlContent: BlockDefinition): boolean {
|
29
|
+
async canGenerateCode(yamlContent: BlockDefinition): Promise<boolean> {
|
30
30
|
if (!yamlContent.spec.target?.kind) {
|
31
31
|
//Not all block types have targets
|
32
32
|
return false;
|
33
33
|
}
|
34
34
|
|
35
|
-
const blockTypes = definitionsManager.getDefinitions(BLOCK_TYPE_KIND);
|
35
|
+
const blockTypes = await definitionsManager.getDefinitions(BLOCK_TYPE_KIND);
|
36
36
|
const blockTypeKinds = blockTypes.map(
|
37
37
|
(blockType) => blockType.definition.metadata.name.toLowerCase() + ':' + blockType.version
|
38
38
|
);
|
package/src/configManager.ts
CHANGED
@@ -80,7 +80,7 @@ class ConfigManager {
|
|
80
80
|
if (systemId) {
|
81
81
|
systemId = normalizeKapetaUri(systemId);
|
82
82
|
}
|
83
|
-
const planAssets = assetManager.getPlans();
|
83
|
+
const planAssets = await assetManager.getPlans();
|
84
84
|
|
85
85
|
const blockUri = parseKapetaUri(blockRef);
|
86
86
|
|
@@ -132,7 +132,7 @@ class ConfigManager {
|
|
132
132
|
async verifyIdentity(blockRef: string, systemId: string, instanceId: string) {
|
133
133
|
blockRef = normalizeKapetaUri(blockRef);
|
134
134
|
systemId = normalizeKapetaUri(systemId);
|
135
|
-
const planAssets = assetManager.getPlans();
|
135
|
+
const planAssets = await assetManager.getPlans();
|
136
136
|
const systemUri = systemId ? parseKapetaUri(systemId) : null;
|
137
137
|
const blockUri = parseKapetaUri(blockRef);
|
138
138
|
let found = false;
|
@@ -1,39 +1,154 @@
|
|
1
1
|
import ClusterConfiguration, { DefinitionInfo } from '@kapeta/local-cluster-config';
|
2
2
|
import { parseKapetaUri } from '@kapeta/nodejs-utils';
|
3
3
|
import { cacheManager, doCached } from './cacheManager';
|
4
|
+
import { KapetaAPI } from '@kapeta/nodejs-api-client';
|
5
|
+
import { Plan } from '@kapeta/schemas';
|
6
|
+
import FS from 'fs-extra';
|
7
|
+
import { normalizeKapetaUri } from './utils/utils';
|
8
|
+
import YAML from 'yaml';
|
9
|
+
import { Actions } from '@kapeta/nodejs-registry-utils';
|
10
|
+
import { ProgressListener } from './progressListener';
|
11
|
+
import Path from 'path';
|
12
|
+
|
13
|
+
export const SAMPLE_PLAN_NAME = 'kapeta/sample-nodejs-plan';
|
14
|
+
|
15
|
+
function applyHandleChange(definition: DefinitionInfo, targetHandle: string) {
|
16
|
+
const originalUri = parseKapetaUri(definition.definition.metadata.name);
|
17
|
+
definition.definition.metadata.name = `${targetHandle}/${originalUri.name}`;
|
18
|
+
return definition;
|
19
|
+
}
|
20
|
+
|
21
|
+
function normalizeFilters(kindFilter?: string | string[]) {
|
22
|
+
let resolvedFilters: string[] = [];
|
23
|
+
|
24
|
+
if (kindFilter) {
|
25
|
+
if (Array.isArray(kindFilter)) {
|
26
|
+
resolvedFilters = [...kindFilter];
|
27
|
+
} else {
|
28
|
+
resolvedFilters = [kindFilter];
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
return resolvedFilters.map((k) => k.toLowerCase());
|
33
|
+
}
|
4
34
|
|
5
35
|
class DefinitionsManager {
|
6
|
-
private
|
7
|
-
|
8
|
-
|
9
|
-
|
36
|
+
private async resolveDefinitionsAndSamples() {
|
37
|
+
const definitions = ClusterConfiguration.getDefinitions();
|
38
|
+
const samplePlan = definitions.find(
|
39
|
+
(d) => d.version === 'local' && d.definition.metadata.name === SAMPLE_PLAN_NAME
|
40
|
+
);
|
41
|
+
|
42
|
+
if (!samplePlan) {
|
43
|
+
return definitions;
|
44
|
+
}
|
45
|
+
|
46
|
+
// We will only rewrite the sample plan once since we change the handle to be the users handle
|
47
|
+
const api = new KapetaAPI();
|
48
|
+
if (!api.hasToken()) {
|
49
|
+
// Not logged in yet, so we can't rewrite the sample plan
|
50
|
+
return definitions;
|
51
|
+
}
|
52
|
+
const profile = await api.getCurrentIdentity();
|
53
|
+
if (!profile) {
|
54
|
+
// Not logged in yet, so we can't rewrite the sample plan
|
55
|
+
return definitions;
|
56
|
+
}
|
57
|
+
|
58
|
+
console.log('Rewriting sample plan to use handle %s', profile.handle);
|
59
|
+
|
60
|
+
applyHandleChange(samplePlan, profile.handle);
|
61
|
+
|
62
|
+
const planDef = samplePlan.definition as Plan;
|
63
|
+
|
64
|
+
const blockRefs = new Set<string>();
|
65
|
+
|
66
|
+
planDef.spec.blocks.forEach((b) => {
|
67
|
+
const blockUri = parseKapetaUri(b.block.ref);
|
68
|
+
if (blockUri.version === 'local') {
|
69
|
+
blockRefs.add(blockUri.id);
|
70
|
+
b.block.ref = normalizeKapetaUri(`${profile.handle}/${blockUri.name}:local`);
|
10
71
|
}
|
11
|
-
|
72
|
+
});
|
73
|
+
|
74
|
+
// Rewrite all blocks that are referenced by the sample plan
|
75
|
+
const rewrittenBlocks = Array.from(blockRefs)
|
76
|
+
.map((ref) =>
|
77
|
+
definitions.find(
|
78
|
+
(d) => normalizeKapetaUri(d.definition.metadata.name + ':' + d.version) === normalizeKapetaUri(ref)
|
79
|
+
)
|
80
|
+
)
|
81
|
+
.filter((d) => d !== undefined)
|
82
|
+
.map((d) => applyHandleChange(d!, profile.handle));
|
83
|
+
|
84
|
+
// Persist the rewritten assets
|
85
|
+
const progressListener = new ProgressListener();
|
86
|
+
const rewrittenAssets = [samplePlan, ...rewrittenBlocks];
|
87
|
+
const originalRefs = [`${SAMPLE_PLAN_NAME}:local`, ...Array.from(blockRefs)];
|
88
|
+
|
89
|
+
// Store the original paths on the assets - we'll need them later
|
90
|
+
for (const asset of rewrittenAssets) {
|
91
|
+
asset.path = await FS.readlink(asset.path);
|
92
|
+
asset.ymlPath = Path.join(asset.path, Path.basename(asset.ymlPath));
|
93
|
+
}
|
94
|
+
|
95
|
+
// Uninstall the original assets
|
96
|
+
// This removes the symlinks
|
97
|
+
console.log('Uninstalling original assets', originalRefs);
|
98
|
+
try {
|
99
|
+
await Actions.uninstall(progressListener, originalRefs);
|
100
|
+
} catch (err) {
|
101
|
+
console.warn('Failed to uninstall original assets', err);
|
12
102
|
}
|
13
|
-
|
103
|
+
|
104
|
+
for (const asset of rewrittenAssets) {
|
105
|
+
console.log('Updating %s ', asset.ymlPath);
|
106
|
+
await FS.writeFile(asset.ymlPath, YAML.stringify(asset.definition));
|
107
|
+
|
108
|
+
console.log('Linking %s ', asset.path);
|
109
|
+
await Actions.link(progressListener, asset.path);
|
110
|
+
}
|
111
|
+
|
112
|
+
console.log('Rewrite done for sample plan');
|
113
|
+
|
114
|
+
// Return the rewritten definitions
|
115
|
+
return ClusterConfiguration.getDefinitions();
|
14
116
|
}
|
15
117
|
|
16
|
-
private
|
17
|
-
|
118
|
+
private applyFilters(definitions: DefinitionInfo[], kindFilter: string[]): DefinitionInfo[] {
|
119
|
+
if (kindFilter.length === 0) {
|
120
|
+
return definitions;
|
121
|
+
}
|
122
|
+
|
123
|
+
return definitions.filter((d) => {
|
124
|
+
return kindFilter.includes(d.definition.kind.toLowerCase());
|
125
|
+
});
|
18
126
|
}
|
19
127
|
|
20
|
-
public getDefinitions(kindFilter?: string | string[]): DefinitionInfo[] {
|
21
|
-
|
128
|
+
public async getDefinitions(kindFilter?: string | string[]): Promise<DefinitionInfo[]> {
|
129
|
+
kindFilter = normalizeFilters(kindFilter);
|
130
|
+
|
131
|
+
const definitions = await doCached<Promise<DefinitionInfo[]>>('definitionsManager:all', () =>
|
132
|
+
this.resolveDefinitionsAndSamples()
|
133
|
+
);
|
22
134
|
|
23
|
-
return
|
135
|
+
return this.applyFilters(definitions, kindFilter);
|
24
136
|
}
|
25
137
|
|
26
|
-
public exists(ref: string) {
|
27
|
-
return !!this.getDefinition(ref);
|
138
|
+
public async exists(ref: string) {
|
139
|
+
return !!(await this.getDefinition(ref));
|
28
140
|
}
|
29
141
|
|
30
|
-
public getProviderDefinitions(): DefinitionInfo[] {
|
31
|
-
return doCached<DefinitionInfo[]>('providers', () =>
|
142
|
+
public async getProviderDefinitions(): Promise<DefinitionInfo[]> {
|
143
|
+
return doCached<DefinitionInfo[]>('definitionsManager:providers', () =>
|
144
|
+
ClusterConfiguration.getProviderDefinitions()
|
145
|
+
);
|
32
146
|
}
|
33
147
|
|
34
|
-
public getDefinition(ref: string) {
|
148
|
+
public async getDefinition(ref: string) {
|
35
149
|
const uri = parseKapetaUri(ref);
|
36
|
-
|
150
|
+
const definitions = await this.getDefinitions();
|
151
|
+
return definitions.find((d) => {
|
37
152
|
if (!uri.version) {
|
38
153
|
return d.definition.metadata.name === uri.fullName;
|
39
154
|
}
|
package/src/instanceManager.ts
CHANGED
@@ -22,7 +22,7 @@ const DEFAULT_HEALTH_PORT_TYPE = 'rest';
|
|
22
22
|
const MIN_TIME_RUNNING = 30000; //If something didnt run for more than 30 secs - it failed
|
23
23
|
|
24
24
|
export class InstanceManager {
|
25
|
-
private _interval:
|
25
|
+
private _interval: any = undefined;
|
26
26
|
|
27
27
|
private readonly _instances: InstanceInfo[] = [];
|
28
28
|
|
@@ -54,14 +54,14 @@ export class InstanceManager {
|
|
54
54
|
return [...this._instances];
|
55
55
|
}
|
56
56
|
|
57
|
-
public getInstancesForPlan(systemId: string) {
|
57
|
+
public async getInstancesForPlan(systemId: string) {
|
58
58
|
if (!this._instances) {
|
59
59
|
return [];
|
60
60
|
}
|
61
61
|
|
62
62
|
systemId = normalizeKapetaUri(systemId);
|
63
63
|
|
64
|
-
const planInfo = definitionsManager.getDefinition(systemId);
|
64
|
+
const planInfo = await definitionsManager.getDefinition(systemId);
|
65
65
|
|
66
66
|
if (!planInfo) {
|
67
67
|
return [];
|
@@ -458,9 +458,9 @@ export class InstanceManager {
|
|
458
458
|
|
459
459
|
const blockSpec = blockAsset.data.spec as BlockDefinitionSpec;
|
460
460
|
if (blockSpec.consumers) {
|
461
|
-
const promises = blockSpec.consumers.map((consumer) => {
|
461
|
+
const promises = blockSpec.consumers.map(async (consumer) => {
|
462
462
|
const consumerUri = parseKapetaUri(consumer.kind);
|
463
|
-
const asset = definitionsManager.getDefinition(consumer.kind);
|
463
|
+
const asset = await definitionsManager.getDefinition(consumer.kind);
|
464
464
|
if (!asset) {
|
465
465
|
// Definition not found
|
466
466
|
return Promise.resolve();
|
package/src/instances/routes.ts
CHANGED
@@ -21,8 +21,8 @@ router.get('/', (req: Request, res: Response) => {
|
|
21
21
|
/**
|
22
22
|
* Get all instances
|
23
23
|
*/
|
24
|
-
router.get('/:systemId/instances', (req: Request, res: Response) => {
|
25
|
-
res.send(instanceManager.getInstancesForPlan(req.params.systemId));
|
24
|
+
router.get('/:systemId/instances', async (req: Request, res: Response) => {
|
25
|
+
res.send(await instanceManager.getInstancesForPlan(req.params.systemId));
|
26
26
|
});
|
27
27
|
|
28
28
|
/**
|
package/src/operatorManager.ts
CHANGED
@@ -15,6 +15,7 @@ import AsyncLock from 'async-lock';
|
|
15
15
|
import { taskManager } from './taskManager';
|
16
16
|
|
17
17
|
export const KIND_OPERATOR = 'core/resource-type-operator';
|
18
|
+
const KIND_PLAN = 'core/plan';
|
18
19
|
|
19
20
|
class Operator {
|
20
21
|
private readonly _data: DefinitionInfo;
|
@@ -57,8 +58,8 @@ class OperatorManager {
|
|
57
58
|
* @param {string} version
|
58
59
|
* @return {Operator}
|
59
60
|
*/
|
60
|
-
getOperator(resourceType: string, version: string) {
|
61
|
-
const operators = definitionsManager.getDefinitions(KIND_OPERATOR);
|
61
|
+
async getOperator(resourceType: string, version: string) {
|
62
|
+
const operators = await definitionsManager.getDefinitions(KIND_OPERATOR);
|
62
63
|
|
63
64
|
const operator: DefinitionInfo | undefined = operators.find(
|
64
65
|
(operator) =>
|
@@ -92,7 +93,7 @@ class OperatorManager {
|
|
92
93
|
environment?: EnvironmentType
|
93
94
|
): Promise<OperatorInfo> {
|
94
95
|
systemId = normalizeKapetaUri(systemId);
|
95
|
-
const plans = definitionsManager.getDefinitions(
|
96
|
+
const plans = await definitionsManager.getDefinitions(KIND_PLAN);
|
96
97
|
|
97
98
|
const planUri = parseKapetaUri(systemId);
|
98
99
|
const currentPlan = plans.find(
|
@@ -109,13 +110,7 @@ class OperatorManager {
|
|
109
110
|
throw new Error(`Unknown instance: ${fromServiceId} in plan ${systemId}`);
|
110
111
|
}
|
111
112
|
|
112
|
-
const
|
113
|
-
const blockDefinition = definitionsManager
|
114
|
-
.getDefinitions()
|
115
|
-
.find(
|
116
|
-
(definition) =>
|
117
|
-
definition.version === blockUri.version && definition.definition.metadata.name === blockUri.fullName
|
118
|
-
);
|
113
|
+
const blockDefinition = await definitionsManager.getDefinition(currentInstance.block.ref);
|
119
114
|
|
120
115
|
if (!blockDefinition) {
|
121
116
|
throw new Error(`Unknown block: ${currentInstance.block.ref} in plan ${systemId}`);
|
@@ -129,7 +124,7 @@ class OperatorManager {
|
|
129
124
|
}
|
130
125
|
|
131
126
|
const kindUri = parseKapetaUri(blockResource.kind);
|
132
|
-
const operator = this.getOperator(resourceType, kindUri.version);
|
127
|
+
const operator = await this.getOperator(resourceType, kindUri.version);
|
133
128
|
const credentials = operator.getCredentials();
|
134
129
|
const container = await this.ensureResource(systemId, resourceType, kindUri.version);
|
135
130
|
const portInfo = await container.getPort(portType);
|
@@ -164,7 +159,7 @@ class OperatorManager {
|
|
164
159
|
systemId = normalizeKapetaUri(systemId);
|
165
160
|
const key = `${systemId}#${resourceType}:${version}`;
|
166
161
|
return await this.operatorLock.acquire(key, async () => {
|
167
|
-
const operator = this.getOperator(resourceType, version);
|
162
|
+
const operator = await this.getOperator(resourceType, version);
|
168
163
|
|
169
164
|
const operatorData = operator.getLocalData();
|
170
165
|
|
package/src/providerManager.ts
CHANGED
@@ -3,12 +3,14 @@ import FSExtra from 'fs-extra';
|
|
3
3
|
import { definitionsManager } from './definitionsManager';
|
4
4
|
import { cacheManager } from './cacheManager';
|
5
5
|
import request from 'request';
|
6
|
+
import { DefinitionInfo } from '@kapeta/local-cluster-config';
|
6
7
|
|
7
8
|
const PROVIDER_FILE_BASE = 'https://providers.kapeta.com/files';
|
8
9
|
|
9
10
|
class ProviderManager {
|
10
|
-
getWebProviders() {
|
11
|
-
|
11
|
+
async getWebProviders(): Promise<DefinitionInfo[]> {
|
12
|
+
const providers = await definitionsManager.getProviderDefinitions();
|
13
|
+
return providers.filter((providerDefinition) => providerDefinition.hasWeb);
|
12
14
|
}
|
13
15
|
|
14
16
|
async getProviderWebJS(handle: string, name: string, version: string, sourceMap: boolean = false) {
|
@@ -22,7 +24,8 @@ class ProviderManager {
|
|
22
24
|
return FSExtra.readFile(file, 'utf8');
|
23
25
|
}
|
24
26
|
|
25
|
-
const
|
27
|
+
const providers = await this.getWebProviders();
|
28
|
+
const installedProvider = providers.find((providerDefinition) => {
|
26
29
|
return providerDefinition.definition.metadata.name === fullName && providerDefinition.version === version;
|
27
30
|
});
|
28
31
|
|
@@ -63,22 +66,27 @@ class ProviderManager {
|
|
63
66
|
}
|
64
67
|
}
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
69
|
+
definitionsManager
|
70
|
+
.getProviderDefinitions()
|
71
|
+
.then((providerDefinitions) => {
|
72
|
+
if (providerDefinitions.length > 0) {
|
73
|
+
console.log('## Loaded the following providers ##');
|
74
|
+
providerDefinitions.forEach((providerDefinition) => {
|
75
|
+
console.log(
|
76
|
+
' - %s[%s:%s]',
|
77
|
+
providerDefinition.definition.kind,
|
78
|
+
providerDefinition.definition.metadata.name,
|
79
|
+
providerDefinition.version
|
80
|
+
);
|
81
|
+
console.log(' from %s', providerDefinition.path);
|
82
|
+
});
|
83
|
+
console.log('##');
|
84
|
+
} else {
|
85
|
+
console.log('## No providers found ##');
|
86
|
+
}
|
87
|
+
})
|
88
|
+
.catch((e) => {
|
89
|
+
console.error('Failed to load providers', e);
|
78
90
|
});
|
79
|
-
console.log('##');
|
80
|
-
} else {
|
81
|
-
console.log('## No providers found ##');
|
82
|
-
}
|
83
91
|
|
84
92
|
export const providerManager = new ProviderManager();
|