mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-03 10:37:21 +09:00
Review notes from IvanHunters on #3385 (LGTM with non-blocking findings). 1. The backup-s3-ca volume carries no `optional: true` while the adjacent useSystemBucket credential refs deliberately do, and the asymmetry was undocumented — an operator naming a Secret that does not exist gets the whole ClickHouse Pod stuck in ContainerCreating, not just the sidecar. Kept the fail-closed behaviour and wrote down why the two cases differ: credentials are projected by the platform after install, so a strict ref would wedge every fresh release until the first BackupJob, whereas this CA is named by the tenant, must already exist, and is trust material — optional would mount an empty dir, the Pod would look healthy, and the first backup would fail deep inside clickhouse-backup with an x509 error naming neither the Secret nor the chart. The comment also states the blast radius plainly. 2. The CA probe swallowed stderr, so an RBAC denial on the cross-namespace read was reported as "CA not found" followed by advice (set S3_CA_SECRET) that cannot fix a permissions problem. It now separates present / absent / not-allowed-to-look and says so, and the README no longer labels step 03 simply "tenant": copying the CA reads a Secret in tenant-root, which is a platform capability. Added a section spelling out the three ways to satisfy that (admin credentials, a one-off admin copy, or skipping the CA entirely on a publicly-trusted endpoint). 3. Caveat, and a usability regression this branch introduced: on a cluster with a publicly-trusted endpoint and no seaweedfs, step 03 hard-exited on a default the user never chose. It now distinguishes an explicitly named Secret (still an error when missing — a typo should not be guessed past) from the unset default, where it warns and continues with backup.endpointCA unset. Verified all four paths against a fake kubectl: Forbidden, absent+default, absent+explicit, and present. 4. Caveat: endpointCA reaches the clickhouse-backup sidecar only. The legacy `schedule` CronJob writes to S3 through restic and does not consume it, so a private-CA endpoint combined with `schedule` still fails TLS. Documented on the field itself, so it lands in values.schema.json, the README and the cozyrds openAPISchema. The PR body's claim about select-e2e.sh/select-install.sh mappings was stale after the restructure that removed them; corrected there rather than in code. Assisted-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Andrey Kolkov <androndo@gmail.com>
373 lines
12 KiB
JSON
373 lines
12 KiB
JSON
{
|
|
"title": "Chart Values",
|
|
"type": "object",
|
|
"properties": {
|
|
"replicas": {
|
|
"description": "Number of ClickHouse replicas.",
|
|
"type": "integer",
|
|
"default": 2
|
|
},
|
|
"shards": {
|
|
"description": "Number of ClickHouse shards.",
|
|
"type": "integer",
|
|
"default": 1
|
|
},
|
|
"resources": {
|
|
"description": "Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"cpu": {
|
|
"description": "CPU available to each replica.",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
},
|
|
"memory": {
|
|
"description": "Memory (RAM) available to each replica.",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
}
|
|
}
|
|
},
|
|
"resourcesPreset": {
|
|
"description": "Default sizing preset used when `resources` is omitted.",
|
|
"type": "string",
|
|
"default": "t1.small",
|
|
"enum": [
|
|
"t1.nano",
|
|
"t1.micro",
|
|
"t1.small",
|
|
"t1.medium",
|
|
"t1.large",
|
|
"t1.xlarge",
|
|
"t1.2xlarge",
|
|
"t1.4xlarge",
|
|
"c1.nano",
|
|
"c1.micro",
|
|
"c1.small",
|
|
"c1.medium",
|
|
"c1.large",
|
|
"c1.xlarge",
|
|
"c1.2xlarge",
|
|
"c1.4xlarge",
|
|
"s1.nano",
|
|
"s1.micro",
|
|
"s1.small",
|
|
"s1.medium",
|
|
"s1.large",
|
|
"s1.xlarge",
|
|
"s1.2xlarge",
|
|
"s1.4xlarge",
|
|
"u1.nano",
|
|
"u1.micro",
|
|
"u1.small",
|
|
"u1.medium",
|
|
"u1.large",
|
|
"u1.xlarge",
|
|
"u1.2xlarge",
|
|
"u1.4xlarge",
|
|
"m1.nano",
|
|
"m1.micro",
|
|
"m1.small",
|
|
"m1.medium",
|
|
"m1.large",
|
|
"m1.xlarge",
|
|
"m1.2xlarge",
|
|
"m1.4xlarge",
|
|
"nano",
|
|
"micro",
|
|
"small",
|
|
"medium",
|
|
"large",
|
|
"xlarge",
|
|
"2xlarge"
|
|
]
|
|
},
|
|
"size": {
|
|
"description": "Persistent Volume Claim size available for application data.",
|
|
"default": "10Gi",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
},
|
|
"storageClass": {
|
|
"description": "StorageClass used to store the data.",
|
|
"type": "string",
|
|
"default": "",
|
|
"x-kubernetes-validations": [
|
|
{
|
|
"rule": "self == oldSelf",
|
|
"message": "storageClass is immutable"
|
|
}
|
|
],
|
|
"x-cozystack-options": {
|
|
"source": "storageclass"
|
|
}
|
|
},
|
|
"logStorageSize": {
|
|
"description": "Size of Persistent Volume for logs.",
|
|
"default": "2Gi",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
},
|
|
"logTTL": {
|
|
"description": "TTL (expiration time) for `query_log` and `query_thread_log`.",
|
|
"type": "integer",
|
|
"default": 15
|
|
},
|
|
"users": {
|
|
"description": "Users configuration map.",
|
|
"type": "object",
|
|
"default": {},
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"properties": {
|
|
"password": {
|
|
"description": "Password for the user.",
|
|
"type": "string"
|
|
},
|
|
"readonly": {
|
|
"description": "User is readonly (default: false).",
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"backup": {
|
|
"description": "Backup configuration.",
|
|
"type": "object",
|
|
"default": {},
|
|
"required": [
|
|
"enabled"
|
|
],
|
|
"properties": {
|
|
"cleanupStrategy": {
|
|
"description": "Legacy. Restic retention policy passed to the legacy CronJob (`restic forget …`). Unused by the Altinity strategy.",
|
|
"type": "string",
|
|
"default": "--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"
|
|
},
|
|
"enabled": {
|
|
"description": "Enable backup integration. Materialises the chart-emitted `\u003crelease\u003e-backup-s3` Secret consumed by the Altinity backup strategy and, when `schedule` is non-empty, also renders the legacy chart-managed CronJob.",
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"endpoint": {
|
|
"description": "DEPRECATED. S3 endpoint URL for the legacy chart-emitted sidecar.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"endpointCA": {
|
|
"description": "CA bundle the sidecar trusts when the S3 endpoint's certificate is signed by a private CA (e.g. Cozystack's in-cluster SeaweedFS). Applies to both the per-tenant and the `useSystemBucket` flow, and to the `clickhouse-backup` sidecar only — the legacy `schedule` CronJob writes to S3 through restic and does not consume it, so a private-CA endpoint combined with `schedule` still fails TLS. Use the BackupClass flow for such an endpoint.",
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"key": {
|
|
"description": "Key inside the Secret holding the PEM CA bundle. Defaults to `ca.crt`.",
|
|
"type": "string",
|
|
"default": "ca.crt"
|
|
},
|
|
"name": {
|
|
"description": "Name of the Secret in the application namespace. Empty (default) mounts nothing and leaves the sidecar on the system trust store only.",
|
|
"type": "string",
|
|
"default": ""
|
|
}
|
|
}
|
|
},
|
|
"resticPassword": {
|
|
"description": "Legacy. Password for Restic backup encryption used by the legacy CronJob. Unused by the Altinity strategy.",
|
|
"type": "string",
|
|
"default": "\u003cpassword\u003e"
|
|
},
|
|
"s3AccessKey": {
|
|
"description": "DEPRECATED. Tenants no longer supply S3 keys; the platform-managed Bucket Secret is the source of truth. Optional now so `useSystemBucket: true` tenants can omit it.",
|
|
"type": "string",
|
|
"default": "\u003cyour-access-key\u003e"
|
|
},
|
|
"s3Bucket": {
|
|
"description": "DEPRECATED. Optional; see `s3Region`.",
|
|
"type": "string",
|
|
"default": "s3.example.org/clickhouse-backups"
|
|
},
|
|
"s3CredentialsSecret": {
|
|
"description": "DEPRECATED. Pre-existing Secret reference for the legacy chart-emitted sidecar. The platform flow projects `cozy-backups-creds` instead.",
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"accessKeyIDKey": {
|
|
"description": "Key in the Secret holding the access key ID. Defaults to `accessKey`.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"bucketKey": {
|
|
"description": "Key in the Secret holding the bucket name. Defaults to `bucketName`.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"endpointKey": {
|
|
"description": "Key in the Secret holding the S3 endpoint URL. Defaults to `endpoint`.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"name": {
|
|
"description": "Name of the Secret in the application namespace. Empty means the chart materialises `\u003crelease\u003e-backup-s3` from the legacy `s3*` fields.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"regionKey": {
|
|
"description": "Key in the Secret holding the S3 region. Defaults to `region`.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"secretAccessKeyKey": {
|
|
"description": "Key in the Secret holding the secret access key. Defaults to `secretKey`.",
|
|
"type": "string",
|
|
"default": ""
|
|
}
|
|
}
|
|
},
|
|
"s3PathOverride": {
|
|
"description": "DEPRECATED. Object-key prefix inside the legacy `s3Bucket`; the new platform flow scopes by namespace automatically.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"s3Region": {
|
|
"description": "DEPRECATED. Per-tenant S3 configuration is being phased out in favour of the platform-managed `cozy-default` BackupClass. Optional now so tenants on `useSystemBucket: true` can omit it.",
|
|
"type": "string",
|
|
"default": "us-east-1"
|
|
},
|
|
"s3SecretKey": {
|
|
"description": "DEPRECATED. Optional; see `s3AccessKey`.",
|
|
"type": "string",
|
|
"default": "\u003cyour-secret-key\u003e"
|
|
},
|
|
"schedule": {
|
|
"description": "Legacy. Cron schedule for the chart-emitted CronJob that runs the dump+restic backup. Empty (default) skips the legacy CronJob; recommended when a `BackupClass` + `Plan` from `backups.cozystack.io` already drives backup orchestration via the Altinity strategy.",
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"useSystemBucket": {
|
|
"description": "Opt-in: when true, the chart-emitted `\u003crelease\u003e-backup-s3` Secret is skipped and the `clickhouse-backup` sidecar reads bucket coordinates + S3 credentials from the platform-projected `cozy-backups-creds` Secret. `S3_PATH` is set to `\u003cnamespace\u003e/\u003crelease\u003e` for cross-tenant isolation. Use together with the platform `cozy-default` BackupClass — tenants do not need to fill any `s3*` field below.",
|
|
"type": "boolean",
|
|
"default": false
|
|
}
|
|
}
|
|
},
|
|
"clickhouseKeeper": {
|
|
"description": "ClickHouse Keeper configuration.",
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"enabled": {
|
|
"description": "Deploy ClickHouse Keeper for cluster coordination.",
|
|
"type": "boolean",
|
|
"default": true
|
|
},
|
|
"replicas": {
|
|
"description": "Number of Keeper replicas.",
|
|
"type": "integer",
|
|
"default": 3
|
|
},
|
|
"resourcesPreset": {
|
|
"description": "Default sizing preset.",
|
|
"type": "string",
|
|
"default": "t1.micro",
|
|
"enum": [
|
|
"t1.nano",
|
|
"t1.micro",
|
|
"t1.small",
|
|
"t1.medium",
|
|
"t1.large",
|
|
"t1.xlarge",
|
|
"t1.2xlarge",
|
|
"t1.4xlarge",
|
|
"c1.nano",
|
|
"c1.micro",
|
|
"c1.small",
|
|
"c1.medium",
|
|
"c1.large",
|
|
"c1.xlarge",
|
|
"c1.2xlarge",
|
|
"c1.4xlarge",
|
|
"s1.nano",
|
|
"s1.micro",
|
|
"s1.small",
|
|
"s1.medium",
|
|
"s1.large",
|
|
"s1.xlarge",
|
|
"s1.2xlarge",
|
|
"s1.4xlarge",
|
|
"u1.nano",
|
|
"u1.micro",
|
|
"u1.small",
|
|
"u1.medium",
|
|
"u1.large",
|
|
"u1.xlarge",
|
|
"u1.2xlarge",
|
|
"u1.4xlarge",
|
|
"m1.nano",
|
|
"m1.micro",
|
|
"m1.small",
|
|
"m1.medium",
|
|
"m1.large",
|
|
"m1.xlarge",
|
|
"m1.2xlarge",
|
|
"m1.4xlarge",
|
|
"nano",
|
|
"micro",
|
|
"small",
|
|
"medium",
|
|
"large",
|
|
"xlarge",
|
|
"2xlarge"
|
|
]
|
|
},
|
|
"size": {
|
|
"description": "Persistent Volume Claim size available for application data.",
|
|
"default": "1Gi",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|