Merge pull request #1267 from pikasTech/fix/2263-frpc-config-rollout
fix: roll frpc on public exposure config changes
This commit is contained in:
@@ -1781,6 +1781,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" const configKey = String(exposure.secretKey || 'frpc.toml');",
|
||||
" const tokenKey = String(exposure.tokenKey || 'token');",
|
||||
" const toml = renderPublicExposureFrpcToml(exposure);",
|
||||
" const tomlSha256 = crypto.createHash('sha256').update(toml).digest('hex');",
|
||||
" let changed = false;",
|
||||
" let foundConfigMap = false;",
|
||||
" let foundDeployment = false;",
|
||||
@@ -1798,6 +1799,11 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" item.spec = item.spec || {};",
|
||||
" const nextStrategy = { type: 'Recreate' };",
|
||||
" if (JSON.stringify(item.spec.strategy || {}) !== JSON.stringify(nextStrategy)) { item.spec.strategy = nextStrategy; changed = true; }",
|
||||
" const templateMetadata = templateMetadataFor(item);",
|
||||
" if (templateMetadata) {",
|
||||
" templateMetadata.annotations = isObject(templateMetadata.annotations) ? templateMetadata.annotations : {};",
|
||||
" if (templateMetadata.annotations['unidesk.ai/frpc-config-sha256'] !== tomlSha256) { templateMetadata.annotations['unidesk.ai/frpc-config-sha256'] = tomlSha256; changed = true; }",
|
||||
" }",
|
||||
" const podSpec = podSpecFor(item);",
|
||||
" for (const container of Array.isArray(podSpec && podSpec.containers) ? podSpec.containers : []) {",
|
||||
" if (!isObject(container)) continue;",
|
||||
@@ -1811,7 +1817,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" process.exit(50);",
|
||||
" }",
|
||||
" if (changed) writeYamlDocuments(file, docs);",
|
||||
" console.error(JSON.stringify({ event: 'unidesk-public-exposure-postprocess', ok: true, applied: true, changed, filePath: file, hostname: exposure.hostname, serverAddr: exposure.serverAddr, serverPort: exposure.serverPort, webProxy: exposure.webProxy.name, apiProxy: exposure.apiProxy.name, extraProxyCount: Array.isArray(exposure.extraProxies) ? exposure.extraProxies.length : 0, configSha256: crypto.createHash('sha256').update(toml).digest('hex') }));",
|
||||
" console.error(JSON.stringify({ event: 'unidesk-public-exposure-postprocess', ok: true, applied: true, changed, filePath: file, hostname: exposure.hostname, serverAddr: exposure.serverAddr, serverPort: exposure.serverPort, webProxy: exposure.webProxy.name, apiProxy: exposure.apiProxy.name, extraProxyCount: Array.isArray(exposure.extraProxies) ? exposure.extraProxies.length : 0, configSha256: tomlSha256 }));",
|
||||
" return { configured: true, changed, foundConfigMap, foundDeployment };",
|
||||
"}",
|
||||
"const kustomizationChanged = patchKustomization();",
|
||||
@@ -1838,6 +1844,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" return `node - <<'NODE_UNIDESK_RUNTIME_GITOPS_VERIFY'",
|
||||
"const fs = require('fs');",
|
||||
"const path = require('path');",
|
||||
"const crypto = require('crypto');",
|
||||
"const YAML = require('yaml');",
|
||||
"const overlay = ${runtimeOverlay};",
|
||||
"const runtimePath = String(overlay.runtimePath || '');",
|
||||
@@ -1868,6 +1875,14 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" if (item.kind === 'CronJob') return item.spec.jobTemplate && item.spec.jobTemplate.spec && item.spec.jobTemplate.spec.template ? item.spec.jobTemplate.spec.template.spec : null;",
|
||||
" return null;",
|
||||
"}",
|
||||
"function templateMetadataFor(item) {",
|
||||
" if (!isObject(item) || !isObject(item.spec)) return null;",
|
||||
" if (item.kind === 'Pod') return item.metadata || null;",
|
||||
" if (['Deployment', 'StatefulSet', 'DaemonSet', 'ReplicaSet', 'ReplicationController'].includes(item.kind)) return item.spec.template ? item.spec.template.metadata : null;",
|
||||
" if (item.kind === 'Job') return item.spec.template ? item.spec.template.metadata : null;",
|
||||
" if (item.kind === 'CronJob') return item.spec.jobTemplate && item.spec.jobTemplate.spec && item.spec.jobTemplate.spec.template ? item.spec.jobTemplate.spec.template.metadata : null;",
|
||||
" return null;",
|
||||
"}",
|
||||
"function envValue(container, name) {",
|
||||
" if (!isObject(container) || !Array.isArray(container.env)) return undefined;",
|
||||
" const item = container.env.find((env) => env && env.name === name);",
|
||||
@@ -2021,11 +2036,15 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" if (!deployment) fail('public-exposure-frpc-deployment-missing', { expected: deploymentName });",
|
||||
" const toml = configMap.data && configMap.data[configKey];",
|
||||
" if (typeof toml !== 'string') fail('public-exposure-frpc-config-missing', { expectedKey: configKey });",
|
||||
" const expectedConfigSha256 = crypto.createHash('sha256').update(toml).digest('hex');",
|
||||
" const expectedProxyTokens = [exposure.webProxy, exposure.apiProxy, ...(Array.isArray(exposure.extraProxies) ? exposure.extraProxies : [])].flatMap((proxy) => [String(proxy.name), String(proxy.remotePort)]);",
|
||||
" for (const expected of [String(exposure.serverAddr), String(exposure.serverPort), ...expectedProxyTokens, 'HWLAB_FRP_TOKEN']) {",
|
||||
" if (!toml.includes(expected)) fail('public-exposure-frpc-config-mismatch', { expected });",
|
||||
" }",
|
||||
" const podSpec = podSpecFor(deployment);",
|
||||
" const templateMetadata = templateMetadataFor(deployment);",
|
||||
" const actualConfigSha256 = templateMetadata && templateMetadata.annotations ? templateMetadata.annotations['unidesk.ai/frpc-config-sha256'] : null;",
|
||||
" if (actualConfigSha256 !== expectedConfigSha256) fail('public-exposure-frpc-config-rollout-hash-mismatch', { expected: expectedConfigSha256, actual: actualConfigSha256 });",
|
||||
" const containers = Array.isArray(podSpec && podSpec.containers) ? podSpec.containers : [];",
|
||||
" const strategyType = deployment.spec && deployment.spec.strategy && deployment.spec.strategy.type;",
|
||||
" if (strategyType !== 'Recreate') fail('public-exposure-frpc-strategy-mismatch', { expected: 'Recreate', actual: strategyType || null });",
|
||||
|
||||
Reference in New Issue
Block a user