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:
@@ -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).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user