Skip to content

Commit

Permalink
Init Helm chart (#255)
Browse files Browse the repository at this point in the history
* Initial chart version

* Add CI/CD for chart

* Fix admin creds template

* Add command, args, env, envFrom

* Render volumes and volumeMounts with tpl

* Change persistance accessMode type

* Add update strategy config

* Use custom types in docs

* Add startup probe config

* Fix web.external_url config
  • Loading branch information
Dmytro Bondar authored Jul 4, 2024
1 parent 8538112 commit 6f52cb2
Show file tree
Hide file tree
Showing 19 changed files with 981 additions and 0 deletions.
84 changes: 84 additions & 0 deletions .github/workflows/chart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Publish chart to the GitHub Container Registry (GHCR) on push to master
# Run the following tests on PRs:
# - Check if chart's documentation is up to date
# - Check chart linting
# - Check chart installation in a Kind cluster
# - Check chart packaging

name: Chart

on:
pull_request:
branches: [master]
paths: [deploy/helm]
push:
branches: [master]
paths: [deploy/helm]

jobs:
lint-test:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

# ct lint requires Python 3.x to run following packages:
# - yamale (https://github.com/23andMe/Yamale)
# - yamllint (https://github.com/adrienverge/yamllint)
- uses: actions/setup-python@v4
with:
python-version: '3.x'

- uses: helm/chart-testing-action@v2

- name: Run chart-testing (lint)
run: ct lint --config ct.yaml

- name: Check docs
run: |
docker run --rm --volume "${PWD}/deploy:/helm-docs" -u "$(id -u)" jnorwood/helm-docs
if ! git diff --exit-code; then
echo "error::Documentation is not up to date. Please run helm-docs and commit changes."
exit 1
fi
- uses: helm/kind-action@v1

- name: Run chart-testing (install)
run: ct install --config ct.yaml

- name: Run helm package charts
run: |
for chart in $(ct list-changed --config ct.yaml); do
helm package $chart -d out
done
publish:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' }}
permissions:
packages: write
steps:
- uses: actions/checkout@v4

- uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- uses: helm/chart-testing-action@v2
- name: Run helm package charts
run: |
for chart in $(ct list-changed --config ct.yaml); do
helm package $chart -d out
done
- name: Push chart to GHCR
working-directory: out
run: |
for pkg in $(ls *.tgz); do
helm push $pkg oci://ghcr.io/${{ github.repository_owner }}/charts
done
5 changes: 5 additions & 0 deletions ct.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# See https://github.com/helm/chart-testing#configuration
remote: origin
chart-dirs: deploy
target-branch: master
validate-maintainers: false
23 changes: 23 additions & 0 deletions deploy/helm/.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/
25 changes: 25 additions & 0 deletions deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: v2
name: wg-portal
description: WireGuard Configuration Portal with LDAP, OAuth, OIDC authentication
# Version is set to ensure compatibility with the chart's Ingress resource.
kubeVersion: '>=1.19.0'
type: application
home: https://wgportal.org
icon: https://wgportal.org/assets/images/logo.svg
sources:
- https://github.com/h44z/wg-portal

annotations:
artifacthub.io/category: networking
artifacthub.io/changes: ""

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: v2.0.0-alpha.2
116 changes: 116 additions & 0 deletions deploy/helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# wg-portal

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.0.0-alpha.2](https://img.shields.io/badge/AppVersion-v2.0.0--alpha.2-informational?style=flat-square)

WireGuard Configuration Portal with LDAP, OAuth, OIDC authentication

**Homepage:** <https://wgportal.org>

## Source Code

* <https://github.com/h44z/wg-portal>

## Requirements

Kubernetes: `>=1.19.0`

## Installing the Chart

To install the chart with the release name `wg-portal`:

```console
helm install wg-portal oci://ghcr.io/h44z/charts/wg-portal
```

This command deploy wg-portal on the Kubernetes cluster in the default configuration.
The [Values](#values) section lists the parameters that can be configured during installation.

## Values

### Parameters

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | Affinity configuration |
| args | list | `[]` | Additional pod arguments |
| command | list | `[]` | Overwrite pod command |
| dnsPolicy | string | `"ClusterFirst"` | Set DNS policy for the pod. Valid values are `ClusterFirstWithHostNet`, `ClusterFirst`, `Default` or `None`. |
| env | tpl/list | `[]` | Additional environment variables |
| envFrom | tpl/list | `[]` | Additional environment variables from a secret or configMap |
| hostNetwork | string | `false`. | Use the host's network namespace. |
| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy |
| image.repository | string | `"ghcr.io/h44z/wg-portal"` | Image repository |
| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion |
| imagePullSecrets | list | `[]` | Image pull secrets |
| initContainers | tpl/list | `[]` | Pod init containers |
| nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node Selector configuration |
| podAnnotations | tpl/object | `{}` | Extra annotations to add to the pod |
| podLabels | object | `{}` | Extra labels to add to the pod |
| podSecurityContext | object | `{}` | Pod Security Context |
| resources | object | `{}` | Resources requests and limits |
| restartPolicy | string | `"Always"` | Restart policy for all containers within the pod. Valid values are `Always`, `OnFailure` or `Never`. |
| revisionHistoryLimit | string | `10` | The number of old ReplicaSets to retain to allow rollback. |
| securityContext.capabilities.add | list | `["NET_ADMIN"]` | Add capabilities to the container |
| sidecarContainers | tpl/list | `[]` | Pod sidecar containers |
| strategy | object | `{"type":"RollingUpdate"}` | Update strategy for the workload Valid values are: `RollingUpdate` or `Recreate` for Deployment, `RollingUpdate` or `OnDelete` for StatefulSet |
| tolerations | list | `[]` | Tolerations configuration |
| volumeMounts | tpl/list | `[]` | Additional volumeMounts |
| volumes | tpl/list | `[]` | Additional volumes |
| workloadType | string | `"Deployment"` | Workload type - `Deployment` or `StatefulSet` |

### Configuration

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| config.advanced | tpl/object | `{}` | Advanced configuration options. |
| config.auth | tpl/object | `{}` | Auth configuration options. |
| config.core | tpl/object | `{}` | Core configuration options.<br> If external admins in `auth` are not defined and there are no `admin_user` and `admin_password` defined here, the default credentials will be generated. |
| config.database | tpl/object | `{}` | Database configuration options |
| config.mail | tpl/object | `{}` | Mail configuration options |
| config.statistics | tpl/object | `{}` | Statistics configuration options |
| config.web | tpl/object | `{}` | Web configuration options.<br> The chart will set `listening_address` automatically from `service.web.port`, and `external_url` from `ingress.host` if enabled. |

### Common

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| extraDeploy | list | `[]` | Array of extra objects to deploy with the release |
| fullnameOverride | string | `""` | Fully override resource names |
| nameOverride | string | `""` | Partially override resource names (adds suffix) |

### Traffic exposure

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| ingress.annotations | object | `{}` | Ingress annotations |
| ingress.className | string | `""` | Ingress class name |
| ingress.enabled | bool | `false` | Specifies whether an ingress resource should be created |
| ingress.host | string | `""` | Ingress host FQDN |
| ingress.path | string | `"/"` | Ingress path |
| ingress.pathType | string | `"ImplementationSpecific"` | Ingress path type |
| ingress.tls | list | `[]` | Ingress TLS configuration |
| service.web.annotations | object | `{}` | Annotations for the web service |
| service.web.port | int | `8888` | Web service port Used for the web interface listener |
| service.web.type | string | `"ClusterIP"` | Web service type |
| service.wireguard.annotations | object | `{}` | Annotations for the WireGuard service |
| service.wireguard.ports | list | `[51820]` | Wireguard service ports. Exposes the WireGuard ports for created interfaces. Lowerest port is selected as start port for the first interface. Increment next port by 1 for each additional interface. |
| service.wireguard.type | string | `"LoadBalancer"` | Wireguard service type |

### Persistence

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| persistence.accessMode | string | `"ReadWriteOnce"` | Persistent Volume Access Mode |
| persistence.annotations | object | `{}` | Persistent Volume Claim annotations |
| persistence.enabled | bool | `false` | Specifies whether an persistent volume should be created |
| persistence.size | string | `"1Gi"` | Persistent Volume size |
| persistence.storageClass | string | `""` | Persistent Volume storage class. If undefined (the default) cluster's default provisioner will be used. |

### RBAC

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| serviceAccount.annotations | object | `{}` | Service account annotations |
| serviceAccount.automount | bool | `false` | Automatically mount a ServiceAccount's API credentials |
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
27 changes: 27 additions & 0 deletions deploy/helm/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{ template "chart.header" . }}
{{ template "chart.deprecationWarning" . }}

{{ template "chart.badgesSection" . }}

{{ template "chart.description" . }}

{{ template "chart.homepageLine" . }}

{{ template "chart.maintainersSection" . }}

{{ template "chart.sourcesSection" . }}

{{ template "chart.requirementsSection" . }}

## Installing the Chart

To install the chart with the release name `wg-portal`:

```console
helm install wg-portal oci://ghcr.io/h44z/charts/wg-portal
```

This command deploy wg-portal on the Kubernetes cluster in the default configuration.
The [Values](#values) section lists the parameters that can be configured during installation.

{{ template "chart.valuesSection" . }}
24 changes: 24 additions & 0 deletions deploy/helm/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{- $serviceName := printf "%s-web" (include "wg-portal.fullname" .) -}}
{{- $servicePort := .Values.service.web.port }}

{{- if not .Values.ingress.enabled }}
Get the application URL by running these commands:
{{- if eq "ClusterIP" .Values.service.web.type }}
kubectl --namespace {{ .Release.Namespace }} port-forward svc/{{ $serviceName }} {{ $servicePort }}:{{ $servicePort }}

Visit http://127.0.0.1:{{ $servicePort }} to use your application

{{- else if eq "LoadBalancer" .Values.service.web.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ $serviceName }}'
export SERVICE_IP=$(kubectl get --namespace {{ .Release.Namespace }} svc {{ $serviceName }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ $servicePort }}

{{- else if eq "NodePort" .Values.service.web.type }}
export NODE_IP=$(kubectl get --namespace {{ .Release.Namespace }} nodes -o jsonpath="{.items[0].status.addresses[0].address}")
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} svc {{ $serviceName }} -o jsonpath="{.spec.ports[0].nodePort}" )
echo http://$NODE_IP:$NODE_PORT
{{- end }}
{{- else }}
Visit http{{ if .Values.ingress.tls }}s{{ end }}://{{ .Values.ingress.host }}{{ .Values.ingress.path }} to use your application
{{- end }}
Loading

0 comments on commit 6f52cb2

Please sign in to comment.