diff --git a/deploy/templates/adminrpc-deployment.yaml b/deploy/templates/adminrpc-deployment.yaml new file mode 100644 index 0000000..77227f9 --- /dev/null +++ b/deploy/templates/adminrpc-deployment.yaml @@ -0,0 +1,89 @@ +{{- if .Values.adminrpc.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "gitdata.fullname" . }}-adminrpc + namespace: {{ include "gitdata.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "gitdata.fullname" . }}-adminrpc + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "gitdata.fullname" . }}-adminrpc + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "gitdata.fullname" . }}-adminrpc + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- if $.Values.image.pullSecrets }} + imagePullSecrets: + {{- range $.Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + terminationGracePeriodSeconds: 10 + containers: + - name: adminrpc + image: "{{ .Values.image.registry }}/{{ .Values.adminrpc.image.repository }}:{{ .Values.adminrpc.image.tag }}" + imagePullPolicy: {{ .Values.adminrpc.image.pullPolicy | default .Values.image.pullPolicy }} + ports: + - name: grpc + containerPort: {{ .Values.adminrpc.service.port }} + protocol: TCP + args: + - --bind + - "0.0.0.0:{{ .Values.adminrpc.service.port }}" + envFrom: + - configMapRef: + name: {{ include "gitdata.fullname" . }}-config + livenessProbe: + tcpSocket: + port: {{ .Values.adminrpc.service.port }} + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: {{ .Values.adminrpc.service.port }} + initialDelaySeconds: 5 + periodSeconds: 5 + {{- if .Values.adminrpc.resources }} + resources: + {{- toYaml .Values.adminrpc.resources | nindent 12 }} + {{- end }} + {{- with .Values.adminrpc.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.adminrpc.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.adminrpc.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "gitdata.fullname" . }}-adminrpc + namespace: {{ include "gitdata.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "gitdata.fullname" . }}-adminrpc + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.adminrpc.service.port }} + targetPort: grpc + protocol: TCP + name: grpc + selector: + app.kubernetes.io/name: {{ include "gitdata.fullname" . }}-adminrpc + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/deploy/values.yaml b/deploy/values.yaml index 21ab647..5adeccb 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -388,3 +388,33 @@ operator: nodeSelector: {} tolerations: [] affinity: {} + +# ============================================================================= +# Admin RPC – internal gRPC service for admin operations (k8s internal only) +# ============================================================================= +adminrpc: + enabled: true + + image: + repository: adminrpc + tag: latest + + service: + port: 9090 + + readinessProbe: + tcpSocket: + port: 9090 + initialDelaySeconds: 3 + periodSeconds: 5 + + resources: + requests: + cpu: 50m + memory: 64Mi + + env: [] + + nodeSelector: {} + tolerations: [] + affinity: {} diff --git a/docker/adminrpc.Dockerfile b/docker/adminrpc.Dockerfile new file mode 100644 index 0000000..3e0525d --- /dev/null +++ b/docker/adminrpc.Dockerfile @@ -0,0 +1,12 @@ +# Runtime only — binary built externally via cargo +FROM debian:bookworm-slim + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates libssl3 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY target/x86_64-unknown-linux-gnu/release/adminrpc /app/adminrpc + +ENV APP_LOG_LEVEL=info +ENTRYPOINT ["/app/adminrpc"] diff --git a/scripts/build.js b/scripts/build.js index 63c647f..7452adc 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -26,7 +26,7 @@ const GIT_SHA_SHORT = execSync('git rev-parse --short HEAD', {encoding: 'utf8'}) const TAG = process.env.TAG || GIT_SHA_SHORT; const BUILD_TARGET = process.env.TARGET || 'x86_64-unknown-linux-gnu'; -const RUST_SERVICES = ['app', 'gitserver', 'email-worker', 'git-hook', 'operator', 'static']; +const RUST_SERVICES = ['app', 'gitserver', 'email-worker', 'git-hook', 'operator', 'static', 'adminrpc']; const ALL_SERVICES = RUST_SERVICES; const args = process.argv.slice(2); @@ -51,6 +51,7 @@ if (rustTargets.length > 0) { const pkgMap = { 'app': 'app', 'gitserver': 'gitserver', 'email-worker': 'email-server', 'git-hook': 'git-hook', 'operator': 'operator', 'static': 'static-server', + 'adminrpc': 'adminrpc', }; return `--package ${pkgMap[s]}`; }).join(' ')} -j ${cpus}`, diff --git a/scripts/deploy.js b/scripts/deploy.js index 4032ccd..b2d823b 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -31,7 +31,7 @@ const args = process.argv.slice(2); const isDryRun = args.includes('--dry-run'); const runMigrate = args.includes('--migrate'); -const SERVICES = ['app', 'gitserver', 'email-worker', 'git-hook', 'operator', 'static']; +const SERVICES = ['app', 'gitserver', 'email-worker', 'git-hook', 'operator', 'static', 'adminrpc']; // Validate kubeconfig if (!fs.existsSync(KUBECONFIG)) { @@ -61,6 +61,7 @@ const setValues = [ `gitHook.image.tag=${TAG}`, `operator.image.tag=${TAG}`, `static.image.tag=${TAG}`, + `adminrpc.image.tag=${TAG}`, ]; if (runMigrate) {