@kapeta/local-cluster-service 0.38.0 → 0.39.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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/src/config/routes.js +2 -2
- package/dist/cjs/src/containerManager.js +5 -3
- package/dist/cjs/src/instanceManager.d.ts +4 -2
- package/dist/cjs/src/instanceManager.js +60 -28
- package/dist/cjs/src/operatorManager.d.ts +4 -2
- package/dist/cjs/src/operatorManager.js +32 -23
- package/dist/cjs/src/serviceManager.d.ts +0 -1
- package/dist/cjs/src/serviceManager.js +2 -8
- package/dist/cjs/src/types.d.ts +1 -29
- package/dist/cjs/src/types.js +2 -1
- package/dist/cjs/src/utils/BlockInstanceRunner.js +30 -30
- package/dist/cjs/src/utils/InternalConfigProvider.d.ts +38 -0
- package/dist/cjs/src/utils/InternalConfigProvider.js +146 -0
- package/dist/cjs/src/utils/utils.d.ts +25 -3
- package/dist/cjs/src/utils/utils.js +46 -7
- package/dist/esm/index.js +4 -1
- package/dist/esm/src/config/routes.js +2 -2
- package/dist/esm/src/containerManager.js +5 -3
- package/dist/esm/src/instanceManager.d.ts +4 -2
- package/dist/esm/src/instanceManager.js +60 -28
- package/dist/esm/src/operatorManager.d.ts +4 -2
- package/dist/esm/src/operatorManager.js +32 -23
- package/dist/esm/src/serviceManager.d.ts +0 -1
- package/dist/esm/src/serviceManager.js +2 -8
- package/dist/esm/src/types.d.ts +1 -29
- package/dist/esm/src/types.js +2 -1
- package/dist/esm/src/utils/BlockInstanceRunner.js +30 -30
- package/dist/esm/src/utils/InternalConfigProvider.d.ts +38 -0
- package/dist/esm/src/utils/InternalConfigProvider.js +146 -0
- package/dist/esm/src/utils/utils.d.ts +25 -3
- package/dist/esm/src/utils/utils.js +46 -7
- package/index.ts +5 -2
- package/package.json +6 -6
- package/src/config/routes.ts +4 -2
- package/src/containerManager.ts +6 -4
- package/src/instanceManager.ts +74 -38
- package/src/operatorManager.ts +46 -37
- package/src/serviceManager.ts +3 -11
- package/src/types.ts +2 -31
- package/src/utils/BlockInstanceRunner.ts +48 -38
- package/src/utils/InternalConfigProvider.ts +214 -0
- package/src/utils/utils.ts +51 -8
@@ -68,7 +68,7 @@ class OperatorManager {
|
|
68
68
|
/**
|
69
69
|
* Get information about a specific consumed resource
|
70
70
|
*/
|
71
|
-
async getConsumerResourceInfo(systemId, fromServiceId, resourceType, portType, name, environment) {
|
71
|
+
async getConsumerResourceInfo(systemId, fromServiceId, resourceType, portType, name, environment, ensureContainer = true) {
|
72
72
|
systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
|
73
73
|
const plans = await definitionsManager_1.definitionsManager.getDefinitions(KIND_PLAN);
|
74
74
|
const planUri = (0, nodejs_utils_1.parseKapetaUri)(systemId);
|
@@ -96,18 +96,20 @@ class OperatorManager {
|
|
96
96
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(blockResource.kind);
|
97
97
|
const operator = await this.getOperator(resourceType, kindUri.version);
|
98
98
|
const credentials = operator.getCredentials();
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
if (ensureContainer) {
|
100
|
+
await this.ensureOperator(systemId, resourceType, kindUri.version);
|
101
|
+
}
|
102
|
+
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, resourceType, portType);
|
103
|
+
if (!hostPort) {
|
102
104
|
throw new Error('Unknown resource port type : ' + resourceType + '#' + portType);
|
103
105
|
}
|
104
106
|
const dbName = name + '_' + fromServiceId.replace(/[^a-z0-9]/gi, '');
|
105
107
|
const safeName = dbName.replace('_', '-');
|
106
108
|
return {
|
107
|
-
host:
|
108
|
-
port:
|
109
|
+
host: (0, utils_1.getRemoteHostForEnvironment)(environment),
|
110
|
+
port: hostPort,
|
109
111
|
type: portType,
|
110
|
-
protocol:
|
112
|
+
protocol: 'tcp',
|
111
113
|
options: {
|
112
114
|
// expose as fullName since that is not operator specific, but unique
|
113
115
|
fullName: safeName,
|
@@ -116,6 +118,26 @@ class OperatorManager {
|
|
116
118
|
credentials,
|
117
119
|
};
|
118
120
|
}
|
121
|
+
async getOperatorPorts(systemId, kind, version) {
|
122
|
+
const operator = await this.getOperator(kind, version);
|
123
|
+
const operatorData = operator.getLocalData();
|
124
|
+
const portTypes = Object.keys(operatorData.ports);
|
125
|
+
portTypes.sort();
|
126
|
+
const ports = {};
|
127
|
+
for (let i = 0; i < portTypes.length; i++) {
|
128
|
+
const portType = portTypes[i];
|
129
|
+
let containerPortInfo = operatorData.ports[portType];
|
130
|
+
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, kind, portType);
|
131
|
+
const portInfo = (0, utils_1.toPortInfo)(containerPortInfo);
|
132
|
+
const portId = portInfo.port + '/' + portInfo.type;
|
133
|
+
ports[portId] = {
|
134
|
+
type: portType,
|
135
|
+
hostPort,
|
136
|
+
protocol: portInfo.type,
|
137
|
+
};
|
138
|
+
}
|
139
|
+
return ports;
|
140
|
+
}
|
119
141
|
/**
|
120
142
|
* Ensure we have a running operator of given type
|
121
143
|
*
|
@@ -129,20 +151,7 @@ class OperatorManager {
|
|
129
151
|
return await this.operatorLock.acquire(key, async () => {
|
130
152
|
const operator = await this.getOperator(kind, version);
|
131
153
|
const operatorData = operator.getLocalData();
|
132
|
-
const
|
133
|
-
portTypes.sort();
|
134
|
-
const ports = {};
|
135
|
-
for (let i = 0; i < portTypes.length; i++) {
|
136
|
-
const portType = portTypes[i];
|
137
|
-
let containerPortInfo = operatorData.ports[portType];
|
138
|
-
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, kind, portType);
|
139
|
-
const portInfo = (0, utils_1.toPortInfo)(containerPortInfo);
|
140
|
-
const portId = portInfo.port + '/' + portInfo.type;
|
141
|
-
ports[portId] = {
|
142
|
-
type: portType,
|
143
|
-
hostPort,
|
144
|
-
};
|
145
|
-
}
|
154
|
+
const ports = await this.getOperatorPorts(systemId, kind, version);
|
146
155
|
const nameParts = [systemId, kind.toLowerCase(), version];
|
147
156
|
const containerName = `kapeta-resource-${(0, md5_1.default)(nameParts.join('_'))}`;
|
148
157
|
const PortBindings = {};
|
@@ -154,14 +163,14 @@ class OperatorManager {
|
|
154
163
|
[containerManager_1.COMPOSE_LABEL_SERVICE]: [kind, version].join('_').replace(/[^a-z0-9]/gi, '_'),
|
155
164
|
};
|
156
165
|
const operatorMetadata = operator.getDefinitionInfo().definition.metadata;
|
157
|
-
const
|
166
|
+
const hostIp = (0, utils_1.getDockerHostIp)();
|
158
167
|
const ExposedPorts = {};
|
159
168
|
lodash_1.default.forEach(ports, (portInfo, containerPort) => {
|
160
169
|
ExposedPorts['' + containerPort] = {};
|
161
170
|
PortBindings['' + containerPort] = [
|
162
171
|
{
|
163
172
|
HostPort: '' + portInfo.hostPort,
|
164
|
-
HostIp:
|
173
|
+
HostIp: hostIp,
|
165
174
|
},
|
166
175
|
];
|
167
176
|
Labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + portInfo.hostPort] = portInfo.type;
|
@@ -9,7 +9,6 @@ export declare const HTTP_PORTS: string[];
|
|
9
9
|
declare class ServiceManager {
|
10
10
|
private _systems;
|
11
11
|
constructor();
|
12
|
-
getLocalHost(environmentType?: EnvironmentType): string;
|
13
12
|
_forLocal(port: string | number, path?: string, environmentType?: EnvironmentType): string;
|
14
13
|
_ensureSystem(systemId: string): any;
|
15
14
|
_ensureService(systemId: string, serviceId: string): any;
|
@@ -13,6 +13,7 @@ const clusterService_1 = require("./clusterService");
|
|
13
13
|
const storageService_1 = require("./storageService");
|
14
14
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
15
15
|
const BlockInstanceRunner_1 = require("./utils/BlockInstanceRunner");
|
16
|
+
const utils_1 = require("./utils/utils");
|
16
17
|
exports.HTTP_PORT_TYPE = 'http';
|
17
18
|
exports.DEFAULT_PORT_TYPE = exports.HTTP_PORT_TYPE;
|
18
19
|
exports.HTTP_PORTS = [exports.HTTP_PORT_TYPE, 'web', 'rest'];
|
@@ -31,18 +32,11 @@ class ServiceManager {
|
|
31
32
|
});
|
32
33
|
});
|
33
34
|
}
|
34
|
-
getLocalHost(environmentType) {
|
35
|
-
if (environmentType === 'docker') {
|
36
|
-
//We're inside a docker container, so we can use this special host name to access the host machine
|
37
|
-
return 'host.docker.internal';
|
38
|
-
}
|
39
|
-
return clusterService_1.clusterService.getClusterServiceHost();
|
40
|
-
}
|
41
35
|
_forLocal(port, path, environmentType) {
|
42
36
|
if (!path) {
|
43
37
|
path = '';
|
44
38
|
}
|
45
|
-
const hostname =
|
39
|
+
const hostname = (0, utils_1.getRemoteHostForEnvironment)(environmentType);
|
46
40
|
if (path.startsWith('/')) {
|
47
41
|
path = path.substring(1);
|
48
42
|
}
|
package/dist/esm/src/types.d.ts
CHANGED
@@ -21,6 +21,7 @@ export type WatchEventName = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir
|
|
21
21
|
export type LogLevel = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE' | 'FATAL';
|
22
22
|
export type LogSource = 'stdout' | 'stderr';
|
23
23
|
export type EnvironmentType = 'docker' | 'process';
|
24
|
+
export declare const DOCKER_HOST_INTERNAL = "host.docker.internal";
|
24
25
|
export interface LogEntry {
|
25
26
|
source: LogSource;
|
26
27
|
level: LogLevel;
|
@@ -60,12 +61,6 @@ export type ProcessInfo = {
|
|
60
61
|
pid?: number | string | null;
|
61
62
|
portType?: string;
|
62
63
|
};
|
63
|
-
export interface Health {
|
64
|
-
cmd: string;
|
65
|
-
interval?: number;
|
66
|
-
timeout?: number;
|
67
|
-
retries?: number;
|
68
|
-
}
|
69
64
|
export type InstanceInfo = {
|
70
65
|
systemId: string;
|
71
66
|
instanceId: string;
|
@@ -83,29 +78,6 @@ export type InstanceInfo = {
|
|
83
78
|
portType?: string;
|
84
79
|
};
|
85
80
|
export type ProxyRequestHandler = (req: StringBodyRequest, res: express.Response, info: ProxyRequestInfo) => void;
|
86
|
-
export interface OperatorInstancePort {
|
87
|
-
protocol: string;
|
88
|
-
port: number;
|
89
|
-
}
|
90
|
-
export interface OperatorInstanceInfo {
|
91
|
-
hostname: string;
|
92
|
-
ports: {
|
93
|
-
[portType: string]: OperatorInstancePort;
|
94
|
-
};
|
95
|
-
path?: string;
|
96
|
-
query?: string;
|
97
|
-
hash?: string;
|
98
|
-
options?: AnyMap;
|
99
|
-
credentials?: AnyMap;
|
100
|
-
}
|
101
|
-
export interface OperatorInfo {
|
102
|
-
host: string;
|
103
|
-
port: string;
|
104
|
-
type: string;
|
105
|
-
protocol: string;
|
106
|
-
options: AnyMap;
|
107
|
-
credentials: AnyMap;
|
108
|
-
}
|
109
81
|
export interface ProxyRequestInfo {
|
110
82
|
address: string;
|
111
83
|
connection: Connection;
|
package/dist/esm/src/types.js
CHANGED
@@ -4,11 +4,12 @@
|
|
4
4
|
* SPDX-License-Identifier: BUSL-1.1
|
5
5
|
*/
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
-
exports.DesiredInstanceStatus = exports.InstanceStatus = exports.InstanceOwner = exports.InstanceType = exports.KIND_BLOCK_TYPE_EXECUTABLE = exports.KIND_BLOCK_TYPE_OPERATOR = exports.KIND_BLOCK_TYPE = exports.KIND_RESOURCE_OPERATOR = void 0;
|
7
|
+
exports.DesiredInstanceStatus = exports.InstanceStatus = exports.InstanceOwner = exports.InstanceType = exports.DOCKER_HOST_INTERNAL = exports.KIND_BLOCK_TYPE_EXECUTABLE = exports.KIND_BLOCK_TYPE_OPERATOR = exports.KIND_BLOCK_TYPE = exports.KIND_RESOURCE_OPERATOR = void 0;
|
8
8
|
exports.KIND_RESOURCE_OPERATOR = 'core/resource-type-operator';
|
9
9
|
exports.KIND_BLOCK_TYPE = 'core/block-type';
|
10
10
|
exports.KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
|
11
11
|
exports.KIND_BLOCK_TYPE_EXECUTABLE = 'core/block-type-executable';
|
12
|
+
exports.DOCKER_HOST_INTERNAL = 'host.docker.internal';
|
12
13
|
var InstanceType;
|
13
14
|
(function (InstanceType) {
|
14
15
|
InstanceType["DOCKER"] = "docker";
|
@@ -21,6 +21,8 @@ const definitionsManager_1 = require("../definitionsManager");
|
|
21
21
|
const node_os_1 = __importDefault(require("node:os"));
|
22
22
|
const node_path_1 = __importDefault(require("node:path"));
|
23
23
|
const taskManager_1 = require("../taskManager");
|
24
|
+
const InternalConfigProvider_1 = require("./InternalConfigProvider");
|
25
|
+
const config_mapper_1 = require("@kapeta/config-mapper");
|
24
26
|
const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
|
25
27
|
const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
|
26
28
|
const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
|
@@ -30,7 +32,7 @@ const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
|
|
30
32
|
*/
|
31
33
|
const DOCKER_ENV_VARS = [
|
32
34
|
`KAPETA_LOCAL_SERVER=0.0.0.0`,
|
33
|
-
`KAPETA_LOCAL_CLUSTER_HOST
|
35
|
+
`KAPETA_LOCAL_CLUSTER_HOST=${types_1.DOCKER_HOST_INTERNAL}`,
|
34
36
|
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
35
37
|
];
|
36
38
|
async function getProvider(uri) {
|
@@ -91,16 +93,6 @@ class BlockInstanceRunner {
|
|
91
93
|
});
|
92
94
|
}
|
93
95
|
async _execute(blockInstance) {
|
94
|
-
const env = {};
|
95
|
-
if (this._systemId) {
|
96
|
-
env[KAPETA_SYSTEM_ID] = this._systemId;
|
97
|
-
}
|
98
|
-
if (blockInstance.ref) {
|
99
|
-
env[KAPETA_BLOCK_REF] = blockInstance.ref;
|
100
|
-
}
|
101
|
-
if (blockInstance.id) {
|
102
|
-
env[KAPETA_INSTANCE_ID] = blockInstance.id;
|
103
|
-
}
|
104
96
|
const blockUri = (0, nodejs_utils_1.parseKapetaUri)(blockInstance.ref);
|
105
97
|
if (!blockUri.version) {
|
106
98
|
blockUri.version = 'local';
|
@@ -114,18 +106,25 @@ class BlockInstanceRunner {
|
|
114
106
|
if (!providerVersion) {
|
115
107
|
throw new Error(`Kind not found: ${kindUri.id}`);
|
116
108
|
}
|
109
|
+
const baseDir = local_cluster_config_1.default.getRepositoryAssetPath(blockUri.handle, blockUri.name, blockUri.version);
|
110
|
+
const realBaseDir = await fs_extra_1.default.realpath(baseDir);
|
111
|
+
const internalConfigProvider = await (0, InternalConfigProvider_1.createInternalConfigProvider)(this._systemId, blockInstance.id, assetVersion);
|
112
|
+
// Resolve the environment variables
|
113
|
+
const envVars = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
|
114
|
+
// Write out the config templates if they exist
|
115
|
+
await (0, config_mapper_1.writeConfigTemplates)(envVars, realBaseDir);
|
117
116
|
let processInfo;
|
118
117
|
if (providerVersion.definition.kind === types_1.KIND_BLOCK_TYPE_OPERATOR) {
|
119
|
-
processInfo = await this._startOperatorProcess(blockInstance, blockUri, providerVersion,
|
118
|
+
processInfo = await this._startOperatorProcess(blockInstance, blockUri, providerVersion, envVars);
|
120
119
|
}
|
121
120
|
else {
|
122
121
|
//We need a port type to know how to connect to the block consistently
|
123
122
|
const portTypes = getServiceProviderPorts(assetVersion, providerVersion);
|
124
123
|
if (blockUri.version === 'local') {
|
125
|
-
processInfo = await this._startLocalProcess(blockInstance, blockUri,
|
124
|
+
processInfo = await this._startLocalProcess(blockInstance, blockUri, envVars, assetVersion);
|
126
125
|
}
|
127
126
|
else {
|
128
|
-
processInfo = await this._startDockerProcess(blockInstance, blockUri,
|
127
|
+
processInfo = await this._startDockerProcess(blockInstance, blockUri, envVars, assetVersion);
|
129
128
|
}
|
130
129
|
if (portTypes.length > 0) {
|
131
130
|
processInfo.portType = portTypes[0];
|
@@ -193,9 +192,13 @@ class BlockInstanceRunner {
|
|
193
192
|
if (localContainer.healthcheck) {
|
194
193
|
HealthCheck = containerManager_1.containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
|
195
194
|
}
|
196
|
-
const Mounts =
|
197
|
-
|
198
|
-
|
195
|
+
const Mounts = isDockerImage
|
196
|
+
? // For docker images we mount the local directory to the working directory
|
197
|
+
containerManager_1.containerManager.toDockerMounts({
|
198
|
+
[workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath),
|
199
|
+
})
|
200
|
+
: // For dockerfiles we don't mount anything
|
201
|
+
[];
|
199
202
|
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
200
203
|
return this.ensureContainer({
|
201
204
|
...dockerOpts,
|
@@ -310,29 +313,26 @@ class BlockInstanceRunner {
|
|
310
313
|
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, providerRef);
|
311
314
|
const task = taskManager_1.taskManager.add(`container:start:${containerName}`, async () => {
|
312
315
|
const logs = new LogData_1.LogData();
|
313
|
-
const
|
316
|
+
const hostIp = (0, utils_1.getDockerHostIp)();
|
314
317
|
const ExposedPorts = {};
|
315
318
|
const addonEnv = {};
|
316
319
|
const PortBindings = {};
|
317
320
|
let HealthCheck = undefined;
|
318
321
|
let Mounts = [];
|
319
|
-
const
|
322
|
+
const instancePorts = await (0, utils_1.getOperatorInstancePorts)(this._systemId, operatorId, local);
|
320
323
|
const labels = {};
|
321
|
-
|
322
|
-
const
|
323
|
-
const dockerPort = `${portInfo.port}/${portInfo.type}`;
|
324
|
+
instancePorts.forEach((portInfo) => {
|
325
|
+
const dockerPort = `${portInfo.port}/${portInfo.protocol}`;
|
324
326
|
ExposedPorts[dockerPort] = {};
|
325
|
-
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = `${portInfo.port}`;
|
326
|
-
const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, operatorId, portType);
|
327
|
+
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portInfo.portType.toUpperCase()}`] = `${portInfo.port}`;
|
327
328
|
PortBindings[dockerPort] = [
|
328
329
|
{
|
329
|
-
HostIp:
|
330
|
-
HostPort: `${
|
330
|
+
HostIp: hostIp,
|
331
|
+
HostPort: `${portInfo.hostPort}`,
|
331
332
|
},
|
332
333
|
];
|
333
|
-
labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX +
|
334
|
+
labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + portInfo.hostPort] = portInfo.portType;
|
334
335
|
});
|
335
|
-
await Promise.all(promises);
|
336
336
|
if (local.env) {
|
337
337
|
Object.entries(local.env).forEach(([key, value]) => {
|
338
338
|
addonEnv[key] = value;
|
@@ -396,7 +396,7 @@ class BlockInstanceRunner {
|
|
396
396
|
* Get the port bindings for a non-operator block
|
397
397
|
*/
|
398
398
|
async getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion) {
|
399
|
-
const
|
399
|
+
const hostIp = (0, utils_1.getDockerHostIp)();
|
400
400
|
const ExposedPorts = {};
|
401
401
|
const addonEnv = {};
|
402
402
|
const PortBindings = {};
|
@@ -410,7 +410,7 @@ class BlockInstanceRunner {
|
|
410
410
|
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = '' + thisPort;
|
411
411
|
PortBindings[dockerPort] = [
|
412
412
|
{
|
413
|
-
HostIp:
|
413
|
+
HostIp: hostIp,
|
414
414
|
HostPort: `${publicPort}`,
|
415
415
|
},
|
416
416
|
];
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
import { BlockInstanceDetails, ConfigProvider, DefaultCredentials, DefaultResourceOptions, InstanceOperator, ResourceInfo } from '@kapeta/sdk-config';
|
6
|
+
import { Definition, DefinitionInfo } from '@kapeta/local-cluster-config';
|
7
|
+
import { BlockDefinition, Plan } from '@kapeta/schemas';
|
8
|
+
import { AnyMap, EnvironmentType } from '../types';
|
9
|
+
/**
|
10
|
+
* A configuration provider that does the same as the LocalConfigProvider
|
11
|
+
* but without calling the API of the local cluster service (since it's running in the same process)
|
12
|
+
*/
|
13
|
+
export declare class InternalConfigProvider implements ConfigProvider {
|
14
|
+
private readonly info;
|
15
|
+
private readonly systemId;
|
16
|
+
private readonly instanceId;
|
17
|
+
private readonly config;
|
18
|
+
private readonly environment;
|
19
|
+
constructor(systemId: string, instanceId: string, info: DefinitionInfo, config: AnyMap, environment?: EnvironmentType);
|
20
|
+
getBlockDefinition(): Definition;
|
21
|
+
getBlockReference(): string;
|
22
|
+
getSystemId(): string;
|
23
|
+
getInstanceId(): string;
|
24
|
+
getServerPort(portType?: string | undefined): Promise<string>;
|
25
|
+
getServiceAddress(serviceName: string, portType: string): Promise<string | null>;
|
26
|
+
getResourceInfo<Options = DefaultResourceOptions, Credentials = DefaultCredentials>(resourceType: string, portType: string, resourceName: string): Promise<ResourceInfo<Options, Credentials> | null>;
|
27
|
+
getInstanceHost(instanceId: string): Promise<string | null>;
|
28
|
+
getServerHost(): Promise<string>;
|
29
|
+
getProviderId(): string;
|
30
|
+
getOrDefault<T = any>(path: string, defaultValue: T): T;
|
31
|
+
get<T = any>(path: string): T | undefined;
|
32
|
+
getInstanceOperator<Options = any, Credentials extends DefaultCredentials = DefaultCredentials>(instanceId: string): Promise<InstanceOperator<Options, Credentials> | null>;
|
33
|
+
getInstanceForConsumer<BlockType = BlockDefinition>(resourceName: string): Promise<BlockInstanceDetails<BlockType> | null>;
|
34
|
+
getInstancesForProvider<BlockType = BlockDefinition>(resourceName: string): Promise<BlockInstanceDetails<BlockType>[]>;
|
35
|
+
getBlock(ref: any): Promise<Definition>;
|
36
|
+
getPlan(): Promise<Plan>;
|
37
|
+
}
|
38
|
+
export declare function createInternalConfigProvider(systemId: string, instanceId: string, info: DefinitionInfo): Promise<InternalConfigProvider>;
|
@@ -0,0 +1,146 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.createInternalConfigProvider = exports.InternalConfigProvider = void 0;
|
7
|
+
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
8
|
+
const configManager_1 = require("../configManager");
|
9
|
+
const lodash_1 = __importDefault(require("lodash"));
|
10
|
+
const serviceManager_1 = require("../serviceManager");
|
11
|
+
const operatorManager_1 = require("../operatorManager");
|
12
|
+
const instanceManager_1 = require("../instanceManager");
|
13
|
+
const definitionsManager_1 = require("../definitionsManager");
|
14
|
+
const utils_1 = require("./utils");
|
15
|
+
/**
|
16
|
+
* A configuration provider that does the same as the LocalConfigProvider
|
17
|
+
* but without calling the API of the local cluster service (since it's running in the same process)
|
18
|
+
*/
|
19
|
+
class InternalConfigProvider {
|
20
|
+
info;
|
21
|
+
systemId;
|
22
|
+
instanceId;
|
23
|
+
config;
|
24
|
+
environment;
|
25
|
+
constructor(systemId, instanceId, info, config, environment = 'docker') {
|
26
|
+
this.info = info;
|
27
|
+
this.systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
|
28
|
+
this.instanceId = instanceId;
|
29
|
+
this.config = config;
|
30
|
+
this.environment = environment;
|
31
|
+
}
|
32
|
+
getBlockDefinition() {
|
33
|
+
return this.info.definition;
|
34
|
+
}
|
35
|
+
getBlockReference() {
|
36
|
+
return (0, nodejs_utils_1.normalizeKapetaUri)(this.info.definition.metadata.name + ':' + this.info.version);
|
37
|
+
}
|
38
|
+
getSystemId() {
|
39
|
+
return this.systemId;
|
40
|
+
}
|
41
|
+
getInstanceId() {
|
42
|
+
return this.instanceId;
|
43
|
+
}
|
44
|
+
getServerPort(portType) {
|
45
|
+
return serviceManager_1.serviceManager.ensureServicePort(this.systemId, this.instanceId, portType);
|
46
|
+
}
|
47
|
+
async getServiceAddress(serviceName, portType) {
|
48
|
+
return serviceManager_1.serviceManager.getConsumerAddress(this.systemId, this.instanceId, serviceName, portType, this.environment);
|
49
|
+
}
|
50
|
+
getResourceInfo(resourceType, portType, resourceName) {
|
51
|
+
return operatorManager_1.operatorManager.getConsumerResourceInfo(this.systemId, this.instanceId, resourceType, portType, resourceName, this.environment, false);
|
52
|
+
}
|
53
|
+
async getInstanceHost(instanceId) {
|
54
|
+
const instance = instanceManager_1.instanceManager.getInstance(this.systemId, instanceId);
|
55
|
+
return instance?.address ?? null;
|
56
|
+
}
|
57
|
+
async getServerHost() {
|
58
|
+
return (0, utils_1.getBindAddressForEnvironment)(this.environment);
|
59
|
+
}
|
60
|
+
getProviderId() {
|
61
|
+
return 'internal';
|
62
|
+
}
|
63
|
+
getOrDefault(path, defaultValue) {
|
64
|
+
return this.get(path) ?? defaultValue;
|
65
|
+
}
|
66
|
+
get(path) {
|
67
|
+
return lodash_1.default.get(this.config, path);
|
68
|
+
}
|
69
|
+
getInstanceOperator(instanceId) {
|
70
|
+
return instanceManager_1.instanceManager.getInstanceOperator(this.systemId, instanceId, this.environment, false);
|
71
|
+
}
|
72
|
+
async getInstanceForConsumer(resourceName) {
|
73
|
+
const plan = await this.getPlan();
|
74
|
+
if (!plan) {
|
75
|
+
throw new Error('Could not find plan');
|
76
|
+
}
|
77
|
+
const instanceId = this.getInstanceId();
|
78
|
+
const connection = plan.spec.connections.find((connection) => connection.consumer.blockId === instanceId && connection.consumer.resourceName === resourceName);
|
79
|
+
if (!connection) {
|
80
|
+
throw new Error(`Could not find connection for consumer ${resourceName}`);
|
81
|
+
}
|
82
|
+
const instance = plan.spec.blocks.find((b) => b.id === connection.provider.blockId);
|
83
|
+
if (!instance) {
|
84
|
+
throw new Error(`Could not find instance ${connection.provider.blockId} in plan`);
|
85
|
+
}
|
86
|
+
const block = await this.getBlock(instance.block.ref);
|
87
|
+
if (!block) {
|
88
|
+
throw new Error(`Could not find block ${instance.block.ref} in plan`);
|
89
|
+
}
|
90
|
+
return {
|
91
|
+
instanceId: connection.provider.blockId,
|
92
|
+
connections: [connection],
|
93
|
+
block: block,
|
94
|
+
};
|
95
|
+
}
|
96
|
+
async getInstancesForProvider(resourceName) {
|
97
|
+
const plan = await this.getPlan();
|
98
|
+
if (!plan) {
|
99
|
+
throw new Error('Could not find plan');
|
100
|
+
}
|
101
|
+
const instanceId = this.getInstanceId();
|
102
|
+
const blockDetails = {};
|
103
|
+
const connections = plan.spec.connections.filter((connection) => connection.provider.blockId === instanceId && connection.provider.resourceName === resourceName);
|
104
|
+
for (const connection of connections) {
|
105
|
+
const blockInstanceId = connection.consumer.blockId;
|
106
|
+
if (blockDetails[blockInstanceId]) {
|
107
|
+
blockDetails[blockInstanceId].connections.push(connection);
|
108
|
+
continue;
|
109
|
+
}
|
110
|
+
const instance = plan.spec.blocks.find((b) => b.id === blockInstanceId);
|
111
|
+
if (!instance) {
|
112
|
+
throw new Error(`Could not find instance ${blockInstanceId} in plan`);
|
113
|
+
}
|
114
|
+
const block = await this.getBlock(instance.block.ref);
|
115
|
+
if (!block) {
|
116
|
+
throw new Error(`Could not find block ${instance.block.ref} in plan`);
|
117
|
+
}
|
118
|
+
blockDetails[blockInstanceId] = {
|
119
|
+
instanceId: blockInstanceId,
|
120
|
+
connections: [connection],
|
121
|
+
block: block,
|
122
|
+
};
|
123
|
+
}
|
124
|
+
return Object.values(blockDetails);
|
125
|
+
}
|
126
|
+
async getBlock(ref) {
|
127
|
+
const definition = await definitionsManager_1.definitionsManager.getDefinition(ref);
|
128
|
+
if (!definition) {
|
129
|
+
throw new Error(`Could not find definition for ${ref}`);
|
130
|
+
}
|
131
|
+
return definition.definition;
|
132
|
+
}
|
133
|
+
async getPlan() {
|
134
|
+
const definition = await definitionsManager_1.definitionsManager.getDefinition(this.systemId);
|
135
|
+
if (!definition) {
|
136
|
+
throw new Error(`Could not find plan ${this.systemId}`);
|
137
|
+
}
|
138
|
+
return definition.definition;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
exports.InternalConfigProvider = InternalConfigProvider;
|
142
|
+
async function createInternalConfigProvider(systemId, instanceId, info) {
|
143
|
+
const config = await configManager_1.configManager.getConfigForBlockInstance(systemId, instanceId);
|
144
|
+
return new InternalConfigProvider(systemId, instanceId, info, config);
|
145
|
+
}
|
146
|
+
exports.createInternalConfigProvider = createInternalConfigProvider;
|
@@ -2,17 +2,39 @@
|
|
2
2
|
* Copyright 2023 Kapeta Inc.
|
3
3
|
* SPDX-License-Identifier: BUSL-1.1
|
4
4
|
*/
|
5
|
-
import { EntityList, LocalInstancePort } from '@kapeta/schemas';
|
6
|
-
import { AnyMap } from '../types';
|
5
|
+
import { EntityList, LocalInstance, LocalInstancePort } from '@kapeta/schemas';
|
6
|
+
import { AnyMap, EnvironmentType } from '../types';
|
7
7
|
export declare function getBlockInstanceContainerName(systemId: string, instanceId: string, blockType?: string): Promise<string>;
|
8
8
|
export declare function toPortInfo(port: LocalInstancePort): LocalInstancePort | {
|
9
9
|
port: number;
|
10
10
|
type: string;
|
11
11
|
};
|
12
|
+
export declare function getOperatorInstancePorts(systemId: string, operatorId: string, local: LocalInstance): Promise<{
|
13
|
+
portType: string;
|
14
|
+
port: number | undefined;
|
15
|
+
hostPort: any;
|
16
|
+
protocol: string | undefined;
|
17
|
+
}[]>;
|
18
|
+
/**
|
19
|
+
* Gets the hostname where all services are available - including the cluster service.
|
20
|
+
*
|
21
|
+
* For docker this is the internal docker host - otherwise it's the local machine
|
22
|
+
* Assumed to be the same address as the cluster service outside docker.
|
23
|
+
*/
|
24
|
+
export declare function getRemoteHostForEnvironment(environment: EnvironmentType | undefined): string;
|
25
|
+
/**
|
26
|
+
* Get the bind address for the given environment.
|
27
|
+
*
|
28
|
+
* Outside of docker we bind to 127.0.0.1 - inside we bind to everything (0.0.0.0)
|
29
|
+
*/
|
30
|
+
export declare function getBindAddressForEnvironment(environment: EnvironmentType | undefined, preferredHost?: string): string;
|
31
|
+
/**
|
32
|
+
* Get the docker host IP address for port binding.
|
33
|
+
*/
|
34
|
+
export declare function getDockerHostIp(preferredHost?: string): string;
|
12
35
|
export declare function getRemoteUrl(id: string, defautValue: string): any;
|
13
36
|
export declare function readYML(path: string): any;
|
14
37
|
export declare function isWindows(): boolean;
|
15
38
|
export declare function isMac(): boolean;
|
16
39
|
export declare function isLinux(): boolean;
|
17
|
-
export declare function getBindHost(preferredHost?: string): string;
|
18
40
|
export declare function getResolvedConfiguration(entities?: EntityList, config?: AnyMap, globalConfiguration?: AnyMap): AnyMap;
|
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
8
|
};
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
-
exports.getResolvedConfiguration = exports.
|
10
|
+
exports.getResolvedConfiguration = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.getRemoteUrl = exports.getDockerHostIp = exports.getBindAddressForEnvironment = exports.getRemoteHostForEnvironment = exports.getOperatorInstancePorts = exports.toPortInfo = exports.getBlockInstanceContainerName = void 0;
|
11
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
12
12
|
const yaml_1 = __importDefault(require("yaml"));
|
13
13
|
const md5_1 = __importDefault(require("md5"));
|
@@ -18,6 +18,8 @@ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-co
|
|
18
18
|
const definitionsManager_1 = require("../definitionsManager");
|
19
19
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
20
20
|
const assetManager_1 = require("../assetManager");
|
21
|
+
const serviceManager_1 = require("../serviceManager");
|
22
|
+
const clusterService_1 = require("../clusterService");
|
21
23
|
async function getBlockInstanceContainerName(systemId, instanceId, blockType) {
|
22
24
|
if (!blockType) {
|
23
25
|
const instance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
|
@@ -51,6 +53,49 @@ function toPortInfo(port) {
|
|
51
53
|
return port;
|
52
54
|
}
|
53
55
|
exports.toPortInfo = toPortInfo;
|
56
|
+
async function getOperatorInstancePorts(systemId, operatorId, local) {
|
57
|
+
const localPorts = local.ports ?? {};
|
58
|
+
const promises = Object.entries(localPorts).map(async ([portType, value]) => {
|
59
|
+
const portInfo = toPortInfo(value);
|
60
|
+
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, operatorId, portType);
|
61
|
+
return {
|
62
|
+
portType,
|
63
|
+
port: portInfo.port,
|
64
|
+
hostPort,
|
65
|
+
protocol: portInfo.type,
|
66
|
+
};
|
67
|
+
});
|
68
|
+
return await Promise.all(promises);
|
69
|
+
}
|
70
|
+
exports.getOperatorInstancePorts = getOperatorInstancePorts;
|
71
|
+
/**
|
72
|
+
* Gets the hostname where all services are available - including the cluster service.
|
73
|
+
*
|
74
|
+
* For docker this is the internal docker host - otherwise it's the local machine
|
75
|
+
* Assumed to be the same address as the cluster service outside docker.
|
76
|
+
*/
|
77
|
+
function getRemoteHostForEnvironment(environment) {
|
78
|
+
return environment === 'docker' ? types_1.DOCKER_HOST_INTERNAL : clusterService_1.clusterService.getClusterServiceHost();
|
79
|
+
}
|
80
|
+
exports.getRemoteHostForEnvironment = getRemoteHostForEnvironment;
|
81
|
+
/**
|
82
|
+
* Get the bind address for the given environment.
|
83
|
+
*
|
84
|
+
* Outside of docker we bind to 127.0.0.1 - inside we bind to everything (0.0.0.0)
|
85
|
+
*/
|
86
|
+
function getBindAddressForEnvironment(environment, preferredHost = '127.0.0.1') {
|
87
|
+
return environment === 'docker' ? '0.0.0.0' : preferredHost;
|
88
|
+
}
|
89
|
+
exports.getBindAddressForEnvironment = getBindAddressForEnvironment;
|
90
|
+
/**
|
91
|
+
* Get the docker host IP address for port binding.
|
92
|
+
*/
|
93
|
+
function getDockerHostIp(preferredHost = '127.0.0.1') {
|
94
|
+
// On Linux we need to bind to 0.0.0.0 to be able to connect to it from docker containers.
|
95
|
+
// TODO: This might pose a security risk - so we should authenticate all requests using a shared secret/nonce that we pass around.
|
96
|
+
return isLinux() ? '0.0.0.0' : preferredHost;
|
97
|
+
}
|
98
|
+
exports.getDockerHostIp = getDockerHostIp;
|
54
99
|
function getRemoteUrl(id, defautValue) {
|
55
100
|
const remoteConfig = local_cluster_config_1.default.getClusterConfig().remote;
|
56
101
|
return remoteConfig?.[id] ?? defautValue;
|
@@ -78,12 +123,6 @@ function isLinux() {
|
|
78
123
|
return !isWindows() && !isMac();
|
79
124
|
}
|
80
125
|
exports.isLinux = isLinux;
|
81
|
-
function getBindHost(preferredHost = '127.0.0.1') {
|
82
|
-
// On Linux we need to bind to 0.0.0.0 to be able to connect to it from docker containers.
|
83
|
-
// TODO: This might pose a security risk - so we should authenticate all requests using a shared secret/nonce that we pass around.
|
84
|
-
return isLinux() ? '0.0.0.0' : preferredHost;
|
85
|
-
}
|
86
|
-
exports.getBindHost = getBindHost;
|
87
126
|
function getResolvedConfiguration(entities, config, globalConfiguration) {
|
88
127
|
if (!entities || !globalConfiguration) {
|
89
128
|
return config || {};
|