feat: 接入 ApiState 自动交付
This commit is contained in:
@@ -313,23 +313,23 @@ sourceAuthority:
|
||||
- key: sub2rank-nc01
|
||||
targetId: NC01
|
||||
upstream:
|
||||
repository: pikasTech/sub2rank
|
||||
cloneUrl: https://github.com/pikasTech/sub2rank.git
|
||||
repository: pikasTech/apistate
|
||||
cloneUrl: https://github.com/pikasTech/apistate.git
|
||||
branch: master
|
||||
gitea:
|
||||
owner: mirrors
|
||||
name: pikasTech-sub2rank
|
||||
name: pikasTech-apistate
|
||||
mirrorMode: controlled-push
|
||||
publicRead: true
|
||||
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-sub2rank.git
|
||||
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-apistate.git
|
||||
gitops:
|
||||
branch: master
|
||||
flushDisposition: not-a-gitops-branch
|
||||
snapshot:
|
||||
naming: application-source-snapshot
|
||||
prefix: refs/unidesk/snapshots/gitea-actions/sub2rank-master-nc01
|
||||
prefix: refs/unidesk/snapshots/gitea-actions/apistate-master-nc01
|
||||
legacyGitMirror:
|
||||
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-sub2rank.git
|
||||
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-apistate.git
|
||||
configRef: config/platform-infra/sub2rank.yaml#application.remote
|
||||
disposition: replaced-by-gitea
|
||||
- key: hwlab-jd01-v03
|
||||
|
||||
@@ -176,18 +176,18 @@ repositories:
|
||||
name: sub2rank-nc01
|
||||
namespace: devops-infra
|
||||
providerType: gitea
|
||||
url: https://gitea.pikapython.com/mirrors/pikasTech-sub2rank
|
||||
cloneUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-sub2rank.git
|
||||
url: https://gitea.pikapython.com/mirrors/pikasTech-apistate
|
||||
cloneUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-apistate.git
|
||||
owner: mirrors
|
||||
repo: pikasTech-sub2rank
|
||||
repo: pikasTech-apistate
|
||||
secretName: pac-gitea-sub2rank-nc01
|
||||
tokenKey: token
|
||||
webhookSecretKey: webhook.secret
|
||||
concurrencyLimit: 1
|
||||
params:
|
||||
git_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-sub2rank.git
|
||||
git_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-apistate.git
|
||||
source_branch: master
|
||||
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/sub2rank-master-nc01
|
||||
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/apistate-master-nc01
|
||||
node: NC01
|
||||
image_repository: 127.0.0.1:5000/sub2rank/sub2rank
|
||||
registry_probe_base: http://127.0.0.1:5000
|
||||
|
||||
@@ -57,6 +57,9 @@ targets:
|
||||
- id: webterm
|
||||
configRef: config/platform-infra/webterm.yaml
|
||||
path: targets[id=local-7683].publicExposure
|
||||
- id: apistate
|
||||
configRef: config/platform-infra/sub2rank.yaml
|
||||
path: targets[id=NC01].publicEdge
|
||||
- id: selfmedia-development
|
||||
configRef: config/selfmedia.yaml
|
||||
path: delivery.targets.NC01.deployment.publicExposure.edge
|
||||
|
||||
@@ -2,7 +2,7 @@ version: 1
|
||||
kind: platform-infra-sub2rank
|
||||
|
||||
metadata:
|
||||
id: sub2rank-public
|
||||
id: apistate-public
|
||||
owner: unidesk
|
||||
relatedIssues: []
|
||||
|
||||
@@ -10,11 +10,11 @@ defaults:
|
||||
targetId: NC01
|
||||
|
||||
application:
|
||||
repository: pikasTech/sub2rank
|
||||
remote: https://github.com/pikasTech/sub2rank.git
|
||||
repository: pikasTech/apistate
|
||||
remote: https://github.com/pikasTech/apistate.git
|
||||
branch: master
|
||||
sourceRoot: /root/sub2rank
|
||||
configRef: /root/sub2rank/config/sub2rank.yaml
|
||||
sourceRoot: /root/apistate
|
||||
configRef: /root/apistate/config/sub2rank.yaml
|
||||
sourceConfigPath: config/sub2rank.yaml
|
||||
dockerfile: Dockerfile
|
||||
runtimeTarget: k8s
|
||||
@@ -34,7 +34,7 @@ delivery:
|
||||
workspaceSize: 4Gi
|
||||
toolsImage: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
|
||||
buildkitImage: 127.0.0.1:5000/hwlab/buildkit:rootless
|
||||
sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/sub2rank-master-nc01
|
||||
sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/apistate-master-nc01
|
||||
build:
|
||||
networkMode: host
|
||||
proxy:
|
||||
@@ -77,11 +77,11 @@ targets:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
publicExposure:
|
||||
enabled: true
|
||||
publicBaseUrl: https://rank.pikapython.com
|
||||
enabled: false
|
||||
publicBaseUrl: https://apistate.hwpod.com
|
||||
dns:
|
||||
hostname: rank.pikapython.com
|
||||
expectedA: 82.156.23.220
|
||||
hostname: apistate.hwpod.com
|
||||
expectedA: 152.53.229.148
|
||||
resolvers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
@@ -105,6 +105,12 @@ targets:
|
||||
caddyConfigPath: /etc/caddy/Caddyfile
|
||||
caddyServiceName: caddy
|
||||
responseHeaderTimeoutSeconds: 60
|
||||
publicEdge:
|
||||
enabled: true
|
||||
hostname: apistate.hwpod.com
|
||||
upstream: sub2rank.platform-infra.svc.cluster.local:8080
|
||||
healthPath: /health
|
||||
expectedA: 152.53.229.148
|
||||
|
||||
runtime:
|
||||
sharedNetworkPolicyRef:
|
||||
@@ -128,16 +134,24 @@ runtime:
|
||||
claimName: sub2rank-data
|
||||
size: 1Gi
|
||||
mountPath: /var/lib/sub2rank
|
||||
hostMounts:
|
||||
- source: /root/unidesk
|
||||
target: /opt/unidesk
|
||||
readOnly: true
|
||||
secret:
|
||||
configRef: config/secrets-distribution.yaml
|
||||
declarationId: sub2rank-runtime
|
||||
requiredTargetKeys:
|
||||
- SUB2RANK_ADMIN_TOKEN
|
||||
- APISTATE_WEB_PASSWORD
|
||||
- APISTATE_API_KEY
|
||||
- APISTATE_SESSION_SECRET
|
||||
- SUB2API_ADMIN_EMAIL
|
||||
- SUB2API_ADMIN_PASSWORD
|
||||
- FRP_TOKEN
|
||||
appEnvTargetKeys:
|
||||
- SUB2RANK_ADMIN_TOKEN
|
||||
- APISTATE_WEB_PASSWORD
|
||||
- APISTATE_API_KEY
|
||||
- APISTATE_SESSION_SECRET
|
||||
- SUB2API_ADMIN_EMAIL
|
||||
- SUB2API_ADMIN_PASSWORD
|
||||
probes:
|
||||
|
||||
@@ -82,16 +82,24 @@ sources:
|
||||
- FRP_TOKEN
|
||||
createIfMissing:
|
||||
enabled: false
|
||||
- sourceRef: platform-infra/sub2rank.env
|
||||
- sourceRef: platform-infra/apistate.env
|
||||
type: env
|
||||
requiredKeys:
|
||||
- SUB2RANK_ADMIN_TOKEN
|
||||
- APISTATE_WEB_PASSWORD
|
||||
- APISTATE_API_KEY
|
||||
- APISTATE_SESSION_SECRET
|
||||
createIfMissing:
|
||||
enabled: true
|
||||
randomBase64Url:
|
||||
SUB2RANK_ADMIN_TOKEN:
|
||||
APISTATE_WEB_PASSWORD:
|
||||
bytes: 32
|
||||
prefix: srk_
|
||||
prefix: asp_
|
||||
APISTATE_API_KEY:
|
||||
bytes: 32
|
||||
prefix: ask_
|
||||
APISTATE_SESSION_SECRET:
|
||||
bytes: 32
|
||||
prefix: ass_
|
||||
- sourceRef: platform-infra/pikaoa.env
|
||||
type: env
|
||||
requiredKeys:
|
||||
@@ -399,9 +407,15 @@ kubernetesSecrets:
|
||||
secretName: sub2rank-secrets
|
||||
type: Opaque
|
||||
data:
|
||||
- sourceRef: platform-infra/sub2rank.env
|
||||
sourceKey: SUB2RANK_ADMIN_TOKEN
|
||||
targetKey: SUB2RANK_ADMIN_TOKEN
|
||||
- sourceRef: platform-infra/apistate.env
|
||||
sourceKey: APISTATE_WEB_PASSWORD
|
||||
targetKey: APISTATE_WEB_PASSWORD
|
||||
- sourceRef: platform-infra/apistate.env
|
||||
sourceKey: APISTATE_API_KEY
|
||||
targetKey: APISTATE_API_KEY
|
||||
- sourceRef: platform-infra/apistate.env
|
||||
sourceKey: APISTATE_SESSION_SECRET
|
||||
targetKey: APISTATE_SESSION_SECRET
|
||||
- sourceRef: platform-infra/sub2api.env
|
||||
sourceKey: ADMIN_EMAIL
|
||||
targetKey: SUB2API_ADMIN_EMAIL
|
||||
|
||||
@@ -279,3 +279,7 @@
|
||||
## R4 [completed]
|
||||
|
||||
关联 [UniDesk #2281](https://github.com/pikasTech/unidesk/issues/2281),增强 Sub2API runtime 模板批量 CRUD:支持通过显式参数按原生 runtime 已配置同类策略和账号类型自动选集,并支持精确排除 selector;dry-run 直接输出最终账号名称、ID、选中来源与排除摘要,confirm 复用既有写后自动回读对账,避免先 list、人工抄账号 ID、再 apply 的重复调用;显式 JSON 使用紧凑 mutation 投影保留 provenance 且不触发输出保护,不修改 Sub2API 源码、版本、runtime、YAML 或外部哨兵,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R4_Task_Report.md)。
|
||||
|
||||
## R5 [in_progress]
|
||||
|
||||
将现有 Sub2Rank 迁移为 ApiState 多页面运维站:源码 authority 切换到 pikasTech/apistate,本地根目录迁到 /root/apistate,沿用 NC01 PaC/Tekton、GitOps/Argo 自动链;默认每 10 分钟通过既有 UniDesk Sub2API CLI 刷新所有分组账号评分,提供账号评分表、用户排名与抽奖多页面、用户名密码登录和 API key 全功能调用;Secret 仅由 YAML sourceRef/targetKey 分发,公网发布到 apistate.hwpod.com,并完成 API 与 web-probe 原入口验收,完成任务后将详细报告写入[任务报告](./details/sub2api-upstream-reliability/R5_Task_Report.md)。
|
||||
|
||||
@@ -237,7 +237,7 @@ export function publicServicePolicyChecks(
|
||||
options: { requireAllowAllManifest?: boolean } = {},
|
||||
): Array<Record<string, unknown>> {
|
||||
const checks: Array<Record<string, unknown>> = [
|
||||
{ name: "no-ingress", ok: !/^\s*kind:\s*Ingress\s*$/mu.test(yaml), detail: `${serviceName} public exposure must use PK01 Caddy+FRP, not Kubernetes Ingress.` },
|
||||
{ name: "no-ingress", ok: !/^\s*kind:\s*Ingress\s*$/mu.test(yaml), detail: `${serviceName} does not own Kubernetes Ingress; public exposure follows its owning YAML.` },
|
||||
{ name: "no-nodeport-or-loadbalancer", ok: !/^\s*type:\s*(NodePort|LoadBalancer)\s*$/mu.test(yaml), detail: "Services must stay ClusterIP." },
|
||||
{ name: "no-host-network", ok: !/^\s*hostNetwork:\s*true\s*$/mu.test(yaml), detail: "Pods must not use host network." },
|
||||
{ name: "no-host-port", ok: !/^\s*hostPort:\s*[0-9]+\s*$/mu.test(yaml), detail: "Pods must not expose host ports." },
|
||||
@@ -435,8 +435,10 @@ export function publicServiceStatusScript(params: {
|
||||
resources: PublicServiceRuntimeResources;
|
||||
healthPath: string;
|
||||
servicePort: number;
|
||||
includeFrpc?: boolean;
|
||||
}): string {
|
||||
const requiredSecretKeys = JSON.stringify(params.resources.requiredSecretKeys);
|
||||
const includeFrpc = params.includeFrpc !== false;
|
||||
return `
|
||||
set -u
|
||||
tmp="$(mktemp -d)"
|
||||
@@ -448,7 +450,7 @@ capture_json() {
|
||||
printf '%s' "$?" >"$tmp/$name.rc"
|
||||
}
|
||||
capture_json app kubectl -n ${params.target.namespace} get deployment ${params.resources.appDeploymentName}
|
||||
capture_json frpc kubectl -n ${params.target.namespace} get deployment ${params.target.publicExposure.frpc.deploymentName}
|
||||
${includeFrpc ? `capture_json frpc kubectl -n ${params.target.namespace} get deployment ${params.target.publicExposure.frpc.deploymentName}` : ""}
|
||||
capture_json service kubectl -n ${params.target.namespace} get service ${params.resources.serviceName}
|
||||
capture_json pvc kubectl -n ${params.target.namespace} get pvc ${params.resources.persistentVolumeClaimName}
|
||||
capture_json configmap kubectl -n ${params.target.namespace} get configmap ${params.resources.configMapName}
|
||||
@@ -483,7 +485,7 @@ pvc = load("pvc") or {}
|
||||
endpoints = load("endpoints") or {}
|
||||
addresses = sum(len(subset.get("addresses", []) or []) for subset in endpoints.get("subsets", []) or [])
|
||||
app = deployment("app")
|
||||
frpc = deployment("frpc")
|
||||
frpc = deployment("frpc") if ${includeFrpc ? "True" : "False"} else {"present": False, "desired": 0, "ready": 0, "available": 0, "ok": True, "skipped": True}
|
||||
payload = {
|
||||
"ok": app["ok"] and frpc["ok"] and rc("service") == 0 and rc("pvc") == 0 and pvc.get("status", {}).get("phase") == "Bound" and rc("configmap") == 0 and rc("secret") == 0 and not missing_keys and addresses > 0${params.resources.sharedNetworkPolicyName === undefined ? "" : ' and rc("networkpolicy") == 0'},
|
||||
"target": "${params.target.id}",
|
||||
|
||||
@@ -80,6 +80,7 @@ export interface Sub2RankConfig {
|
||||
configMap: { name: string; key: string; mountPath: string };
|
||||
command: string[];
|
||||
storage: { claimName: string; size: string; mountPath: string };
|
||||
hostMounts: Array<{ source: string; target: string; readOnly: true }>;
|
||||
secret: ResolvedSecretDeclaration & { configRef: string; declarationId: string; requiredTargetKeys: string[]; appEnvTargetKeys: string[] };
|
||||
probes: { healthPath: string; initialDelaySeconds: number; periodSeconds: number; timeoutSeconds: number; failureThreshold: number };
|
||||
rollout: { fieldManager: string; waitTimeoutSeconds: number };
|
||||
@@ -218,7 +219,14 @@ function parseApplication(record: Record<string, unknown>): Sub2RankConfig["appl
|
||||
server: {
|
||||
listenPort: integerValue(server.listenPort, `${configRef}.runtime.serverTargets.${runtimeTarget}.listenPort`),
|
||||
databasePath: absolutePathValue(server.databasePath, `${configRef}.runtime.serverTargets.${runtimeTarget}.databasePath`),
|
||||
envKeys: ["adminTokenEnv", "sub2apiAdminEmailEnv", "sub2apiAdminPasswordEnv"].map((key) => envKeyValue(server[key], `${configRef}.runtime.serverTargets.${runtimeTarget}.${key}`)),
|
||||
envKeys: [...new Set([
|
||||
"adminTokenEnv",
|
||||
"sub2apiAdminEmailEnv",
|
||||
"sub2apiAdminPasswordEnv",
|
||||
"webPasswordEnv",
|
||||
"apiKeyEnv",
|
||||
"sessionSecretEnv",
|
||||
].map((key) => envKeyValue(server[key], `${configRef}.runtime.serverTargets.${runtimeTarget}.${key}`)))],
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -293,6 +301,11 @@ function parseRuntime(record: Record<string, unknown>): Omit<Sub2RankConfig["run
|
||||
const sharedNetworkPolicyRef = y.objectField(record, "sharedNetworkPolicyRef", "runtime");
|
||||
const configMap = y.objectField(record, "configMap", "runtime");
|
||||
const storage = y.objectField(record, "storage", "runtime");
|
||||
const hostMounts = y.arrayOfRecords(record.hostMounts, "runtime.hostMounts").map((mount, index) => ({
|
||||
source: y.absolutePathField(mount, "source", `runtime.hostMounts[${index}]`),
|
||||
target: y.absolutePathField(mount, "target", `runtime.hostMounts[${index}]`),
|
||||
readOnly: requiredTrueField(mount, "readOnly", `runtime.hostMounts[${index}]`),
|
||||
}));
|
||||
const secret = y.objectField(record, "secret", "runtime");
|
||||
const probes = y.objectField(record, "probes", "runtime");
|
||||
const rollout = y.objectField(record, "rollout", "runtime");
|
||||
@@ -314,6 +327,7 @@ function parseRuntime(record: Record<string, unknown>): Omit<Sub2RankConfig["run
|
||||
size: storageSize(y.stringField(storage, "size", "runtime.storage")),
|
||||
mountPath: y.absolutePathField(storage, "mountPath", "runtime.storage"),
|
||||
},
|
||||
hostMounts,
|
||||
secret: {
|
||||
configRef: configRefValue,
|
||||
declarationId: simpleId(y.stringField(secret, "declarationId", "runtime.secret"), "runtime.secret.declarationId"),
|
||||
@@ -486,6 +500,12 @@ function disabledField(record: Record<string, unknown>, key: string, path: strin
|
||||
return false;
|
||||
}
|
||||
|
||||
function requiredTrueField(record: Record<string, unknown>, key: string, path: string): true {
|
||||
const value = y.booleanField(record, key, path);
|
||||
if (!value) throw new Error(`${sub2RankConfigLabel}.${path}.${key} must be true`);
|
||||
return true;
|
||||
}
|
||||
|
||||
function storageSize(value: string): string {
|
||||
if (!/^[1-9][0-9]*(?:Mi|Gi|Ti)$/u.test(value)) throw new Error(`${sub2RankConfigLabel}.runtime.storage.size must use Mi, Gi, or Ti`);
|
||||
return value;
|
||||
|
||||
@@ -34,7 +34,7 @@ export function sub2RankHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts platform-infra sub2rank validate [--target NC01] [--full|--raw]",
|
||||
],
|
||||
configTruth: sub2RankConfigLabel,
|
||||
applicationConfigRef: "/root/sub2rank/config/sub2rank.yaml",
|
||||
applicationConfigRef: "application.configRef in config/platform-infra/sub2rank.yaml",
|
||||
artifactPolicy: "Application PR merge is the sole delivery trigger; PaC/Tekton builds the image and publishes a digest-pinned GitOps manifest.",
|
||||
secretPolicy: "Resolves the existing Secret declaration from config/secrets-distribution.yaml and never reads or prints runtime Secret values.",
|
||||
};
|
||||
@@ -76,11 +76,14 @@ function plan(options: OpsCommonOptions): Record<string, unknown> {
|
||||
pipeline: sub2rank.delivery.pipeline.name,
|
||||
},
|
||||
},
|
||||
topology: `client -> PK01 Caddy -> PK01 frps:${target.publicExposure.frpc.remotePort} -> ${target.id} frpc -> ${sub2rank.runtime.service.name}.${target.namespace}.svc.cluster.local:${sub2rank.runtime.service.port}`,
|
||||
topology: target.publicExposure.enabled
|
||||
? `client -> PK01 Caddy -> PK01 frps:${target.publicExposure.frpc.remotePort} -> ${target.id} frpc -> ${sub2rank.runtime.service.name}.${target.namespace}.svc.cluster.local:${sub2rank.runtime.service.port}`
|
||||
: `client -> ${target.id} shared public-edge -> ${sub2rank.runtime.service.name}.${target.namespace}.svc.cluster.local:${sub2rank.runtime.service.port}`,
|
||||
next: {
|
||||
secrets: "bun scripts/cli.ts secrets sync --config config/secrets-distribution.yaml --scope sub2rank --confirm",
|
||||
publicExposureDryRun: `bun scripts/cli.ts platform-infra sub2rank public-exposure --target ${target.id} --dry-run`,
|
||||
publicExposureApply: `bun scripts/cli.ts platform-infra sub2rank public-exposure --target ${target.id} --confirm`,
|
||||
publicExposureDryRun: target.publicExposure.enabled ? `bun scripts/cli.ts platform-infra sub2rank public-exposure --target ${target.id} --dry-run` : null,
|
||||
publicExposureApply: target.publicExposure.enabled ? `bun scripts/cli.ts platform-infra sub2rank public-exposure --target ${target.id} --confirm` : null,
|
||||
sharedPublicEdge: target.publicExposure.enabled ? null : `bun scripts/cli.ts platform-infra public-edge plan --target ${target.id}`,
|
||||
status: `bun scripts/cli.ts platform-infra sub2rank status --target ${target.id}`,
|
||||
validate: `bun scripts/cli.ts platform-infra sub2rank validate --target ${target.id}`,
|
||||
},
|
||||
@@ -90,6 +93,17 @@ function plan(options: OpsCommonOptions): Record<string, unknown> {
|
||||
async function publicExposure(config: UniDeskConfig, options: OpsApplyOptions): Promise<Record<string, unknown>> {
|
||||
const sub2rank = readSub2RankConfig();
|
||||
const target = resolveSub2RankTarget(sub2rank, options.targetId);
|
||||
if (!target.publicExposure.enabled) {
|
||||
return {
|
||||
ok: true,
|
||||
action: "platform-infra-sub2rank-public-exposure",
|
||||
mode: "disabled",
|
||||
mutation: false,
|
||||
target: targetSummary(target),
|
||||
reason: "legacy-public-exposure-disabled",
|
||||
next: `bun scripts/cli.ts platform-infra public-edge plan --target ${target.id}`,
|
||||
};
|
||||
}
|
||||
if (options.dryRun) {
|
||||
return {
|
||||
ok: true,
|
||||
@@ -126,6 +140,7 @@ async function status(config: UniDeskConfig, options: OpsCommonOptions): Promise
|
||||
resources,
|
||||
healthPath: sub2rank.runtime.probes.healthPath,
|
||||
servicePort: sub2rank.runtime.service.port,
|
||||
includeFrpc: target.publicExposure.enabled,
|
||||
}));
|
||||
const parsed = parseJsonOutput(remote.stdout);
|
||||
return {
|
||||
@@ -173,6 +188,8 @@ export function renderSub2RankManifest(config: Sub2RankConfig, target: Sub2RankT
|
||||
const sourceCommit = options.sourceCommit ?? config.application.sourceCommit;
|
||||
const configHash = createHash("sha256").update(JSON.stringify({ deployment: deploymentHashInput(config), target })).digest("hex").slice(0, 16);
|
||||
const appEnv = runtime.secret.appEnvTargetKeys.map((key) => ` - name: ${key}\n valueFrom:\n secretKeyRef:\n name: ${runtime.secret.secretName}\n key: ${key}`).join("\n");
|
||||
const hostVolumeMounts = runtime.hostMounts.map((mount, index) => ` - name: host-source-${index}\n mountPath: ${mount.target}\n readOnly: true`).join("\n");
|
||||
const hostVolumes = runtime.hostMounts.map((mount, index) => ` - name: host-source-${index}\n hostPath:\n path: ${mount.source}\n type: Directory`).join("\n");
|
||||
const command = runtime.command.map((value) => ` - ${yamlQuoted(value)}`).join("\n");
|
||||
return `apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@@ -283,6 +300,7 @@ ${appEnv}
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: ${runtime.storage.mountPath}
|
||||
${hostVolumeMounts.length > 0 ? hostVolumeMounts : ""}
|
||||
volumes:
|
||||
- name: app-config
|
||||
configMap:
|
||||
@@ -290,6 +308,7 @@ ${appEnv}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: ${runtime.storage.claimName}
|
||||
${hostVolumes.length > 0 ? hostVolumes : ""}
|
||||
${renderEnvSecretFrpcManifest(target, {
|
||||
configMapName: target.publicExposure.frpc.configMapName,
|
||||
configKey: target.publicExposure.frpc.configKey,
|
||||
@@ -332,6 +351,7 @@ function configSummary(config: Sub2RankConfig, target: Sub2RankTarget): Record<s
|
||||
secret: secretSummary(config),
|
||||
},
|
||||
publicExposure: {
|
||||
enabled: target.publicExposure.enabled,
|
||||
publicBaseUrl: target.publicExposure.publicBaseUrl,
|
||||
expectedA: target.publicExposure.dns.expectedA,
|
||||
remotePort: target.publicExposure.frpc.remotePort,
|
||||
|
||||
Reference in New Issue
Block a user