@kapeta/local-cluster-service 0.19.7 → 0.20.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 CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.20.0](https://github.com/kapetacom/local-cluster-service/compare/v0.19.7...v0.20.0) (2023-09-10)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add support for block instance default configuration ([#73](https://github.com/kapetacom/local-cluster-service/issues/73)) ([7ea0f94](https://github.com/kapetacom/local-cluster-service/commit/7ea0f94a3167f14453e6c45aab7501181bff7398))
7
+
1
8
  ## [0.19.7](https://github.com/kapetacom/local-cluster-service/compare/v0.19.6...v0.19.7) (2023-09-10)
2
9
 
3
10
 
@@ -12,7 +12,6 @@ const cors_1 = require("../middleware/cors");
12
12
  const kapeta_1 = require("../middleware/kapeta");
13
13
  const stringBody_1 = require("../middleware/stringBody");
14
14
  const router = (0, express_promise_router_1.default)();
15
- const SYSTEM_ID = '$plan';
16
15
  router.use('/', cors_1.corsHandler);
17
16
  router.use('/', kapeta_1.kapetaHeaders);
18
17
  router.use('/', stringBody_1.stringBody);
@@ -54,7 +53,7 @@ router.put('/instance', async (req, res) => {
54
53
  * Returns the full configuration for a plan
55
54
  */
56
55
  router.get('/system', (req, res) => {
57
- const config = configManager_1.configManager.getConfigForSection(req.kapeta.systemId, SYSTEM_ID);
56
+ const config = configManager_1.configManager.getConfigForSection(req.kapeta.systemId, configManager_1.SYSTEM_ID);
58
57
  res.send(config);
59
58
  });
60
59
  /**
@@ -65,7 +64,7 @@ router.put('/system', (req, res) => {
65
64
  if (!config) {
66
65
  config = {};
67
66
  }
68
- configManager_1.configManager.setConfigForSection(req.kapeta.systemId, SYSTEM_ID, config);
67
+ configManager_1.configManager.setConfigForSection(req.kapeta.systemId, configManager_1.SYSTEM_ID, config);
69
68
  res.status(202).send({ ok: true });
70
69
  });
71
70
  /**
@@ -1,3 +1,4 @@
1
+ export declare const SYSTEM_ID = "$plan";
1
2
  type AnyMap = {
2
3
  [key: string]: any;
3
4
  };
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configManager = void 0;
3
+ exports.configManager = exports.SYSTEM_ID = void 0;
4
4
  const storageService_1 = require("./storageService");
5
5
  const assetManager_1 = require("./assetManager");
6
6
  const nodejs_utils_1 = require("@kapeta/nodejs-utils");
7
7
  const utils_1 = require("./utils/utils");
8
+ exports.SYSTEM_ID = '$plan';
8
9
  class ConfigManager {
9
10
  _config;
10
11
  constructor() {
@@ -390,11 +390,12 @@ class InstanceManager {
390
390
  }
391
391
  }
392
392
  const instanceConfig = await configManager_1.configManager.getConfigForSection(systemId, instanceId);
393
+ const resolvedConfig = (0, utils_1.getResolvedConfiguration)(blockSpec.configuration, instanceConfig, blockInstance.defaultConfiguration);
393
394
  const task = taskManager_1.taskManager.add(`instance:start:${systemId}:${instanceId}`, async () => {
394
395
  const runner = new BlockInstanceRunner_1.BlockInstanceRunner(systemId);
395
396
  const startTime = Date.now();
396
397
  try {
397
- const processInfo = await runner.start(blockRef, instanceId, instanceConfig);
398
+ const processInfo = await runner.start(blockRef, instanceId, resolvedConfig);
398
399
  instance.status = types_1.InstanceStatus.STARTING;
399
400
  return this.saveInternalInstance({
400
401
  ...instance,
@@ -1,3 +1,5 @@
1
+ import { EntityList } from '@kapeta/schemas';
2
+ import { AnyMap } from '../types';
1
3
  export declare function getBlockInstanceContainerName(systemId: string, instanceId: string): string;
2
4
  export declare function normalizeKapetaUri(uri: string): string;
3
5
  export declare function readYML(path: string): any;
@@ -5,3 +7,4 @@ export declare function isWindows(): boolean;
5
7
  export declare function isMac(): boolean;
6
8
  export declare function isLinux(): boolean;
7
9
  export declare function getBindHost(preferredHost?: string): string;
10
+ export declare function getResolvedConfiguration(entities?: EntityList, config?: AnyMap, globalConfiguration?: AnyMap): AnyMap;
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.normalizeKapetaUri = exports.getBlockInstanceContainerName = void 0;
6
+ exports.getResolvedConfiguration = exports.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.normalizeKapetaUri = exports.getBlockInstanceContainerName = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const yaml_1 = __importDefault(require("yaml"));
9
9
  const nodejs_utils_1 = require("@kapeta/nodejs-utils");
10
10
  const md5_1 = __importDefault(require("md5"));
11
+ const lodash_1 = __importDefault(require("lodash"));
11
12
  function getBlockInstanceContainerName(systemId, instanceId) {
12
13
  return `kapeta-block-instance-${(0, md5_1.default)(systemId + instanceId)}`;
13
14
  }
@@ -51,3 +52,26 @@ function getBindHost(preferredHost = '127.0.0.1') {
51
52
  return isLinux() ? '0.0.0.0' : preferredHost;
52
53
  }
53
54
  exports.getBindHost = getBindHost;
55
+ function getResolvedConfiguration(entities, config, globalConfiguration) {
56
+ if (!entities || !globalConfiguration) {
57
+ return config || {};
58
+ }
59
+ const mergedConfig = config ? lodash_1.default.cloneDeep(config) : {};
60
+ entities.types?.forEach((type) => {
61
+ if (!type.properties) {
62
+ return;
63
+ }
64
+ Object.entries(type.properties).forEach(([propertyName, property]) => {
65
+ if (!property.global) {
66
+ return;
67
+ }
68
+ const configPath = type.name + '.' + propertyName;
69
+ const defaultValue = globalConfiguration ? lodash_1.default.get(globalConfiguration, configPath) : undefined;
70
+ if (!lodash_1.default.has(mergedConfig, configPath)) {
71
+ lodash_1.default.set(mergedConfig, configPath, defaultValue);
72
+ }
73
+ });
74
+ });
75
+ return mergedConfig;
76
+ }
77
+ exports.getResolvedConfiguration = getResolvedConfiguration;
@@ -12,7 +12,6 @@ const cors_1 = require("../middleware/cors");
12
12
  const kapeta_1 = require("../middleware/kapeta");
13
13
  const stringBody_1 = require("../middleware/stringBody");
14
14
  const router = (0, express_promise_router_1.default)();
15
- const SYSTEM_ID = '$plan';
16
15
  router.use('/', cors_1.corsHandler);
17
16
  router.use('/', kapeta_1.kapetaHeaders);
18
17
  router.use('/', stringBody_1.stringBody);
@@ -54,7 +53,7 @@ router.put('/instance', async (req, res) => {
54
53
  * Returns the full configuration for a plan
55
54
  */
56
55
  router.get('/system', (req, res) => {
57
- const config = configManager_1.configManager.getConfigForSection(req.kapeta.systemId, SYSTEM_ID);
56
+ const config = configManager_1.configManager.getConfigForSection(req.kapeta.systemId, configManager_1.SYSTEM_ID);
58
57
  res.send(config);
59
58
  });
60
59
  /**
@@ -65,7 +64,7 @@ router.put('/system', (req, res) => {
65
64
  if (!config) {
66
65
  config = {};
67
66
  }
68
- configManager_1.configManager.setConfigForSection(req.kapeta.systemId, SYSTEM_ID, config);
67
+ configManager_1.configManager.setConfigForSection(req.kapeta.systemId, configManager_1.SYSTEM_ID, config);
69
68
  res.status(202).send({ ok: true });
70
69
  });
71
70
  /**
@@ -1,3 +1,4 @@
1
+ export declare const SYSTEM_ID = "$plan";
1
2
  type AnyMap = {
2
3
  [key: string]: any;
3
4
  };
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configManager = void 0;
3
+ exports.configManager = exports.SYSTEM_ID = void 0;
4
4
  const storageService_1 = require("./storageService");
5
5
  const assetManager_1 = require("./assetManager");
6
6
  const nodejs_utils_1 = require("@kapeta/nodejs-utils");
7
7
  const utils_1 = require("./utils/utils");
8
+ exports.SYSTEM_ID = '$plan';
8
9
  class ConfigManager {
9
10
  _config;
10
11
  constructor() {
@@ -390,11 +390,12 @@ class InstanceManager {
390
390
  }
391
391
  }
392
392
  const instanceConfig = await configManager_1.configManager.getConfigForSection(systemId, instanceId);
393
+ const resolvedConfig = (0, utils_1.getResolvedConfiguration)(blockSpec.configuration, instanceConfig, blockInstance.defaultConfiguration);
393
394
  const task = taskManager_1.taskManager.add(`instance:start:${systemId}:${instanceId}`, async () => {
394
395
  const runner = new BlockInstanceRunner_1.BlockInstanceRunner(systemId);
395
396
  const startTime = Date.now();
396
397
  try {
397
- const processInfo = await runner.start(blockRef, instanceId, instanceConfig);
398
+ const processInfo = await runner.start(blockRef, instanceId, resolvedConfig);
398
399
  instance.status = types_1.InstanceStatus.STARTING;
399
400
  return this.saveInternalInstance({
400
401
  ...instance,
@@ -1,3 +1,5 @@
1
+ import { EntityList } from '@kapeta/schemas';
2
+ import { AnyMap } from '../types';
1
3
  export declare function getBlockInstanceContainerName(systemId: string, instanceId: string): string;
2
4
  export declare function normalizeKapetaUri(uri: string): string;
3
5
  export declare function readYML(path: string): any;
@@ -5,3 +7,4 @@ export declare function isWindows(): boolean;
5
7
  export declare function isMac(): boolean;
6
8
  export declare function isLinux(): boolean;
7
9
  export declare function getBindHost(preferredHost?: string): string;
10
+ export declare function getResolvedConfiguration(entities?: EntityList, config?: AnyMap, globalConfiguration?: AnyMap): AnyMap;
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.normalizeKapetaUri = exports.getBlockInstanceContainerName = void 0;
6
+ exports.getResolvedConfiguration = exports.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.normalizeKapetaUri = exports.getBlockInstanceContainerName = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const yaml_1 = __importDefault(require("yaml"));
9
9
  const nodejs_utils_1 = require("@kapeta/nodejs-utils");
10
10
  const md5_1 = __importDefault(require("md5"));
11
+ const lodash_1 = __importDefault(require("lodash"));
11
12
  function getBlockInstanceContainerName(systemId, instanceId) {
12
13
  return `kapeta-block-instance-${(0, md5_1.default)(systemId + instanceId)}`;
13
14
  }
@@ -51,3 +52,26 @@ function getBindHost(preferredHost = '127.0.0.1') {
51
52
  return isLinux() ? '0.0.0.0' : preferredHost;
52
53
  }
53
54
  exports.getBindHost = getBindHost;
55
+ function getResolvedConfiguration(entities, config, globalConfiguration) {
56
+ if (!entities || !globalConfiguration) {
57
+ return config || {};
58
+ }
59
+ const mergedConfig = config ? lodash_1.default.cloneDeep(config) : {};
60
+ entities.types?.forEach((type) => {
61
+ if (!type.properties) {
62
+ return;
63
+ }
64
+ Object.entries(type.properties).forEach(([propertyName, property]) => {
65
+ if (!property.global) {
66
+ return;
67
+ }
68
+ const configPath = type.name + '.' + propertyName;
69
+ const defaultValue = globalConfiguration ? lodash_1.default.get(globalConfiguration, configPath) : undefined;
70
+ if (!lodash_1.default.has(mergedConfig, configPath)) {
71
+ lodash_1.default.set(mergedConfig, configPath, defaultValue);
72
+ }
73
+ });
74
+ });
75
+ return mergedConfig;
76
+ }
77
+ exports.getResolvedConfiguration = getResolvedConfiguration;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.19.7",
3
+ "version": "0.20.0",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -1,17 +1,15 @@
1
1
  import Router from 'express-promise-router';
2
- import { configManager } from '../configManager';
2
+ import { configManager, SYSTEM_ID } from '../configManager';
3
3
  import { serviceManager } from '../serviceManager';
4
4
  import { operatorManager } from '../operatorManager';
5
5
  import { instanceManager } from '../instanceManager';
6
- import { StringBodyRequest } from '../middleware/stringBody';
7
6
  import { corsHandler } from '../middleware/cors';
8
7
  import { kapetaHeaders, KapetaRequest } from '../middleware/kapeta';
9
8
  import { stringBody } from '../middleware/stringBody';
10
- import { EnvironmentType, KapetaBodyRequest } from '../types';
9
+ import { KapetaBodyRequest } from '../types';
11
10
  import { Response } from 'express';
12
11
 
13
12
  const router = Router();
14
- const SYSTEM_ID = '$plan';
15
13
 
16
14
  router.use('/', corsHandler);
17
15
  router.use('/', kapetaHeaders);
@@ -5,6 +5,7 @@ import { assetManager } from './assetManager';
5
5
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
6
6
  import { normalizeKapetaUri } from './utils/utils';
7
7
 
8
+ export const SYSTEM_ID = '$plan';
8
9
  type AnyMap = { [key: string]: any };
9
10
 
10
11
  interface MatchedIdentity {
@@ -15,7 +15,7 @@ import {
15
15
  import { configManager } from './configManager';
16
16
  import { DesiredInstanceStatus, InstanceInfo, InstanceOwner, InstanceStatus, InstanceType, LogEntry } from './types';
17
17
  import { BlockDefinitionSpec, BlockInstance, Plan } from '@kapeta/schemas';
18
- import { getBlockInstanceContainerName, normalizeKapetaUri } from './utils/utils';
18
+ import { getBlockInstanceContainerName, getResolvedConfiguration, normalizeKapetaUri } from './utils/utils';
19
19
  import { KIND_OPERATOR, operatorManager } from './operatorManager';
20
20
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
21
21
  import { definitionsManager } from './definitionsManager';
@@ -497,13 +497,18 @@ export class InstanceManager {
497
497
  }
498
498
 
499
499
  const instanceConfig = await configManager.getConfigForSection(systemId, instanceId);
500
+ const resolvedConfig = getResolvedConfiguration(
501
+ blockSpec.configuration,
502
+ instanceConfig,
503
+ blockInstance.defaultConfiguration
504
+ );
500
505
  const task = taskManager.add(
501
506
  `instance:start:${systemId}:${instanceId}`,
502
507
  async () => {
503
508
  const runner = new BlockInstanceRunner(systemId);
504
509
  const startTime = Date.now();
505
510
  try {
506
- const processInfo = await runner.start(blockRef, instanceId, instanceConfig);
511
+ const processInfo = await runner.start(blockRef, instanceId, resolvedConfig);
507
512
 
508
513
  instance.status = InstanceStatus.STARTING;
509
514
 
@@ -2,6 +2,9 @@ import FS from 'node:fs';
2
2
  import YAML from 'yaml';
3
3
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
4
4
  import md5 from 'md5';
5
+ import { EntityList } from '@kapeta/schemas';
6
+ import _ from 'lodash';
7
+ import { AnyMap } from '../types';
5
8
 
6
9
  export function getBlockInstanceContainerName(systemId: string, instanceId: string) {
7
10
  return `kapeta-block-instance-${md5(systemId + instanceId)}`;
@@ -47,3 +50,29 @@ export function getBindHost(preferredHost = '127.0.0.1') {
47
50
  // TODO: This might pose a security risk - so we should authenticate all requests using a shared secret/nonce that we pass around.
48
51
  return isLinux() ? '0.0.0.0' : preferredHost;
49
52
  }
53
+
54
+ export function getResolvedConfiguration(entities?: EntityList, config?: AnyMap, globalConfiguration?: AnyMap): AnyMap {
55
+ if (!entities || !globalConfiguration) {
56
+ return config || {};
57
+ }
58
+
59
+ const mergedConfig = config ? _.cloneDeep(config) : {};
60
+ entities.types?.forEach((type) => {
61
+ if (!type.properties) {
62
+ return;
63
+ }
64
+ Object.entries(type.properties).forEach(([propertyName, property]) => {
65
+ if (!property.global) {
66
+ return;
67
+ }
68
+
69
+ const configPath = type.name + '.' + propertyName;
70
+ const defaultValue = globalConfiguration ? _.get(globalConfiguration, configPath) : undefined;
71
+ if (!_.has(mergedConfig, configPath)) {
72
+ _.set(mergedConfig, configPath, defaultValue);
73
+ }
74
+ });
75
+ });
76
+
77
+ return mergedConfig;
78
+ }