mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-06 12:03:39 +09:00
refactor(kafka): drop null from tls.enabled schema, use kindIs invalid pattern
cozyvalues-gen v1.5.0 natively emits *bool for @param {*bool} fields,
so the post-generate sed patch for types.go and the jq patch forcing
["boolean","null"] on values.schema.json are no longer needed. Remove
both patches from the Makefile.
Regenerate values.schema.json and cozyrds/kafka.yaml so tls.enabled
carries "type":"boolean" instead of ["boolean","null"]. The single-string
type is required by apiextv1.JSONSchemaProps, which cozystack-api uses for
server-side defaulting; the array form silently disabled defaulting for
the Kafka app.
Refactor the inline tri-state TLS guard in kafka.yaml to use the canonical
kindIs "invalid" pattern and extract it into a dedicated _tls.tpl named
template (kafka.tls.enabled). Add three explicit test cases (J-1, J-2, J-3)
covering the inherit-from-external path, the explicit-false override, and
the external-gate suppression cases.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
This commit is contained in:
6 files changed
+76
-20
No files matched your search
@@ -3,10 +3,6 @@ PRESET_ENUM := ["nano","micro","small","medium","large","xlarge","2xlarge"]
|
||||
|
||||
generate:
|
||||
cozyvalues-gen -m 'kafka' -v values.yaml -s values.schema.json -r README.md -g ../../../api/apps/v1alpha1/kafka/types.go
|
||||
sed -i 's/Enabled bool `json:"enabled,omitempty"`/Enabled *bool `json:"enabled,omitempty"`/' ../../../api/apps/v1alpha1/kafka/types.go
|
||||
grep -q 'Enabled \*bool `json:"enabled,omitempty"`' ../../../api/apps/v1alpha1/kafka/types.go || (echo "ERROR: failed to patch TLS.Enabled to *bool in types.go" && exit 1)
|
||||
jq '.properties.tls.properties.enabled.type = ["boolean", "null"]' values.schema.json > values.schema.json.tmp && mv values.schema.json.tmp values.schema.json
|
||||
jq -e '.properties.tls.properties.enabled.type == ["boolean", "null"]' values.schema.json > /dev/null || (echo "ERROR: jq patch failed" && exit 1)
|
||||
../../../hack/update-crd.sh
|
||||
|
||||
test:
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{{- /*
|
||||
kafka.tls.enabled — tri-state TLS decision for the external listener (port 9094).
|
||||
|
||||
Resolution order:
|
||||
1. If tls.enabled is explicitly set (true or false), that value wins.
|
||||
2. If tls.enabled is absent (nil / not provided), TLS inherits from .Values.external.
|
||||
|
||||
Null detection uses `kindIs "invalid"` which is the canonical Helm pattern for
|
||||
distinguishing an absent/nil value from an explicit false.
|
||||
|
||||
Note: this helper only returns the TLS flag value. Whether the external listener
|
||||
is rendered at all is controlled by .Values.external in the caller.
|
||||
*/ -}}
|
||||
{{- define "kafka.tls.enabled" -}}
|
||||
{{- if kindIs "invalid" .Values.tls.enabled -}}
|
||||
{{- .Values.external | default false -}}
|
||||
{{- else -}}
|
||||
{{- .Values.tls.enabled -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -5,21 +5,14 @@
|
||||
- tls.enabled controls TLS *on the external listener* (independent of whether
|
||||
the listener exists):
|
||||
- If tls.enabled is explicitly set (true or false), that value wins.
|
||||
- If tls.enabled is unset (nil), TLS inherits from .Values.external
|
||||
- If tls.enabled is unset (nil / absent), TLS inherits from .Values.external
|
||||
(auto-on when external is true, off otherwise).
|
||||
- tls.enabled does NOT control whether the external listener is created.
|
||||
Setting tls.enabled=true with external=false has no effect on listeners.
|
||||
Internal TLS listener (port 9093) is always on; Strimzi manages the PKI.
|
||||
Null detection uses `kindIs "invalid"` (canonical pattern) — see _tls.tpl.
|
||||
*/ -}}
|
||||
{{- $tlsMap := .Values.tls | default dict -}}
|
||||
{{- $tlsEnabledRaw := index $tlsMap "enabled" -}}
|
||||
{{- $tlsEnabledExplicit := and (hasKey $tlsMap "enabled") (ne $tlsEnabledRaw nil) -}}
|
||||
{{- $tlsEnabled := false -}}
|
||||
{{- if $tlsEnabledExplicit -}}
|
||||
{{- $tlsEnabled = $tlsEnabledRaw -}}
|
||||
{{- else -}}
|
||||
{{- $tlsEnabled = .Values.external | default false -}}
|
||||
{{- end -}}
|
||||
{{- $tlsEnabled := include "kafka.tls.enabled" . | trim -}}
|
||||
{{- $showExternal := .Values.external -}}
|
||||
apiVersion: kafka.strimzi.io/v1beta2
|
||||
kind: Kafka
|
||||
|
||||
@@ -97,6 +97,56 @@ tests:
|
||||
path: spec.kafka.listeners
|
||||
count: 2
|
||||
|
||||
########################################
|
||||
# kindIs "invalid" guard — Category J #
|
||||
########################################
|
||||
|
||||
# J-1: external=true, tls.enabled absent → inherit path: TLS is on
|
||||
- it: "kindIs-guard: TLS inherits from external when tls.enabled is absent and external is true"
|
||||
release:
|
||||
name: test-kafka
|
||||
namespace: tenant-test
|
||||
set:
|
||||
external: true
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.kafka.listeners
|
||||
content:
|
||||
name: external
|
||||
port: 9094
|
||||
type: loadbalancer
|
||||
tls: true
|
||||
|
||||
# J-2: external=true, tls.enabled=false → explicit override wins: TLS is off
|
||||
- it: "kindIs-guard: explicit tls.enabled=false overrides external=true"
|
||||
release:
|
||||
name: test-kafka
|
||||
namespace: tenant-test
|
||||
set:
|
||||
external: true
|
||||
tls.enabled: false
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.kafka.listeners
|
||||
content:
|
||||
name: external
|
||||
port: 9094
|
||||
type: loadbalancer
|
||||
tls: false
|
||||
|
||||
# J-3: external=false, tls.enabled=true → external gate wins: no listener rendered
|
||||
- it: "kindIs-guard: external gate suppresses listener even when tls.enabled=true"
|
||||
release:
|
||||
name: test-kafka
|
||||
namespace: tenant-test
|
||||
set:
|
||||
external: false
|
||||
tls.enabled: true
|
||||
asserts:
|
||||
- lengthEqual:
|
||||
path: spec.kafka.listeners
|
||||
count: 2
|
||||
|
||||
########################################
|
||||
# Internal listeners unaffected by TLS #
|
||||
########################################
|
||||
|
||||
@@ -8,16 +8,13 @@
|
||||
"default": false
|
||||
},
|
||||
"tls": {
|
||||
"description": "TLS configuration. Strimzi manages the cluster PKI automatically (no cert-manager is involved for this chart): the operator auto-creates `<release>-cluster-ca-cert` and `<release>-clients-ca-cert` secrets, both exposed for client trust setup. The internal TLS listener on 9093 is always on; this toggle only controls the external listener on 9094.",
|
||||
"description": "TLS configuration. Strimzi manages the cluster PKI automatically (no cert-manager is involved for this chart): the operator auto-creates `\u003crelease\u003e-cluster-ca-cert` and `\u003crelease\u003e-clients-ca-cert` secrets, both exposed for client trust setup. The internal TLS listener on 9093 is always on; this toggle only controls the external listener on 9094.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable TLS on the external listener. When unset, inherits the value of `external` (TLS is on when external access is enabled). Warning: setting this to false while external is true exposes Kafka over plaintext on a public IP via LoadBalancer. Strimzi does not provide authentication on this listener unless SCRAM, mTLS, or OAuth is separately configured. Use only in controlled networks.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@ spec:
|
||||
plural: kafkas
|
||||
singular: kafka
|
||||
openAPISchema: |-
|
||||
{"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"tls":{"description":"TLS configuration. Strimzi manages the cluster PKI automatically (no cert-manager is involved for this chart): the operator auto-creates `<release>-cluster-ca-cert` and `<release>-clients-ca-cert` secrets, both exposed for client trust setup. The internal TLS listener on 9093 is always on; this toggle only controls the external listener on 9094.","type":"object","default":{},"properties":{"enabled":{"description":"Enable TLS on the external listener. When unset, inherits the value of `external` (TLS is on when external access is enabled). Warning: setting this to false while external is true exposes Kafka over plaintext on a public IP via LoadBalancer. Strimzi does not provide authentication on this listener unless SCRAM, mTLS, or OAuth is separately configured. Use only in controlled networks.","type":["boolean","null"]}}},"topics":{"description":"Topics configuration.","type":"array","default":[],"items":{"type":"object","required":["config","name","partitions","replicas"],"properties":{"config":{"description":"Topic configuration.","type":"object","x-kubernetes-preserve-unknown-fields":true},"name":{"description":"Topic name.","type":"string"},"partitions":{"description":"Number of partitions.","type":"integer"},"replicas":{"description":"Number of replicas.","type":"integer"}}}},"kafka":{"description":"Kafka configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of Kafka replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. 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":"c1.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 size for Kafka.","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 Kafka data.","type":"string","default":"","x-kubernetes-validations":[{"rule":"self == oldSelf","message":"storageClass is immutable"}]}}},"zookeeper":{"description":"ZooKeeper configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of ZooKeeper replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. 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":"c1.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.4xlaLine truncated
|
||||
{"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"tls":{"description":"TLS configuration. Strimzi manages the cluster PKI automatically (no cert-manager is involved for this chart): the operator auto-creates `<release>-cluster-ca-cert` and `<release>-clients-ca-cert` secrets, both exposed for client trust setup. The internal TLS listener on 9093 is always on; this toggle only controls the external listener on 9094.","type":"object","default":{},"properties":{"enabled":{"description":"Enable TLS on the external listener. When unset, inherits the value of `external` (TLS is on when external access is enabled). Warning: setting this to false while external is true exposes Kafka over plaintext on a public IP via LoadBalancer. Strimzi does not provide authentication on this listener unless SCRAM, mTLS, or OAuth is separately configured. Use only in controlled networks.","type":"boolean"}}},"topics":{"description":"Topics configuration.","type":"array","default":[],"items":{"type":"object","required":["config","name","partitions","replicas"],"properties":{"config":{"description":"Topic configuration.","type":"object","x-kubernetes-preserve-unknown-fields":true},"name":{"description":"Topic name.","type":"string"},"partitions":{"description":"Number of partitions.","type":"integer"},"replicas":{"description":"Number of replicas.","type":"integer"}}}},"kafka":{"description":"Kafka configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of Kafka replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. 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":"c1.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 size for Kafka.","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 Kafka data.","type":"string","default":"","x-kubernetes-validations":[{"rule":"self == oldSelf","message":"storageClass is immutable"}]}}},"zookeeper":{"description":"ZooKeeper configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of ZooKeeper replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. 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":"c1.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.Line truncated
|
||||
release:
|
||||
prefix: kafka-
|
||||
labels:
|
||||
|
||||
Reference in new issue
Block a user