Compare commits
No commits in common. "master" and "v4.5.5" have entirely different histories.
106
changelog.md
106
changelog.md
@ -1,111 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2025-04-25 - 5.0.4 - fix(platformservice/mta)
|
|
||||||
Update getEmailStatus response schema: make details property optional
|
|
||||||
|
|
||||||
- Changed details property from required with fixed message to optional with a flexible message structure in IReq_GetEMailStats response
|
|
||||||
|
|
||||||
## 2025-04-25 - 5.0.3 - fix(mta)
|
|
||||||
update email status response type in MTA platform service
|
|
||||||
|
|
||||||
- Changed the response 'status' field in IRequest_CheckEmailStatus from a literal 'unknown' to a generic string for improved flexibility
|
|
||||||
|
|
||||||
## 2025-04-25 - 5.0.2 - fix(platformservice/mta)
|
|
||||||
Refactor email status response in MTA service
|
|
||||||
|
|
||||||
- Updated IReq_CheckEmailStatus response: replaced union type ('ok' | 'not ok') with fixed status 'unknown' and added a details object with message 'Email not found'.
|
|
||||||
|
|
||||||
## 2025-04-25 - 5.0.1 - fix(mta)
|
|
||||||
Update email stats response interface in mta platform service to include totalEmailsSent, totalEmailsDelivered, totalEmailsBounced, averageDeliveryTimeMs, and lastUpdated timestamp.
|
|
||||||
|
|
||||||
- Modified IReq_GetEMailStats response in ts_interfaces/platformservice/mta.ts from an empty status object to a detailed email statistics structure.
|
|
||||||
|
|
||||||
## 2025-04-25 - 5.0.0 - BREAKING CHANGE(ts_interfaces/platformservice/mta)
|
|
||||||
Rename mta interfaces and upgrade dependency versions
|
|
||||||
|
|
||||||
- Upgraded devDependencies: @git.zone/tsbuild, tsbundle, tsdoc, tstest, tswatch, and @push.rocks/tapbundle to newer versions.
|
|
||||||
- Upgraded dependencies: @design.estate/dees-catalog, dees-domtools, dees-element, @push.rocks/smartdata, smartexpect, smartfile, smartpromise, smartrequest, smartrx, and tsclass (v4.2.0 to v9.0.0).
|
|
||||||
- Added new packageManager field in package.json and introduced pnpm-workspace.yaml for additional workspace configuration.
|
|
||||||
- Refactored mta API interfaces: renamed IRequest_SendEmail to IReq_SendEmail and IRequestRegisterRecipient to IReq_RegisterRecipient; added IReq_CheckEmailStatus and IReq_GetEMailStats.
|
|
||||||
|
|
||||||
## 2025-01-20 - 4.13.0 - feat(service)
|
|
||||||
Add support for service creation, update, and deletion.
|
|
||||||
|
|
||||||
- Implemented TypedHandlers for creating a new service.
|
|
||||||
- Added features to update existing service details.
|
|
||||||
- Enabled deletion of services by their unique ID.
|
|
||||||
|
|
||||||
## 2025-01-20 - 4.12.2 - fix(service)
|
|
||||||
Fix secret bundle and service management bugs
|
|
||||||
|
|
||||||
- Corrected the field name from 'includedImages' to 'imageClaims' in secret bundles.
|
|
||||||
- Implemented 'getFlatKeyValueObject' for secret bundles and modified related API interactions.
|
|
||||||
- Enhanced the Service class with methods for handling secret bundle data by resolving related groups and environments.
|
|
||||||
|
|
||||||
## 2025-01-02 - 4.12.1 - fix(deps)
|
|
||||||
Updated @git.zone/tspublish to version ^1.9.1
|
|
||||||
|
|
||||||
|
|
||||||
## 2025-01-02 - 4.12.0 - feat(cli)
|
|
||||||
Add CLI support and external registries view
|
|
||||||
|
|
||||||
- Adds CLI client functionality
|
|
||||||
- Introduces a new view for External Registries in the dashboard
|
|
||||||
|
|
||||||
## 2024-12-30 - 4.11.0 - feat(external-registry)
|
|
||||||
Introduce external registry management
|
|
||||||
|
|
||||||
- Added ExternalRegistryManager to handle external registry operations.
|
|
||||||
- Implemented ability to create, retrieve, and delete external registries.
|
|
||||||
- Enhanced Cloudly class to include ExternalRegistryManager.
|
|
||||||
|
|
||||||
## 2024-12-29 - 4.10.0 - feat(apiclient)
|
|
||||||
Added support for managing external registries in the API client.
|
|
||||||
|
|
||||||
- Introduced methods to get a registry by ID, get all registries, and create a new registry in the externalRegistry object.
|
|
||||||
- Updated external registry request interfaces to match new API client capabilities.
|
|
||||||
|
|
||||||
## 2024-12-29 - 4.9.0 - feat(apiclient)
|
|
||||||
Add external registry management capabilities to Cloudly API client.
|
|
||||||
|
|
||||||
- Introduce ExternalRegistry class with methods for getting, creating, and updating external registries.
|
|
||||||
- Expand requests module to handle external registry management, including creation and deletion.
|
|
||||||
|
|
||||||
## 2024-12-28 - 4.8.1 - fix(interfaces)
|
|
||||||
Fix image location schema in IImage interface
|
|
||||||
|
|
||||||
- Refactored the 'external' object within IImage data to a 'location' object.
|
|
||||||
- Added 'internal' boolean to 'location' to specify internal/external status.
|
|
||||||
|
|
||||||
## 2024-12-28 - 4.8.0 - feat(manager.registry)
|
|
||||||
Add external registry management
|
|
||||||
|
|
||||||
- Introduced ExternalRegistry class for handling external registry configurations.
|
|
||||||
- Updated IExternalRegistry interface to include registry details.
|
|
||||||
- Enhanced IImage interface to support linking with external registries.
|
|
||||||
|
|
||||||
## 2024-12-28 - 4.7.1 - fix(secretmanagement)
|
|
||||||
Refactor secret bundle actions and improve authorization handling
|
|
||||||
|
|
||||||
- Refactored secret bundle handling by renaming methods and reorganizing static and instance methods in SecretBundle class.
|
|
||||||
- Added getSecretBundleByAuthorization method to SecretBundle.
|
|
||||||
- Improved getFlatKeyValueObjectForEnvironment to accurately retrieve key-value pairs for specified environments.
|
|
||||||
- Removed deprecated IEnvBundle interface and related request handler for better clarity and code usage.
|
|
||||||
- Updated request interfaces related to secret bundles for consistent method naming and arguments.
|
|
||||||
|
|
||||||
## 2024-12-22 - 4.7.0 - feat(apiclient)
|
|
||||||
Add method to flatten secret bundles into key-value objects.
|
|
||||||
|
|
||||||
- SecretBundle: Implemented toFlatKeyValueObject method to flatten secret groups into key-value pairs.
|
|
||||||
- Removed stale SecretManager class from apiclient.
|
|
||||||
|
|
||||||
## 2024-12-22 - 4.6.0 - feat(cloudlyapiclient)
|
|
||||||
Extend CloudlyApiClient with cluster, secretbundle, and secretgroup methods
|
|
||||||
|
|
||||||
- Added methods to CloudlyApiClient for managing clusters: getClusterById, getClusters, createCluster.
|
|
||||||
- Added methods to CloudlyApiClient for managing secret bundles: getSecretBundleById, getSecretBundles, createSecretBundle.
|
|
||||||
- Added methods to CloudlyApiClient for managing secret groups: getSecretGroupById, getSecretGroups, createSecretGroup.
|
|
||||||
|
|
||||||
## 2024-12-22 - 4.5.5 - fix(apiclient)
|
## 2024-12-22 - 4.5.5 - fix(apiclient)
|
||||||
Fixed image creation method in cloudlyApiClient
|
Fixed image creation method in cloudlyApiClient
|
||||||
|
|
||||||
|
45
package.json
45
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/cloudly",
|
"name": "@serve.zone/cloudly",
|
||||||
"version": "5.0.4",
|
"version": "4.5.5",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.",
|
"description": "A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@ -22,27 +22,27 @@
|
|||||||
"docs": "tsdoc aidoc"
|
"docs": "tsdoc aidoc"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^2.3.2",
|
"@git.zone/tsbuild": "^2.2.0",
|
||||||
"@git.zone/tsbundle": "^2.2.5",
|
"@git.zone/tsbundle": "^2.1.0",
|
||||||
"@git.zone/tsdoc": "^1.4.4",
|
"@git.zone/tsdoc": "^1.4.2",
|
||||||
"@git.zone/tspublish": "^1.9.1",
|
"@git.zone/tspublish": "^1.7.7",
|
||||||
"@git.zone/tstest": "^1.0.96",
|
"@git.zone/tstest": "^1.0.90",
|
||||||
"@git.zone/tswatch": "^2.1.0",
|
"@git.zone/tswatch": "^2.0.37",
|
||||||
"@push.rocks/tapbundle": "^5.6.3",
|
"@push.rocks/tapbundle": "^5.5.3",
|
||||||
"@types/node": "^22.15.2"
|
"@types/node": "^22.10.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@api.global/typedrequest": "3.1.10",
|
"@api.global/typedrequest": "3.1.10",
|
||||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||||
"@api.global/typedserver": "^3.0.74",
|
"@api.global/typedserver": "^3.0.51",
|
||||||
"@api.global/typedsocket": "^3.0.1",
|
"@api.global/typedsocket": "^3.0.1",
|
||||||
"@apiclient.xyz/cloudflare": "^6.0.1",
|
"@apiclient.xyz/cloudflare": "^6.0.1",
|
||||||
"@apiclient.xyz/docker": "^1.3.0",
|
"@apiclient.xyz/docker": "^1.2.7",
|
||||||
"@apiclient.xyz/hetznercloud": "^1.2.0",
|
"@apiclient.xyz/hetznercloud": "^1.2.0",
|
||||||
"@apiclient.xyz/slack": "^3.0.9",
|
"@apiclient.xyz/slack": "^3.0.9",
|
||||||
"@design.estate/dees-catalog": "^1.8.0",
|
"@design.estate/dees-catalog": "^1.3.2",
|
||||||
"@design.estate/dees-domtools": "^2.3.2",
|
"@design.estate/dees-domtools": "^2.0.64",
|
||||||
"@design.estate/dees-element": "^2.0.42",
|
"@design.estate/dees-element": "^2.0.39",
|
||||||
"@git.zone/tsrun": "^1.3.3",
|
"@git.zone/tsrun": "^1.3.3",
|
||||||
"@push.rocks/early": "^4.0.3",
|
"@push.rocks/early": "^4.0.3",
|
||||||
"@push.rocks/npmextra": "^5.1.2",
|
"@push.rocks/npmextra": "^5.1.2",
|
||||||
@ -52,11 +52,11 @@
|
|||||||
"@push.rocks/smartbucket": "^3.3.7",
|
"@push.rocks/smartbucket": "^3.3.7",
|
||||||
"@push.rocks/smartcli": "^4.0.11",
|
"@push.rocks/smartcli": "^4.0.11",
|
||||||
"@push.rocks/smartclickhouse": "^2.0.17",
|
"@push.rocks/smartclickhouse": "^2.0.17",
|
||||||
"@push.rocks/smartdata": "^5.15.1",
|
"@push.rocks/smartdata": "^5.2.10",
|
||||||
"@push.rocks/smartdelay": "^3.0.5",
|
"@push.rocks/smartdelay": "^3.0.5",
|
||||||
"@push.rocks/smartexit": "^1.0.23",
|
"@push.rocks/smartexit": "^1.0.23",
|
||||||
"@push.rocks/smartexpect": "^1.6.1",
|
"@push.rocks/smartexpect": "^1.2.1",
|
||||||
"@push.rocks/smartfile": "^11.2.0",
|
"@push.rocks/smartfile": "^11.0.23",
|
||||||
"@push.rocks/smartguard": "^3.1.0",
|
"@push.rocks/smartguard": "^3.1.0",
|
||||||
"@push.rocks/smartjson": "^5.0.19",
|
"@push.rocks/smartjson": "^5.0.19",
|
||||||
"@push.rocks/smartjwt": "^2.2.1",
|
"@push.rocks/smartjwt": "^2.2.1",
|
||||||
@ -64,9 +64,9 @@
|
|||||||
"@push.rocks/smartlog-destination-clickhouse": "^1.0.13",
|
"@push.rocks/smartlog-destination-clickhouse": "^1.0.13",
|
||||||
"@push.rocks/smartlog-interfaces": "^3.0.2",
|
"@push.rocks/smartlog-interfaces": "^3.0.2",
|
||||||
"@push.rocks/smartpath": "^5.0.18",
|
"@push.rocks/smartpath": "^5.0.18",
|
||||||
"@push.rocks/smartpromise": "^4.2.3",
|
"@push.rocks/smartpromise": "^4.0.4",
|
||||||
"@push.rocks/smartrequest": "^2.1.0",
|
"@push.rocks/smartrequest": "^2.0.23",
|
||||||
"@push.rocks/smartrx": "^3.0.10",
|
"@push.rocks/smartrx": "^3.0.7",
|
||||||
"@push.rocks/smartssh": "^2.0.1",
|
"@push.rocks/smartssh": "^2.0.1",
|
||||||
"@push.rocks/smartstate": "^2.0.19",
|
"@push.rocks/smartstate": "^2.0.19",
|
||||||
"@push.rocks/smartstream": "^3.2.5",
|
"@push.rocks/smartstream": "^3.2.5",
|
||||||
@ -74,7 +74,7 @@
|
|||||||
"@push.rocks/smartunique": "^3.0.9",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"@push.rocks/taskbuffer": "^3.0.2",
|
"@push.rocks/taskbuffer": "^3.0.2",
|
||||||
"@push.rocks/webjwt": "^1.0.9",
|
"@push.rocks/webjwt": "^1.0.9",
|
||||||
"@tsclass/tsclass": "^9.0.0"
|
"@tsclass/tsclass": "^4.2.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
@ -126,6 +126,5 @@
|
|||||||
"frontend",
|
"frontend",
|
||||||
"backend",
|
"backend",
|
||||||
"security"
|
"security"
|
||||||
],
|
]
|
||||||
"packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6"
|
|
||||||
}
|
}
|
||||||
|
5050
pnpm-lock.yaml
generated
5050
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
|||||||
onlyBuiltDependencies:
|
|
||||||
- esbuild
|
|
||||||
- mongodb-memory-server
|
|
||||||
- puppeteer
|
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/cloudly',
|
name: '@serve.zone/cloudly',
|
||||||
version: '5.0.4',
|
version: '4.5.5',
|
||||||
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ for (let i = 0; i < demoSecretGroups.length; i++) {
|
|||||||
id: `configBundleId${i + 1}`,
|
id: `configBundleId${i + 1}`,
|
||||||
data: {
|
data: {
|
||||||
name: `Demo Config Bundle ${i + 1}`,
|
name: `Demo Config Bundle ${i + 1}`,
|
||||||
imageClaims: [],
|
includedImages: [],
|
||||||
type: 'external',
|
type: 'external',
|
||||||
description: 'Demo Purpose',
|
description: 'Demo Purpose',
|
||||||
includedSecretGroupIds: [secretGroup.id],
|
includedSecretGroupIds: [secretGroup.id],
|
||||||
|
@ -20,7 +20,6 @@ import { CloudlyTaskmanager } from './manager.task/taskmanager.js';
|
|||||||
import { CloudlySecretManager } from './manager.secret/classes.secretmanager.js';
|
import { CloudlySecretManager } from './manager.secret/classes.secretmanager.js';
|
||||||
import { CloudlyServerManager } from './manager.server/classes.servermanager.js';
|
import { CloudlyServerManager } from './manager.server/classes.servermanager.js';
|
||||||
import { ExternalApiManager } from './manager.status/statusmanager.js';
|
import { ExternalApiManager } from './manager.status/statusmanager.js';
|
||||||
import { ExternalRegistryManager } from './manager.externalregistry/index.js';
|
|
||||||
import { ImageManager } from './manager.image/classes.imagemanager.js';
|
import { ImageManager } from './manager.image/classes.imagemanager.js';
|
||||||
import { logger } from './logger.js';
|
import { logger } from './logger.js';
|
||||||
import { CloudlyAuthManager } from './manager.auth/classes.authmanager.js';
|
import { CloudlyAuthManager } from './manager.auth/classes.authmanager.js';
|
||||||
@ -55,7 +54,6 @@ export class Cloudly {
|
|||||||
public clusterManager: ClusterManager;
|
public clusterManager: ClusterManager;
|
||||||
public coreflowManager: CloudlyCoreflowManager;
|
public coreflowManager: CloudlyCoreflowManager;
|
||||||
public externalApiManager: ExternalApiManager;
|
public externalApiManager: ExternalApiManager;
|
||||||
public externalRegistryManager: ExternalRegistryManager;
|
|
||||||
public imageManager: ImageManager;
|
public imageManager: ImageManager;
|
||||||
public taskManager: CloudlyTaskmanager;
|
public taskManager: CloudlyTaskmanager;
|
||||||
public serverManager: CloudlyServerManager;
|
public serverManager: CloudlyServerManager;
|
||||||
@ -82,7 +80,6 @@ export class Cloudly {
|
|||||||
this.clusterManager = new ClusterManager(this);
|
this.clusterManager = new ClusterManager(this);
|
||||||
this.coreflowManager = new CloudlyCoreflowManager(this);
|
this.coreflowManager = new CloudlyCoreflowManager(this);
|
||||||
this.externalApiManager = new ExternalApiManager(this);
|
this.externalApiManager = new ExternalApiManager(this);
|
||||||
this.externalRegistryManager = new ExternalRegistryManager(this);
|
|
||||||
this.imageManager = new ImageManager(this);
|
this.imageManager = new ImageManager(this);
|
||||||
this.taskManager = new CloudlyTaskmanager(this);
|
this.taskManager = new CloudlyTaskmanager(this);
|
||||||
this.secretManager = new CloudlySecretManager(this);
|
this.secretManager = new CloudlySecretManager(this);
|
||||||
|
@ -44,7 +44,7 @@ export class ClusterManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
|
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
|
||||||
new plugins.typedrequest.TypedHandler('getClusters', async (dataArg) => {
|
new plugins.typedrequest.TypedHandler('getAllClusters', async (dataArg) => {
|
||||||
// TODO: do authentication here
|
// TODO: do authentication here
|
||||||
const clusters = await this.getAllClusters();
|
const clusters = await this.getAllClusters();
|
||||||
return {
|
return {
|
||||||
@ -57,11 +57,11 @@ export class ClusterManager {
|
|||||||
|
|
||||||
// delete cluster
|
// delete cluster
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_DeleteClusterById>(
|
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_DeleteClusterById>(
|
||||||
new plugins.typedrequest.TypedHandler('deleteClusterById', async (reqDataArg, toolsArg) => {
|
new plugins.typedrequest.TypedHandler('deleteCluster', async (reqDataArg, toolsArg) => {
|
||||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqDataArg);
|
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqDataArg);
|
||||||
await this.deleteCluster(reqDataArg.clusterId);
|
await this.deleteCluster(reqDataArg.clusterId);
|
||||||
return {
|
return {
|
||||||
ok: true,
|
success: true,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
import * as plugins from '../plugins.js';
|
|
||||||
import * as paths from '../paths.js';
|
|
||||||
import type { Cloudly } from 'ts/classes.cloudly.js';
|
|
||||||
import type { ExternalRegistryManager } from './classes.externalregistrymanager.js';
|
|
||||||
|
|
||||||
export class ExternalRegistry extends plugins.smartdata.SmartDataDbDoc<ExternalRegistry, plugins.servezoneInterfaces.data.IExternalRegistry, ExternalRegistryManager> {
|
|
||||||
// STATIC
|
|
||||||
public static async getRegistryById(registryIdArg: string) {
|
|
||||||
const externalRegistry = await this.getInstance({
|
|
||||||
id: registryIdArg,
|
|
||||||
});
|
|
||||||
return externalRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async getRegistries() {
|
|
||||||
const externalRegistries = await this.getInstances({});
|
|
||||||
return externalRegistries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async createExternalRegistry(registryDataArg: Partial<plugins.servezoneInterfaces.data.IExternalRegistry['data']>) {
|
|
||||||
const externalRegistry = new ExternalRegistry();
|
|
||||||
externalRegistry.id = await ExternalRegistry.getNewId();
|
|
||||||
Object.assign(externalRegistry, registryDataArg);
|
|
||||||
await externalRegistry.save();
|
|
||||||
return externalRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INSTANCE
|
|
||||||
|
|
||||||
@plugins.smartdata.svDb()
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@plugins.smartdata.svDb()
|
|
||||||
public data: plugins.servezoneInterfaces.data.IExternalRegistry['data'];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import * as plugins from '../plugins.js';
|
|
||||||
import { Cloudly } from '../classes.cloudly.js';
|
|
||||||
import { ExternalRegistry } from './classes.externalregistry.js';
|
|
||||||
|
|
||||||
export class ExternalRegistryManager {
|
|
||||||
public cloudlyRef: Cloudly;
|
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
public CExternalRegistry = plugins.smartdata.setDefaultManagerForDoc(this, ExternalRegistry);
|
|
||||||
|
|
||||||
get db() {
|
|
||||||
return this.cloudlyRef.mongodbConnector.smartdataDb;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(cloudlyRef: Cloudly) {
|
|
||||||
this.cloudlyRef = cloudlyRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async start() {
|
|
||||||
// lets set up a typedrouter
|
|
||||||
this.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistryById>(
|
|
||||||
new plugins.typedrequest.TypedHandler('getExternalRegistryById', async (dataArg) => {
|
|
||||||
const registry = await ExternalRegistry.getRegistryById(dataArg.id);
|
|
||||||
return {
|
|
||||||
registry: await registry.createSavableObject(),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistries>(
|
|
||||||
new plugins.typedrequest.TypedHandler('getExternalRegistries', async (dataArg) => {
|
|
||||||
const registries = await ExternalRegistry.getRegistries();
|
|
||||||
return {
|
|
||||||
registries: await Promise.all(
|
|
||||||
registries.map((registry) => registry.createSavableObject())
|
|
||||||
),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_CreateRegistry>(
|
|
||||||
new plugins.typedrequest.TypedHandler('createExternalRegistry', async (dataArg) => {
|
|
||||||
const registry = await ExternalRegistry.createExternalRegistry(dataArg.registryData);
|
|
||||||
return {
|
|
||||||
registry: await registry.createSavableObject(),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
export * from './classes.externalregistrymanager.js';
|
|
||||||
export * from './classes.externalregistry.js';
|
|
@ -59,16 +59,4 @@ export class SecretBundle extends plugins.smartdata.SmartDataDbDoc<
|
|||||||
}
|
}
|
||||||
return returnObject;
|
return returnObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFlatKeyValueObject(environmentArg: string) {
|
|
||||||
if (!environmentArg) {
|
|
||||||
throw new Error('environment is required');
|
|
||||||
}
|
|
||||||
const secretGroups = await this.getSecretGroups();
|
|
||||||
const returnObject = {};
|
|
||||||
for (const secretGroup of secretGroups) {
|
|
||||||
returnObject[secretGroup.data.key] = secretGroup.data.environments[environmentArg].value;
|
|
||||||
}
|
|
||||||
return returnObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -148,26 +148,30 @@ export class CloudlySecretManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler(
|
this.typedrouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetFlatKeyValueObject>(
|
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetEnvBundle>(
|
||||||
'getFlatKeyValueObject',
|
'getEnvBundle',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
const wantedBundle = await SecretBundle.getInstance({
|
const wantedBundle = await SecretBundle.getInstance({
|
||||||
data: {
|
data: {
|
||||||
authorizations: {
|
authorizations: {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
$elemMatch: {
|
$elemMatch: {
|
||||||
secretAccessKey: dataArg.secretBundleAuthorization.secretAccessKey,
|
secretAccessKey: dataArg.authorization,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const authorization = await wantedBundle.getAuthorizationFromAuthKey(
|
const authorization = await wantedBundle.getAuthorizationFromAuthKey(
|
||||||
dataArg.secretBundleAuthorization.secretAccessKey,
|
dataArg.authorization,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
flatKeyValueObject: await wantedBundle.getKeyValueObjectForEnvironment(
|
envBundle: {
|
||||||
authorization.environment,
|
configKeyValueObject: await wantedBundle.getKeyValueObjectForEnvironment(
|
||||||
),
|
authorization.environment,
|
||||||
|
),
|
||||||
|
environment: authorization.environment,
|
||||||
|
timeSensitive: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { SecretBundle } from 'ts/manager.secret/classes.secretbundle.js';
|
|
||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { ServiceManager } from './classes.servicemanager.js';
|
import { ServiceManager } from './classes.servicemanager.js';
|
||||||
|
|
||||||
@ -7,51 +6,9 @@ export class Service extends plugins.smartdata.SmartDataDbDoc<
|
|||||||
plugins.servezoneInterfaces.data.IService,
|
plugins.servezoneInterfaces.data.IService,
|
||||||
ServiceManager
|
ServiceManager
|
||||||
> {
|
> {
|
||||||
// STATIC
|
|
||||||
public static async getServiceById(serviceIdArg: string) {
|
|
||||||
const service = await this.getInstance({
|
|
||||||
id: serviceIdArg,
|
|
||||||
});
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async getServices() {
|
|
||||||
const services = await this.getInstances({});
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async createService(serviceDataArg: Partial<plugins.servezoneInterfaces.data.IService['data']>) {
|
|
||||||
const service = new Service();
|
|
||||||
service.id = await Service.getNewId();
|
|
||||||
Object.assign(service, serviceDataArg);
|
|
||||||
await service.save();
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INSTANCE
|
|
||||||
@plugins.smartdata.svDb()
|
@plugins.smartdata.svDb()
|
||||||
public id: string;
|
public id: string;
|
||||||
|
|
||||||
@plugins.smartdata.svDb()
|
@plugins.smartdata.svDb()
|
||||||
public data: plugins.servezoneInterfaces.data.IService['data'];
|
public data: plugins.servezoneInterfaces.data.IService['data'];
|
||||||
|
|
||||||
/**
|
|
||||||
* a service runs in a specific environment
|
|
||||||
* so -> this method returns the secret bundles as a flat object accordingly.
|
|
||||||
* in other words, it resolves secret groups for the relevant environment
|
|
||||||
* @param environmentArg
|
|
||||||
*/
|
|
||||||
public async getSecretBundlesAsFlatObject(environmentArg: string = 'production') {
|
|
||||||
const secreBundleIds = this.data.additionalSecretBundleIds || [];
|
|
||||||
secreBundleIds.push(this.data.secretBundleId); // put this last, so it overwrites any other secret bundles.
|
|
||||||
let finalFlatObject = {};
|
|
||||||
for (const secretBundleId of secreBundleIds) {
|
|
||||||
const secretBundle = await SecretBundle.getInstance({
|
|
||||||
id: secretBundleId,
|
|
||||||
});
|
|
||||||
const flatObject = await secretBundle.getFlatKeyValueObject(environmentArg);
|
|
||||||
Object.assign(finalFlatObject, flatObject);
|
|
||||||
}
|
|
||||||
return finalFlatObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -35,66 +35,5 @@ export class ServiceManager {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler(
|
|
||||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject>(
|
|
||||||
'getServiceSecretBundlesAsFlatObject',
|
|
||||||
async (dataArg) => {
|
|
||||||
const service = await Service.getInstance({
|
|
||||||
id: dataArg.serviceId,
|
|
||||||
});
|
|
||||||
const flatKeyValueObject = await service.getSecretBundlesAsFlatObject(dataArg.environment);
|
|
||||||
return {
|
|
||||||
flatKeyValueObject: flatKeyValueObject,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler(
|
|
||||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_CreateService>(
|
|
||||||
'createService',
|
|
||||||
async (dataArg) => {
|
|
||||||
const service = await Service.createService(dataArg.serviceData);
|
|
||||||
return {
|
|
||||||
service: await service.createSavableObject(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler(
|
|
||||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_UpdateService>(
|
|
||||||
'updateService',
|
|
||||||
async (dataArg) => {
|
|
||||||
const service = await Service.getInstance({
|
|
||||||
id: dataArg.serviceId,
|
|
||||||
});
|
|
||||||
service.data = {
|
|
||||||
...service.data,
|
|
||||||
...dataArg.serviceData,
|
|
||||||
};
|
|
||||||
await service.save();
|
|
||||||
return {
|
|
||||||
service: await service.createSavableObject(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler(
|
|
||||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_DeleteServiceById>(
|
|
||||||
'deleteServiceById',
|
|
||||||
async (dataArg) => {
|
|
||||||
const service = await Service.getInstance({
|
|
||||||
id: dataArg.serviceId,
|
|
||||||
});
|
|
||||||
await service.delete();
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,6 @@ export type TClientType = 'api' | 'ci' | 'coreflow' | 'cli' | 'serverconfig';
|
|||||||
|
|
||||||
import { Image } from './classes.image.js';
|
import { Image } from './classes.image.js';
|
||||||
import { Service } from './classes.service.js';
|
import { Service } from './classes.service.js';
|
||||||
import { Cluster } from './classes.cluster.js';
|
|
||||||
import { SecretBundle } from './classes.secretbundle.js';
|
|
||||||
import { SecretGroup } from './classes.secretgroup.js';
|
|
||||||
import { ExternalRegistry } from './classes.externalregistry.js';
|
|
||||||
|
|
||||||
export class CloudlyApiClient {
|
export class CloudlyApiClient {
|
||||||
private cloudlyUrl: string;
|
private cloudlyUrl: string;
|
||||||
@ -160,19 +156,6 @@ export class CloudlyApiClient {
|
|||||||
return typedResponse.certificate;
|
return typedResponse.certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public externalRegistry = {
|
|
||||||
// ExternalRegistry
|
|
||||||
getRegistryById: async (registryNameArg: string) => {
|
|
||||||
return ExternalRegistry.getExternalRegistryById(this, registryNameArg);
|
|
||||||
},
|
|
||||||
getRegistries: async () => {
|
|
||||||
return ExternalRegistry.getExternalRegistries(this);
|
|
||||||
},
|
|
||||||
createRegistry: async (optionsArg: Parameters<typeof ExternalRegistry.createExternalRegistry>[1]) => {
|
|
||||||
return ExternalRegistry.createExternalRegistry(this, optionsArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public image = {
|
public image = {
|
||||||
// Images
|
// Images
|
||||||
getImageById: async (imageIdArg: string) => {
|
getImageById: async (imageIdArg: string) => {
|
||||||
@ -198,43 +181,4 @@ export class CloudlyApiClient {
|
|||||||
return Service.createService(this, optionsArg);
|
return Service.createService(this, optionsArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public cluster = {
|
|
||||||
// Clusters
|
|
||||||
getClusterById: async (clusterIdArg: string) => {
|
|
||||||
return Cluster.getClusterById(this, clusterIdArg);
|
|
||||||
},
|
|
||||||
getClusters: async () => {
|
|
||||||
return Cluster.getClusters(this);
|
|
||||||
},
|
|
||||||
createCluster: async (optionsArg: Parameters<typeof Cluster.createCluster>[1]) => {
|
|
||||||
return Cluster.createCluster(this, optionsArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public secretbundle = {
|
|
||||||
// SecretBundles
|
|
||||||
getSecretBundleById: async (secretBundleIdArg: string) => {
|
|
||||||
return SecretBundle.getSecretBundleById(this, secretBundleIdArg);
|
|
||||||
},
|
|
||||||
getSecretBundles: async () => {
|
|
||||||
return SecretBundle.getSecretBundles(this);
|
|
||||||
},
|
|
||||||
createSecretBundle: async (optionsArg: Parameters<typeof SecretBundle.createSecretBundle>[1]) => {
|
|
||||||
return SecretBundle.createSecretBundle(this, optionsArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public secretgroup = {
|
|
||||||
// SecretGroups
|
|
||||||
getSecretGroupById: async (secretGroupIdArg: string) => {
|
|
||||||
return SecretGroup.getSecretGroupById(this, secretGroupIdArg);
|
|
||||||
},
|
|
||||||
getSecretGroups: async () => {
|
|
||||||
return SecretGroup.getSecretGroups(this);
|
|
||||||
},
|
|
||||||
createSecretGroup: async (optionsArg: Parameters<typeof SecretGroup.createSecretGroup>[1]) => {
|
|
||||||
return SecretGroup.createSecretGroup(this, optionsArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
import * as plugins from './plugins.js';
|
|
||||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
|
||||||
|
|
||||||
export class ExternalRegistry implements plugins.servezoneInterfaces.data.IExternalRegistry {
|
|
||||||
// STATIC
|
|
||||||
public static async getExternalRegistryById(cloudlyClientRef: CloudlyApiClient, registryNameArg: string) {
|
|
||||||
const getRegistryByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistryById>(
|
|
||||||
'getExternalRegistryById'
|
|
||||||
);
|
|
||||||
const response = await getRegistryByIdTR.fire({
|
|
||||||
identity: cloudlyClientRef.identity,
|
|
||||||
id: registryNameArg,
|
|
||||||
});
|
|
||||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
|
||||||
Object.assign(newRegistry, response.registry);
|
|
||||||
return newRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async getExternalRegistries(cloudlyClientRef: CloudlyApiClient) {
|
|
||||||
const getRegistriesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistries>(
|
|
||||||
'getExternalRegistries'
|
|
||||||
);
|
|
||||||
const response = await getRegistriesTR.fire({
|
|
||||||
identity: cloudlyClientRef.identity,
|
|
||||||
});
|
|
||||||
const registryConfigs: ExternalRegistry[] = [];
|
|
||||||
for (const registryConfig of response.registries) {
|
|
||||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
|
||||||
Object.assign(newRegistry, registryConfig);
|
|
||||||
registryConfigs.push(newRegistry);
|
|
||||||
}
|
|
||||||
return registryConfigs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async createExternalRegistry(cloudlyClientRef: CloudlyApiClient, registryDataArg: Partial<plugins.servezoneInterfaces.data.IExternalRegistry['data']>) {
|
|
||||||
const createRegistryTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_CreateRegistry>(
|
|
||||||
'createExternalRegistry'
|
|
||||||
);
|
|
||||||
const response = await createRegistryTR.fire({
|
|
||||||
identity: cloudlyClientRef.identity,
|
|
||||||
registryData: registryDataArg as plugins.servezoneInterfaces.data.IExternalRegistry['data'],
|
|
||||||
});
|
|
||||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
|
||||||
Object.assign(newRegistry, response.registry);
|
|
||||||
return newRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INSTANCE
|
|
||||||
public id: string;
|
|
||||||
public data: plugins.servezoneInterfaces.data.IExternalRegistry['data'];
|
|
||||||
public cloudlyClientRef: CloudlyApiClient;
|
|
||||||
|
|
||||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
|
||||||
this.cloudlyClientRef = cloudlyClientRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async update() {
|
|
||||||
const updateRegistryTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_UpdateRegistry>(
|
|
||||||
'updateExternalRegistry'
|
|
||||||
);
|
|
||||||
const response = await updateRegistryTR.fire({
|
|
||||||
identity: this.cloudlyClientRef.identity,
|
|
||||||
registryData: this.data,
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultRegistryData = response.resultRegistry.data;
|
|
||||||
plugins.smartexpect.expect(resultRegistryData).toEqual(this.data);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async delete(cloudlyClientRef: CloudlyApiClient, registryIdArg: string) {
|
|
||||||
const deleteRegistryTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_DeleteRegistryById>(
|
|
||||||
'deleteExternalRegistryById'
|
|
||||||
);
|
|
||||||
const response = await deleteRegistryTR.fire({
|
|
||||||
identity: cloudlyClientRef.identity,
|
|
||||||
registryId: this.id,
|
|
||||||
});
|
|
||||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,16 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from './plugins.js';
|
||||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||||
import { SecretGroup } from './classes.secretgroup.js';
|
|
||||||
|
|
||||||
export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBundle {
|
export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBundle {
|
||||||
// STATIC
|
public cloudlyClientRef: CloudlyApiClient;
|
||||||
|
|
||||||
|
public id: string;
|
||||||
|
public data: plugins.servezoneInterfaces.data.ISecretBundle['data'];
|
||||||
|
|
||||||
|
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||||
|
this.cloudlyClientRef = cloudlyClientRef;
|
||||||
|
}
|
||||||
|
|
||||||
public static async getSecretBundleById(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
|
public static async getSecretBundleById(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
|
||||||
const getSecretBundleByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
|
const getSecretBundleByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
|
||||||
'getSecretBundleById'
|
'getSecretBundleById'
|
||||||
@ -17,19 +24,6 @@ export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBun
|
|||||||
return newSecretBundle;
|
return newSecretBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getSecretBundleByAuthorization(cloudlyClientRef: CloudlyApiClient, secretBundleAuthorizationArg: plugins.servezoneInterfaces.data.ISecretBundleAuthorization) {
|
|
||||||
const getSecretBundleByAuthorizationTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleByAuthorization>(
|
|
||||||
'getSecretBundleByAuthorization'
|
|
||||||
);
|
|
||||||
const response = await getSecretBundleByAuthorizationTR.fire({
|
|
||||||
identity: cloudlyClientRef.identity,
|
|
||||||
secretBundleAuthorization: secretBundleAuthorizationArg,
|
|
||||||
});
|
|
||||||
const newSecretBundle = new SecretBundle(cloudlyClientRef);
|
|
||||||
Object.assign(newSecretBundle, response.secretBundle);
|
|
||||||
return newSecretBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async getSecretBundles(cloudlyClientRef: CloudlyApiClient) {
|
public static async getSecretBundles(cloudlyClientRef: CloudlyApiClient) {
|
||||||
const getSecretBundlesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
|
const getSecretBundlesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
|
||||||
'getSecretBundles'
|
'getSecretBundles'
|
||||||
@ -59,7 +53,7 @@ export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBun
|
|||||||
description: secretBundleDataArg.description,
|
description: secretBundleDataArg.description,
|
||||||
type: secretBundleDataArg.type,
|
type: secretBundleDataArg.type,
|
||||||
authorizations: secretBundleDataArg.authorizations,
|
authorizations: secretBundleDataArg.authorizations,
|
||||||
imageClaims: secretBundleDataArg.imageClaims,
|
includedImages: secretBundleDataArg.includedImages,
|
||||||
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
|
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
|
||||||
includedTags: secretBundleDataArg.includedTags,
|
includedTags: secretBundleDataArg.includedTags,
|
||||||
},
|
},
|
||||||
@ -70,17 +64,6 @@ export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBun
|
|||||||
return newSecretBundle;
|
return newSecretBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// INSTANCE
|
|
||||||
|
|
||||||
public cloudlyClientRef: CloudlyApiClient;
|
|
||||||
|
|
||||||
public id: string;
|
|
||||||
public data: plugins.servezoneInterfaces.data.ISecretBundle['data'];
|
|
||||||
|
|
||||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
|
||||||
this.cloudlyClientRef = cloudlyClientRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async update() {
|
public async update() {
|
||||||
const updateSecretBundleTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
|
const updateSecretBundleTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
|
||||||
'updateSecretBundle'
|
'updateSecretBundle'
|
||||||
@ -110,26 +93,4 @@ export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBun
|
|||||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
plugins.smartexpect.expect(response.ok).toBeTrue();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFlatKeyValueObjectForEnvironment(environmentArg: string = 'production') {
|
|
||||||
const bundleAuthorization = this.data.authorizations.find(authorization => {
|
|
||||||
return authorization.environment === environmentArg;
|
|
||||||
});
|
|
||||||
if (bundleAuthorization) {
|
|
||||||
throw new Error(`no matching environment >>${environmentArg} found in secret bundle`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const getFlatKeyValueObjectTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetFlatKeyValueObject>(
|
|
||||||
'getFlatKeyValueObject'
|
|
||||||
);
|
|
||||||
const response = await getFlatKeyValueObjectTR.fire({
|
|
||||||
identity: this.cloudlyClientRef.identity,
|
|
||||||
seccretBundleId: this.id,
|
|
||||||
secretBundleAuthorization: bundleAuthorization,
|
|
||||||
});
|
|
||||||
|
|
||||||
const flatKeyValueObject: {[key: string]: string} = response.flatKeyValueObject;
|
|
||||||
|
|
||||||
return flatKeyValueObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -72,7 +72,14 @@ export class SecretGroup implements plugins.servezoneInterfaces.data.ISecretGrou
|
|||||||
identity: this.cloudlyClientRef.identity,
|
identity: this.cloudlyClientRef.identity,
|
||||||
secretGroup: {
|
secretGroup: {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
data: this.data,
|
data: {
|
||||||
|
name: this.data.name,
|
||||||
|
description: this.data.description,
|
||||||
|
environments: this.data.environments,
|
||||||
|
key: this.data.key,
|
||||||
|
tags: this.data.tags,
|
||||||
|
priority: this.data.priority,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
27
ts_apiclient/classes.secretmanager.ts
Normal file
27
ts_apiclient/classes.secretmanager.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import * as plugins from './plugins.js';
|
||||||
|
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||||
|
|
||||||
|
import { SecretBundle } from './classes.secretbundle.js';
|
||||||
|
import { SecretGroup } from './classes.secretgroup.js';
|
||||||
|
|
||||||
|
export class SecretManager {
|
||||||
|
// INSTANCE
|
||||||
|
cloudlyClientRef: CloudlyApiClient;
|
||||||
|
|
||||||
|
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||||
|
this.cloudlyClientRef = cloudlyClientRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSecretGroupsAndBundles() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The secret group has a secret bundle.
|
||||||
|
* This function essentially returns the secret bundle as a flat object.
|
||||||
|
* In other words, it resolves secret groups and
|
||||||
|
*/
|
||||||
|
public async getSecretBundleAsFlatObject(environmentArg: string = 'production') {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,19 @@ export class Service implements plugins.servezoneInterfaces.data.IService {
|
|||||||
);
|
);
|
||||||
const response = await createServiceTR.fire({
|
const response = await createServiceTR.fire({
|
||||||
identity: cloudlyClientRef.identity,
|
identity: cloudlyClientRef.identity,
|
||||||
serviceData: serviceDataArg as plugins.servezoneInterfaces.data.IService['data'],
|
name: serviceDataArg.name,
|
||||||
|
description: serviceDataArg.description,
|
||||||
|
imageId: serviceDataArg.imageId,
|
||||||
|
imageVersion: serviceDataArg.imageVersion,
|
||||||
|
environment: {},
|
||||||
|
secretBundleId: null,
|
||||||
|
scaleFactor: 1,
|
||||||
|
balancingStrategy: serviceDataArg.balancingStrategy,
|
||||||
|
ports: {
|
||||||
|
web: null,
|
||||||
|
},
|
||||||
|
resources: serviceDataArg.resources,
|
||||||
|
domains: [],
|
||||||
});
|
});
|
||||||
const newService = new Service(cloudlyClientRef);
|
const newService = new Service(cloudlyClientRef);
|
||||||
Object.assign(newService, response.service);
|
Object.assign(newService, response.service);
|
||||||
@ -63,16 +75,6 @@ export class Service implements plugins.servezoneInterfaces.data.IService {
|
|||||||
* In other words, it resolves secret groups and
|
* In other words, it resolves secret groups and
|
||||||
*/
|
*/
|
||||||
public async getSecretBundleAsFlatObject(environmentArg: string = 'production') {
|
public async getSecretBundleAsFlatObject(environmentArg: string = 'production') {
|
||||||
const getServiceSecretBundlesAsFlatObjectTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject>(
|
|
||||||
'getServiceSecretBundlesAsFlatObject'
|
|
||||||
);
|
|
||||||
const response = await getServiceSecretBundlesAsFlatObjectTR.fire({
|
|
||||||
identity: this.cloudlyClientRef.identity,
|
|
||||||
serviceId: this.id,
|
|
||||||
environment: environmentArg,
|
|
||||||
});
|
|
||||||
const flatKeyValueObject: {[key: string]: string} = response.flatKeyValueObject;
|
|
||||||
|
|
||||||
return flatKeyValueObject;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import * as plugins from './plugins.js';
|
|
||||||
import { CloudlyApiClient } from '@serve.zone/api';
|
|
||||||
|
|
||||||
export class CliClient {
|
|
||||||
public cloudlyApiClient: CloudlyApiClient;
|
|
||||||
|
|
||||||
constructor(cloudlyApiClientArg: CloudlyApiClient) {
|
|
||||||
this.cloudlyApiClient = cloudlyApiClientArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getClusters() {
|
|
||||||
const clusters = await this.cloudlyApiClient.cluster.getClusters();
|
|
||||||
console.log(clusters);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1 @@
|
|||||||
import * as plugins from './plugins.js';
|
console.log('this is the cli client.');
|
||||||
import { CliClient } from "./classes.cliclient.js";
|
|
||||||
|
|
||||||
export const runCli = async () => {
|
|
||||||
const cliQenv = new plugins.qenv.Qenv();
|
|
||||||
const apiClient = new plugins.servezoneApi.CloudlyApiClient({
|
|
||||||
registerAs: 'cli',
|
|
||||||
cloudlyUrl: await cliQenv.getEnvVarOnDemand('CLOUDLY_URL'),
|
|
||||||
});
|
|
||||||
const cliClient = new CliClient(apiClient);
|
|
||||||
};
|
|
@ -1,17 +0,0 @@
|
|||||||
// @serve.zone scope
|
|
||||||
import * as servezoneApi from '@serve.zone/api';
|
|
||||||
import * as servezoneInterfaces from '@serve.zone/interfaces';
|
|
||||||
|
|
||||||
export {
|
|
||||||
servezoneApi,
|
|
||||||
servezoneInterfaces
|
|
||||||
}
|
|
||||||
|
|
||||||
// @push.rocks scope
|
|
||||||
import * as projectinfo from '@push.rocks/projectinfo';
|
|
||||||
import * as qenv from '@push.rocks/qenv';
|
|
||||||
|
|
||||||
export {
|
|
||||||
projectinfo,
|
|
||||||
qenv,
|
|
||||||
}
|
|
@ -1,15 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/cli",
|
"name": "@serve.zone/cli",
|
||||||
"dependencies": [
|
"dependencies": [],
|
||||||
"@serve.zone/api",
|
|
||||||
"@serve.zone/interfaces",
|
|
||||||
"@push.rocks/projectinfo",
|
|
||||||
"@push.rocks/qenv",
|
|
||||||
"@push.rocks/smartcli"
|
|
||||||
],
|
|
||||||
"registries": [
|
"registries": [
|
||||||
"registry.npmjs.org:public",
|
"registry.npmjs.org:public",
|
||||||
"verdaccio.lossless.digital:public"
|
"verdaccio.lossless.digital:public"
|
||||||
],
|
]
|
||||||
"bin": ["servezone"]
|
|
||||||
}
|
}
|
6
ts_interfaces/data/env.ts
Normal file
6
ts_interfaces/data/env.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export interface IEnvBundle {
|
||||||
|
environment: string;
|
||||||
|
timeSensitive: boolean;
|
||||||
|
configKeyValueObject: {[key: string]: string};
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
import * as plugins from '../plugins.js';
|
|
||||||
|
|
||||||
export interface IExternalRegistry {
|
|
||||||
id: string;
|
|
||||||
data: {
|
|
||||||
type: 'docker' | 'npm';
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
};
|
|
||||||
}
|
|
@ -4,11 +4,6 @@ export interface IImage {
|
|||||||
id: string;
|
id: string;
|
||||||
data: {
|
data: {
|
||||||
name: string;
|
name: string;
|
||||||
location: {
|
|
||||||
internal: boolean;
|
|
||||||
externalRegistryId: string;
|
|
||||||
externalImageTag: string;
|
|
||||||
}
|
|
||||||
description: string;
|
description: string;
|
||||||
versions: Array<{
|
versions: Array<{
|
||||||
versionString: string;
|
versionString: string;
|
||||||
|
@ -3,8 +3,8 @@ export * from './cluster.js';
|
|||||||
export * from './config.js';
|
export * from './config.js';
|
||||||
export * from './deployment.js';
|
export * from './deployment.js';
|
||||||
export * from './docker.js';
|
export * from './docker.js';
|
||||||
|
export * from './env.js';
|
||||||
export * from './event.js';
|
export * from './event.js';
|
||||||
export * from './externalregistry.js';
|
|
||||||
export * from './image.js';
|
export * from './image.js';
|
||||||
export * from './secretbundle.js';
|
export * from './secretbundle.js';
|
||||||
export * from './secretgroup.js'
|
export * from './secretgroup.js'
|
||||||
|
@ -21,19 +21,13 @@ export interface ISecretBundle {
|
|||||||
*/
|
*/
|
||||||
type: 'service' | 'npmci' | 'gitzone' | 'external';
|
type: 'service' | 'npmci' | 'gitzone' | 'external';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set this if the secretBundle belongs to a service
|
|
||||||
*/
|
|
||||||
serviceId?: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You can add specific secret groups using this
|
* You can add specific secret groups using this
|
||||||
*/
|
*/
|
||||||
includedSecretGroupIds: string[];
|
includedSecretGroupIds: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* access to this secretBundle also grants access to resources with matching tags
|
* You can add specific tags using this
|
||||||
*/
|
*/
|
||||||
includedTags: {
|
includedTags: {
|
||||||
key: string;
|
key: string;
|
||||||
@ -41,21 +35,19 @@ export interface ISecretBundle {
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* access to this secretBundle also grants access to the images
|
* add images
|
||||||
*/
|
*/
|
||||||
imageClaims: {
|
includedImages: {
|
||||||
imageId: string;
|
imageId: string;
|
||||||
permissions: ('read' | 'write')[];
|
permissions: ('read' | 'write')[];
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* authrozations select a specific environment of a config bundle
|
* authrozations select a specific environment of a config bundle
|
||||||
*/
|
*/
|
||||||
authorizations: Array<ISecretBundleAuthorization>;
|
authorizations: Array<{
|
||||||
|
secretAccessKey: string;
|
||||||
|
environment: string;
|
||||||
|
}>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISecretBundleAuthorization {
|
|
||||||
secretAccessKey: string;
|
|
||||||
environment: string;
|
|
||||||
}
|
|
||||||
|
@ -8,15 +8,7 @@ export interface IService {
|
|||||||
imageId: string;
|
imageId: string;
|
||||||
imageVersion: string;
|
imageVersion: string;
|
||||||
environment: { [key: string]: string };
|
environment: { [key: string]: string };
|
||||||
/**
|
|
||||||
* the main secret bundle id, exclusive to the service
|
|
||||||
*/
|
|
||||||
secretBundleId: string;
|
secretBundleId: string;
|
||||||
/**
|
|
||||||
* those secret bundle ids do not belong to the service itself
|
|
||||||
* and thus live past the service lifecycle
|
|
||||||
*/
|
|
||||||
additionalSecretBundleIds?: string[];
|
|
||||||
scaleFactor: number;
|
scaleFactor: number;
|
||||||
balancingStrategy: 'round-robin' | 'least-connections';
|
balancingStrategy: 'round-robin' | 'least-connections';
|
||||||
ports: {
|
ports: {
|
||||||
|
@ -2,9 +2,9 @@ import * as plugins from '../plugins.js';
|
|||||||
|
|
||||||
export type TTemplates = 'default' | 'linkaction' | 'notification';
|
export type TTemplates = 'default' | 'linkaction' | 'notification';
|
||||||
|
|
||||||
export interface IReq_SendEmail extends plugins.typedrequestInterfaces.implementsTR<
|
export interface IRequest_SendEmail extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
IReq_SendEmail
|
IRequest_SendEmail
|
||||||
> {
|
> {
|
||||||
method: 'sendEmail';
|
method: 'sendEmail';
|
||||||
request: {
|
request: {
|
||||||
@ -25,9 +25,9 @@ export interface IReq_SendEmail extends plugins.typedrequestInterfaces.implement
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IReq_RegisterRecipient extends plugins.typedrequestInterfaces.implementsTR<
|
export interface IRequestRegisterRecipient extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
IReq_RegisterRecipient
|
IRequestRegisterRecipient
|
||||||
> {
|
> {
|
||||||
method: 'registerRecepient';
|
method: 'registerRecepient';
|
||||||
request: {
|
request: {
|
||||||
@ -37,34 +37,3 @@ export interface IReq_RegisterRecipient extends plugins.typedrequestInterfaces.i
|
|||||||
status: 'ok' | 'not ok';
|
status: 'ok' | 'not ok';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IReq_CheckEmailStatus extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_CheckEmailStatus
|
|
||||||
> {
|
|
||||||
method: 'checkEmailStatus';
|
|
||||||
request: {
|
|
||||||
emailId: string;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
status: string,
|
|
||||||
details?: { message: string; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_GetEMailStats extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_GetEMailStats
|
|
||||||
> {
|
|
||||||
method: 'getEmailStats';
|
|
||||||
request: {
|
|
||||||
jwt: string;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
totalEmailsSent: number;
|
|
||||||
totalEmailsDelivered: number;
|
|
||||||
totalEmailsBounced: number;
|
|
||||||
averageDeliveryTimeMs: number;
|
|
||||||
lastUpdated: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
import * as plugins from '../plugins.js';
|
|
||||||
import * as data from '../data/index.js';
|
|
||||||
import * as userInterfaces from '../data/user.js';
|
|
||||||
|
|
||||||
export interface IReq_GetRegistryById extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_GetRegistryById
|
|
||||||
> {
|
|
||||||
method: 'getExternalRegistryById';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
registry: data.IExternalRegistry;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_GetRegistries extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_GetRegistries
|
|
||||||
> {
|
|
||||||
method: 'getExternalRegistries';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
registries: data.IExternalRegistry[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_CreateRegistry extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_CreateRegistry
|
|
||||||
> {
|
|
||||||
method: 'createExternalRegistry';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
registryData: data.IExternalRegistry['data'];
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
registry: data.IExternalRegistry;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_UpdateRegistry extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_UpdateRegistry
|
|
||||||
> {
|
|
||||||
method: 'updateExternalRegistry';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
registryData: data.IExternalRegistry['data'];
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
resultRegistry: data.IExternalRegistry;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_DeleteRegistryById extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_DeleteRegistryById
|
|
||||||
> {
|
|
||||||
method: 'deleteExternalRegistryById';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
registryId: string;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
ok: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import * as adminRequests from './admin.js';
|
|||||||
import * as certificateRequests from './certificate.js';
|
import * as certificateRequests from './certificate.js';
|
||||||
import * as clusterRequests from './cluster.js';
|
import * as clusterRequests from './cluster.js';
|
||||||
import * as configRequests from './config.js';
|
import * as configRequests from './config.js';
|
||||||
import * as externalRegistryRequests from './externalregistry.js';
|
|
||||||
import * as identityRequests from './identity.js';
|
import * as identityRequests from './identity.js';
|
||||||
import * as imageRequests from './image.js';
|
import * as imageRequests from './image.js';
|
||||||
import * as informRequests from './inform.js';
|
import * as informRequests from './inform.js';
|
||||||
@ -23,7 +22,6 @@ export {
|
|||||||
certificateRequests as certificate,
|
certificateRequests as certificate,
|
||||||
clusterRequests as cluster,
|
clusterRequests as cluster,
|
||||||
configRequests as config,
|
configRequests as config,
|
||||||
externalRegistryRequests as externalRegistry,
|
|
||||||
identityRequests as identity,
|
identityRequests as identity,
|
||||||
imageRequests as image,
|
imageRequests as image,
|
||||||
informRequests as inform,
|
informRequests as inform,
|
||||||
|
@ -2,6 +2,26 @@ import * as plugins from '../plugins.js';
|
|||||||
import * as data from '../data/index.js';
|
import * as data from '../data/index.js';
|
||||||
import * as userInterfaces from '../data/user.js';
|
import * as userInterfaces from '../data/user.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* when retrieving secrets for actual use, you do this in the form of an envBundle.
|
||||||
|
*/
|
||||||
|
export interface IReq_GetEnvBundle extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetEnvBundle
|
||||||
|
> {
|
||||||
|
method: 'getEnvBundle';
|
||||||
|
request: {
|
||||||
|
authorization: string;
|
||||||
|
/**
|
||||||
|
* specify this if you want to get a warning, if the envBundle is for an unexpected environment
|
||||||
|
*/
|
||||||
|
environment?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
envBundle: data.IEnvBundle;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface IReq_GetSecretBundles extends plugins.typedrequestInterfaces.implementsTR<
|
export interface IReq_GetSecretBundles extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
IReq_GetSecretBundles
|
IReq_GetSecretBundles
|
||||||
@ -72,32 +92,3 @@ export interface IReq_DeleteSecretBundleById extends plugins.typedrequestInterfa
|
|||||||
ok: boolean;
|
ok: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IReq_GetSecretBundleByAuthorization extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_GetSecretBundleByAuthorization
|
|
||||||
> {
|
|
||||||
method: 'getSecretBundleByAuthorization';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
secretBundleAuthorization: data.ISecretBundleAuthorization;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
secretBundle: data.ISecretBundle;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IReq_GetFlatKeyValueObject extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IReq_GetFlatKeyValueObject
|
|
||||||
> {
|
|
||||||
method: 'getFlatKeyValueObject';
|
|
||||||
request: {
|
|
||||||
identity: userInterfaces.IIdentity;
|
|
||||||
seccretBundleId: string;
|
|
||||||
secretBundleAuthorization: data.ISecretBundleAuthorization;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
flatKeyValueObject: {[key: string]: string};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -40,7 +40,24 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|||||||
method: 'createService';
|
method: 'createService';
|
||||||
request: {
|
request: {
|
||||||
identity: IIdentity;
|
identity: IIdentity;
|
||||||
serviceData: IService['data'];
|
name: string;
|
||||||
|
description: string;
|
||||||
|
imageId: string;
|
||||||
|
imageVersion: string;
|
||||||
|
environment: { [key: string]: string };
|
||||||
|
secretBundleId: string;
|
||||||
|
scaleFactor: number;
|
||||||
|
balancingStrategy: 'round-robin' | 'least-connections';
|
||||||
|
ports: {
|
||||||
|
web: number;
|
||||||
|
custom?: { [domain: string]: string };
|
||||||
|
};
|
||||||
|
resources?: IServiceRessources;
|
||||||
|
domains: {
|
||||||
|
name: string;
|
||||||
|
port?: number;
|
||||||
|
protocol?: 'http' | 'https' | 'ssh';
|
||||||
|
}[];
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
service: IService;
|
service: IService;
|
||||||
@ -56,19 +73,36 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|||||||
request: {
|
request: {
|
||||||
identity: IIdentity;
|
identity: IIdentity;
|
||||||
serviceId: string;
|
serviceId: string;
|
||||||
serviceData: IService['data'];
|
name: string;
|
||||||
|
description: string;
|
||||||
|
imageId: string;
|
||||||
|
imageVersion: string;
|
||||||
|
environment: { [key: string]: string };
|
||||||
|
secretBundleId: string;
|
||||||
|
scaleFactor: number;
|
||||||
|
balancingStrategy: 'round-robin' | 'least-connections';
|
||||||
|
ports: {
|
||||||
|
web: number;
|
||||||
|
custom?: { [domain: string]: string };
|
||||||
|
};
|
||||||
|
resources?: IServiceRessources;
|
||||||
|
domains: {
|
||||||
|
name: string;
|
||||||
|
port?: number;
|
||||||
|
protocol?: 'http' | 'https' | 'ssh';
|
||||||
|
}[];
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
service: IService;
|
service: IService;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRequest_Any_Cloudly_DeleteServiceById
|
export interface IRequest_Any_Cloudly_DeleteService
|
||||||
extends plugins.typedrequestInterfaces.implementsTR<
|
extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
IRequest_Any_Cloudly_DeleteServiceById
|
IRequest_Any_Cloudly_DeleteService
|
||||||
> {
|
> {
|
||||||
method: 'deleteServiceById';
|
method: 'deleteService';
|
||||||
request: {
|
request: {
|
||||||
identity: IIdentity;
|
identity: IIdentity;
|
||||||
serviceId: string;
|
serviceId: string;
|
||||||
@ -77,19 +111,3 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|||||||
success: boolean;
|
success: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject
|
|
||||||
extends plugins.typedrequestInterfaces.implementsTR<
|
|
||||||
plugins.typedrequestInterfaces.ITypedRequest,
|
|
||||||
IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject
|
|
||||||
> {
|
|
||||||
method: 'getServiceSecretBundlesAsFlatObject';
|
|
||||||
request: {
|
|
||||||
identity: IIdentity;
|
|
||||||
serviceId: string;
|
|
||||||
environment: string;
|
|
||||||
};
|
|
||||||
response: {
|
|
||||||
flatKeyValueObject: {[key: string]: string};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/cloudly',
|
name: '@serve.zone/cloudly',
|
||||||
version: '5.0.4',
|
version: '4.5.5',
|
||||||
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import { CloudlyViewS3 } from './cloudly-view-s3.js';
|
|||||||
import { CloudlyViewSecretBundles } from './cloudly-view-secretbundles.js';
|
import { CloudlyViewSecretBundles } from './cloudly-view-secretbundles.js';
|
||||||
import { CloudlyViewSecretGroups } from './cloudly-view-secretgroups.js';
|
import { CloudlyViewSecretGroups } from './cloudly-view-secretgroups.js';
|
||||||
import { CloudlyViewServices } from './cloudly-view-services.js';
|
import { CloudlyViewServices } from './cloudly-view-services.js';
|
||||||
import { CloudlyViewExternalRegistries } from './cloudly-view-externalregistries.js';
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
@ -90,10 +89,6 @@ export class CloudlyDashboard extends DeesElement {
|
|||||||
name: 'Clusters',
|
name: 'Clusters',
|
||||||
element: CloudlyViewClusters,
|
element: CloudlyViewClusters,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'ExternalRegistries',
|
|
||||||
element: CloudlyViewExternalRegistries,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'Images',
|
name: 'Images',
|
||||||
element: CloudlyViewImages,
|
element: CloudlyViewImages,
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
import * as plugins from '../plugins.js';
|
|
||||||
import * as shared from '../elements/shared/index.js';
|
|
||||||
|
|
||||||
import {
|
|
||||||
DeesElement,
|
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
state,
|
|
||||||
css,
|
|
||||||
cssManager,
|
|
||||||
} from '@design.estate/dees-element';
|
|
||||||
|
|
||||||
import * as appstate from '../appstate.js';
|
|
||||||
|
|
||||||
@customElement('cloudly-view-externalregistries')
|
|
||||||
export class CloudlyViewExternalRegistries extends DeesElement {
|
|
||||||
@state()
|
|
||||||
private data: appstate.IDataState = {
|
|
||||||
secretGroups: [],
|
|
||||||
secretBundles: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
const subecription = appstate.dataState
|
|
||||||
.select((stateArg) => stateArg)
|
|
||||||
.subscribe((dataArg) => {
|
|
||||||
this.data = dataArg;
|
|
||||||
});
|
|
||||||
this.rxSubscriptions.push(subecription);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static styles = [
|
|
||||||
cssManager.defaultStyles,
|
|
||||||
shared.viewHostCss,
|
|
||||||
css`
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
return html`
|
|
||||||
<cloudly-sectionheading>External Registries</cloudly-sectionheading>
|
|
||||||
<dees-table
|
|
||||||
.heading1=${'External Registries'}
|
|
||||||
.heading2=${'decoded in client'}
|
|
||||||
.data=${this.data.deployments}
|
|
||||||
.displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => {
|
|
||||||
return {
|
|
||||||
id: itemArg.id,
|
|
||||||
serverAmount: itemArg.data.servers.length,
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
.dataActions=${[
|
|
||||||
{
|
|
||||||
name: 'add configBundle',
|
|
||||||
iconName: 'plus',
|
|
||||||
type: ['header', 'footer'],
|
|
||||||
actionFunc: async (dataActionArg) => {
|
|
||||||
const modal = await plugins.deesCatalog.DeesModal.createAndShow({
|
|
||||||
heading: 'Add ConfigBundle',
|
|
||||||
content: html`
|
|
||||||
<dees-form>
|
|
||||||
<dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text>
|
|
||||||
<dees-input-text
|
|
||||||
.key=${'data.secretGroupIds'}
|
|
||||||
.label=${'secretGroupIds'}
|
|
||||||
.value=${''}
|
|
||||||
></dees-input-text>
|
|
||||||
<dees-input-text
|
|
||||||
.key=${'data.includedTags'}
|
|
||||||
.label=${'includedTags'}
|
|
||||||
.value=${''}
|
|
||||||
></dees-input-text>
|
|
||||||
</dees-form>
|
|
||||||
`,
|
|
||||||
menuOptions: [
|
|
||||||
{ name: 'create', action: async (modalArg) => {} },
|
|
||||||
{
|
|
||||||
name: 'cancel',
|
|
||||||
action: async (modalArg) => {
|
|
||||||
modalArg.destroy();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'delete',
|
|
||||||
iconName: 'trash',
|
|
||||||
type: ['contextmenu', 'inRow'],
|
|
||||||
actionFunc: async (actionDataArg) => {
|
|
||||||
plugins.deesCatalog.DeesModal.createAndShow({
|
|
||||||
heading: `Delete ConfigBundle ${actionDataArg.item.id}`,
|
|
||||||
content: html`
|
|
||||||
<div style="text-align:center">
|
|
||||||
Do you really want to delete the ConfigBundle?
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style="font-size: 0.8em; color: red; text-align:center; padding: 16px; margin-top: 24px; border: 1px solid #444; font-family: Intel One Mono; font-size: 16px;"
|
|
||||||
>
|
|
||||||
${actionDataArg.item.id}
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
menuOptions: [
|
|
||||||
{
|
|
||||||
name: 'cancel',
|
|
||||||
action: async (modalArg) => {
|
|
||||||
await modalArg.destroy();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'delete',
|
|
||||||
action: async (modalArg) => {
|
|
||||||
appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, {
|
|
||||||
configBundleId: actionDataArg.item.id,
|
|
||||||
});
|
|
||||||
await modalArg.destroy();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as plugins.deesCatalog.ITableAction[]}
|
|
||||||
></dees-table>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,28 +18,11 @@ export class CloudlySectionheading extends DeesElement {
|
|||||||
public static styles = [
|
public static styles = [
|
||||||
cssManager.defaultStyles,
|
cssManager.defaultStyles,
|
||||||
css`
|
css`
|
||||||
:host {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: min-content min-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-family: 'Cal Sans';
|
font-family: 'Cal Sans';
|
||||||
letter-spacing: 0.025em;
|
letter-spacing: 0.025em;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #8a0183;
|
|
||||||
height: 20px;
|
|
||||||
padding: 2px 4px;
|
|
||||||
margin-left: 16px;
|
|
||||||
font-size: 12px;
|
|
||||||
transform: translateY(12px);
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
]
|
]
|
||||||
@ -47,7 +30,6 @@ export class CloudlySectionheading extends DeesElement {
|
|||||||
public render() {
|
public render() {
|
||||||
return html`
|
return html`
|
||||||
<h1><slot></slot></h1>
|
<h1><slot></slot></h1>
|
||||||
<div class="flag">stability: alpha</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user