update
This commit is contained in:
@@ -18,6 +18,7 @@ export class OpsServer {
|
||||
public pipelinesHandler!: handlers.PipelinesHandler;
|
||||
public logsHandler!: handlers.LogsHandler;
|
||||
public webhookHandler!: handlers.WebhookHandler;
|
||||
public actionsHandler!: handlers.ActionsHandler;
|
||||
|
||||
constructor(gitopsAppRef: GitopsApp) {
|
||||
this.gitopsAppRef = gitopsAppRef;
|
||||
@@ -58,6 +59,7 @@ export class OpsServer {
|
||||
this.secretsHandler = new handlers.SecretsHandler(this);
|
||||
this.pipelinesHandler = new handlers.PipelinesHandler(this);
|
||||
this.logsHandler = new handlers.LogsHandler(this);
|
||||
this.actionsHandler = new handlers.ActionsHandler(this);
|
||||
|
||||
logger.success('OpsServer TypedRequest handlers initialized');
|
||||
}
|
||||
|
||||
50
ts/opsserver/handlers/actions.handler.ts
Normal file
50
ts/opsserver/handlers/actions.handler.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import * as plugins from '../../plugins.ts';
|
||||
import type { OpsServer } from '../classes.opsserver.ts';
|
||||
import * as interfaces from '../../../ts_interfaces/index.ts';
|
||||
import { requireValidIdentity } from '../helpers/guards.ts';
|
||||
|
||||
export class ActionsHandler {
|
||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
|
||||
constructor(private opsServerRef: OpsServer) {
|
||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||
this.registerHandlers();
|
||||
}
|
||||
|
||||
private registerHandlers(): void {
|
||||
// Force scan secrets
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ForceScanSecrets>(
|
||||
'forceScanSecrets',
|
||||
async (dataArg) => {
|
||||
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
const result = await scanService.fullScan();
|
||||
return {
|
||||
ok: true,
|
||||
connectionsScanned: result.connectionsScanned,
|
||||
secretsFound: result.secretsFound,
|
||||
errors: result.errors,
|
||||
durationMs: result.durationMs,
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// Get scan status
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetScanStatus>(
|
||||
'getScanStatus',
|
||||
async (dataArg) => {
|
||||
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
return {
|
||||
lastScanTimestamp: scanService.lastScanTimestamp,
|
||||
isScanning: scanService.isScanning,
|
||||
lastResult: scanService.lastScanResult,
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,3 +6,4 @@ export { SecretsHandler } from './secrets.handler.ts';
|
||||
export { PipelinesHandler } from './pipelines.handler.ts';
|
||||
export { LogsHandler } from './logs.handler.ts';
|
||||
export { WebhookHandler } from './webhook.handler.ts';
|
||||
export { ActionsHandler } from './actions.handler.ts';
|
||||
|
||||
@@ -12,12 +12,25 @@ export class SecretsHandler {
|
||||
}
|
||||
|
||||
private registerHandlers(): void {
|
||||
// Get all secrets (bulk fetch across all entities)
|
||||
// Get all secrets (cache-first, falls back to live fetch)
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetAllSecrets>(
|
||||
'getAllSecrets',
|
||||
async (dataArg) => {
|
||||
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
|
||||
// Try cache first
|
||||
const hasCached = await scanService.hasCachedData(dataArg.connectionId, dataArg.scope);
|
||||
if (hasCached) {
|
||||
const secrets = await scanService.getCachedSecrets({
|
||||
connectionId: dataArg.connectionId,
|
||||
scope: dataArg.scope,
|
||||
});
|
||||
return { secrets };
|
||||
}
|
||||
|
||||
// Cache miss: live fetch and save to cache
|
||||
const provider = this.opsServerRef.gitopsAppRef.connectionManager.getProvider(
|
||||
dataArg.connectionId,
|
||||
);
|
||||
@@ -26,13 +39,18 @@ export class SecretsHandler {
|
||||
|
||||
if (dataArg.scope === 'project') {
|
||||
const projects = await provider.getProjects();
|
||||
// Fetch in batches of 5 for performance
|
||||
for (let i = 0; i < projects.length; i += 5) {
|
||||
const batch = projects.slice(i, i + 5);
|
||||
const results = await Promise.allSettled(
|
||||
batch.map(async (p) => {
|
||||
const secrets = await provider.getProjectSecrets(p.id);
|
||||
return secrets.map((s) => ({ ...s, scopeName: p.fullPath || p.name }));
|
||||
return secrets.map((s) => ({
|
||||
...s,
|
||||
scopeName: p.fullPath || p.name,
|
||||
scope: 'project' as const,
|
||||
scopeId: p.id,
|
||||
connectionId: dataArg.connectionId,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
for (const result of results) {
|
||||
@@ -48,7 +66,13 @@ export class SecretsHandler {
|
||||
const results = await Promise.allSettled(
|
||||
batch.map(async (g) => {
|
||||
const secrets = await provider.getGroupSecrets(g.id);
|
||||
return secrets.map((s) => ({ ...s, scopeName: g.fullPath || g.name }));
|
||||
return secrets.map((s) => ({
|
||||
...s,
|
||||
scopeName: g.fullPath || g.name,
|
||||
scope: 'group' as const,
|
||||
scopeId: g.id,
|
||||
connectionId: dataArg.connectionId,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
for (const result of results) {
|
||||
@@ -59,23 +83,49 @@ export class SecretsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Save fetched secrets to cache (fire-and-forget)
|
||||
scanService.saveSecrets(allSecrets).catch(() => {});
|
||||
|
||||
return { secrets: allSecrets };
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// Get secrets
|
||||
// Get secrets (cache-first for single entity)
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSecrets>(
|
||||
'getSecrets',
|
||||
async (dataArg) => {
|
||||
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
|
||||
// Try cache first
|
||||
const cached = await scanService.getCachedSecrets({
|
||||
connectionId: dataArg.connectionId,
|
||||
scope: dataArg.scope,
|
||||
scopeId: dataArg.scopeId,
|
||||
});
|
||||
if (cached.length > 0) {
|
||||
return { secrets: cached };
|
||||
}
|
||||
|
||||
// Cache miss: live fetch
|
||||
const provider = this.opsServerRef.gitopsAppRef.connectionManager.getProvider(
|
||||
dataArg.connectionId,
|
||||
);
|
||||
const secrets = dataArg.scope === 'project'
|
||||
? await provider.getProjectSecrets(dataArg.scopeId)
|
||||
: await provider.getGroupSecrets(dataArg.scopeId);
|
||||
|
||||
// Save to cache (fire-and-forget)
|
||||
const fullSecrets = secrets.map((s) => ({
|
||||
...s,
|
||||
scope: dataArg.scope,
|
||||
scopeId: dataArg.scopeId,
|
||||
connectionId: dataArg.connectionId,
|
||||
}));
|
||||
scanService.saveSecrets(fullSecrets).catch(() => {});
|
||||
|
||||
return { secrets };
|
||||
},
|
||||
),
|
||||
@@ -93,6 +143,9 @@ export class SecretsHandler {
|
||||
const secret = dataArg.scope === 'project'
|
||||
? await provider.createProjectSecret(dataArg.scopeId, dataArg.key, dataArg.value)
|
||||
: await provider.createGroupSecret(dataArg.scopeId, dataArg.key, dataArg.value);
|
||||
// Refresh cache for this entity
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
scanService.scanEntity(dataArg.connectionId, dataArg.scope, dataArg.scopeId).catch(() => {});
|
||||
return { secret };
|
||||
},
|
||||
),
|
||||
@@ -110,6 +163,9 @@ export class SecretsHandler {
|
||||
const secret = dataArg.scope === 'project'
|
||||
? await provider.updateProjectSecret(dataArg.scopeId, dataArg.key, dataArg.value)
|
||||
: await provider.updateGroupSecret(dataArg.scopeId, dataArg.key, dataArg.value);
|
||||
// Refresh cache for this entity
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
scanService.scanEntity(dataArg.connectionId, dataArg.scope, dataArg.scopeId).catch(() => {});
|
||||
return { secret };
|
||||
},
|
||||
),
|
||||
@@ -129,6 +185,9 @@ export class SecretsHandler {
|
||||
} else {
|
||||
await provider.deleteGroupSecret(dataArg.scopeId, dataArg.key);
|
||||
}
|
||||
// Refresh cache for this entity
|
||||
const scanService = this.opsServerRef.gitopsAppRef.secretsScanService;
|
||||
scanService.scanEntity(dataArg.connectionId, dataArg.scope, dataArg.scopeId).catch(() => {});
|
||||
return { ok: true };
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user