feat(api-client): Add advanced cluster creation method and refactor login actions to use API client

This commit is contained in:
2025-09-10 20:23:12 +00:00
parent 124c4ca46f
commit dc0d128892
2 changed files with 105 additions and 126 deletions

View File

@@ -271,6 +271,14 @@ export class CloudlyApiClient {
}, },
createCluster: async (optionsArg: Parameters<typeof Cluster.createCluster>[1]) => { createCluster: async (optionsArg: Parameters<typeof Cluster.createCluster>[1]) => {
return Cluster.createCluster(this, optionsArg); return Cluster.createCluster(this, optionsArg);
},
createClusterAdvanced: async (clusterName: string, setupMode?: 'manual' | 'hetzner' | 'aws' | 'digitalocean') => {
const op = 'createCluster';
const payload: any = { identity: this.identity, clusterName };
if (setupMode) payload.setupMode = setupMode;
const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.cluster.IRequest_CreateCluster>(op);
if (wsReq) return wsReq.fire(payload);
return this.createHttpRequest<plugins.servezoneInterfaces.requests.cluster.IRequest_CreateCluster>(op).fire(payload);
} }
} }

View File

@@ -14,27 +14,19 @@ export const loginStatePart: plugins.smartstate.StatePart<unknown, ILoginState>
export const loginAction = loginStatePart.createAction<{ username: string; password: string }>( export const loginAction = loginStatePart.createAction<{ username: string; password: string }>(
async (statePartArg, payloadArg) => { async (statePartArg, payloadArg) => {
const currentState = statePartArg.getState(); const currentState = statePartArg.getState();
const trLogin = let identity: plugins.interfaces.data.IIdentity = null;
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>( try {
'/typedrequest', identity = await apiClient.loginWithUsernameAndPassword(payloadArg.username, payloadArg.password) as any;
'adminLoginWithUsernameAndPassword' } catch (err) {
);
const response = await trLogin.fire({
username: payloadArg.username,
password: payloadArg.password,
}).catch(err => {
console.log(err); console.log(err);
return { }
...statePartArg.getState(),
}
});
const newState = { const newState = {
...currentState, ...currentState,
...(response.identity ? { identity: response.identity } : {}), ...(identity ? { identity } : {}),
}; };
try { try {
// Keep shared API client in sync and establish WS for modules using sockets // Keep shared API client in sync and establish WS for modules using sockets
apiClient.identity = (response as any)?.identity || null; apiClient.identity = identity || null;
if (apiClient.identity) { if (apiClient.identity) {
if (!apiClient['typedsocketClient']) { if (!apiClient['typedsocketClient']) {
await apiClient.start(); await apiClient.start();
@@ -105,60 +97,67 @@ export const apiClient = new plugins.servezoneApi.CloudlyApiClient({
export const getAllDataAction = dataState.createAction(async (statePartArg) => { export const getAllDataAction = dataState.createAction(async (statePartArg) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
// SecretsGroups // SecretsGroups
const trGetSecretGroups = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_GetSecretGroups>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const secretGroups = await apiClient.secretgroup.getSecretGroups();
'getSecretGroups' currentState = {
); ...currentState,
const response = await trGetSecretGroups.fire({ secretGroups: secretGroups as any,
identity: loginStatePart.getState().identity, };
}); } catch (err) {
currentState = { console.error('Failed to fetch secret groups:', err);
...currentState, currentState = {
secretGroups: response.secretGroups, ...currentState,
}; secretGroups: [],
};
}
// SecretBundles // SecretBundles
const trGetSecretBundles = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_GetSecretBundles>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const responseSecretBundles = await apiClient.secretbundle.getSecretBundles();
'getSecretBundles' currentState = {
); ...currentState,
const responseSecretBundles = await trGetSecretBundles.fire({ secretBundles: responseSecretBundles as any,
identity: loginStatePart.getState().identity, };
}); } catch (err) {
currentState = { console.error('Failed to fetch secret bundles:', err);
...currentState, currentState = {
secretBundles: responseSecretBundles.secretBundles, ...currentState,
}; secretBundles: [],
};
}
// images // images
const trGetImages = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_GetAllImages>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const images = await apiClient.image.getImages();
'getAllImages' currentState = {
); ...currentState,
const responseImages = await trGetImages.fire({ images: images as any,
identity: loginStatePart.getState().identity, };
}); } catch (err) {
currentState = { console.error('Failed to fetch images:', err);
...currentState, currentState = {
images: responseImages.images, ...currentState,
}; images: [],
};
}
// Clusters // Clusters
const trGetClusters = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const clusters = await apiClient.cluster.getClusters();
'getClusters' currentState = {
); ...currentState,
const responseClusters = await trGetClusters.fire({ clusters: clusters as any,
identity: loginStatePart.getState().identity, }
}); } catch (err) {
console.error('Failed to fetch clusters:', err);
currentState = { currentState = {
...currentState, ...currentState,
clusters: responseClusters.clusters, clusters: [],
}
} }
// External Registries via shared API client // External Registries via shared API client
@@ -178,18 +177,12 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => {
} }
// Services // Services
const trGetServices =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.service.IRequest_Any_Cloudly_GetServices>(
'/typedrequest',
'getServices'
);
try { try {
const responseServices = await trGetServices.fire({ apiClient.identity = loginStatePart.getState().identity;
identity: loginStatePart.getState().identity, const services = await apiClient.services.getServices();
});
currentState = { currentState = {
...currentState, ...currentState,
services: responseServices?.services || [], services: services as any,
}; };
} catch (error) { } catch (error) {
console.error('Failed to fetch services:', error); console.error('Failed to fetch services:', error);
@@ -200,15 +193,9 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => {
} }
// Deployments // Deployments
const trGetDeployments =
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.deployment.IReq_Any_Cloudly_GetDeployments>(
'/typedrequest',
'getDeployments'
);
try { try {
const responseDeployments = await trGetDeployments.fire({ apiClient.identity = loginStatePart.getState().identity;
identity: loginStatePart.getState().identity, const responseDeployments = await apiClient.deployments.getDeployments();
});
currentState = { currentState = {
...currentState, ...currentState,
deployments: responseDeployments?.deployments || [], deployments: responseDeployments?.deployments || [],
@@ -291,16 +278,13 @@ export const deleteServiceAction = dataState.createAction(
export const createSecretGroupAction = dataState.createAction( 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 = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_CreateSecretGroup>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', await apiClient.secretgroup.createSecretGroup(payloadArg.data);
'createSecretGroup' currentState = await dataState.dispatchAction(getAllDataAction, null);
); } catch (err) {
const response = await trCreateSecretGroup.fire({ console.error('Failed to create secret group:', err);
identity: loginStatePart.getState().identity, }
secretGroup: payloadArg,
});
currentState = await dataState.dispatchAction(getAllDataAction, null);
return currentState; return currentState;
return currentState; return currentState;
} }
@@ -309,16 +293,16 @@ export const createSecretGroupAction = dataState.createAction(
export const deleteSecretGroupAction = dataState.createAction( 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 = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_DeleteSecretGroupById>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const sg = (currentState.secretGroups as any[])?.find(s => s.id === payloadArg.secretGroupId);
'deleteSecretGroupById' if (sg) {
); await sg.delete(apiClient as any, sg.id);
const response = await trDeleteSecretGroup.fire({ }
identity: loginStatePart.getState().identity, currentState = await dataState.dispatchAction(getAllDataAction, null);
secretGroupId: payloadArg.secretGroupId, } catch (err) {
}); console.error('Failed to delete secret group:', err);
currentState = await dataState.dispatchAction(getAllDataAction, null); }
return currentState; return currentState;
} }
); );
@@ -327,16 +311,16 @@ export const deleteSecretGroupAction = dataState.createAction(
export const deleteSecretBundleAction = dataState.createAction( 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 = try {
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_DeleteSecretBundleById>( apiClient.identity = loginStatePart.getState().identity;
'/typedrequest', const sb = (currentState.secretBundles as any[])?.find(b => b.id === payloadArg.configBundleId);
'deleteSecretBundleById' if (sb) {
); await sb.delete(apiClient as any, sb.id);
const response = await trDeleteConfigBundle.fire({ }
identity: loginStatePart.getState().identity, currentState = await dataState.dispatchAction(getAllDataAction, null);
secretBundleId: payloadArg.configBundleId, } catch (err) {
}); console.error('Failed to delete secret bundle:', err);
currentState = await dataState.dispatchAction(getAllDataAction, null); }
return currentState; return currentState;
} }
); );
@@ -603,21 +587,8 @@ export const addClusterAction = dataState.createAction(
} }
) => { ) => {
let currentState = statePartArg.getState(); let currentState = statePartArg.getState();
const trAddCluster = apiClient.identity = loginStatePart.getState().identity;
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IRequest_CreateCluster>( await apiClient.cluster.createClusterAdvanced(payloadArg.clusterName, payloadArg.setupMode);
'/typedrequest', return await dataState.dispatchAction(getAllDataAction, null);
'createCluster'
);
const response = await trAddCluster.fire({
identity: loginStatePart.getState().identity,
...payloadArg,
});
currentState = {
...currentState,
...{
clusters: [...currentState.clusters, response.cluster],
},
}
return currentState;
} }
); );