fix(secret-management): Refactor secret management to use distinct secret bundle and group APIs. Introduce API client classes for secret bundles and groups.

This commit is contained in:
Philipp Kunz 2024-12-21 20:21:54 +01:00
parent d453da709f
commit 4b993fc6b3
15 changed files with 533 additions and 157 deletions

View File

@ -1,5 +1,12 @@
# Changelog # Changelog
## 2024-12-21 - 4.5.3 - fix(secret-management)
Refactor secret management to use distinct secret bundle and group APIs. Introduce API client classes for secret bundles and groups.
- Updated secret management logic to separate secret bundle and group APIs.
- Implemented new API client classes for managing secret bundles and groups.
- Fixed incorrect method usages for secret-related actions.
## 2024-12-20 - 4.5.2 - fix(apiclient) ## 2024-12-20 - 4.5.2 - fix(apiclient)
Implemented IService interface in Service class and improved secret bundle documentation. Implemented IService interface in Service class and improved secret bundle documentation.

2
pnpm-lock.yaml generated
View File

@ -6569,7 +6569,9 @@ snapshots:
'@push.rocks/smartshell': 3.2.2 '@push.rocks/smartshell': 3.2.2
'@push.rocks/taskbuffer': 3.1.7 '@push.rocks/taskbuffer': 3.1.7
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil
- supports-color - supports-color
- utf-8-validate
'@hapi/bourne@3.0.0': {} '@hapi/bourne@3.0.0': {}

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/cloudly', name: '@serve.zone/cloudly',
version: '4.5.2', version: '4.5.3',
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.'
} }

View File

@ -35,20 +35,71 @@ export class CloudlySecretManager {
this.typedrouter = new plugins.typedrequest.TypedRouter(); this.typedrouter = new plugins.typedrequest.TypedRouter();
this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter); this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter);
this.typedrouter.addTypedHandler( // secretbundle routes
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>( this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
'adminGetConfigBundlesAndSecretGroups', new plugins.typedrequest.TypedHandler(
'getSecretBundles',
async (dataArg, toolsArg) => { async (dataArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], dataArg); await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], dataArg);
dataArg.identity.jwt; dataArg.identity.jwt;
const secretBundles = await SecretBundle.getInstances({}); const secretBundles = await SecretBundle.getInstances({});
const secretGroups = await SecretGroup.getInstances({});
return { return {
secretBundles: [ secretBundles: [
...(await Promise.all( ...(await Promise.all(
secretBundles.map((configBundle) => configBundle.createSavableObject()), secretBundles.map((configBundle) => configBundle.createSavableObject()),
)), )),
], ],
};
},
),
);
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
new plugins.typedrequest.TypedHandler('createSecretBundle', async (dataArg) => {
const secretBundle = new SecretBundle();
secretBundle.id = plugins.smartunique.shortId(8);
secretBundle.data = dataArg.secretBundle.data;
await secretBundle.save();
return {
resultSecretBundle: await secretBundle.createSavableObject(),
};
}),
);
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
new plugins.typedrequest.TypedHandler('updateSecretBundle', async (dataArg) => {
const secretBundle = await SecretBundle.getInstance({
id: dataArg.secretBundle.id,
});
secretBundle.data = dataArg.secretBundle.data;
await secretBundle.save();
return {
resultSecretBundle: await secretBundle.createSavableObject(),
};
}),
);
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
new plugins.typedrequest.TypedHandler('deleteSecretBundleById', async (dataArg) => {
const secretBundle = await SecretBundle.getInstance({
id: dataArg.secretBundleId,
});
await secretBundle.delete();
return {
ok: true,
};
}),
);
// secretgroup routes
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroups>(
new plugins.typedrequest.TypedHandler(
'getSecretGroups',
async (dataArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], dataArg);
dataArg.identity.jwt;
const secretGroups = await SecretGroup.getInstances({});
return {
secretGroups: [ secretGroups: [
...(await Promise.all( ...(await Promise.all(
secretGroups.map((secretGroup) => secretGroup.createSavableObject()), secretGroups.map((secretGroup) => secretGroup.createSavableObject()),
@ -59,50 +110,45 @@ export class CloudlySecretManager {
), ),
); );
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_CreateConfigBundlesAndSecretGroups>( this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_CreateSecretGroup>(
new plugins.typedrequest.TypedHandler( new plugins.typedrequest.TypedHandler('createSecretGroup', async (dataArg) => {
'adminCreateConfigBundlesAndSecretGroups', const secretGroup = new SecretGroup();
async (dataArg) => { secretGroup.id = plugins.smartunique.shortId(8);
for (const secretGroupObject of dataArg.secretGroups) { secretGroup.data = dataArg.secretGroup.data;
const secretGroup = new SecretGroup(); await secretGroup.save();
secretGroup.id = plugins.smartunique.shortId(8); return {
secretGroup.data = secretGroupObject.data; resultSecretGroup: await secretGroup.createSavableObject(),
await secretGroup.save(); };
} }),
return { );
ok: true,
}; this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_UpdateSecretGroup>(
}, new plugins.typedrequest.TypedHandler('updateSecretGroup', async (dataArg) => {
), const secretGroup = await SecretGroup.getInstance({
id: dataArg.secretGroup.id,
});
secretGroup.data = dataArg.secretGroup.data;
await secretGroup.save();
return {
resultSecretGroup: await secretGroup.createSavableObject(),
};
}),
);
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
new plugins.typedrequest.TypedHandler('deleteSecretGroupById', async (dataArg) => {
const secretGroup = await SecretGroup.getInstance({
id: dataArg.secretGroupId,
});
await secretGroup.delete();
return {
ok: true,
};
}),
); );
this.typedrouter.addTypedHandler( this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>( new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetEnvBundle>(
'adminDeleteConfigBundlesAndSecretGroups',
async (dataArg) => {
for (const secretGroupId of dataArg.secretGroupIds) {
const secretGroup = await SecretGroup.getInstance({
id: secretGroupId,
});
await secretGroup.delete();
}
for (const secretBundleId of dataArg.secretBundleIds) {
const configBundle = await SecretBundle.getInstance({
id: secretBundleId,
});
await configBundle.delete();
console.log(`deleted configbundle ${secretBundleId}`);
}
return {
ok: true,
};
},
),
);
// lets add typedrouter routes for accessing the configvailt from apps
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_GetEnvBundle>(
'getEnvBundle', 'getEnvBundle',
async (dataArg) => { async (dataArg) => {
const wantedBundle = await SecretBundle.getInstance({ const wantedBundle = await SecretBundle.getInstance({

View File

@ -0,0 +1,96 @@
import * as plugins from './plugins.js';
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBundle {
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) {
const getSecretBundleByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
'getSecretBundleById'
);
const response = await getSecretBundleByIdTR.fire({
identity: cloudlyClientRef.identity,
secretBundleId: secretBundleIdArg,
});
const newSecretBundle = new SecretBundle(cloudlyClientRef);
Object.assign(newSecretBundle, response.secretBundle);
return newSecretBundle;
}
public static async getSecretBundles(cloudlyClientRef: CloudlyApiClient) {
const getSecretBundlesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
'getSecretBundles'
);
const response = await getSecretBundlesTR.fire({
identity: cloudlyClientRef.identity,
});
const secretBundles: SecretBundle[] = [];
for (const secretBundle of response.secretBundles) {
const newSecretBundle = new SecretBundle(cloudlyClientRef);
Object.assign(newSecretBundle, secretBundle);
secretBundles.push(newSecretBundle);
}
return secretBundles;
}
public static async createSecretBundle(cloudlyClientRef: CloudlyApiClient, secretBundleDataArg: Partial<plugins.servezoneInterfaces.data.ISecretBundle['data']>) {
const createSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
'createSecretBundle'
);
const response = await createSecretBundleTR.fire({
identity: cloudlyClientRef.identity,
secretBundle: {
id: null,
data: {
name: secretBundleDataArg.name,
description: secretBundleDataArg.description,
type: secretBundleDataArg.type,
authorizations: secretBundleDataArg.authorizations,
includedImages: secretBundleDataArg.includedImages,
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
includedTags: secretBundleDataArg.includedTags,
},
},
});
const newSecretBundle = new SecretBundle(cloudlyClientRef);
Object.assign(newSecretBundle, response.resultSecretBundle);
return newSecretBundle;
}
public async update() {
const updateSecretBundleTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
'updateSecretBundle'
);
const response = await updateSecretBundleTR.fire({
identity: this.cloudlyClientRef.identity,
secretBundle: {
id: this.id,
data: this.data,
},
});
const resultSecretBundleData = response.resultSecretBundle.data;
plugins.smartexpect.expect(resultSecretBundleData).toEqual(this.data);
return this;
}
public async delete(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
const deleteSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
'deleteSecretBundleById'
);
const response = await deleteSecretBundleTR.fire({
identity: cloudlyClientRef.identity,
secretBundleId: this.id,
});
plugins.smartexpect.expect(response.ok).toBeTrue();
return null;
}
}

View File

@ -0,0 +1,103 @@
import * as plugins from './plugins.js';
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
export class SecretGroup implements plugins.servezoneInterfaces.data.ISecretGroup {
public cloudlyClientRef: CloudlyApiClient;
public id: string;
public data: plugins.servezoneInterfaces.data.ISecretGroup['data'];
constructor(cloudlyClientRef: CloudlyApiClient) {
this.cloudlyClientRef = cloudlyClientRef;
}
public static async getSecretGroupById(cloudlyClientRef: CloudlyApiClient, secretGroupIdArg: string) {
const getSecretGroupByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroupById>(
'getSecretGroupById'
);
const response = await getSecretGroupByIdTR.fire({
identity: cloudlyClientRef.identity,
secretGroupId: secretGroupIdArg,
});
const newSecretGroup = new SecretGroup(cloudlyClientRef);
Object.assign(newSecretGroup, response.secretGroup);
return newSecretGroup;
}
public static async getSecretGroups(cloudlyClientRef: CloudlyApiClient) {
const getSecretGroupsTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroups>(
'getSecretGroups'
);
const response = await getSecretGroupsTR.fire({
identity: cloudlyClientRef.identity,
});
const secretGroups: SecretGroup[] = [];
for (const secretGroup of response.secretGroups) {
const newSecretGroup = new SecretGroup(cloudlyClientRef);
Object.assign(newSecretGroup, secretGroup);
secretGroups.push(newSecretGroup);
}
return secretGroups;
}
public static async createSecretGroup(cloudlyClientRef: CloudlyApiClient, secretGroupDataArg: Partial<plugins.servezoneInterfaces.data.ISecretGroup['data']>) {
const createSecretGroupTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_CreateSecretGroup>(
'createSecretGroup'
);
const response = await createSecretGroupTR.fire({
identity: cloudlyClientRef.identity,
secretGroup: {
id: null,
data: {
name: secretGroupDataArg.name,
description: secretGroupDataArg.description,
environments: secretGroupDataArg.environments,
key: secretGroupDataArg.key,
tags: secretGroupDataArg.tags,
priority: secretGroupDataArg.priority,
},
},
});
const newSecretGroup = new SecretGroup(cloudlyClientRef);
Object.assign(newSecretGroup, response.resultSecretGroup);
return newSecretGroup;
}
// INSTANCE
public async update() {
const updateSecretGroupTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_UpdateSecretGroup>(
'updateSecretGroup'
);
const response = await updateSecretGroupTR.fire({
identity: this.cloudlyClientRef.identity,
secretGroup: {
id: this.id,
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,
},
},
});
const resultSecretGroupData = response.resultSecretGroup.data;
plugins.smartexpect.expect(resultSecretGroupData).toEqual(this.data);
return this;
}
public async delete(cloudlyClientRef: CloudlyApiClient, secretGroupIdArg: string) {
const deleteSecretGroupTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
'deleteSecretGroupById'
);
const response = await deleteSecretGroupTR.fire({
identity: cloudlyClientRef.identity,
secretGroupId: this.id,
});
plugins.smartexpect.expect(response.ok).toBeTrue();
return null;
}
}

View 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') {
}
}

View File

@ -6,11 +6,13 @@ export {
} }
// @push.rocks scope // @push.rocks scope
import * as smartexpect from '@push.rocks/smartexpect';
import * as smartpromise from '@push.rocks/smartpromise'; import * as smartpromise from '@push.rocks/smartpromise';
import * as smartrx from '@push.rocks/smartrx'; import * as smartrx from '@push.rocks/smartrx';
import * as webstream from '@push.rocks/smartstream/web'; import * as webstream from '@push.rocks/smartstream/web';
export { export {
smartexpect,
smartpromise, smartpromise,
smartrx, smartrx,
webstream, webstream,

View File

@ -0,0 +1,16 @@
import * as plugins from '../plugins.js';
import * as userInterfaces from '../data/user.js';
export interface IReq_Admin_LoginWithUsernameAndPassword extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_LoginWithUsernameAndPassword
> {
method: 'adminLoginWithUsernameAndPassword';
request: {
username: string;
password: string;
};
response: {
identity: userInterfaces.IIdentity;
}
}

View File

@ -1,5 +1,6 @@
import * as plugins from '../plugins.js'; import * as plugins from '../plugins.js';
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';
@ -9,13 +10,15 @@ import * as informRequests from './inform.js';
import * as logRequests from './log.js'; import * as logRequests from './log.js';
import * as networkRequests from './network.js'; import * as networkRequests from './network.js';
import * as routingRequests from './routing.js'; import * as routingRequests from './routing.js';
import * as secretRequests from './secret.js'; import * as secretBundleRequests from './secretbundle.js';
import * as secretGroupRequests from './secretgroup.js';
import * as serverRequests from './server.js'; import * as serverRequests from './server.js';
import * as serviceRequests from './service.js'; import * as serviceRequests from './service.js';
import * as statusRequests from './status.js'; import * as statusRequests from './status.js';
import * as versionRequests from './version.js'; import * as versionRequests from './version.js';
export { export {
adminRequests as admin,
certificateRequests as certificate, certificateRequests as certificate,
clusterRequests as cluster, clusterRequests as cluster,
configRequests as config, configRequests as config,
@ -25,7 +28,8 @@ export {
logRequests as log, logRequests as log,
networkRequests as network, networkRequests as network,
routingRequests as routing, routingRequests as routing,
secretRequests as secret, secretBundleRequests as secretbundle,
secretGroupRequests as secretgroup,
serverRequests as server, serverRequests as server,
serviceRequests as service, serviceRequests as service,
statusRequests as status, statusRequests as status,

View File

@ -1,94 +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_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_Admin_LoginWithUsernameAndPassword extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_LoginWithUsernameAndPassword
> {
method: 'adminLoginWithUsernameAndPassword';
request: {
username: string;
password: string;
};
response: {
identity: userInterfaces.IIdentity;
}
}
export interface IReq_Admin_GetConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_GetConfigBundlesAndSecretGroups
> {
method: 'adminGetConfigBundlesAndSecretGroups';
request: {
identity: userInterfaces.IIdentity;
};
response: {
secretBundles: data.ISecretBundle[];
secretGroups: data.ISecretGroup[];
};
}
export interface IReq_Admin_CreateConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_CreateConfigBundlesAndSecretGroups
> {
method: 'adminCreateConfigBundlesAndSecretGroups';
request: {
identity: userInterfaces.IIdentity;
secretBundles: data.ISecretBundle[];
secretGroups: data.ISecretGroup[];
};
response: {
ok: boolean;
};
}
export interface IReq_Admin_UpdateConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_UpdateConfigBundlesAndSecretGroups
> {
method: 'adminUpdateConfigBundlesAndSecretGroups';
request: {
identity: userInterfaces.IIdentity;
configBundles: data.ISecretBundle[];
secretGroups: data.ISecretGroup[];
};
response: {
ok: boolean;
};
}
export interface IReq_Admin_DeleteConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_Admin_DeleteConfigBundlesAndSecretGroups
> {
method: 'adminDeleteConfigBundlesAndSecretGroups';
request: {
identity: userInterfaces.IIdentity;
secretBundleIds: string[];
secretGroupIds: string[];
};
response: {
ok: boolean;
};
}

View File

@ -0,0 +1,79 @@
import * as plugins from '../plugins.js';
import * as data from '../data/index.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<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_GetSecretBundles
> {
method: 'getSecretBundles';
request: {
identity: userInterfaces.IIdentity;
};
response: {
secretBundles: data.ISecretBundle[];
};
}
export interface IReq_CreateSecretBundle extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_CreateSecretBundle
> {
method: 'createSecretBundle';
request: {
identity: userInterfaces.IIdentity;
secretBundle: data.ISecretBundle;
};
response: {
resultSecretBundle: data.ISecretBundle;
};
}
export interface IReq_UpdateSecretBundle extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_UpdateSecretBundle
> {
method: 'updateSecretBundle';
request: {
identity: userInterfaces.IIdentity;
secretBundle: data.ISecretBundle;
};
response: {
resultSecretBundle: data.ISecretBundle;
};
}
export interface IReq_DeleteSecretBundleById extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_DeleteSecretBundleById
> {
method: 'deleteSecretBundleById';
request: {
identity: userInterfaces.IIdentity;
secretBundleId: string;
};
response: {
ok: boolean;
};
}

View File

@ -0,0 +1,74 @@
import * as plugins from '../plugins.js';
import * as data from '../data/index.js';
import * as userInterfaces from '../data/user.js';
export interface IReq_GetSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_GetSecretGroups
> {
method: 'getSecretGroups';
request: {
identity: userInterfaces.IIdentity;
};
response: {
secretGroups: data.ISecretGroup[];
};
}
export interface IReq_GetSecretGroupById extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_GetSecretGroupById
> {
method: 'getSecretGroupById';
request: {
identity: userInterfaces.IIdentity;
secretGroupId: string;
};
response: {
secretGroup: data.ISecretGroup;
};
}
export interface IReq_CreateSecretGroup extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_CreateSecretGroup
> {
method: 'createSecretGroup';
request: {
identity: userInterfaces.IIdentity;
secretGroup: data.ISecretGroup;
};
response: {
resultSecretGroup: data.ISecretGroup;
};
}
export interface IReq_UpdateSecretGroup extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_UpdateSecretGroup
> {
method: 'updateSecretGroup';
request: {
identity: userInterfaces.IIdentity;
secretGroup: data.ISecretGroup;
};
response: {
resultSecretGroup: data.ISecretGroup;
};
}
export interface IReq_DeleteSecretGroupById extends plugins.typedrequestInterfaces.implementsTR<
plugins.typedrequestInterfaces.ITypedRequest,
IReq_DeleteSecretGroupById
> {
method: 'deleteSecretGroupById';
request: {
identity: userInterfaces.IIdentity;
secretGroupId: string;
};
response: {
ok: boolean;
};
}

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/cloudly', name: '@serve.zone/cloudly',
version: '4.5.2', version: '4.5.3',
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.'
} }

View File

@ -15,7 +15,7 @@ export const loginAction = loginStatePart.createAction<{ username: string; passw
async (statePartArg, payloadArg) => { async (statePartArg, payloadArg) => {
const currentState = statePartArg.getState(); const currentState = statePartArg.getState();
const trLogin = const trLogin =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_LoginWithUsernameAndPassword>( new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>(
'/typedrequest', '/typedrequest',
'adminLoginWithUsernameAndPassword' 'adminLoginWithUsernameAndPassword'
); );
@ -77,20 +77,34 @@ export const dataState = await appstate.getStatePart<IDataState>(
); );
// Getting data // Getting data
export const getAllDataAction = dataState.createAction(async (statePartArg, partialArg?: 'secrets' | 'images') => { export const getAllDataAction = dataState.createAction(async (statePartArg) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
// Secrets // SecretsGroups
const trGetSecrets = const trGetSecretGroups =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>( new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_GetSecretGroups>(
'/typedrequest', '/typedrequest',
'adminGetConfigBundlesAndSecretGroups' 'getSecretGroups'
); );
const response = await trGetSecrets.fire({ const response = await trGetSecretGroups.fire({
identity: loginStatePart.getState().identity, identity: loginStatePart.getState().identity,
}); });
currentState = { currentState = {
...currentState, ...currentState,
...response, secretGroups: response.secretGroups,
};
// SecretBundles
const trGetSecretBundles =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_GetSecretBundles>(
'/typedrequest',
'getSecretBundles'
);
const responseSecretBundles = await trGetSecretBundles.fire({
identity: loginStatePart.getState().identity,
});
currentState = {
...currentState,
secretBundles: responseSecretBundles.secretBundles,
}; };
// images // images
@ -104,7 +118,7 @@ export const getAllDataAction = dataState.createAction(async (statePartArg, part
}); });
currentState = { currentState = {
...currentState, ...currentState,
...responseImages, images: responseImages.images,
}; };
// Clusters // Clusters
@ -119,7 +133,7 @@ export const getAllDataAction = dataState.createAction(async (statePartArg, part
currentState = { currentState = {
...currentState, ...currentState,
...responseClusters, clusters: responseClusters.clusters,
} }
return currentState; return currentState;
@ -130,9 +144,9 @@ export const createSecretGroupAction = dataState.createAction(
async (statePartArg, payloadArg: plugins.interfaces.data.ISecretGroup) => { async (statePartArg, payloadArg: plugins.interfaces.data.ISecretGroup) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
const trCreateSecretGroup = const trCreateSecretGroup =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_CreateConfigBundlesAndSecretGroups>( new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_CreateSecretBundlesAndGroups>(
'/typedrequest', '/typedrequest',
'adminCreateConfigBundlesAndSecretGroups' 'adminCreateSecretBundlesAndGroups'
); );
const response = await trCreateSecretGroup.fire({ const response = await trCreateSecretGroup.fire({
identity: loginStatePart.getState().identity, identity: loginStatePart.getState().identity,
@ -149,7 +163,7 @@ export const deleteSecretGroupAction = dataState.createAction(
async (statePartArg, payloadArg: { secretGroupId: string }) => { async (statePartArg, payloadArg: { secretGroupId: string }) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
const trDeleteSecretGroup = const trDeleteSecretGroup =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>( new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteSecretBundlesAndGroups>(
'/typedrequest', '/typedrequest',
'adminDeleteConfigBundlesAndSecretGroups' 'adminDeleteConfigBundlesAndSecretGroups'
); );
@ -168,7 +182,7 @@ export const deleteSecretBundleAction = dataState.createAction(
async (statePartArg, payloadArg: { configBundleId: string }) => { async (statePartArg, payloadArg: { configBundleId: string }) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
const trDeleteConfigBundle = const trDeleteConfigBundle =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>( new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteSecretBundlesAndGroups>(
'/typedrequest', '/typedrequest',
'adminDeleteConfigBundlesAndSecretGroups' 'adminDeleteConfigBundlesAndSecretGroups'
); );