mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 13:30:46 +02:00
helm: quote the label values the policies emit
The same int-coercion the hook templates were fixed for, in the file this PR adds: unquoted, a release named 123 renders app.kubernetes.io/instance as a YAML integer in the metadata, the podSelector and both peer selectors, and the API server rejects the object - a policy that silently never applies. CI now renders the chart as release "123" and fails if any policy label comes out as a non-string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7fc5f6d6bb
commit
180c799474
@@ -1029,6 +1029,39 @@ jobs:
|
||||
else:
|
||||
print(f"{dropped}=null: the key is left out rather than rendered as null")
|
||||
|
||||
# Helm allows a release named "123", and an unquoted label value then
|
||||
# renders as a YAML integer. Label values are strings in the API, so the
|
||||
# whole object gets rejected - a policy that never applies, silently.
|
||||
# Every label the policies emit, in metadata and in every selector, has
|
||||
# to survive that release name as a string.
|
||||
numeric = subprocess.check_output(
|
||||
["helm", "template", "123", chart,
|
||||
"--set", "networkPolicy.enabled=true",
|
||||
"--set", "networkPolicy.egress.enabled=true",
|
||||
"--set", "networkPolicy.egress.kubeApiServer.cidrs[0]=10.96.0.1/32",
|
||||
"--set", "s3.enabled=true", "--set", "s3.createBuckets[0].name=b"],
|
||||
text=True, stderr=subprocess.STDOUT)
|
||||
|
||||
def label_maps(policy):
|
||||
yield "metadata", policy["metadata"].get("labels", {})
|
||||
yield "podSelector", policy["spec"]["podSelector"]["matchLabels"]
|
||||
for direction in ("ingress", "egress"):
|
||||
for i, rule in enumerate(policy["spec"].get(direction) or []):
|
||||
for peer in rule.get("to") or rule.get("from") or []:
|
||||
for key in ("podSelector", "namespaceSelector"):
|
||||
sel = peer.get(key) or {}
|
||||
yield f"{direction}[{i}].{key}", sel.get("matchLabels", {})
|
||||
|
||||
coerced = [(comp, where, k, v)
|
||||
for comp, p in policies(numeric).items()
|
||||
for where, labels in label_maps(p)
|
||||
for k, v in labels.items() if not isinstance(v, str)]
|
||||
if coerced:
|
||||
failed.append(f"release name 123: label values are not strings, so the API "
|
||||
f"server rejects the policy: {coerced}")
|
||||
else:
|
||||
print("a numeric release name keeps every policy label a string")
|
||||
|
||||
out = render(egress_on)
|
||||
pols = policies(out)
|
||||
|
||||
|
||||
@@ -133,11 +133,11 @@ metadata:
|
||||
name: {{ include "seaweedfs.componentName" (list $ $component) }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" $ }}
|
||||
app.kubernetes.io/name: {{ include "seaweedfs.name" $ | quote }}
|
||||
helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ $.Release.Service }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name }}
|
||||
app.kubernetes.io/component: {{ $component }}
|
||||
app.kubernetes.io/managed-by: {{ $.Release.Service | quote }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name | quote }}
|
||||
app.kubernetes.io/component: {{ $component | quote }}
|
||||
{{- if $target.hook }}
|
||||
annotations:
|
||||
{{- /* Only before-hook-creation: the policy has to outlive the Job it
|
||||
@@ -151,9 +151,9 @@ metadata:
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" $ }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name }}
|
||||
app.kubernetes.io/component: {{ $component }}
|
||||
app.kubernetes.io/name: {{ include "seaweedfs.name" $ | quote }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name | quote }}
|
||||
app.kubernetes.io/component: {{ $component | quote }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
{{- if $egressCfg.enabled }}
|
||||
@@ -168,8 +168,8 @@ spec:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" $ }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name }}
|
||||
app.kubernetes.io/name: {{ include "seaweedfs.name" $ | quote }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name | quote }}
|
||||
ports:
|
||||
{{- range $port := $target.ports }}
|
||||
- protocol: TCP
|
||||
@@ -184,8 +184,8 @@ spec:
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" $ }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name }}
|
||||
app.kubernetes.io/name: {{ include "seaweedfs.name" $ | quote }}
|
||||
app.kubernetes.io/instance: {{ $.Release.Name | quote }}
|
||||
{{- if $egressCfg.allowDNS }}
|
||||
{{- /* Emit only the selectors that are set. An empty one has to be left out
|
||||
rather than rendered as null: a missing podSelector means every pod in
|
||||
|
||||
Reference in New Issue
Block a user