Add ttyd app
This commit is contained in:
parent
c2331dc5d1
commit
9bf49b956c
25
argocd-apps/ttyd.yaml
Normal file
25
argocd-apps/ttyd.yaml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: ttyd
|
||||||
|
namespace: argocd
|
||||||
|
labels:
|
||||||
|
env: infra
|
||||||
|
spec:
|
||||||
|
project: infra
|
||||||
|
source:
|
||||||
|
repoURL: 'ssh://git@gitea-ssh.dev-tools.svc.cluster.local:2222/dvirlabs/infra.git'
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: charts/ttyd
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- ../../manifests/ttyd/values.yaml
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: infra
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
16
charts/ttyd/Chart.yaml
Normal file
16
charts/ttyd/Chart.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: ttyd
|
||||||
|
description: Browser-based terminal via ttyd, managed by ArgoCD
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "latest"
|
||||||
|
keywords:
|
||||||
|
- terminal
|
||||||
|
- ttyd
|
||||||
|
- kubectl
|
||||||
|
- web-terminal
|
||||||
|
maintainers:
|
||||||
|
- name: dvirlabs
|
||||||
|
home: https://github.com/tsl0922/ttyd
|
||||||
|
sources:
|
||||||
|
- https://github.com/tsl0922/ttyd
|
||||||
62
charts/ttyd/templates/_helpers.tpl
Normal file
62
charts/ttyd/templates/_helpers.tpl
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||||
|
If release name contains chart name it will be used as a full name.
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "ttyd.chart" . }}
|
||||||
|
{{ include "ttyd.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "ttyd.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "ttyd.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "ttyd.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
94
charts/ttyd/templates/clusterrole.yaml
Normal file
94
charts/ttyd/templates/clusterrole.yaml
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
# WARNING: This ClusterRole grants broad read + exec access across the cluster.
|
||||||
|
# It is intentionally permissive for lab/troubleshooting use.
|
||||||
|
# Review and restrict these permissions before using in a production environment.
|
||||||
|
#
|
||||||
|
# Future auth integration note:
|
||||||
|
# When oauth2-proxy is added in front of ttyd, consider scoping this role
|
||||||
|
# further to match the actual user's identity or group permissions.
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: {{ include "ttyd.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
rules:
|
||||||
|
# Core workload resources — read + basic management for kubectl troubleshooting
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources:
|
||||||
|
- pods
|
||||||
|
- pods/log
|
||||||
|
- services
|
||||||
|
- endpoints
|
||||||
|
- configmaps
|
||||||
|
- secrets # WARNING: includes secret read access; tighten in production
|
||||||
|
- events
|
||||||
|
- namespaces
|
||||||
|
- nodes
|
||||||
|
- persistentvolumeclaims
|
||||||
|
- persistentvolumes
|
||||||
|
- replicationcontrollers
|
||||||
|
- serviceaccounts
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
|
# Pod exec and log streaming (needed for `kubectl exec` and `kubectl logs -f`)
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources:
|
||||||
|
- pods/exec
|
||||||
|
- pods/attach
|
||||||
|
- pods/portforward
|
||||||
|
verbs: ["create"]
|
||||||
|
|
||||||
|
# Pod and service management (basic ops for lab use)
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources:
|
||||||
|
- pods
|
||||||
|
- services
|
||||||
|
- configmaps
|
||||||
|
verbs: ["delete", "patch", "update"]
|
||||||
|
|
||||||
|
# Apps resources
|
||||||
|
- apiGroups: ["apps"]
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
- replicasets
|
||||||
|
- statefulsets
|
||||||
|
- daemonsets
|
||||||
|
verbs: ["get", "list", "watch", "patch", "delete"]
|
||||||
|
|
||||||
|
# Batch resources
|
||||||
|
- apiGroups: ["batch"]
|
||||||
|
resources:
|
||||||
|
- jobs
|
||||||
|
- cronjobs
|
||||||
|
verbs: ["get", "list", "watch", "delete"]
|
||||||
|
|
||||||
|
# Networking resources
|
||||||
|
- apiGroups: ["networking.k8s.io"]
|
||||||
|
resources:
|
||||||
|
- ingresses
|
||||||
|
- ingressclasses
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
|
# RBAC resources (read-only, for inspection purposes)
|
||||||
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
|
resources:
|
||||||
|
- roles
|
||||||
|
- rolebindings
|
||||||
|
- clusterroles
|
||||||
|
- clusterrolebindings
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
|
# Storage classes (read-only)
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources:
|
||||||
|
- storageclasses
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
|
# Metrics (optional, useful for `kubectl top`)
|
||||||
|
- apiGroups: ["metrics.k8s.io"]
|
||||||
|
resources:
|
||||||
|
- pods
|
||||||
|
- nodes
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
{{- end }}
|
||||||
18
charts/ttyd/templates/clusterrolebinding.yaml
Normal file
18
charts/ttyd/templates/clusterrolebinding.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
# Binds the ttyd ClusterRole to its dedicated ServiceAccount.
|
||||||
|
# WARNING: This grants cluster-wide permissions. See clusterrole.yaml for details.
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: {{ include "ttyd.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: {{ include "ttyd.fullname" . }}
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: {{ include "ttyd.serviceAccountName" . }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
{{- end }}
|
||||||
72
charts/ttyd/templates/deployment.yaml
Normal file
72
charts/ttyd/templates/deployment.yaml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "ttyd.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "ttyd.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "ttyd.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
# ttyd args: bind port, then pass the shell command to execute in the browser terminal.
|
||||||
|
# To use kubectl, switch image.repository to a custom image that bundles ttyd + kubectl.
|
||||||
|
args:
|
||||||
|
- "--port={{ .Values.ttyd.port }}"
|
||||||
|
- {{ .Values.ttyd.command | quote }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.ttyd.port }}
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 20
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
|
failureThreshold: 3
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
35
charts/ttyd/templates/ingress.yaml
Normal file
35
charts/ttyd/templates/ingress.yaml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{{- if .Values.ingress.enabled -}}
|
||||||
|
{{- $fullName := include "ttyd.fullname" . -}}
|
||||||
|
{{- $svcPort := .Values.service.port -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if .Values.ingress.className }}
|
||||||
|
ingressClassName: {{ .Values.ingress.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.tls.enabled }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.host | quote }}
|
||||||
|
secretName: {{ .Values.ingress.tls.secretName }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: {{ .Values.ingress.path }}
|
||||||
|
pathType: {{ .Values.ingress.pathType }}
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}
|
||||||
|
port:
|
||||||
|
number: {{ $svcPort }}
|
||||||
|
{{- end }}
|
||||||
15
charts/ttyd/templates/service.yaml
Normal file
15
charts/ttyd/templates/service.yaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "ttyd.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "ttyd.selectorLabels" . | nindent 4 }}
|
||||||
8
charts/ttyd/templates/serviceaccount.yaml
Normal file
8
charts/ttyd/templates/serviceaccount.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "ttyd.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "ttyd.labels" . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
54
charts/ttyd/values.yaml
Normal file
54
charts/ttyd/values.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: tsl0922/ttyd
|
||||||
|
tag: latest
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 7681
|
||||||
|
|
||||||
|
ttyd:
|
||||||
|
port: 7681
|
||||||
|
# Shell command passed to ttyd. Switch to a custom image with kubectl for full functionality.
|
||||||
|
command: "/bin/sh"
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: traefik
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
host: kctl.dvirlabs.com
|
||||||
|
path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
secretName: tls-ttyd-ingress
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 128Mi
|
||||||
|
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
|
||||||
|
securityContext: {}
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
affinity: {}
|
||||||
48
manifests/ttyd/values.yaml
Normal file
48
manifests/ttyd/values.yaml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# ttyd environment-specific values
|
||||||
|
# Overrides charts/ttyd/values.yaml defaults
|
||||||
|
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
image:
|
||||||
|
# Switch to a custom image that bundles ttyd + kubectl for full kubectl support.
|
||||||
|
# Example: repository: registry.dvirlabs.com/ttyd-kubectl
|
||||||
|
repository: tsl0922/ttyd
|
||||||
|
tag: latest
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
service:
|
||||||
|
port: 7681
|
||||||
|
|
||||||
|
ttyd:
|
||||||
|
port: 7681
|
||||||
|
# Shell to launch in the browser terminal.
|
||||||
|
# Change to /bin/bash if using a custom image that includes bash + kubectl.
|
||||||
|
command: "/bin/sh"
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: traefik
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
host: kctl.dvirlabs.com
|
||||||
|
path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
secretName: tls-ttyd-ingress
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 128Mi
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
tolerations: []
|
||||||
|
affinity: {}
|
||||||
Loading…
x
Reference in New Issue
Block a user