Add per-cluster Tools Management and stop auto-installing side tools.

Introduce a catalog-driven Tools Management section under Clusters so
admins can install/uninstall infrastructure tools per cluster: cert-manager
(Helm/jetstack), ClusterIssuer (email + HTTP01 form, depends on cert-manager),
and central Elasticsearch. Cluster creation no longer auto-installs Elastic
or the cloudhost-node-cluster-dns DaemonSet; build bootstrap stays automatic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
keyhan
2026-05-31 16:55:51 +03:30
parent be2587dcf5
commit 786689e0fd
9 changed files with 798 additions and 247 deletions
+68
View File
@@ -95,6 +95,74 @@ export class HelmService {
}
}
/**
* Install or upgrade a Helm release from a remote chart repository.
* Adds/refreshes the repo first, then runs `helm upgrade --install`.
* Used for third-party infrastructure tools (e.g. jetstack/cert-manager).
*/
async installRemoteChart(opts: {
repoName: string;
repoUrl: string;
chart: string;
version?: string;
releaseName: string;
namespace: string;
values?: Record<string, any>;
setValues?: Record<string, string>;
kubeconfig: string;
wait?: boolean;
timeout?: string;
}): Promise<{ stdout: string; stderr: string }> {
const kubeconfigFile = await this.writeTempKubeconfig(opts.kubeconfig);
const valuesFile =
opts.values && Object.keys(opts.values).length
? await this.writeTempValues(opts.values)
: null;
try {
await execFileAsync(
'helm',
['repo', 'add', opts.repoName, opts.repoUrl, '--force-update'],
{ timeout: 60_000 },
);
await execFileAsync('helm', ['repo', 'update', opts.repoName], {
timeout: 120_000,
});
const args = [
'upgrade', '--install',
opts.releaseName,
opts.chart,
'--namespace', opts.namespace,
'--create-namespace',
'--history-max', '10',
'--kubeconfig', kubeconfigFile,
];
if (opts.version) args.push('--version', opts.version);
if (valuesFile) args.push('--values', valuesFile);
for (const [k, v] of Object.entries(opts.setValues || {})) {
args.push('--set', `${k}=${v}`);
}
if (opts.wait !== false) {
args.push('--wait', '--timeout', opts.timeout || '5m');
}
this.logger.log(
`Helm install remote: ${opts.releaseName} (${opts.chart}${opts.version ? `@${opts.version}` : ''}) in ${opts.namespace}`,
);
const result = await execFileAsync('helm', args, { timeout: 660_000 });
this.logger.log(`Helm release ${opts.releaseName} installed/upgraded successfully`);
return result;
} catch (error: any) {
this.logger.error(
`Helm remote install failed for ${opts.releaseName}: ${error.stderr || error.message}`,
);
throw new Error(`Helm install failed: ${error.stderr || error.message}`);
} finally {
this.cleanupTempFiles(kubeconfigFile, ...(valuesFile ? [valuesFile] : []));
}
}
/**
* Install or upgrade the central logging stack (Elasticsearch + Kibana).
*/