Files
cozystack/packages/apps/redis/values.schema.json
Yasar Rahman 8be7fb2e66 feat(redis): expose min-replicas-to-write and min-replicas-max-lag
Lets an operator bound the writes lost when an isolated Redis master is
failed over: the master refuses writes while fewer replicas than
configured are connected and recent. Both values are unset by default, so
the rendered Redis config is unchanged.

Redis treats 0 in either directive as disabling the check, so the
chart refuses minReplicasMaxLag 0 next to a replica requirement
instead of silently turning the protection off.

Negative values are refused by the schema (minimum 0), since Redis
rejects them at CONFIG SET and the operator would stop healing the
Sentinels of that instance. A requirement of replicas or more is
refused at render: a master with replicas pods has replicas-1
replicas, so it would refuse every write for good.

Assisted-by: LLM
Signed-off-by: Yasar Rahman <yasar.rehman@gmail.com>
2026-10-12 02:03:17 +05:00

268 lines
9.0 KiB
JSON

{
"title": "Chart Values",
"type": "object",
"properties": {
"replicas": {
"description": "Number of Redis replicas.",
"type": "integer",
"default": 2
},
"resources": {
"description": "Explicit CPU and memory configuration for each Redis 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.nano",
"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
},
"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"
}
},
"external": {
"description": "Enable external access from outside the cluster. Can be enabled only when the instance is created, together with `tls.enabled: true`; turning it on for an existing instance, or changing `tls.enabled` while it is on, is refused at admission.",
"type": "boolean",
"default": false
},
"version": {
"description": "Redis major version to deploy. The Redis and Sentinel pods run the same image.",
"type": "string",
"default": "v8",
"enum": [
"v8",
"v7"
]
},
"tls": {
"description": "TLS configuration. TLS is opt-in and is not inferred from `external`.",
"type": "object",
"default": {},
"properties": {
"authClients": {
"description": "Maps to the Redis `tls-auth-clients` directive. Defaults to `no` — the server certificate is presented but client certificates are not validated. `yes` requires a client certificate signed by this release's CA, which the platform does not issue. Changing it restarts the Redis and Sentinel pods, because the directive is read from the config file once at startup.",
"type": "string",
"enum": [
"no",
"optional",
"yes"
]
},
"enabled": {
"description": "Enable TLS for Redis and Sentinel connections. Disabled unless set. Enabling it moves Redis and Sentinel to a TLS-only listener, so existing plaintext clients must be migrated at the same time. Encryption is provided by the redis-operator fork that mounts the certificate Secret into both Redis and Sentinel pods at `/tls`.",
"type": "boolean"
}
}
},
"authEnabled": {
"description": "Enable password generation.",
"type": "boolean",
"default": true
},
"minReplicasToWrite": {
"description": "Redis `min-replicas-to-write`: the master refuses writes unless at least this many replicas are connected and within `minReplicasMaxLag`. Unset by default, which leaves the Redis default (disabled). With `replicas: 2` and a value of 1 the master rejects writes while its only replica is down, trading availability for a bound on the writes lost if an isolated master is failed over. Replication stays asynchronous, so this bounds the loss, it does not remove it. Must be 0 or more and below `replicas` (a master with `replicas` pods has `replicas - 1` replicas), otherwise every write is refused; the chart refuses such a value.",
"type": "integer",
"minimum": 0
},
"minReplicasMaxLag": {
"description": "Redis `min-replicas-max-lag`, in seconds: a replica whose last acknowledgement is older than this does not count towards `minReplicasToWrite`. Unset by default, which leaves the Redis default (10). Has no effect unless `minReplicasToWrite` is set. Must be at least 1 when `minReplicasToWrite` is set: Redis treats 0 as disabling the check, so the chart refuses it.",
"type": "integer",
"minimum": 0
},
"sentinel": {
"description": "Sentinel configuration. When `sentinel.resources` is empty and `sentinel.resourcesPreset` is unset, the three Sentinel pods are sized like the Redis pods (`resources` and `resourcesPreset`). An empty `sentinel.resources` map counts as unset, as an empty top-level `resources` does.",
"type": "object",
"default": {},
"properties": {
"resources": {
"description": "Explicit CPU and memory configuration for each Sentinel pod. Keys left out are filled from the preset in `sentinel.resourcesPreset`.",
"type": "object",
"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": "Sizing preset for the Sentinel pods. Defaults to `resourcesPreset`.",
"type": "string",
"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"
]
}
}
}
}
}