fix(service): Fix secret bundle and service management bugs
This commit is contained in:
parent
7084d76c43
commit
04b278ee28
@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 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)
|
## 2025-01-02 - 4.12.1 - fix(deps)
|
||||||
Updated @git.zone/tspublish to version ^1.9.1
|
Updated @git.zone/tspublish to version ^1.9.1
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/cloudly',
|
name: '@serve.zone/cloudly',
|
||||||
version: '4.12.1',
|
version: '4.12.2',
|
||||||
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}`,
|
||||||
includedImages: [],
|
imageClaims: [],
|
||||||
type: 'external',
|
type: 'external',
|
||||||
description: 'Demo Purpose',
|
description: 'Demo Purpose',
|
||||||
includedSecretGroupIds: [secretGroup.id],
|
includedSecretGroupIds: [secretGroup.id],
|
||||||
|
@ -59,4 +59,16 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
@ -6,9 +7,51 @@ 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,5 +35,32 @@ 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(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,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,
|
||||||
includedImages: secretBundleDataArg.includedImages,
|
imageClaims: secretBundleDataArg.imageClaims,
|
||||||
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
|
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
|
||||||
includedTags: secretBundleDataArg.includedTags,
|
includedTags: secretBundleDataArg.includedTags,
|
||||||
},
|
},
|
||||||
|
@ -75,6 +75,16 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
ts_cliclient/classes.cliclient.ts
Normal file
15
ts_cliclient/classes.cliclient.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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,3 +1,11 @@
|
|||||||
|
import * as plugins from './plugins.js';
|
||||||
|
import { CliClient } from "./classes.cliclient.js";
|
||||||
|
|
||||||
export const runCli = async () => {
|
export const runCli = async () => {
|
||||||
console.log('serve.zone cli client');
|
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);
|
||||||
};
|
};
|
17
ts_cliclient/plugins.ts
Normal file
17
ts_cliclient/plugins.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// @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,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"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"
|
||||||
|
@ -21,13 +21,19 @@ 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[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You can add specific tags using this
|
* access to this secretBundle also grants access to resources with matching tags
|
||||||
*/
|
*/
|
||||||
includedTags: {
|
includedTags: {
|
||||||
key: string;
|
key: string;
|
||||||
@ -35,12 +41,12 @@ export interface ISecretBundle {
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add images
|
* access to this secretBundle also grants access to the images
|
||||||
*/
|
*/
|
||||||
includedImages: {
|
imageClaims: {
|
||||||
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
|
||||||
|
@ -8,7 +8,15 @@ 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: {
|
||||||
|
@ -111,3 +111,19 @@ 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: '4.12.1',
|
version: '4.12.2',
|
||||||
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.'
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user