Skip to content

Commit 1a363ee

Browse files
harishb93actions-usersys-orch
authored
Single tenancy init job (#264)
Co-authored-by: GitHub Action <[email protected]> Co-authored-by: sys-orch <[email protected]>
1 parent c33377c commit 1a363ee

File tree

25 files changed

+2014
-0
lines changed

25 files changed

+2014
-0
lines changed

.github/workflows/lint-test-build-publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ jobs:
321321
squidProxy,
322322
tokenFS,
323323
tenancyAPIMapping,
324+
tenancyInit,
324325
tenancyManager,
325326
tenancyDatamodel,
326327
nexusAPIGateway,

.trivyignore.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ misconfigurations:
3333
- "charts/statefulset-wait/templates/job.yaml"
3434
- "charts/token-fs/templates/deployment.yaml"
3535
- "charts/vertical-pod-autoscaler/templates/deployment.yaml"
36+
- "charts/tenancy-init/templates/serviceAccount.yaml"
3637
statement: readOnlyRootFilesystem is injected by Kyverno policy in charts/kyverno-extra-policies/templates/restricted-policy-orch.yaml
3738

3839
- id: AVD-KSV-0118
@@ -54,3 +55,11 @@ misconfigurations:
5455
- "charts/keycloak-tenant-controller/templates/configmap.yaml"
5556
- "charts/traefik-pre/templates/jwt-plugin-configmap-generated.yaml"
5657
statement: ConfigMaps contain legitimate scripts and configuration templates, not actual secrets in production
58+
- id: AVD-KSV-0041
59+
paths:
60+
- "charts/tenancy-init/templates/serviceAccount.yaml"
61+
statement: Cross-namespace secret access required for tenancy initialization
62+
- id: AVD-KSV-0056
63+
paths:
64+
- "charts/tenancy-init/templates/serviceAccount.yaml"
65+
statement: Service access required for pod communication and tenancy initialization operations

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ docker-build-squid-proxy:
5454
docker-build-tenancy-api-mapping:
5555
mage build:tenancyAPIMapping
5656

57+
docker-build-tenancy-init:
58+
mage build:tenancyInit
59+
5760
docker-build-tenancy-datamodel:
5861
mage build:tenancyDatamodel
5962

charts/tenancy-init/.appref.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: 2025 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
---
5+
6+
repo: https://github.com/open-edge-platform/orch-utils.git
7+
filter: "*.*.*"

charts/tenancy-init/.helmignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: 2025 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
.DS_Store
6+
# Common VCS dirs
7+
.git/
8+
.gitignore
9+
.bzr/
10+
.bzrignore
11+
.hg/
12+
.hgignore
13+
.svn/
14+
# Common backup files
15+
*.swp
16+
*.bak
17+
*.tmp
18+
*.orig
19+
*~
20+
# Various IDEs
21+
.project
22+
.idea/
23+
*.tmproj
24+
.vscode/

charts/tenancy-init/Chart.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
# SPDX-FileCopyrightText: 2025 Intel Corporation
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
apiVersion: v2
6+
name: tenancy-init
7+
description: A Helm chart for bootstrapping the 'tenancy-init'
8+
type: application
9+
version: 25.2.5
10+
appVersion: "25.2.0"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# SPDX-FileCopyrightText: 2025 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
---
6+
{{/*
7+
Expand the name of the chart.
8+
*/}}
9+
{{- define "iam.name" -}}
10+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
11+
{{- end }}
12+
13+
{{/*
14+
Create a default fully qualified app name.
15+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
16+
If release name contains chart name it will be used as a full name.
17+
*/}}
18+
{{- define "iam.fullname" -}}
19+
{{- if .Values.fullnameOverride }}
20+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
21+
{{- else }}
22+
{{- $name := default .Chart.Name .Values.nameOverride }}
23+
{{- if contains $name .Release.Name }}
24+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
25+
{{- else }}
26+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
27+
{{- end }}
28+
{{- end }}
29+
{{- end }}
30+
31+
{{/*
32+
Create chart name and version as used by the chart label.
33+
*/}}
34+
{{- define "iam.chart" -}}
35+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
36+
{{- end }}
37+
38+
{{/*
39+
Common labels
40+
*/}}
41+
{{- define "iam.labels" -}}
42+
helm.sh/chart: {{ include "iam.chart" . }}
43+
{{ include "iam.selectorLabels" . }}
44+
{{- if .Chart.AppVersion }}
45+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
46+
{{- end }}
47+
app.kubernetes.io/managed-by: {{ .Release.Service }}
48+
{{- end }}
49+
50+
{{/*
51+
Selector labels
52+
*/}}
53+
{{- define "iam.selectorLabels" -}}
54+
app.kubernetes.io/name: {{ include "iam.name" . }}
55+
app.kubernetes.io/instance: {{ .Release.Name }}
56+
{{- end }}
57+
58+
{{/*
59+
Create the name of the service account to use
60+
*/}}
61+
{{- define "iam.serviceAccountName" -}}
62+
{{- if .Values.serviceAccount.create }}
63+
{{- default (include "iam.fullname" .) .Values.serviceAccount.name }}
64+
{{- else }}
65+
{{- default "default" .Values.serviceAccount.name }}
66+
{{- end }}
67+
{{- end }}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
3+
# SPDX-FileCopyrightText: 2025 Intel Corporation
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
---
7+
8+
{{- $registry := .Values.global.registry -}}
9+
{{ if .Values.image.registry }}
10+
{{- $registry = .Values.image.registry -}}
11+
{{ end }}
12+
apiVersion: batch/v1
13+
kind: Job
14+
metadata:
15+
name: {{ include "iam.fullname" . }}
16+
labels:
17+
{{- include "iam.labels" . | nindent 4 }}
18+
namespace: {{ default .Release.Namespace .Values.global.namespace }}
19+
annotations:
20+
"helm.sh/hook": post-install
21+
spec:
22+
ttlSecondsAfterFinished: 600
23+
backoffLimit: 6
24+
template:
25+
metadata:
26+
annotations:
27+
"sidecar.istio.io/inject": "false"
28+
spec:
29+
activeDeadlineSeconds: 600
30+
{{- with .Values.imagePullSecrets }}
31+
imagePullSecrets:
32+
{{- toYaml . | nindent 8 }}
33+
{{- end }}
34+
securityContext:
35+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
36+
serviceAccountName: {{ include "iam.serviceAccountName" . }}
37+
restartPolicy: Never
38+
initContainers:
39+
- name: job-wait-for-tenancy-crds
40+
image: alpine/kubectl:1.34.1
41+
securityContext:
42+
{{- toYaml .Values.securityContext | nindent 12 }}
43+
command: ["/bin/sh", "-c"]
44+
args:
45+
- |
46+
set -e
47+
echo "Waiting for Tenant CRDs to be available..."
48+
for CRD in "orgs.org.edge-orchestrator.intel.com" \
49+
"orgwatchers.orgwatcher.edge-orchestrator.intel.com" \
50+
"orgactivewatchers.orgactivewatcher.edge-orchestrator.intel.com" \
51+
"runtimeorgs.runtimeorg.edge-orchestrator.intel.com" \
52+
"projects.project.edge-orchestrator.intel.com" \
53+
"projectwatchers.projectwatcher.edge-orchestrator.intel.com" \
54+
"projectactivewatchers.projectactivewatcher.edge-orchestrator.intel.com" \
55+
"runtimeprojects.runtimeproject.edge-orchestrator.intel.com"; do
56+
echo "Checking for CRD: $CRD"
57+
until kubectl get crd $CRD; do
58+
echo "CRD $CRD not found, waiting..."
59+
sleep 30
60+
done
61+
echo "CRD $CRD is available."
62+
done
63+
echo "Checking for KTC pod existence"
64+
until kubectl get po -l app=keycloak-tenant-controller-pod -A | grep -qv "No resources found"; do
65+
echo "KTC pod not found, waiting..."
66+
sleep 30
67+
done
68+
echo "KTC pod found. Checking for KTC status"
69+
while kubectl wait --for=condition=Ready po -l app=keycloak-tenant-controller-pod -A 2>&1 | grep -q "error: timed out waiting for the condition on pods"; do
70+
echo "KTC pod not ready, retrying..."
71+
done
72+
containers:
73+
- name: {{ .Chart.Name }}
74+
securityContext:
75+
{{- toYaml .Values.securityContext | nindent 12 }}
76+
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
77+
imagePullPolicy: {{ .Values.image.pullPolicy }}
78+
args:
79+
- "--org={{ .Values.tenant.orgName }}"
80+
- "--project={{ .Values.tenant.projectName }}"
81+
env:
82+
- name: LOG_LEVEL
83+
value: {{ .Values.logLevel }}
84+
- name: KEYCLOAK_SERVICE
85+
value: {{ .Values.keycloak.service.name }}
86+
- name: KEYCLOAK_PORT
87+
value: "{{ .Values.keycloak.service.port }}"
88+
- name: KEYCLOAK_NAMESPACE
89+
value: {{ .Values.keycloak.service.namespace }}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
3+
# SPDX-FileCopyrightText: 2025 Intel Corporation
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
---
7+
8+
apiVersion: v1
9+
kind: ServiceAccount
10+
metadata:
11+
name: {{ include "iam.serviceAccountName" . }}
12+
namespace: {{ default .Release.Namespace .Values.global.namespace }}
13+
automountServiceAccountToken: true
14+
---
15+
apiVersion: rbac.authorization.k8s.io/v1
16+
kind: ClusterRole
17+
metadata:
18+
name: tenant-init-installer-role
19+
namespace: {{ default .Release.Namespace .Values.global.namespace }}
20+
rules:
21+
- apiGroups: ["apiextensions.k8s.io"]
22+
resources: ["customresourcedefinitions"]
23+
verbs: ["get","list"]
24+
# Access to organization and project CRDs
25+
- apiGroups: ["orgactivewatcher.edge-orchestrator.intel.com"]
26+
resources: ["orgactivewatchers"]
27+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
28+
- apiGroups: ["orgwatcher.edge-orchestrator.intel.com"]
29+
resources: ["orgwatchers"]
30+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
31+
- apiGroups: ["projectactivewatcher.edge-orchestrator.intel.com"]
32+
resources: ["projectactivewatchers"]
33+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
34+
- apiGroups: ["projectwatcher.edge-orchestrator.intel.com"]
35+
resources: ["projectwatchers"]
36+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
37+
# Access to runtime org and project resources
38+
- apiGroups: ["runtimeorg.edge-orchestrator.intel.com"]
39+
resources: ["runtimeorgs"]
40+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
41+
- apiGroups: ["runtimeproject.edge-orchestrator.intel.com"]
42+
resources: ["runtimeprojects"]
43+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
44+
# Access to org resources
45+
- apiGroups: ["org.edge-orchestrator.intel.com"]
46+
resources: ["orgs"]
47+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
48+
# Access to project resources
49+
- apiGroups: ["project.edge-orchestrator.intel.com"]
50+
resources: ["projects"]
51+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
52+
# Access to config resources
53+
- apiGroups: ["config.edge-orchestrator.intel.com"]
54+
resources: ["configs"]
55+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
56+
# Access to folder resources
57+
- apiGroups: ["folder.edge-orchestrator.intel.com"]
58+
resources: ["folders"]
59+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
60+
# Access to tenancy resources
61+
- apiGroups: ["tenancy.edge-orchestrator.intel.com"]
62+
resources: ["multitenancies"]
63+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
64+
# Access to runtime folder resources
65+
- apiGroups: ["runtimefolder.edge-orchestrator.intel.com"]
66+
resources: ["runtimefolders"]
67+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
68+
# Access to runtime resources
69+
- apiGroups: ["runtime.edge-orchestrator.intel.com"]
70+
resources: ["runtimes"]
71+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
72+
# Access to API mapping config resources
73+
- apiGroups: ["apimappingconfig.edge-orchestrator.intel.com"]
74+
resources: ["apimappingconfigs"]
75+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
76+
# Access to network resources
77+
- apiGroups: ["network.edge-orchestrator.intel.com"]
78+
resources: ["networks"]
79+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
80+
# Access to pods
81+
- apiGroups: [""]
82+
resources: ["pods", "namespaces", "configmaps", "services"]
83+
verbs: ["get", "list", "watch", "create", "update"]
84+
# Access to secrets
85+
- apiGroups: [""]
86+
resources: ["secrets"]
87+
verbs: ["get", "list", "watch", "create", "update"]
88+
---
89+
apiVersion: rbac.authorization.k8s.io/v1
90+
kind: ClusterRoleBinding
91+
metadata:
92+
name: tenant-init-installer
93+
namespace: {{ default .Release.Namespace .Values.global.namespace }}
94+
subjects:
95+
- kind: ServiceAccount
96+
name: {{ include "iam.serviceAccountName" . }}
97+
namespace: {{ default .Release.Namespace .Values.global.namespace }}
98+
roleRef:
99+
kind: ClusterRole
100+
name: tenant-init-installer-role
101+
apiGroup: rbac.authorization.k8s.io
102+

charts/tenancy-init/values.yaml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# SPDX-FileCopyrightText: 2025 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
---
5+
6+
global:
7+
name: tenancy-init
8+
9+
imagePullSecrets: ""
10+
image:
11+
registry: registry-rs.edgeorchestration.intel.com/edge-orch
12+
repository: common/tenancy-init
13+
pullPolicy: IfNotPresent
14+
15+
serviceAccount:
16+
# Specifies whether a service account should be created
17+
create: true
18+
# Annotations to add to the service account
19+
annotations: {}
20+
# The name of the service account to use.
21+
# If not set and create is true, a name is generated using the fullname template
22+
name: tenant-init-k8s-api-service-account
23+
24+
podSecurityContext:
25+
seccompProfile:
26+
type: RuntimeDefault
27+
28+
securityContext:
29+
capabilities:
30+
drop:
31+
- ALL
32+
readOnlyRootFilesystem: true
33+
allowPrivilegeEscalation: false
34+
runAsNonRoot: true
35+
runAsUser: 1000
36+
37+
tolerations: []
38+
39+
affinity: {}
40+
41+
nodeSelector: {}
42+
43+
podAnnotations: {}
44+
45+
logLevel: info
46+
47+
tenant:
48+
orgName: "default"
49+
projectName: "default"
50+
keycloak:
51+
service:
52+
name: "platform-keycloak"
53+
port: "8080"
54+
namespace: "orch-platform"

0 commit comments

Comments
 (0)