From 370cd1009682ab649fe280a536a7024046636d06 Mon Sep 17 00:00:00 2001 From: James Greenhill Date: Sun, 28 Jun 2020 16:55:16 -0700 Subject: [PATCH] misc: update helm chart configs and readme (#1751) * fix wiki helm * update readme * include service account as a stub * use lightweight healthz for readiness and health endpoint * remove if block for setting DB_TYPE, only postgres is supported in this chart for now --- dev/helm/.helmignore | 23 +++ dev/helm/Chart.lock | 6 + dev/helm/Chart.yaml | 29 +++- dev/helm/README.md | 140 +++++++++++++++++- dev/helm/charts/postgresql-6.5.0.tgz | Bin 0 -> 23426 bytes dev/helm/requirements.yaml | 5 - dev/helm/templates/NOTES.txt | 21 +++ dev/helm/templates/_helpers.tpl | 108 ++++++++++++++ dev/helm/templates/deployment.yaml | 75 ++++++++++ dev/helm/templates/ingress.yaml | 62 ++++---- dev/helm/templates/secrets.yaml | 13 -- dev/helm/templates/service.yaml | 31 +--- dev/helm/templates/serviceaccount.yaml | 12 ++ dev/helm/templates/tests/test-connection.yaml | 15 ++ dev/helm/values.yaml | 111 +++++++++++--- 15 files changed, 549 insertions(+), 102 deletions(-) create mode 100644 dev/helm/.helmignore create mode 100644 dev/helm/Chart.lock create mode 100644 dev/helm/charts/postgresql-6.5.0.tgz delete mode 100644 dev/helm/requirements.yaml create mode 100644 dev/helm/templates/NOTES.txt create mode 100644 dev/helm/templates/_helpers.tpl create mode 100644 dev/helm/templates/deployment.yaml delete mode 100644 dev/helm/templates/secrets.yaml create mode 100644 dev/helm/templates/serviceaccount.yaml create mode 100644 dev/helm/templates/tests/test-connection.yaml diff --git a/dev/helm/.helmignore b/dev/helm/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/dev/helm/.helmignore @@ -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/ diff --git a/dev/helm/Chart.lock b/dev/helm/Chart.lock new file mode 100644 index 00000000..7289185d --- /dev/null +++ b/dev/helm/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 6.5.0 +digest: sha256:e94b0117531082cb4efc287999abf5c5f7d58fecb8127251c20a7f0fc2ea65da +generated: "2020-04-21T18:55:53.994556-07:00" diff --git a/dev/helm/Chart.yaml b/dev/helm/Chart.yaml index bee62aa6..d81bd456 100644 --- a/dev/helm/Chart.yaml +++ b/dev/helm/Chart.yaml @@ -1,7 +1,11 @@ -apiVersion: v1 -name: Wiki.js -version: 2.0.0 -appVersion: 2.0.0 +apiVersion: v2 +name: wiki +# 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. +version: 2.0.1 +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +AppVersion: latest description: The most powerful and extensible open source Wiki software. keywords: - wiki @@ -10,6 +14,20 @@ keywords: - docs - reference - editor +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application +dependencies: + - name: postgresql + version: 6.5.0 + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: postgresql.enabled home: https://wiki.js.org icon: https://github.com/Requarks/wiki/raw/master/client/static/favicons/android-chrome-192x192.png sources: @@ -18,4 +36,7 @@ maintainers: - name: Nicolas Giard email: github@ngpixel.com url: https://github.com/NGPixel + - name: James Greenhill + email: james@fuziontech.net + url: https://github.com/fuziontech engine: gotpl diff --git a/dev/helm/README.md b/dev/helm/README.md index b3c43d86..86cc5223 100644 --- a/dev/helm/README.md +++ b/dev/helm/README.md @@ -1,2 +1,138 @@ -# Work in progress -##### Do not use! +
+ +Wiki.js + +[![Release](https://img.shields.io/github/release/Requarks/wiki.svg?style=flat&maxAge=3600)](https://github.com/Requarks/wiki/releases) +[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg?style=flat)](https://github.com/requarks/wiki/blob/master/LICENSE) +[![Backers on Open Collective](https://opencollective.com/wikijs/all/badge.svg)](https://opencollective.com/wikijs) +[![Downloads](https://img.shields.io/github/downloads/Requarks/wiki/total.svg?style=flat)](https://github.com/Requarks/wiki/releases) +[![Docker Pulls](https://img.shields.io/docker/pulls/requarks/wiki.svg)](https://hub.docker.com/r/requarks/wiki/) +[![Build status](https://dev.azure.com/requarks/wiki/_apis/build/status/build)](https://dev.azure.com/requarks/wiki/_build/latest?definitionId=9) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=wiki&metric=alert_status)](https://sonarcloud.io/dashboard?id=wiki) +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=wiki&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=wiki) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=wiki&metric=security_rating)](https://sonarcloud.io/dashboard?id=wiki) +[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) +[![Chat on Slack](https://img.shields.io/badge/slack-requarks-CC2B5E.svg?style=flat&logo=slack)](https://wiki.requarks.io/slack) +[![Twitter Follow](https://img.shields.io/badge/follow-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks) +[![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp)](https://wiki.js.org/newsletter) + +##### A modern, lightweight and powerful wiki app built on NodeJS + +
+ +- **[Official Website](https://wiki.js.org/)** +- **[Documentation](https://docs.requarks.io/)** + +

Donate

+ +
+ +Wiki.js is an open source project that has been made possible due to the generous contributions by community [backers](https://wiki.js.org/about). If you are interested in supporting this project, please consider [becoming a sponsor](https://github.com/users/NGPixel/sponsorship), [becoming a patron](https://www.patreon.com/requarks), donating to our [OpenCollective](https://opencollective.com/wikijs), via [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FLV5X255Z9CJU&source=url) or via Ethereum (`0xe1d55c19ae86f6bcbfb17e7f06ace96bdbb22cb5`). + + [![Become a Sponsor](https://img.shields.io/badge/donate-github-ea4aaa.svg?style=popout&logo=github)](https://github.com/users/NGPixel/sponsorship) + [![Become a Patron](https://img.shields.io/badge/donate-patreon-orange.svg?style=popout&logo=patreon)](https://www.patreon.com/requarks) + [![Donate on OpenCollective](https://img.shields.io/badge/donate-open%20collective-blue.svg?style=popout&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNTZweCIgaGVpZ2h0PSIyNTZweCIgdmlld0JveD0iMCAwIDI1NiAyNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxnPjxwYXRoIGQ9Ik0yMDkuNzY1MTQ0LDEyOC4xNDk5NzkgQzIwOS43NjUxNDQsMTQ0LjE2MzMgMjA0Ljg2NDM4MSwxNTkuNDg5ODkgMTk2LjQ5ODc0NywxNzIuNzI1MDcyIEwyMjkuOTQ1Njc1LDIwNi4xNzE5OTkgQzI0Ni42ODIxMDUsMTgzLjg1Njc1OSAyNTUuNzI5MzA3LDE1Ni43MTUxNTIgMjU1LjcyOTMwNywxMjguODIxMTAyIEMyNTUuNzI5MzA3LDk5LjU1Njk5MTcgMjQ1Ljk3NDYwMyw3My4wNzEwMjA3IDIyOS4yNTg5NDQsNTEuNDg1ODEyOCBMMTk2LjQ4MzE0LDg0LjIxNDc5NCBDMjA1LjEyMjU2MSw5Ny4yMjI0NjgzIDIwOS43MzY5MDcsMTEyLjQ4NzgxIDIwOS43NDk1MzcsMTI4LjEwMzE1NiBMMjA5Ljc2NTE0NCwxMjguMTQ5OTc5IFoiIGZpbGw9IiNCOEQzRjQiPjwvcGF0aD48cGF0aCBkPSJNMTI3LjUxMzQ4NCwyMTAuMzU0ODE2IEM4Mi4xNDYwODcyLDIxMC4yNjg5NTggNDUuMzg3NTA5NCwxNzMuNTE3MzU4IDQ1LjI5MzAzOTMsMTI4LjE0OTk3OSBDNDUuMzYxNzUwMiw4Mi43NjQzMTM4IDgyLjEyNzg0ODcsNDUuOTg0MjU3IDEyNy41MTM0ODQsNDUuODk4MzE4NiBDMTQ0LjI0NDc1Miw0NS44OTgzMTg2IDE1OS41NzEzNDIsNTAuNzk5MDgxNyAxNzIuMTE5NzkyLDU5LjE2NDcxNTQgTDIwNC44NjQzODEsMjYuMzg4OTExNiBDMTgyLjU0MzY1LDkuNjY2NjUxMjkgMTU1LjQwMzQyOSwwLjYzMDg2MzI5OCAxMjcuNTEzNDg0LDAuNjM2NDk0NDAzIEM1Ny4xMjM1NDM3LDAuNjM2NDk0NDAzIDAsNTcuNzYwMDM4MSAwLDEyOC4xNDk5NzkgQzAsMTk4LjUwODcwNCA1Ny4xMjM1NDM3LDI1NS42NjM0NjMgMTI3LjUxMzQ4NCwyNTUuNjYzNDYzIEMxNTUuNTM3MzUyLDI1NS43NDA4NzYgMTgyLjc3NTk4OSwyNDYuNDA4NTEgMjA0Ljg2NDM4MSwyMjkuMTYxODg0IEwxNzEuNDE3NDU0LDE5NS43MzA1NjQgQzE1OS41NTU3MzQsMjA1LjQ4NTI2OCAxNDQuMjYwMzU5LDIxMC4zNTQ4MTYgMTI3LjUxMzQ4NCwyMTAuMzU0ODE2IEwxMjcuNTEzNDg0LDIxMC4zNTQ4MTYgWiIgZmlsbD0iIzdGQURGMiI+PC9wYXRoPjwvZz48L3N2Zz4=)](https://opencollective.com/wikijs) + [![Donate via Paypal](https://img.shields.io/badge/donate-paypal-blue.svg?style=popout&logo=paypal)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FLV5X255Z9CJU&source=url) + [![Donate via Ethereum](https://img.shields.io/badge/donate-ethereum-999.svg?style=popout&logo=ethereum&logoColor=CCC)](https://etherscan.io/address/0xe1d55c19ae86f6bcbfb17e7f06ace96bdbb22cb5) + [![Donate via Bitcoin](https://img.shields.io/badge/donate-bitcoin-ff9900.svg?style=popout&logo=bitcoin&logoColor=CCC)](https://checkout.opennode.com/p/2553c612-f863-4407-82b3-1a7685268747) + [![Buy a T-Shirt](https://img.shields.io/badge/buy-t--shirts-teal.svg?style=popout&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4Igp3aWR0aD0iMjQiIGhlaWdodD0iMjQiCnZpZXdCb3g9IjAgMCAxOTIgMTkyIgpzdHlsZT0iIGZpbGw6IzAwMDAwMDsiPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIGZvbnQtZmFtaWx5PSJub25lIiBmb250LXdlaWdodD0ibm9uZSIgZm9udC1zaXplPSJub25lIiB0ZXh0LWFuY2hvcj0ibm9uZSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0wLDE5MnYtMTkyaDE5MnYxOTJ6IiBmaWxsPSJub25lIj48L3BhdGg+PGcgZmlsbD0iIzFhYmM5YyI+PGcgaWQ9InN1cmZhY2UxIj48cGF0aCBkPSJNOTYsMGMtMTUuMjE4NzUsMCAtMjQuNjg3NSwzLjY1NjI1IC0yNS41LDRsLTIyLjUsNy4yNWMtMTAuNDA2MjUsMy4xODc1IC0xOS4wOTM3NSw5LjQzNzUgLTI1LjUsMTguMjVsLTIyLjUsNDIuNWwyNy4yNSwxNi43NWwxMi43NSwtMjR2MTE5LjI1YzAsNC40MDYyNSAyNS4wNjI1LDggNTYsOGMzMC45Mzc1LDAgNTYsLTMuNTkzNzUgNTYsLTh2LTExOS4yNWwxMi43NSwyNGwyNy4yNSwtMTYuNzVsLTIyLjUsLTQyLjVjLTYuNDA2MjUsLTguODEyNSAtMTUuMTU2MjUsLTE1LjA2MjUgLTI0Ljc1LC0xOC4yNWwtMjIuMjUsLTcuMjVjLTAuMTg3NSwwIC0xLjAzMTI1LDEuMzEyNSAtMiwyLjc1bDEuMjUsLTIuNWMwLDAgLTkuODQzNzUsLTQuMjUgLTI1Ljc1LC00LjI1ek05Niw4YzExLjQwNjI1LDAgMTguNDM3NSwyLjI1IDIxLDMuMjVjLTQuNDY4NzUsNS43NSAtMTEuNDA2MjUsMTIuNzUgLTIxLDEyLjc1Yy05LjQwNjI1LDAgLTE2LjQwNjI1LC03LjA2MjUgLTIwLjc1LC0xMi43NWMyLjg3NSwtMS4wNjI1IDkuODc1LC0zLjI1IDIwLjc1LC0zLjI1eiI+PC9wYXRoPjwvZz48L2c+PC9nPjwvc3ZnPg==)](https://wikijs.threadless.com) + +
+ +## Introduction + +This chart bootstraps a Wiki.js deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +It also optionally packages the [PostgreSQL](https://github.com/kubernetes/charts/tree/master/stable/postgresql) as the database but you are free to bring your own. + +## Prerequisites + +- PV provisioner support in the underlying infrastructure (with persistence storage enabled) if you want data persistance + +## Installing the Chart + +To install the chart with the release name `my-release` run the following from this (`helm`) directory: + +```console +$ helm install --name my-release . +``` + +The command deploys Wiki.js on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +> **Warning**: Persistant Volume Claims for the database are not deleted automatically. They need to be manually deleted + +```console +$ kubectl delete pvc/data-wiki-postgresql-0 +``` + +## Configuration + +The following table lists the configurable parameters of the Wiki.js chart and their default values. + +| Parameter | Description | Default | +| ------------------------------- | ------------------------------- | ---------------------------------------------------------- | +| `image.repository` | Wiki.js image | `requarks/wiki` | +| `image.tag` | Wiki.js image tag | `latest` | +| `imagePullPolicy` | Image pull policy | `IfNotPresent` | +| `replicacount` | Amount of wiki.js service pods to run | `1` | +| `resources.limits` | wiki.js service resource limits | `{cpu: 500m, memory: 500Mi}` | +| `resources.requests` | wiki.js service resource requests | `{cpu: 300m, memory: 300Mi}` | +| `nodeSelector` | Node labels for wiki.js pod assignment | `{}` | +| `affinity` | Affinity settings for wiki.js pod assignment | `{}` | +| `schedulerName` | Name of an alternate scheduler for wiki.js pod | `nil` | +| `tolerations` | Toleration labels for wiki.jsk pod assignment | `[]` | +| `ingress.enabled` | Enable ingress controller resource | `false` | +| `ingress.annotations` | Ingress annotations | `{}` | +| `ingress.hostname` | URL to address your Wiki.js installation | `wiki.local` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `postgresql.enabled` | Deploy postgres server (see below) | `true` | +| `postgresql.postgresqlDatabase` | Postgres database name | `wiki` | +| `postgresql.postgresqlUser` | Postgres username | `postgres` | +| `postgresql.postgresqlHost` | External postgres host | `nil` | +| `postgresql.postgresqlPassword` | External postgres password | `nil` | +| `postgresql.postgresqlPort` | External postgres port | `5432` | +| `postgresql.persistence.enabled` | Enable postgres persistence using PVC | `true` | +| `postgresql.persistence.existingClaim` | Provide an existing `PersistentVolumeClaim` for postgres | `nil` | +| `postgresql.persistence.storageClass` | Postgres PVC Storage Class (example: `nfs`) | `nil` | +| `postgresql.persistence.size` | Postgers PVC Storage Request | `10Gi` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install --name my-release \ + --set postgresql.persistence.enabled=false \ + . +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install --name my-release -f values.yaml . +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## PostgresSQL + +By default, PostgreSQL is installed as part of the chart. To use an external PostgreSQL server set `postgresql.enabled` to `false` and then set `postgresql.postgresqlHost` and `postgresql.postgresqlPassword`. The other options (`postgresql.postgresqlDatabase`, `postgresql.postgresqlUser` and `postgresql.postgresqlPort`) may also want changing from their default values. + +## Persistence + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Configuration](#configuration) section to configure the PVC or to disable persistence. + +## Ingress + +This chart provides support for Ingress resource. If you have an available Ingress Controller such as Nginx or Traefik you maybe want to set `ingress.enabled` to true and choose an `ingress.hostname` for the URL. Then, you should be able to access the installation using that address. diff --git a/dev/helm/charts/postgresql-6.5.0.tgz b/dev/helm/charts/postgresql-6.5.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..acc79962ce8f45da1a26062d7d64520e3e065af8 GIT binary patch literal 23426 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 LD}N+mWTgK9>s^5l literal 0 HcmV?d00001 diff --git a/dev/helm/requirements.yaml b/dev/helm/requirements.yaml deleted file mode 100644 index 16900131..00000000 --- a/dev/helm/requirements.yaml +++ /dev/null @@ -1,5 +0,0 @@ -dependencies: - - name: postgresql - version: 3.18.4 - repository: https://kubernetes-charts.storage.googleapis.com/ - condition: postgresql.enabled diff --git a/dev/helm/templates/NOTES.txt b/dev/helm/templates/NOTES.txt new file mode 100644 index 00000000..5199428e --- /dev/null +++ b/dev/helm/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "wiki.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.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 {{ include "wiki.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "wiki.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "wiki.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/dev/helm/templates/_helpers.tpl b/dev/helm/templates/_helpers.tpl new file mode 100644 index 00000000..40af2a9e --- /dev/null +++ b/dev/helm/templates/_helpers.tpl @@ -0,0 +1,108 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "wiki.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 "wiki.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 "wiki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "wiki.labels" -}} +helm.sh/chart: {{ include "wiki.chart" . }} +{{ include "wiki.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "wiki.selectorLabels" -}} +app.kubernetes.io/name: {{ include "wiki.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "wiki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "wiki.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- 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). +*/}} +{{- define "wiki.postgresql.fullname" -}} +{{- if .Values.postgresql.fullnameOverride -}} +{{- .Values.postgresql.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{ printf "%s-%s" .Chart.Name "postgresql"}} +{{- end -}} +{{- end -}} + +{{/* +Set postgres host +*/}} +{{- define "wiki.postgresql.host" -}} +{{- if .Values.postgresql.enabled -}} +{{- template "wiki.postgresql.fullname" . -}} +{{- else -}} +{{- .Values.postgresql.postgresqlHost | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Set postgres secret +*/}} +{{- define "wiki.postgresql.secret" -}} +{{- if .Values.postgresql.enabled -}} +{{- template "wiki.postgresql.fullname" . -}} +{{- else -}} +{{- template "wiki.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Set postgres secretKey +*/}} +{{- define "wiki.postgresql.secretKey" -}} +{{- if .Values.postgresql.enabled -}} +"postgresql-password" +{{- else -}} +{{- default "postgresql-password" .Values.postgresql.existingSecretKey | quote -}} +{{- end -}} +{{- end -}} diff --git a/dev/helm/templates/deployment.yaml b/dev/helm/templates/deployment.yaml new file mode 100644 index 00000000..7611db99 --- /dev/null +++ b/dev/helm/templates/deployment.yaml @@ -0,0 +1,75 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "wiki.fullname" . }} + labels: + {{- include "wiki.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "wiki.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "wiki.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "wiki.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: DB_TYPE + value: postgres + - name: DB_HOST + value: {{ template "wiki.postgresql.host" . }} + - name: DB_PORT + value: "{{ default "5432" .Values.postgresql.postgresqlPort }}" + - name: DB_NAME + value: {{ default "wiki" .Values.postgresql.postgresqlDatabase }} + - name: DB_USER + value: {{ default "wiki" .Values.postgresql.postgresqlUser }} + - name: DB_PASS + valueFrom: + secretKeyRef: + {{- if .Values.postgresql.existingSecret }} + name: {{ .Values.postgresql.existingSecret }} + {{- else }} + name: {{ template "wiki.postgresql.secret" . }} + {{- end }} + key: {{ template "wiki.postgresql.secretKey" . }} + ports: + - name: http + containerPort: 3000 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: http + readinessProbe: + httpGet: + path: /healthz + port: http + 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 }} diff --git a/dev/helm/templates/ingress.yaml b/dev/helm/templates/ingress.yaml index 01d60ffb..0b08134d 100644 --- a/dev/helm/templates/ingress.yaml +++ b/dev/helm/templates/ingress.yaml @@ -1,39 +1,41 @@ -{{- if .Values.ingress.enabled }} -{{- range .Values.ingress.hosts }} +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "wiki.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} apiVersion: extensions/v1beta1 +{{- end }} kind: Ingress metadata: - name: {{ template "wiki.fullname" $ }} + name: {{ $fullName }} labels: - app: {{ template "wiki.name" $ }} - chart: {{ template "wiki.chart" $ }} - release: {{ $.Release.Name | quote }} - heritage: {{ $.Release.Service | quote }} + {{- include "wiki.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} annotations: - {{- if .tls }} - ingress.kubernetes.io/secure-backends: "true" - {{- end }} - {{- if .certManager }} - kubernetes.io/tls-acme: "true" - {{- end }} - {{- range $key, $value := .annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: - rules: - - host: {{ .name }} - http: - paths: - - path: {{ default "/" .path }} - backend: - serviceName: {{ template "wiki.fullname" $ }} - servicePort: 80 -{{- if .tls }} +{{- if .Values.ingress.tls }} tls: - - hosts: - - {{ .name }} - secretName: {{ .tlsSecret }} -{{- end }} ---- + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} {{- end }} diff --git a/dev/helm/templates/secrets.yaml b/dev/helm/templates/secrets.yaml deleted file mode 100644 index 66241deb..00000000 --- a/dev/helm/templates/secrets.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "wiki.fullname" . }} - labels: - app: {{ template "wiki.fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - db-user: {{ .Values.postgresql.postgresUser | b64enc | quote }} - db-password: {{ .Values.postgresql.postgresPassword | b64enc | quote }} diff --git a/dev/helm/templates/service.yaml b/dev/helm/templates/service.yaml index 1bf029bb..567282e7 100644 --- a/dev/helm/templates/service.yaml +++ b/dev/helm/templates/service.yaml @@ -1,32 +1,15 @@ apiVersion: v1 kind: Service metadata: - name: {{ template "wiki.fullname" . }} + name: {{ include "wiki.fullname" . }} labels: - app: {{ template "wiki.name" . }} - chart: {{ template "wiki.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} + {{- include "wiki.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} - {{- if .Values.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }} - externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} - {{- end }} ports: - - name: http - port: {{ .Values.service.port }} - targetPort: http - {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePorts.http)))}} - nodePort: {{ .Values.service.nodePorts.http }} - {{- end }} - - name: https - port: {{ .Values.service.httpsPort }} - targetPort: https - {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePorts.https)))}} - nodePort: {{ .Values.service.nodePorts.https }} - {{- end }} + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http selector: - app: {{ template "wiki.name" . }} + {{- include "wiki.selectorLabels" . | nindent 4 }} diff --git a/dev/helm/templates/serviceaccount.yaml b/dev/helm/templates/serviceaccount.yaml new file mode 100644 index 00000000..7f6c8917 --- /dev/null +++ b/dev/helm/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "wiki.serviceAccountName" . }} + labels: + {{- include "wiki.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/dev/helm/templates/tests/test-connection.yaml b/dev/helm/templates/tests/test-connection.yaml new file mode 100644 index 00000000..2d0887d4 --- /dev/null +++ b/dev/helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "wiki.fullname" . }}-test-connection" + labels: + {{- include "wiki.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "wiki.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/dev/helm/values.yaml b/dev/helm/values.yaml index 2a5ec42c..e4149df7 100644 --- a/dev/helm/values.yaml +++ b/dev/helm/values.yaml @@ -1,41 +1,104 @@ -## +# Default values for wiki. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: requarks/wiki + pullPolicy: IfNotPresent + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: wiki.local + paths: ["/"] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + ## Configuration values for the postgresql dependency. ## ref: https://github.com/kubernetes/charts/blob/master/stable/postgresql/README.md +## postgresql: - ## ## Use the PostgreSQL chart dependency. - ## Set to false if bringing your own PostgreSQL. - enabled: true - ## - ## If you are bringing your own PostgreSQL, you should set postgresHost and - ## also probably service.port, postgresUser, postgresPassword, and postgresDatabase - ## postgresHost: + ## Set to false if bringing your own PostgreSQL, and set secret value postgresql-uri. ## - ## PostgreSQL port - service: - port: 5432 - ## PostgreSQL User to create. - postgresUser: wiki - ## - ## PostgreSQL Password for the new user. - ## If not set, a random 10 characters password will be used. - postgresPassword: wikijsrocks + enabled: true + ### PostgreSQL User to create. ## + postgresqlUser: postgres ## PostgreSQL Database to create. - postgresDatabase: wiki ## + postgresqlDatabase: wiki ## Persistent Volume Storage configuration. ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes + ## persistence: - ## ## Enable PostgreSQL persistence using Persistent Volume Claims. + ## enabled: true + ## concourse data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) ## - ## Persistant class - # storageClass: classname + # storageClass: "-" + ## Persistent Volume Access Mode. ## - ## Access mode: accessMode: ReadWriteOnce + ## Persistent Volume Storage Size. ## - ## Requested size: - size: 10Gi + size: 8Gi