Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/helm-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ jobs:
- name: Template monitoring chart
run: helm template monitoring helm/monitoring/ > /dev/null

tunnel-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/setup-helm@v4
with:
version: v3.14.0
- name: Lint tunnel chart
run: helm lint helm/cloudflare-tunnel/
- name: Template tunnel chart
run: helm template tunnel helm/cloudflare-tunnel/ --set tunnel.token=dummy-token > /dev/null

kubeconform:
runs-on: ubuntu-latest
needs: helm-template
Expand Down Expand Up @@ -99,7 +111,7 @@ jobs:
run: pip install yamllint
- name: Lint YAML files
run: |
yamllint -d relaxed helm/disentangle/Chart.yaml helm/disentangle/values.yaml helm/disentangle/values.schema.json helm/monitoring/Chart.yaml helm/monitoring/values.yaml gitops/
yamllint -d relaxed helm/disentangle/Chart.yaml helm/disentangle/values.yaml helm/disentangle/values.schema.json helm/monitoring/Chart.yaml helm/monitoring/values.yaml helm/cloudflare-tunnel/Chart.yaml helm/cloudflare-tunnel/values.yaml gitops/

helm-unittest:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Thumbs.db
# Helm
helm/disentangle/charts/
helm/monitoring/charts/
helm/cloudflare-tunnel/charts/
*.tgz
.helm/
helm-plugins/
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.PHONY: help lint test test-unit test-golden test-policy test-integration test-all clean lint-monitoring template-monitoring deps-monitoring
.PHONY: help lint test test-unit test-golden test-policy test-integration test-all clean lint-monitoring template-monitoring deps-monitoring lint-tunnel template-tunnel

CHART_DIR := helm/disentangle
MONITORING_CHART_DIR := helm/monitoring
TUNNEL_CHART_DIR := helm/cloudflare-tunnel
NAMESPACE := disentangle-test
RELEASE := test-release

Expand All @@ -10,7 +11,7 @@ help: ## Show this help

# === Linting ===

lint: lint-helm lint-monitoring lint-yaml lint-shell ## Run all linters
lint: lint-helm lint-monitoring lint-tunnel lint-yaml lint-shell ## Run all linters

lint-helm: ## Lint Helm chart
helm lint $(CHART_DIR)
Expand All @@ -24,6 +25,12 @@ template-monitoring: ## Render monitoring chart templates
deps-monitoring: ## Build monitoring chart dependencies
helm dependency build $(MONITORING_CHART_DIR)

lint-tunnel: ## Lint cloudflare-tunnel chart
helm lint $(TUNNEL_CHART_DIR)

template-tunnel: ## Render cloudflare-tunnel templates
helm template tunnel $(TUNNEL_CHART_DIR) --set tunnel.token=dummy-token > /dev/null

lint-yaml: ## Lint YAML files (excluding Helm templates)
@command -v yamllint >/dev/null 2>&1 || { echo "Install yamllint: pip install yamllint"; exit 1; }
yamllint -d relaxed gitops/ $(CHART_DIR)/Chart.yaml $(CHART_DIR)/values.yaml
Expand Down
23 changes: 23 additions & 0 deletions helm/cloudflare-tunnel/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
7 changes: 7 additions & 0 deletions helm/cloudflare-tunnel/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v2
name: cloudflare-tunnel
description: Cloudflare Tunnel (cloudflared) for zero-trust ingress to Disentangle Network services

Check warning on line 3 in helm/cloudflare-tunnel/Chart.yaml

View workflow job for this annotation

GitHub Actions / yamllint

3:81 [line-length] line too long (99 > 80 characters)
type: application
version: 0.1.0
appVersion: "2026.2.0"
license: Apache-2.0
68 changes: 68 additions & 0 deletions helm/cloudflare-tunnel/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "cloudflare-tunnel.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
*/}}
{{- define "cloudflare-tunnel.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 "cloudflare-tunnel.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "cloudflare-tunnel.labels" -}}
helm.sh/chart: {{ include "cloudflare-tunnel.chart" . }}
{{ include "cloudflare-tunnel.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "cloudflare-tunnel.selectorLabels" -}}
app.kubernetes.io/name: {{ include "cloudflare-tunnel.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the image string
*/}}
{{- define "cloudflare-tunnel.image" -}}
{{- $tag := .Values.image.tag | default .Chart.AppVersion }}
{{- printf "%s:%s" .Values.image.repository $tag }}
{{- end }}

{{/*
Determine the secret name for the tunnel token
*/}}
{{- define "cloudflare-tunnel.secretName" -}}
{{- if .Values.tunnel.existingSecret }}
{{- .Values.tunnel.existingSecret }}
{{- else }}
{{- include "cloudflare-tunnel.fullname" . }}-token
{{- end }}
{{- end }}
66 changes: 66 additions & 0 deletions helm/cloudflare-tunnel/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{{- if and (not .Values.tunnel.token) (not .Values.tunnel.existingSecret) }}
{{- fail "Either tunnel.token or tunnel.existingSecret must be set" }}
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}
labels:
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: cloudflared
image: {{ include "cloudflare-tunnel.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- cloudflared
- tunnel
- --no-autoupdate
- run
- --token
- $(TUNNEL_TOKEN)
env:
- name: TUNNEL_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "cloudflare-tunnel.secretName" . }}
key: token
readinessProbe:
httpGet:
path: /ready
port: 2000
initialDelaySeconds: 5
periodSeconds: 10
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
11 changes: 11 additions & 0 deletions helm/cloudflare-tunnel/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if and .Values.tunnel.token (not .Values.tunnel.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}-token
labels:
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
type: Opaque
data:
token: {{ .Values.tunnel.token | b64enc | quote }}
{{- end }}
55 changes: 55 additions & 0 deletions helm/cloudflare-tunnel/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Cloudflare Tunnel configuration
# Requires a tunnel token from the Cloudflare Zero Trust dashboard
# Create at: https://one.dash.cloudflare.com/ -> Networks -> Tunnels

# Tunnel authentication
tunnel:
# Existing secret name containing the tunnel token
# The secret must have key 'token' with the tunnel token value
existingSecret: ""
# Or specify the token directly (not recommended for production)
token: ""

image:
repository: cloudflare/cloudflared
tag: "" # defaults to appVersion
pullPolicy: IfNotPresent

replicaCount: 1

resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi

# Pod security
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532 # nonroot user

# Ingress rules for the tunnel
# Maps external hostnames to internal K8s services
ingressRules: []
# - hostname: rpc.disentangle.network
# service: http://disentangle-rpc.disentangle.svc.cluster.local:8000
# - hostname: grafana.disentangle.network
# service: http://disentangle-monitoring-grafana.monitoring.svc.cluster.local:80

Check warning on line 48 in helm/cloudflare-tunnel/values.yaml

View workflow job for this annotation

GitHub Actions / yamllint

48:81 [line-length] line too long (84 > 80 characters)

# Catch-all rule for unmatched requests
catchAllService: http_status:404

nodeSelector: {}
tolerations: []
affinity: {}
Loading