Skip to content

Commit b9a5ea7

Browse files
committed
Group migrator
1 parent fa07b58 commit b9a5ea7

File tree

6 files changed

+181
-1
lines changed

6 files changed

+181
-1
lines changed

.github/charts-values-update-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ charts:
1414
- ghcr.io/netcracker/qubership-docker-zookeeper:${release}
1515
- ghcr.io/netcracker/qubership-zookeeper-monitoring:${release}
1616
- ghcr.io/netcracker/qubership-zookeeper-backup-daemon:${release}
17-
- ghcr.io/netcracker/qubership-zookeeper-integration-tests:${release}
17+
- ghcr.io/netcracker/qubership-zookeeper-integration-tests:${release}
18+
- ghcr.io/netcracker/qubership-docker-kubectl:#latest

operator/charts/helm/zookeeper-service/templates/_helpers.tpl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ Find a zookeeper image in various places.
236236
{{- printf "%s" .Values.zooKeeper.dockerImage -}}
237237
{{- end -}}
238238

239+
{{/*
240+
Find a kubectl image in various places.
241+
*/}}
242+
{{- define "kubectl.image" -}}
243+
{{- printf "%s" .Values.groupMigration.image -}}
244+
{{- end -}}
245+
246+
239247
{{/*
240248
ZooKeeper admin username.
241249
*/}}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{{- if .Values.groupMigration.enabled }}
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: {{ .Release.Name }}-ownerref-migrator
6+
labels:
7+
app.kubernetes.io/instance: {{ .Release.Name }}
8+
annotations:
9+
"helm.sh/hook": pre-install,pre-upgrade
10+
"helm.sh/hook-weight": "0"
11+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
12+
spec:
13+
template:
14+
metadata:
15+
labels:
16+
app.kubernetes.io/instance: {{ .Release.Name }}
17+
spec:
18+
serviceAccountName: {{ .Release.Name }}-ownerref-migrator
19+
restartPolicy: OnFailure
20+
{{- if .Values.groupMigration.runAsNonRoot }}
21+
securityContext:
22+
runAsNonRoot: true
23+
seccompProfile: { type: RuntimeDefault }
24+
{{- end }}
25+
containers:
26+
- name: migrator
27+
image: {{ template "kubectl.image" . }}
28+
imagePullPolicy: {{ .Values.groupMigration.imagePullPolicy | default "IfNotPresent" }}
29+
command: ["/bin/sh","-c"]
30+
args:
31+
- |
32+
set -euo pipefail
33+
34+
# Ensure jq is present
35+
command -v jq >/dev/null 2>&1 || { echo "[migrator] jq is required"; exit 1; }
36+
37+
# Config
38+
KUBECTL="kubectl"
39+
NS="{{ .Release.Namespace }}"
40+
RESOURCES="${RESOURCES:-deployments,statefulsets,configmaps,secrets,services,persistentvolumeclaims}"
41+
SELECTOR="{{ .Values.groupMigration.labelSelector }}"
42+
OLD_GROUP="{{ .Values.groupMigration.oldGroupPrefix }}"
43+
44+
# Build optional selector flag
45+
if [ -n "${SELECTOR}" ]; then SEL="-l ${SELECTOR}"; else SEL=""; fi
46+
47+
IFS=','; for r in $RESOURCES; do
48+
r="$(echo "$r" | xargs)"; [ -z "$r" ] && continue
49+
50+
# Get items JSON; on RBAC/list error warn and continue
51+
ITEMS_JSON="$($KUBECTL -n "$NS" get "$r" $SEL -o json 2>/dev/null || true)"
52+
if [ -z "$ITEMS_JSON" ]; then
53+
echo "[migrator][WARN] cannot list $r (RBAC or not found)"; continue
54+
fi
55+
56+
# Extract names having ownerRefs with apiVersion starting with OLD_GROUP
57+
NAMES="$(printf "%s" "$ITEMS_JSON" \
58+
| jq -r --arg grp "$OLD_GROUP" '.items[]
59+
| select([(.metadata.ownerReferences // [])[]?
60+
| .apiVersion|tostring
61+
| startswith($grp)] | any)
62+
| .metadata.name')"
63+
64+
[ -z "$NAMES" ] && continue
65+
# Iterate names without here-strings (portable for /bin/sh)
66+
printf "%s\n" "$NAMES" | while IFS= read -r name; do
67+
[ -z "$name" ] && continue
68+
69+
OBJ_JSON="$($KUBECTL -n "$NS" get "$r" "$name" -o json 2>/dev/null || true)"
70+
if [ -z "$OBJ_JSON" ]; then
71+
echo "[migrator][WARN] cannot get $r/$name"; continue
72+
fi
73+
74+
# Build merge-patch that removes matching ownerRefs
75+
PATCH="$(printf "%s" "$OBJ_JSON" | jq -c --arg grp "$OLD_GROUP" '
76+
{"metadata":{"ownerReferences":[
77+
(.metadata.ownerReferences // [])[]
78+
| select((.apiVersion|tostring)|startswith($grp)|not)
79+
]}}')"
80+
81+
if $KUBECTL -n "$NS" patch "$r" "$name" --type=merge -p "$PATCH" >/dev/null 2>&1; then
82+
echo "[migrator] $r/$name patched"
83+
else
84+
echo "[migrator][WARN] patch failed for $r/$name"
85+
fi
86+
done
87+
done
88+
89+
echo "[migrator] done"
90+
resources:
91+
limits:
92+
cpu: {{ .Values.groupMigration.resources.limits.cpu }}
93+
memory: {{ .Values.groupMigration.resources.limits.memory }}
94+
requests:
95+
cpu: {{ .Values.operator.resources.requests.cpu }}
96+
memory: {{ .Values.operator.resources.requests.memory }}
97+
{{- if .Values.groupMigration.runAsNonRoot }}
98+
securityContext:
99+
allowPrivilegeEscalation: false
100+
readOnlyRootFilesystem: true
101+
capabilities: { drop: ["ALL"] }
102+
{{- end }}
103+
{{- end }}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- if .Values.groupMigration.enabled }}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: Role
4+
metadata:
5+
name: {{ .Release.Name }}-ownerref-migrator
6+
labels:
7+
app.kubernetes.io/instance: {{ .Release.Name }}
8+
annotations:
9+
"helm.sh/hook": pre-install,pre-upgrade
10+
"helm.sh/hook-weight": "-190"
11+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
12+
rules:
13+
- apiGroups: ["apps"]
14+
resources: ["deployments","statefulsets"]
15+
verbs: ["get","list","patch","update"]
16+
- apiGroups: [""]
17+
resources: ["configmaps","secrets","services","persistentvolumeclaims"]
18+
verbs: ["get","list","patch","update"]
19+
---
20+
apiVersion: rbac.authorization.k8s.io/v1
21+
kind: RoleBinding
22+
metadata:
23+
name: {{ .Release.Name }}-ownerref-migrator
24+
labels:
25+
app.kubernetes.io/instance: {{ .Release.Name }}
26+
annotations:
27+
"helm.sh/hook": pre-install,pre-upgrade
28+
"helm.sh/hook-weight": "-180"
29+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
30+
"argocd.argoproj.io/hook": PreSync
31+
"argocd.argoproj.io/hook-delete-policy": HookSucceeded
32+
subjects:
33+
- kind: ServiceAccount
34+
name: {{ .Release.Name }}-ownerref-migrator
35+
namespace: {{ .Release.Namespace }}
36+
roleRef:
37+
apiGroup: rbac.authorization.k8s.io
38+
kind: Role
39+
name: {{ .Release.Name }}-ownerref-migrator
40+
{{- end }}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{{- if .Values.groupMigration.enabled }}
2+
apiVersion: v1
3+
kind: ServiceAccount
4+
metadata:
5+
name: {{ .Release.Name }}-ownerref-migrator
6+
labels:
7+
app.kubernetes.io/instance: {{ .Release.Name }}
8+
annotations:
9+
"helm.sh/hook": pre-install,pre-upgrade
10+
"helm.sh/hook-weight": "-200"
11+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
12+
{{- end }}

operator/charts/helm/zookeeper-service/values.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,22 @@ integrationTests:
368368
customLabels: {}
369369
securityContext: {}
370370

371+
groupMigration:
372+
enabled: true
373+
oldGroupPrefix: "qubership.org/"
374+
# labelSelector: "app.kubernetes.io/part-of=app-name"
375+
labelSelector: ""
376+
resources:
377+
requests:
378+
memory: 64Mi
379+
cpu: 20m
380+
limits:
381+
memory: 256Mi
382+
cpu: 100m
383+
image: "ghcr.io/netcracker/qubership-docker-kubectl:main"
384+
imagePullPolicy: Always
385+
runAsNonRoot: true
386+
371387
# Cloud Release Integration
372388
# The name of the Service exposed for the database.
373389
SERVICE_NAME: "zookeeper-service"

0 commit comments

Comments
 (0)