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