Browse Source

Merge branch 'develop' of github.com:Budibase/budibase into multistep-forms

master
Andrew Kingston 5 years ago
parent
commit
f127d86d11
  1. 12
      .github/workflows/release.yml
  2. 4
      .gitignore
  3. 4
      .husky/pre-commit
  4. BIN
      docs/budibase-0.1.0.tgz
  5. BIN
      docs/budibase-0.1.1.tgz
  6. 9
      docs/index.html
  7. 54
      docs/index.yaml
  8. 23
      hosting/kubernetes/budibase/.helmignore
  9. 40
      hosting/kubernetes/budibase/Chart.yaml
  10. 39
      hosting/kubernetes/budibase/README.md
  11. 19
      hosting/kubernetes/budibase/charts/couchdb/Chart.yaml
  12. 244
      hosting/kubernetes/budibase/charts/couchdb/README.md
  13. 3
      hosting/kubernetes/budibase/charts/couchdb/ci/required-values.yaml
  14. 9
      hosting/kubernetes/budibase/charts/couchdb/ci/sidecar.yaml
  15. 2
      hosting/kubernetes/budibase/charts/couchdb/password.ini
  16. 20
      hosting/kubernetes/budibase/charts/couchdb/templates/NOTES.txt
  17. 81
      hosting/kubernetes/budibase/charts/couchdb/templates/_helpers.tpl
  18. 23
      hosting/kubernetes/budibase/charts/couchdb/templates/configmap.yaml
  19. 17
      hosting/kubernetes/budibase/charts/couchdb/templates/headless.yaml
  20. 33
      hosting/kubernetes/budibase/charts/couchdb/templates/ingress.yaml
  21. 31
      hosting/kubernetes/budibase/charts/couchdb/templates/networkpolicy.yaml
  22. 19
      hosting/kubernetes/budibase/charts/couchdb/templates/secrets.yaml
  23. 23
      hosting/kubernetes/budibase/charts/couchdb/templates/service.yaml
  24. 15
      hosting/kubernetes/budibase/charts/couchdb/templates/serviceaccount.yaml
  25. 202
      hosting/kubernetes/budibase/charts/couchdb/templates/statefulset.yaml
  26. 201
      hosting/kubernetes/budibase/charts/couchdb/values.yaml
  27. BIN
      hosting/kubernetes/budibase/charts/ingress-nginx-3.35.0.tgz
  28. 22
      hosting/kubernetes/budibase/templates/NOTES.txt
  29. 83
      hosting/kubernetes/budibase/templates/_helpers.tpl
  30. 101
      hosting/kubernetes/budibase/templates/app-service-deployment.yaml
  31. 19
      hosting/kubernetes/budibase/templates/app-service-service.yaml
  32. 28
      hosting/kubernetes/budibase/templates/hpa.yaml
  33. 61
      hosting/kubernetes/budibase/templates/ingress.yaml
  34. 16
      hosting/kubernetes/budibase/templates/minio-data-persistentvolumeclaim.yaml
  35. 70
      hosting/kubernetes/budibase/templates/minio-service-deployment.yaml
  36. 21
      hosting/kubernetes/budibase/templates/minio-service-service.yaml
  37. 38
      hosting/kubernetes/budibase/templates/proxy-service-deployment.yaml
  38. 20
      hosting/kubernetes/budibase/templates/proxy-service-service.yaml
  39. 16
      hosting/kubernetes/budibase/templates/redis-data-persistentvolumeclaim.yaml
  40. 49
      hosting/kubernetes/budibase/templates/redis-service-deployment.yaml
  41. 21
      hosting/kubernetes/budibase/templates/redis-service-service.yaml
  42. 17
      hosting/kubernetes/budibase/templates/secrets.yaml
  43. 15
      hosting/kubernetes/budibase/templates/service.yaml
  44. 12
      hosting/kubernetes/budibase/templates/serviceaccount.yaml
  45. 15
      hosting/kubernetes/budibase/templates/tests/test-connection.yaml
  46. 94
      hosting/kubernetes/budibase/templates/worker-service-deployment.yaml
  47. 19
      hosting/kubernetes/budibase/templates/worker-service-service.yaml
  48. 140
      hosting/kubernetes/budibase/values.yaml
  49. 4
      hosting/kubernetes/envoy/Dockerfile
  50. 125
      hosting/kubernetes/envoy/envoy.yaml
  51. 2
      lerna.json
  52. 5
      package.json
  53. 2
      packages/auth/package.json
  54. 8
      packages/auth/src/db/utils.js
  55. 2
      packages/auth/src/environment.js
  56. 2
      packages/bbui/package.json
  57. 7
      packages/bbui/src/ActionMenu/ActionMenu.svelte
  58. 8
      packages/builder/package.json
  59. 59
      packages/builder/src/components/backend/DatasourceNavigator/modals/UpdateDatasourceModal.svelte
  60. 4
      packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte
  61. 5
      packages/builder/src/components/start/UpdateAppModal.svelte
  62. 20
      packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte
  63. 6
      packages/builder/src/pages/builder/portal/settings/organisation.svelte
  64. 11
      packages/builder/src/stores/backend/datasources.js
  65. 2
      packages/cli/package.json
  66. 8
      packages/client/package.json
  67. 10
      packages/server/package.json
  68. 22
      packages/server/src/api/controllers/datasource.js
  69. 5
      packages/server/src/api/routes/datasource.js
  70. 10
      packages/server/src/db/client.js
  71. 2
      packages/server/src/environment.js
  72. 2
      packages/server/src/utilities/index.js
  73. 4
      packages/standard-components/package.json
  74. 2
      packages/string-templates/package.json
  75. 6
      packages/worker/package.json
  76. 10
      packages/worker/src/db/index.js
  77. 3
      scripts/release_helm_chart.sh
  78. 5
      yarn.lock

12
.github/workflows/release.yml

@ -50,3 +50,15 @@ jobs:
env:
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
- uses: azure/setup-helm@v1
id: install
- run: yarn release:helm
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.1.0
with:
charts_dir: docs
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

4
.gitignore

@ -55,7 +55,7 @@ typings/
.node_repl_history
# Output of 'npm pack'
*.tgz
# *.tgz
# Yarn Integrity file
.yarn-integrity
@ -91,4 +91,4 @@ hosting/.generated-envoy.dev.yaml
# Sublime text
*.sublime-project
*.sublime-workspace
*.sublime-workspace

4
.husky/pre-commit

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn run lint

BIN
docs/budibase-0.1.0.tgz

Binary file not shown.

BIN
docs/budibase-0.1.1.tgz

Binary file not shown.

9
docs/index.html

@ -0,0 +1,9 @@
<html>
<head>
<title>Budibase Helm Chart Repo</title>
</head>
<body>
<h1>Budibase Charts Repo</h1>
<p>Point Helm at this repo to see charts.</p>
</body>
</html>

54
docs/index.yaml

@ -0,0 +1,54 @@
apiVersion: v1
entries:
budibase:
- apiVersion: v2
appVersion: 0.9.56
created: "2021-08-18T18:41:52.640176+01:00"
dependencies:
- condition: services.couchdb.enabled
name: couchdb
repository: https://apache.github.io/couchdb-helm
version: 3.3.4
- name: ingress-nginx
repository: https://github.com/kubernetes/ingress-nginx
version: 3.35.0
description: Budibase is an open source low-code platform, helping thousands of teams build apps for their workplace in minutes.
digest: 8dc4f2ed4d98cad5adf25936aefea680042d3e4e17832f846b961fd8708ad192
keywords:
- low-code
- database
- cluster
name: budibase
sources:
- https://github.com/Budibase/budibase
- https://budibase.com
type: application
urls:
- https://budibase.github.io/budibase/budibase-0.1.1.tgz
version: 0.1.1
- apiVersion: v2
appVersion: 0.9.56
created: "2021-08-18T18:41:52.635603+01:00"
dependencies:
- condition: services.couchdb.enabled
name: couchdb
repository: https://apache.github.io/couchdb-helm
version: 3.3.4
- name: ingress-nginx
repository: https://github.com/kubernetes/ingress-nginx
version: 3.35.0
description: Budibase is an open source low-code platform, helping thousands of teams build apps for their workplace in minutes.
digest: 08031b0803cce0eff64472e569d454d9176119c8207aa9873a9c95ee66cc7d3f
keywords:
- low-code
- database
- cluster
name: budibase
sources:
- https://github.com/Budibase/budibase
- https://budibase.com
type: application
urls:
- https://budibase.github.io/budibase/budibase-0.1.0.tgz
version: 0.1.0
generated: "2021-08-18T18:41:52.629415+01:00"

23
hosting/kubernetes/budibase/.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/

40
hosting/kubernetes/budibase/Chart.yaml

@ -0,0 +1,40 @@
apiVersion: v2
name: budibase
description: Budibase is an open source low-code platform, helping thousands of teams build apps for their workplace in minutes.
keywords:
- low-code
- database
- cluster
sources:
- https://github.com/Budibase/budibase
- https://budibase.com
# 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
# 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.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. 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: "0.9.56"
dependencies:
- name: couchdb
version: 3.3.4
repository: https://apache.github.io/couchdb-helm
condition: services.couchdb.enabled
- name: ingress-nginx
version: 3.35.0
repository: https://github.com/kubernetes/ingress-nginx

39
hosting/kubernetes/budibase/README.md

@ -0,0 +1,39 @@
# Budibase
[Budibase](https://budibase.com/) Budibase is an open source low-code platform, helping thousands of teams build apps for their workplace in minutes.
## TL;DR;
```console
$ cd chart
$ helm install budibase .
```
## Introduction
This chart bootstraps a [Budibase](https://budibase.com/) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- helm v3 or above
- Kubernetes 1.4+
- PV provisioner support in the underlying infrastructure (with persistence storage enabled)
## Installing the Chart
To install the chart with the release name `budi-release`:
```console
$ helm install budi-release .
```
The command deploys Budibase 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
```

19
hosting/kubernetes/budibase/charts/couchdb/Chart.yaml

@ -0,0 +1,19 @@
apiVersion: v1
appVersion: 3.1.0
description: A database featuring seamless multi-master sync, that scales from big
data to mobile, with an intuitive HTTP/JSON API and designed for reliability.
home: https://couchdb.apache.org/
icon: http://couchdb.apache.org/CouchDB-visual-identity/logo/CouchDB-couch-symbol.svg
keywords:
- couchdb
- database
- nosql
maintainers:
- email: kocolosk@apache.org
name: kocolosk
- email: willholley@apache.org
name: willholley
name: couchdb
sources:
- https://github.com/apache/couchdb-docker
version: 3.3.4

244
hosting/kubernetes/budibase/charts/couchdb/README.md

@ -0,0 +1,244 @@
# CouchDB
Apache CouchDB is a database featuring seamless multi-master sync, that scales
from big data to mobile, with an intuitive HTTP/JSON API and designed for
reliability.
This chart deploys a CouchDB cluster as a StatefulSet. It creates a ClusterIP
Service in front of the Deployment for load balancing by default, but can also
be configured to deploy other Service types or an Ingress Controller. The
default persistence mechanism is simply the ephemeral local filesystem, but
production deployments should set `persistentVolume.enabled` to `true` to attach
storage volumes to each Pod in the Deployment.
## TL;DR
```bash
$ helm repo add couchdb https://apache.github.io/couchdb-helm
$ helm install couchdb/couchdb \
--set allowAdminParty=true \
--set couchdbConfig.couchdb.uuid=$(curl https://www.uuidgenerator.net/api/version4 2>/dev/null | tr -d -)
```
## Prerequisites
- Kubernetes 1.9+ with Beta APIs enabled
- Ingress requires Kubernetes 1.14+
## Installing the Chart
To install the chart with the release name `my-release`:
Add the CouchDB Helm repository:
```bash
$ helm repo add couchdb https://apache.github.io/couchdb-helm
```
Afterwards install the chart replacing the UUID
`decafbaddecafbaddecafbaddecafbad` with a custom one:
```bash
$ helm install \
--name my-release \
--set couchdbConfig.couchdb.uuid=decafbaddecafbaddecafbaddecafbad \
couchdb/couchdb
```
This will create a Secret containing the admin credentials for the cluster.
Those credentials can be retrieved as follows:
```bash
$ kubectl get secret my-release-couchdb -o go-template='{{ .data.adminPassword }}' | base64 --decode
```
If you prefer to configure the admin credentials directly you can create a
Secret containing `adminUsername`, `adminPassword` and `cookieAuthSecret` keys:
```bash
$ kubectl create secret generic my-release-couchdb --from-literal=adminUsername=foo --from-literal=adminPassword=bar --from-literal=cookieAuthSecret=baz
```
If you want to set the `adminHash` directly to achieve consistent salts between
different nodes you need to addionally add the key `password.ini` to the secret:
```bash
$ kubectl create secret generic my-release-couchdb \
--from-literal=adminUsername=foo \
--from-literal=cookieAuthSecret=baz \
--from-file=./my-password.ini
```
With the following contents in `my-password.ini`:
```
[admins]
foo = <pbkdf2-hash>
```
and then install the chart while overriding the `createAdminSecret` setting:
```bash
$ helm install \
--name my-release \
--set createAdminSecret=false \
--set couchdbConfig.couchdb.uuid=decafbaddecafbaddecafbaddecafbad \
couchdb/couchdb
```
This Helm chart deploys CouchDB on the Kubernetes cluster in a 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:
```bash
$ helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and
deletes the release.
## Upgrading an existing Release to a new major version
A major chart version change (like v0.2.3 -> v1.0.0) indicates that there is an
incompatible breaking change needing manual actions.
### Upgrade to 3.0.0
Since version 3.0.0 setting the CouchDB server instance UUID is mandatory.
Therefore you need to generate a UUID and supply it as a value during the
upgrade as follows:
```bash
$ helm upgrade <release-name> \
--reuse-values \
--set couchdbConfig.couchdb.uuid=<UUID> \
couchdb/couchdb
```
## Migrating from stable/couchdb
This chart replaces the `stable/couchdb` chart previously hosted by Helm and continues the
version semantics. You can upgrade directly from `stable/couchdb` to this chart using:
```bash
$ helm repo add couchdb https://apache.github.io/couchdb-helm
$ helm upgrade my-release couchdb/couchdb
```
## Configuration
The following table lists the most commonly configured parameters of the
CouchDB chart and their default values:
| Parameter | Description | Default |
|---------------------------------|-------------------------------------------------------|----------------------------------------|
| `clusterSize` | The initial number of nodes in the CouchDB cluster | 3 |
| `couchdbConfig` | Map allowing override elements of server .ini config | *See below* |
| `allowAdminParty` | If enabled, start cluster without admin account | false (requires creating a Secret) |
| `createAdminSecret` | If enabled, create an admin account and cookie secret | true |
| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` |
| `erlangFlags` | Map of flags supplied to the underlying Erlang VM | name: couchdb, setcookie: monster
| `persistentVolume.enabled` | Boolean determining whether to attach a PV to each node | false
| `persistentVolume.size` | If enabled, the size of the persistent volume to attach | 10Gi
| `enableSearch` | Adds a sidecar for Lucene-powered text search | false |
You can set the values of the `couchdbConfig` map according to the
[official configuration][4]. The following shows the map's default values and
required options to set:
| Parameter | Description | Default |
|---------------------------------|--------------------------------------------------------------------|----------------------------------------|
| `couchdb.uuid` | UUID for this CouchDB server instance ([Required in a cluster][5]) | |
| `chttpd.bind_address` | listens on all interfaces when set to any | any |
| `chttpd.require_valid_user` | disables all the anonymous requests to the port 5984 when true | false |
A variety of other parameters are also configurable. See the comments in the
`values.yaml` file for further details:
| Parameter | Default |
|--------------------------------------|----------------------------------------|
| `adminUsername` | admin |
| `adminPassword` | auto-generated |
| `adminHash` | |
| `cookieAuthSecret` | auto-generated |
| `image.repository` | couchdb |
| `image.tag` | 3.1.0 |
| `image.pullPolicy` | IfNotPresent |
| `searchImage.repository` | kocolosk/couchdb-search |
| `searchImage.tag` | 0.1.0 |
| `searchImage.pullPolicy` | IfNotPresent |
| `initImage.repository` | busybox |
| `initImage.tag` | latest |
| `initImage.pullPolicy` | Always |
| `ingress.enabled` | false |
| `ingress.hosts` | chart-example.local |
| `ingress.annotations` | |
| `ingress.path` | / |
| `ingress.tls` | |
| `persistentVolume.accessModes` | ReadWriteOnce |
| `persistentVolume.storageClass` | Default for the Kube cluster |
| `podManagementPolicy` | Parallel |
| `affinity` | |
| `annotations` | |
| `tolerations` | |
| `resources` | |
| `service.annotations` | |
| `service.enabled` | true |
| `service.type` | ClusterIP |
| `service.externalPort` | 5984 |
| `dns.clusterDomainSuffix` | cluster.local |
| `networkPolicy.enabled` | true |
| `serviceAccount.enabled` | true |
| `serviceAccount.create` | true |
| `serviceAccount.imagePullSecrets` | |
| `sidecars` | {} |
| `livenessProbe.enabled` | true |
| `livenessProbe.failureThreshold` | 3 |
| `livenessProbe.initialDelaySeconds` | 0 |
| `livenessProbe.periodSeconds` | 10 |
| `livenessProbe.successThreshold` | 1 |
| `livenessProbe.timeoutSeconds` | 1 |
| `readinessProbe.enabled` | true |
| `readinessProbe.failureThreshold` | 3 |
| `readinessProbe.initialDelaySeconds` | 0 |
| `readinessProbe.periodSeconds` | 10 |
| `readinessProbe.successThreshold` | 1 |
| `readinessProbe.timeoutSeconds` | 1 |
## Feedback, Issues, Contributing
General feedback is welcome at our [user][1] or [developer][2] mailing lists.
Apache CouchDB has a [CONTRIBUTING][3] file with details on how to get started
with issue reporting or contributing to the upkeep of this project. In short,
use GitHub Issues, do not report anything on Docker's website.
## Non-Apache CouchDB Development Team Contributors
- [@natarajaya](https://github.com/natarajaya)
- [@satchpx](https://github.com/satchpx)
- [@spanato](https://github.com/spanato)
- [@jpds](https://github.com/jpds)
- [@sebastien-prudhomme](https://github.com/sebastien-prudhomme)
- [@stepanstipl](https://github.com/sebastien-stepanstipl)
- [@amatas](https://github.com/amatas)
- [@Chimney42](https://github.com/Chimney42)
- [@mattjmcnaughton](https://github.com/mattjmcnaughton)
- [@mainephd](https://github.com/mainephd)
- [@AdamDang](https://github.com/AdamDang)
- [@mrtyler](https://github.com/mrtyler)
- [@kevinwlau](https://github.com/kevinwlau)
- [@jeyenzo](https://github.com/jeyenzo)
- [@Pinpin31.](https://github.com/Pinpin31)
[1]: http://mail-archives.apache.org/mod_mbox/couchdb-user/
[2]: http://mail-archives.apache.org/mod_mbox/couchdb-dev/
[3]: https://github.com/apache/couchdb/blob/master/CONTRIBUTING.md
[4]: https://docs.couchdb.org/en/stable/config/index.html
[5]: https://docs.couchdb.org/en/latest/setup/cluster.html#preparing-couchdb-nodes-to-be-joined-into-a-cluster

3
hosting/kubernetes/budibase/charts/couchdb/ci/required-values.yaml

@ -0,0 +1,3 @@
couchdbConfig:
couchdb:
uuid: "decafbaddecafbaddecafbaddecafbad"

9
hosting/kubernetes/budibase/charts/couchdb/ci/sidecar.yaml

@ -0,0 +1,9 @@
sidecars:
- name: foo
image: "busybox"
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "0.1"
memory: 10Mi
command: ['while true; do echo "foo"; sleep 5; done;']

2
hosting/kubernetes/budibase/charts/couchdb/password.ini

@ -0,0 +1,2 @@
[admins]
{{ .Values.adminUsername }} = {{ .Values.adminHash }}

20
hosting/kubernetes/budibase/charts/couchdb/templates/NOTES.txt

@ -0,0 +1,20 @@
Apache CouchDB is starting. Check the status of the Pods using:
kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "couchdb.name" . }},release={{ .Release.Name }}"
Once all of the Pods are fully Ready, execute the following command to create
some required system databases:
kubectl exec --namespace {{ .Release.Namespace }} {{ if not .Values.allowAdminParty }}-it {{ end }}{{ template "couchdb.fullname" . }}-0 -c couchdb -- \
curl -s \
http://127.0.0.1:5984/_cluster_setup \
-X POST \
-H "Content-Type: application/json" \
{{- if .Values.allowAdminParty }}
-d '{"action": "finish_cluster"}'
{{- else }}
-d '{"action": "finish_cluster"}' \
-u <adminUsername>
{{- end }}
Then it's time to relax.

81
hosting/kubernetes/budibase/charts/couchdb/templates/_helpers.tpl

@ -0,0 +1,81 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "couchdb.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).
*/}}
{{- define "couchdb.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- printf "%s-%s" .Values.fullnameOverride .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{/*
In the event that we create both a headless service and a traditional one,
ensure that the latter gets a unique name.
*/}}
{{- define "couchdb.svcname" -}}
{{- if .Values.fullnameOverride -}}
{{- printf "%s-svc-%s" .Values.fullnameOverride .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-svc-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{/*
Create a random string if the supplied key does not exist
*/}}
{{- define "couchdb.defaultsecret" -}}
{{- if . -}}
{{- . | b64enc | quote -}}
{{- else -}}
{{- randAlphaNum 20 | b64enc | quote -}}
{{- end -}}
{{- end -}}
{{/*
Labels used to define Pods in the CouchDB statefulset
*/}}
{{- define "couchdb.ss.selector" -}}
app: {{ template "couchdb.name" . }}
release: {{ .Release.Name }}
{{- end -}}
{{/*
Generates a comma delimited list of nodes in the cluster
*/}}
{{- define "couchdb.seedlist" -}}
{{- $nodeCount := min 5 .Values.clusterSize | int }}
{{- range $index0 := until $nodeCount -}}
{{- $index1 := $index0 | add1 -}}
{{ $.Values.erlangFlags.name }}@{{ template "couchdb.fullname" $ }}-{{ $index0 }}.{{ template "couchdb.fullname" $ }}.{{ $.Release.Namespace }}.svc.{{ $.Values.dns.clusterDomainSuffix }}{{ if ne $index1 $nodeCount }},{{ end }}
{{- end -}}
{{- end -}}
{{/*
If serviceAccount.name is specified, use that, else use the couchdb instance name
*/}}
{{- define "couchdb.serviceAccount" -}}
{{- if .Values.serviceAccount.name -}}
{{- .Values.serviceAccount.name }}
{{- else -}}
{{- template "couchdb.fullname" . -}}
{{- end -}}
{{- end -}}
{{/*
Fail if couchdbConfig.couchdb.uuid is undefined
*/}}
{{- define "couchdb.uuid" -}}
{{- required "A value for couchdbConfig.couchdb.uuid must be set" (.Values.couchdbConfig.couchdb | default dict).uuid -}}
{{- end -}}

23
hosting/kubernetes/budibase/charts/couchdb/templates/configmap.yaml

@ -0,0 +1,23 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
heritage: {{ .Release.Service | quote }}
release: {{ .Release.Name | quote }}
data:
inifile: |
{{ $couchdbConfig := dict "couchdb" (dict "uuid" (include "couchdb.uuid" .)) -}}
{{- $couchdbConfig := merge $couchdbConfig .Values.couchdbConfig -}}
{{- range $section, $settings := $couchdbConfig -}}
{{ printf "[%s]" $section }}
{{ range $key, $value := $settings -}}
{{ printf "%s = %s" $key ($value | toString) }}
{{ end }}
{{ end }}
seedlistinifile: |
[cluster]
seedlist = {{ template "couchdb.seedlist" . }}

17
hosting/kubernetes/budibase/charts/couchdb/templates/headless.yaml

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
clusterIP: None
publishNotReadyAddresses: true
ports:
- name: couchdb
port: 5984
selector:
{{ include "couchdb.ss.selector" . | indent 4 }}

33
hosting/kubernetes/budibase/charts/couchdb/templates/ingress.yaml

@ -0,0 +1,33 @@
{{- if .Values.ingress.enabled -}}
{{- $serviceName := include "couchdb.fullname" . -}}
{{- $servicePort := .Values.service.externalPort -}}
{{- $path := .Values.ingress.path | quote -}}
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
rules:
{{- range $host := .Values.ingress.hosts }}
- host: {{ $host }}
http:
paths:
- path: {{ $path }}
backend:
serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }}
{{- end -}}
{{- if .Values.ingress.tls }}
tls:
{{ toYaml .Values.ingress.tls | indent 4 }}
{{- end -}}
{{- end -}}

31
hosting/kubernetes/budibase/charts/couchdb/templates/networkpolicy.yaml

@ -0,0 +1,31 @@
{{- if .Values.networkPolicy.enabled }}
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
podSelector:
matchLabels:
{{ include "couchdb.ss.selector" . | indent 6 }}
ingress:
- ports:
- protocol: TCP
port: 5984
- ports:
- protocol: TCP
port: 9100
- protocol: TCP
port: 4369
from:
- podSelector:
matchLabels:
{{ include "couchdb.ss.selector" . | indent 14 }}
policyTypes:
- Ingress
{{- end }}

19
hosting/kubernetes/budibase/charts/couchdb/templates/secrets.yaml

@ -0,0 +1,19 @@
{{- if .Values.createAdminSecret -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
type: Opaque
data:
adminUsername: {{ template "couchdb.defaultsecret" .Values.adminUsername }}
adminPassword: {{ template "couchdb.defaultsecret" .Values.adminPassword }}
cookieAuthSecret: {{ template "couchdb.defaultsecret" .Values.cookieAuthSecret }}
{{- if .Values.adminHash }}
password.ini: {{ tpl (.Files.Get "password.ini") . | b64enc }}
{{- end -}}
{{- end -}}

23
hosting/kubernetes/budibase/charts/couchdb/templates/service.yaml

@ -0,0 +1,23 @@
{{- if .Values.service.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "couchdb.svcname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
{{- end }}
spec:
ports:
- port: {{ .Values.service.externalPort }}
protocol: TCP
targetPort: 5984
type: {{ .Values.service.type }}
selector:
{{ include "couchdb.ss.selector" . | indent 4 }}
{{- end -}}

15
hosting/kubernetes/budibase/charts/couchdb/templates/serviceaccount.yaml

@ -0,0 +1,15 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "couchdb.serviceAccount" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- if .Values.serviceAccount.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.serviceAccount.imagePullSecrets }}
{{- end }}
{{- end }}

202
hosting/kubernetes/budibase/charts/couchdb/templates/statefulset.yaml

@ -0,0 +1,202 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "couchdb.fullname" . }}
labels:
app: {{ template "couchdb.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.clusterSize }}
serviceName: {{ template "couchdb.fullname" . }}
podManagementPolicy: {{ .Values.podManagementPolicy }}
selector:
matchLabels:
{{ include "couchdb.ss.selector" . | indent 6 }}
template:
metadata:
labels:
{{ include "couchdb.ss.selector" . | indent 8 }}
{{- with .Values.annotations }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{ toYaml . | indent 8 }}
{{- end }}
spec:
{{- if .Values.schedulerName }}
schedulerName: "{{ .Values.schedulerName }}"
{{- end }}
{{- if .Values.serviceAccount.enabled }}
serviceAccountName: {{ template "couchdb.serviceAccount" . }}
{{- end }}
initContainers:
- name: init-copy
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: {{ .Values.initImage.pullPolicy }}
command: ['sh','-c','cp /tmp/chart.ini /default.d; cp /tmp/seedlist.ini /default.d; ls -lrt /default.d;']
volumeMounts:
- name: config
mountPath: /tmp/
- name: config-storage
mountPath: /default.d
{{- if .Values.adminHash }}
- name: admin-hash-copy
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: {{ .Values.initImage.pullPolicy }}
command: ['sh','-c','cp /tmp/password.ini /local.d/ ;']
volumeMounts:
- name: admin-password
mountPath: /tmp/password.ini
subPath: "password.ini"
- name: local-config-storage
mountPath: /local.d
{{- end }}
containers:
- name: couchdb
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: couchdb
containerPort: 5984
- name: epmd
containerPort: 4369
- containerPort: 9100
env:
{{- if not .Values.allowAdminParty }}
- name: COUCHDB_USER
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminUsername
- name: COUCHDB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminPassword
- name: COUCHDB_SECRET
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: cookieAuthSecret
{{- end }}
- name: ERL_FLAGS
value: "{{ range $k, $v := .Values.erlangFlags }} -{{ $k }} {{ $v }} {{ end }}"
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
{{- if .Values.couchdbConfig.chttpd.require_valid_user }}
exec:
command:
- sh
- -c
- curl -G --silent --fail -u ${COUCHDB_USER}:${COUCHDB_PASSWORD} http://localhost:5984/_up
{{- else }}
httpGet:
path: /_up
port: 5984
{{- end }}
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
{{- if .Values.couchdbConfig.chttpd.require_valid_user }}
exec:
command:
- sh
- -c
- curl -G --silent --fail -u ${COUCHDB_USER}:${COUCHDB_PASSWORD} http://localhost:5984/_up
{{- else }}
httpGet:
path: /_up
port: 5984
{{- end }}
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
{{- end }}
resources:
{{ toYaml .Values.resources | indent 12 }}
volumeMounts:
- name: config-storage
mountPath: /opt/couchdb/etc/default.d
{{- if .Values.adminHash }}
- name: local-config-storage
mountPath: /opt/couchdb/etc/local.d
{{- end }}
- name: database-storage
mountPath: /opt/couchdb/data
{{- if .Values.enableSearch }}
- name: clouseau
image: "{{ .Values.searchImage.repository }}:{{ .Values.searchImage.tag }}"
imagePullPolicy: {{ .Values.searchImage.pullPolicy }}
volumeMounts:
- name: database-storage
mountPath: /opt/couchdb-search/data
{{- end }}
{{- if .Values.sidecars }}
{{ toYaml .Values.sidecars | indent 8}}
{{- end }}
{{- if .Values.nodeSelector }}
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
volumes:
- name: config-storage
emptyDir: {}
- name: config
configMap:
name: {{ template "couchdb.fullname" . }}
items:
- key: inifile
path: chart.ini
- key: seedlistinifile
path: seedlist.ini
{{- if .Values.adminHash }}
- name: local-config-storage
emptyDir: {}
- name: admin-password
secret:
secretName: {{ template "couchdb.fullname" . }}
{{- end -}}
{{- if not .Values.persistentVolume.enabled }}
- name: database-storage
emptyDir: {}
{{- else }}
volumeClaimTemplates:
- metadata:
name: database-storage
labels:
app: {{ template "couchdb.name" . }}
release: {{ .Release.Name }}
spec:
accessModes:
{{- range .Values.persistentVolume.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistentVolume.size | quote }}
{{- if .Values.persistentVolume.storageClass }}
{{- if (eq "-" .Values.persistentVolume.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistentVolume.storageClass }}"
{{- end }}
{{- end }}
{{- end }}

201
hosting/kubernetes/budibase/charts/couchdb/values.yaml

@ -0,0 +1,201 @@
## clusterSize is the initial size of the CouchDB cluster.
clusterSize: 3
## If allowAdminParty is enabled the cluster will start up without any database
## administrator account; i.e., all users will be granted administrative
## access. Otherwise, the system will look for a Secret called
## <ReleaseName>-couchdb containing `adminUsername`, `adminPassword` and
## `cookieAuthSecret` keys. See the `createAdminSecret` flag.
## ref: https://kubernetes.io/docs/concepts/configuration/secret/
allowAdminParty: false
## If createAdminSecret is enabled a Secret called <ReleaseName>-couchdb will
## be created containing auto-generated credentials. Users who prefer to set
## these values themselves have a couple of options:
##
## 1) The `adminUsername`, `adminPassword`, `adminHash`, and `cookieAuthSecret`
## can be defined directly in the chart's values. Note that all of a chart's
## values are currently stored in plaintext in a ConfigMap in the tiller
## namespace.
##
## 2) This flag can be disabled and a Secret with the required keys can be
## created ahead of time.
createAdminSecret: true
# adminUsername: budibase
# adminPassword: budibase
# adminHash: -pbkdf2-this_is_not_necessarily_secure_either
# cookieAuthSecret: admin
## When enabled, will deploy a networkpolicy that allows CouchDB pods to
## communicate with each other for clustering and ingress on port 5984
networkPolicy:
enabled: true
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
# Use a service account
serviceAccount:
enabled: true
create: true
# name:
# imagePullSecrets:
# - name: myimagepullsecret
## The storage volume used by each Pod in the StatefulSet. If a
## persistentVolume is not enabled, the Pods will use `emptyDir` ephemeral
## local storage. Setting the storageClass attribute to "-" disables dynamic
## provisioning of Persistent Volumes; leaving it unset will invoke the default
## provisioner.
persistentVolume:
enabled: false
accessModes:
- ReadWriteOnce
size: 10Gi
storageClass: ""
## The CouchDB image
image:
repository: couchdb
tag: 3.1.0
pullPolicy: IfNotPresent
## Experimental integration with Lucene-powered fulltext search
searchImage:
repository: kocolosk/couchdb-search
tag: 0.2.0
pullPolicy: IfNotPresent
## Flip this to flag to include the Search container in each Pod
enableSearch: true
initImage:
repository: busybox
tag: latest
pullPolicy: Always
## CouchDB is happy to spin up cluster nodes in parallel, but if you encounter
## problems you can try setting podManagementPolicy to the StatefulSet default
## `OrderedReady`
podManagementPolicy: Parallel
## To better tolerate Node failures, we can prevent Kubernetes scheduler from
## assigning more than one Pod of CouchDB StatefulSet per Node using podAntiAffinity.
affinity: {}
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchExpressions:
# - key: "app"
# operator: In
# values:
# - couchdb
# topologyKey: "kubernetes.io/hostname"
## Optional pod annotations
annotations: {}
## Optional tolerations
tolerations: []
## A StatefulSet requires a headless Service to establish the stable network
## identities of the Pods, and that Service is created automatically by this
## chart without any additional configuration. The Service block below refers
## to a second Service that governs how clients connect to the CouchDB cluster.
service:
# annotations:
enabled: true
type: ClusterIP
externalPort: 5984
## An Ingress resource can provide name-based virtual hosting and TLS
## termination among other things for CouchDB deployments which are accessed
## from outside the Kubernetes cluster.
## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/
ingress:
enabled: false
hosts:
- chart-example.local
path: /
annotations: []
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
tls:
# Secrets must be manually created in the namespace.
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
## Optional resource requests and limits for the CouchDB container
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
resources:
{}
# requests:
# cpu: 100m
# memory: 128Mi
# limits:
# cpu: 56
# memory: 256Gi
## erlangFlags is a map that is passed to the Erlang VM as flags using the
## ERL_FLAGS env. `name` and `setcookie` flags are minimally required to
## establish connectivity between cluster nodes.
## ref: http://erlang.org/doc/man/erl.html#init_flags
erlangFlags:
name: couchdb
setcookie: monster
## couchdbConfig will override default CouchDB configuration settings.
## The contents of this map are reformatted into a .ini file laid down
## by a ConfigMap object.
## ref: http://docs.couchdb.org/en/latest/config/index.html
couchdbConfig:
couchdb:
uuid: budibase-couchdb # REQUIRED: Unique identifier for this CouchDB server instance
# cluster:
# q: 8 # Create 8 shards for each database
chttpd:
bind_address: any
# chttpd.require_valid_user disables all the anonymous requests to the port
# 5984 when is set to true.
require_valid_user: false
# Kubernetes local cluster domain.
# This is used to generate FQDNs for peers when joining the CouchDB cluster.
dns:
clusterDomainSuffix: cluster.local
## Configure liveness and readiness probe values
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes
livenessProbe:
enabled: true
failureThreshold: 3
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
enabled: true
failureThreshold: 3
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
# Configure arbitrary sidecar containers for CouchDB pods created by the
# StatefulSet
sidecars: {}
# - name: foo
# image: "busybox"
# imagePullPolicy: IfNotPresent
# resources:
# requests:
# cpu: "0.1"
# memory: 10Mi
# command: ['echo "foo";']
# volumeMounts:
# - name: database-storage
# mountPath: /opt/couchdb/data/

BIN
hosting/kubernetes/budibase/charts/ingress-nginx-3.35.0.tgz

Binary file not shown.

22
hosting/kubernetes/budibase/templates/NOTES.txt

@ -0,0 +1,22 @@
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 }}{{ .path }}
{{- 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 "budibase.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 "budibase.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "budibase.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 "budibase.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

83
hosting/kubernetes/budibase/templates/_helpers.tpl

@ -0,0 +1,83 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "budibase.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).
*/}}
{{- define "budibase.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- printf "%s-%s" .Values.fullnameOverride .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{/*
CouchDB secret identifier
*/}}
{{- define "couchdb.fullname" -}}
{{- $name := "couchdb" -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Internal DNS
*/}}
{{- define "budibase.serviceDns" -}}
{{- printf "%s.%s.%s" .Release.Namespace "svc" .Values.services.dns -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "budibase.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "budibase.labels" -}}
helm.sh/chart: {{ include "budibase.chart" . }}
{{ include "budibase.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "budibase.selectorLabels" -}}
app.kubernetes.io/name: {{ include "budibase.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "budibase.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "budibase.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create a random string if the supplied key does not exist
*/}}
{{- define "budibase.defaultsecret" -}}
{{- if . -}}
{{- . | b64enc | quote -}}
{{- else -}}
{{- randAlphaNum 20 | b64enc | quote -}}
{{- end -}}
{{- end -}}

101
hosting/kubernetes/budibase/templates/app-service-deployment.yaml

@ -0,0 +1,101 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: app-service
name: app-service
spec:
replicas: {{ .Values.services.apps.replicaCount }}
selector:
matchLabels:
io.kompose.service: app-service
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: app-service
spec:
containers:
- env:
- name: BUDIBASE_ENVIRONMENT
value: {{ .Values.globals.budibaseEnv }}
- name: COUCH_DB_URL
{{ if .Values.services.couchdb.url }}
value: {{ .Values.services.couchdb.url }}
{{ else }}
value: http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}
{{ end }}
- name: COUCH_DB_USER
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminUsername
- name: COUCH_DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminPassword
- name: ENABLE_ANALYTICS
value: {{ .Values.globals.enableAnalytics | quote }}
- name: INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: internalApiKey
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: jwtSecret
- name: LOG_LEVEL
value: {{ .Values.services.apps.logLevel | default "info" | quote }}
- name: MINIO_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreAccess
- name: MINIO_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreSecret
- name: MINIO_URL
{{ if .Values.services.objectStore.url }}
value: {{ .Values.services.objectStore.url }}
{{ else }}
value: http://minio-service:{{ .Values.services.objectStore.port }}
{{ end }}
- name: PORT
value: {{ .Values.services.apps.port | quote }}
- name: REDIS_PASSWORD
value: {{ .Values.services.redis.password }}
- name: REDIS_URL
{{ if .Values.services.redis.url }}
value: {{ .Values.services.redis.url }}
{{ else }}
value: redis-service:{{ .Values.services.redis.port }}
{{ end }}
- name: SELF_HOSTED
value: {{ .Values.globals.selfHosted | quote }}
- name: SENTRY_DSN
value: {{ .Values.globals.sentryDSN }}
- name: WORKER_URL
value: worker-service:{{ .Values.services.worker.port }}
image: budibase/apps
imagePullPolicy: Always
name: bbapps
ports:
- containerPort: {{ .Values.services.apps.port }}
resources: {}
restartPolicy: Always
serviceAccountName: ""
status: {}

19
hosting/kubernetes/budibase/templates/app-service-service.yaml

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: app-service
name: app-service
spec:
ports:
- name: {{ .Values.services.apps.port | quote }}
port: {{ .Values.services.apps.port }}
targetPort: {{ .Values.services.apps.port }}
selector:
io.kompose.service: app-service
status:
loadBalancer: {}

28
hosting/kubernetes/budibase/templates/hpa.yaml

@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "budibase.fullname" . }}
labels:
{{- include "budibase.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "budibase.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

61
hosting/kubernetes/budibase/templates/ingress.yaml

@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "budibase.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "budibase.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- 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: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- else }}
serviceName: {{ .backend.service.name }}
servicePort: {{ .backend.service.port.number }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

16
hosting/kubernetes/budibase/templates/minio-data-persistentvolumeclaim.yaml

@ -0,0 +1,16 @@
{{- if .Values.services.objectStore.minio }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: minio-data
name: minio-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.services.objectStore.storage }}
status: {}
{{- end }}

70
hosting/kubernetes/budibase/templates/minio-service-deployment.yaml

@ -0,0 +1,70 @@
{{- if .Values.services.objectStore.minio }}
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: minio-service
name: minio-service
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: minio-service
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: minio-service
spec:
containers:
- args:
- server
- /data
env:
- name: MINIO_BROWSER
value: {{ .Values.services.objectStore.browser | quote }}
- name: MINIO_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreAccess
- name: MINIO_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreSecret
image: minio/minio
imagePullPolicy: ""
livenessProbe:
exec:
command:
- curl
- -f
- http://localhost:9000/minio/health/live
failureThreshold: 3
periodSeconds: 30
timeoutSeconds: 20
name: minio-service
ports:
- containerPort: {{ .Values.services.objectStore.port }}
resources: {}
volumeMounts:
- mountPath: /data
name: minio-data
restartPolicy: Always
serviceAccountName: ""
volumes:
- name: minio-data
persistentVolumeClaim:
claimName: minio-data
status: {}
{{- end }}

21
hosting/kubernetes/budibase/templates/minio-service-service.yaml

@ -0,0 +1,21 @@
{{- if .Values.services.objectStore.minio }}
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: minio-service
name: minio-service
spec:
ports:
- name: {{ .Values.services.objectStore.port | quote }}
port: {{ .Values.services.objectStore.port }}
targetPort: {{ .Values.services.objectStore.port }}
selector:
io.kompose.service: minio-service
status:
loadBalancer: {}
{{- end }}

38
hosting/kubernetes/budibase/templates/proxy-service-deployment.yaml

@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
app.kubernetes.io/name: budibase-proxy
name: proxy-service
spec:
replicas: {{ .Values.services.proxy.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: budibase-proxy
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
app.kubernetes.io/name: budibase-proxy
spec:
containers:
- image: budibase/proxy
imagePullPolicy: ""
name: proxy-service
ports:
- containerPort: {{ .Values.services.proxy.port }}
resources: {}
volumeMounts:
restartPolicy: Always
serviceAccountName: ""
volumes:
status: {}

20
hosting/kubernetes/budibase/templates/proxy-service-service.yaml

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
app.kubernetes.io/name: budibase-proxy
name: proxy-service
spec:
type: NodePort
ports:
- port: {{ .Values.services.proxy.port }}
targetPort: {{ .Values.services.proxy.port }}
protocol: TCP
selector:
app.kubernetes.io/name: budibase-proxy
status:
loadBalancer: {}

16
hosting/kubernetes/budibase/templates/redis-data-persistentvolumeclaim.yaml

@ -0,0 +1,16 @@
{{- if .Values.services.redis.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: redis-data
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.services.redis.storage }}
status: {}
{{- end }}

49
hosting/kubernetes/budibase/templates/redis-service-deployment.yaml

@ -0,0 +1,49 @@
{{- if .Values.services.redis.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: redis-service
name: redis-service
spec:
replicas: {{ .Values.services.redis.replicaCount }}
selector:
matchLabels:
io.kompose.service: redis-service
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: redis-service
spec:
containers:
- args:
- redis-server
- --requirepass
- {{ .Values.services.redis.password }}
image: redis
imagePullPolicy: ""
name: redis-service
ports:
- containerPort: {{ .Values.services.redis.port }}
resources: {}
volumeMounts:
- mountPath: /data
name: redis-data
restartPolicy: Always
serviceAccountName: ""
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-data
status: {}
{{- end }}

21
hosting/kubernetes/budibase/templates/redis-service-service.yaml

@ -0,0 +1,21 @@
{{- if .Values.services.redis.enabled }}
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: redis-service
name: redis-service
spec:
ports:
- name: {{ .Values.services.redis.port | quote }}
port: {{ .Values.services.redis.port }}
targetPort: {{ .Values.services.redis.port }}
selector:
io.kompose.service: redis-service
status:
loadBalancer: {}
{{- end }}

17
hosting/kubernetes/budibase/templates/secrets.yaml

@ -0,0 +1,17 @@
{{- if .Values.globals.createSecrets -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "budibase.fullname" . }}
labels:
app: {{ template "budibase.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
type: Opaque
data:
internalApiKey: {{ template "budibase.defaultsecret" .Values.globals.internalApiKey }}
jwtSecret: {{ template "budibase.defaultsecret" .Values.globals.jwtSecret }}
objectStoreAccess: {{ template "budibase.defaultsecret" .Values.services.objectStore.accessKey }}
objectStoreSecret: {{ template "budibase.defaultsecret" .Values.services.objectStore.secretKey }}
{{- end -}}

15
hosting/kubernetes/budibase/templates/service.yaml

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "budibase.fullname" . }}
labels:
{{- include "budibase.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "budibase.selectorLabels" . | nindent 4 }}

12
hosting/kubernetes/budibase/templates/serviceaccount.yaml

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "budibase.serviceAccountName" . }}
labels:
{{- include "budibase.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

15
hosting/kubernetes/budibase/templates/tests/test-connection.yaml

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "budibase.fullname" . }}-test-connection"
labels:
{{- include "budibase.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "budibase.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

94
hosting/kubernetes/budibase/templates/worker-service-deployment.yaml

@ -0,0 +1,94 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: worker-service
name: worker-service
spec:
replicas: {{ .Values.services.worker.replicaCount }}
selector:
matchLabels:
io.kompose.service: worker-service
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: worker-service
spec:
containers:
- env:
- name: CLUSTER_PORT
value: {{ .Values.services.worker.port | quote }}
- name: COUCH_DB_USER
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminUsername
- name: COUCH_DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "couchdb.fullname" . }}
key: adminPassword
- name: COUCH_DB_URL
{{ if .Values.services.couchdb.url }}
value: {{ .Values.services.couchdb.url }}
{{ else }}
value: http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}
{{ end }}
- name: INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: internalApiKey
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: jwtSecret
- name: MINIO_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreAccess
- name: MINIO_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ template "budibase.fullname" . }}
key: objectStoreSecret
- name: MINIO_URL
{{ if .Values.services.objectStore.url }}
value: {{ .Values.services.objectStore.url }}
{{ else }}
value: http://minio-service:{{ .Values.services.objectStore.port }}
{{ end }}
- name: PORT
value: {{ .Values.services.worker.port | quote }}
- name: REDIS_PASSWORD
value: {{ .Values.services.redis.password | quote }}
- name: REDIS_URL
{{ if .Values.services.redis.url }}
value: {{ .Values.services.redis.url }}
{{ else }}
value: redis-service:{{ .Values.services.redis.port }}
{{ end }}
- name: SELF_HOSTED
value: {{ .Values.globals.selfHosted | quote }}
image: budibase/worker
imagePullPolicy: Always
name: bbworker
ports:
- containerPort: {{ .Values.services.worker.port }}
resources: {}
restartPolicy: Always
serviceAccountName: ""
status: {}

19
hosting/kubernetes/budibase/templates/worker-service-service.yaml

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: worker-service
name: worker-service
spec:
ports:
- name: {{ .Values.services.worker.port | quote }}
port: {{ .Values.services.worker.port }}
targetPort: {{ .Values.services.worker.port }}
selector:
io.kompose.service: worker-service
status:
loadBalancer: {}

140
hosting/kubernetes/budibase/values.yaml

@ -0,0 +1,140 @@
# Default values for budibase.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
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: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 10000
ingress:
enabled: true
certificateArn: ""
className: ""
annotations:
kubernetes.io/ingress.class: nginx
hosts:
- host: # change if using custom domain
paths:
- path: /
pathType: Prefix
backend:
service:
name: proxy-service
port:
number: 10000
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
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
globals:
budibaseEnv: PRODUCTION
enableAnalytics: false
posthogToken: ""
sentryDSN: ""
logLevel: info
selfHosted: 1
createSecrets: true # creates an internal API key, JWT secrets and redis password for you
# if createSecrets is set to false, you can hard-code your secrets here
internalApiKey: ""
jwtSecret: ""
services:
dns: cluster.local
proxy:
port: 10000
replicaCount: 1
apps:
port: 4002
replicaCount: 1
logLevel: info
worker:
port: 4001
replicaCount: 1
couchdb:
enabled: true
replicaCount: 3
url: "" # only change if pointing to existing couch server
user: "" # only change if pointing to existing couch server
password: "" # only change if pointing to existing couch server
port: 5984
storage: 100Mi
redis:
enabled: true # disable if using external redis
port: 6379
replicaCount: 1
url: "" # only change if pointing to existing redis cluster and enabled: false
password: "budibase" # recommended to override if using built-in redis
storage: 100Mi
objectStore:
minio: true
browser: true
port: 9000
replicaCount: 1
accessKey: "" # AWS_ACCESS_KEY if using S3 or existing minio access key
secretKey: "" # AWS_SECRET_ACCESS_KEY if using S3 or existing minio secret
url: "" # only change if pointing to existing minio cluster and minio: false
storage: 100Mi

4
hosting/kubernetes/envoy/Dockerfile

@ -0,0 +1,4 @@
FROM envoyproxy/envoy:v1.16-latest
COPY envoy.yaml /etc/envoy/envoy.yaml
RUN chmod go+r /etc/envoy/envoy.yaml

125
hosting/kubernetes/envoy/envoy.yaml

@ -0,0 +1,125 @@
static_resources:
listeners:
- name: main_listener
address:
socket_address: { address: 0.0.0.0, port_value: 10000 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
codec_type: auto
route_config:
name: local_route
virtual_hosts:
- name: local_services
domains: ["*"]
routes:
- match: { prefix: "/app/" }
route:
cluster: app-service
prefix_rewrite: "/"
- match: { prefix: "/builder/" }
route:
cluster: app-service
- match: { prefix: "/builder" }
route:
cluster: app-service
- match: { prefix: "/app_" }
route:
cluster: app-service
# special case for worker admin API
- match: { prefix: "/api/admin/" }
route:
cluster: worker-service
- match: { path: "/" }
route:
cluster: app-service
# special case for when API requests are made, can just forward, not to minio
- match: { prefix: "/api/" }
route:
cluster: app-service
- match: { prefix: "/worker/" }
route:
cluster: worker-service
prefix_rewrite: "/"
- match: { prefix: "/db/" }
route:
cluster: couchdb-service
prefix_rewrite: "/"
# minio is on the default route because this works
# best, minio + AWS SDK doesn't handle path proxy
- match: { prefix: "/" }
route:
cluster: minio-service
http_filters:
- name: envoy.filters.http.router
clusters:
- name: app-service
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: app-service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: app-service.budibase.svc.cluster.local
port_value: 4002
- name: minio-service
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: minio-service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: minio-service.budibase.svc.cluster.local
port_value: 9000
- name: worker-service
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: worker-service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: worker-service.budibase.svc.cluster.local
port_value: 4001
- name: couchdb-service
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: couchdb-service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: couchdb-service.budibase.svc.cluster.local
port_value: 5984

2
lerna.json

@ -1,5 +1,5 @@
{
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"npmClient": "yarn",
"packages": [
"packages/*"

5
package.json

@ -7,6 +7,7 @@
"eslint": "^7.28.0",
"eslint-plugin-cypress": "^2.11.3",
"eslint-plugin-svelte3": "^3.2.0",
"husky": "^7.0.1",
"kill-port": "^1.6.1",
"lerna": "3.14.1",
"prettier": "^2.3.1",
@ -44,7 +45,9 @@
"test:e2e:ci": "lerna run cy:ci",
"build:docker": "lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -",
"build:docker:develop": "node scripts/pinVersions && lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh develop && cd -",
"release:helm": "./scripts/release_helm_chart.sh",
"multi:enable": "lerna run multi:enable",
"multi:disable": "lerna run multi:disable"
"multi:disable": "lerna run multi:disable",
"postinstall": "husky install"
}
}

2
packages/auth/package.json

@ -1,6 +1,6 @@
{
"name": "@budibase/auth",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js",
"author": "Budibase",

8
packages/auth/src/db/utils.js

@ -159,6 +159,8 @@ exports.getDeployedAppID = appId => {
}
exports.getCouchUrl = () => {
if (!env.COUCH_DB_URL) return
// username and password already exist in URL
if (env.COUCH_DB_URL.includes("@")) {
return env.COUCH_DB_URL
@ -166,6 +168,12 @@ exports.getCouchUrl = () => {
const [protocol, ...rest] = env.COUCH_DB_URL.split("://")
if (!env.COUCH_DB_USERNAME || !env.COUCH_DB_PASSWORD) {
throw new Error(
"CouchDB configuration invalid. You must provide a fully qualified CouchDB url, or the COUCH_DB_USER and COUCH_DB_PASSWORD environment variables."
)
}
return `${protocol}://${env.COUCH_DB_USERNAME}:${env.COUCH_DB_PASSWORD}@${rest}`
}

2
packages/auth/src/environment.js

@ -9,7 +9,7 @@ function isTest() {
module.exports = {
JWT_SECRET: process.env.JWT_SECRET,
COUCH_DB_URL: process.env.COUCH_DB_URL,
COUCH_DB_USERNAME: process.env.COUCH_DB_USER || process.env.COUCH_DB_USERNAME,
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
SALT_ROUNDS: process.env.SALT_ROUNDS,
REDIS_URL: process.env.REDIS_URL,

2
packages/bbui/package.json

@ -1,7 +1,7 @@
{
"name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"license": "AGPL-3.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",

7
packages/bbui/src/ActionMenu/ActionMenu.svelte

@ -23,8 +23,11 @@
dropdown.show()
}
const openMenu = () => {
if (!disabled) show()
const openMenu = event => {
if (!disabled) {
event.stopPropagation()
show()
}
}
setContext("actionMenu", { show, hide })

8
packages/builder/package.json

@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"license": "AGPL-3.0",
"private": true,
"scripts": {
@ -65,10 +65,10 @@
}
},
"dependencies": {
"@budibase/bbui": "^0.9.105-alpha.19",
"@budibase/client": "^0.9.105-alpha.19",
"@budibase/bbui": "^0.9.105-alpha.26",
"@budibase/client": "^0.9.105-alpha.26",
"@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.105-alpha.19",
"@budibase/string-templates": "^0.9.105-alpha.26",
"@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",

59
packages/builder/src/components/backend/DatasourceNavigator/modals/UpdateDatasourceModal.svelte

@ -0,0 +1,59 @@
<script>
import { datasources } from "stores/backend"
import { notifications } from "@budibase/bbui"
import { Input, ModalContent, Modal } from "@budibase/bbui"
import analytics from "analytics"
let error = ""
let modal
let name
export let datasource
export let onCancel = undefined
export const show = () => {
name = datasource?.name
modal.show()
}
export const hide = () => {
modal.hide()
}
function checkValid(evt) {
const datasourceName = evt.target.value
if ($datasources?.list.some(ds => ds.name === datasourceName)) {
error = `Datasource with name ${datasourceName} already exists. Please choose another name.`
return
}
error = ""
}
async function updateDatasource() {
const updatedDatasource = {
...datasource,
name,
}
await datasources.save(updatedDatasource)
notifications.success(`Datasource ${name} updated successfully.`)
analytics.captureEvent("Datasource Updated", updatedDatasource)
hide()
}
</script>
<Modal bind:this={modal} on:hide={onCancel}>
<ModalContent
title="Update Datasource"
size="L"
confirmText="Update"
onConfirm={updateDatasource}
disabled={error || !name || !datasource?.type}
>
<Input
data-cy="datasource-name-input"
label="Datasource Name"
on:input={checkValid}
bind:value={name}
{error}
/>
</ModalContent>
</Modal>

4
packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte

@ -4,10 +4,12 @@
import { notifications } from "@budibase/bbui"
import { ActionMenu, MenuItem, Icon } from "@budibase/bbui"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import UpdateDatasourceModal from "components/backend/DatasourceNavigator/modals/UpdateDatasourceModal.svelte"
export let datasource
let confirmDeleteDialog
let updateDatasourceDialog
async function deleteDatasource() {
const wasSelectedSource = $datasources.selected
@ -24,6 +26,7 @@
<div slot="control" class="icon">
<Icon size="S" hoverable name="MoreSmallList" />
</div>
<MenuItem icon="Edit" on:click={updateDatasourceDialog.show}>Update</MenuItem>
<MenuItem icon="Delete" on:click={confirmDeleteDialog.show}>Delete</MenuItem>
</ActionMenu>
@ -37,6 +40,7 @@
<i>{datasource.name}?</i>
This action cannot be undone.
</ConfirmDialog>
<UpdateDatasourceModal {datasource} bind:this={updateDatasourceDialog} />
<style>
div.icon {

5
packages/builder/src/components/start/UpdateAppModal.svelte

@ -108,10 +108,7 @@
onConfirm={updateApp}
disabled={!(valid && dirty)}
>
<Body size="S">
Give your new app a name, and choose which groups have access (paid plans
only).
</Body>
<Body size="S">Update the name of your app.</Body>
<Input
bind:value={$values.name}
error={$touched.name && $errors.name}

20
packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte

@ -1,5 +1,5 @@
<script>
import { goto, beforeUrlChange } from "@roxi/routify"
import { goto } from "@roxi/routify"
import { Button, Heading, Body, Divider, Layout, Modal } from "@budibase/bbui"
import { datasources, integrations, queries, tables } from "stores/backend"
import { notifications } from "@budibase/bbui"
@ -9,7 +9,6 @@
import ICONS from "components/backend/DatasourceNavigator/icons"
import { capitalise } from "helpers"
let unsaved = false
let relationshipModal
let displayColumnModal
let selectedFromRelationship, selectedToRelationship
@ -71,7 +70,6 @@
// Create datasource
await datasources.save(datasource)
notifications.success(`Datasource ${name} updated successfully.`)
unsaved = false
} catch (err) {
notifications.error(`Error saving datasource: ${err}`)
}
@ -81,7 +79,6 @@
try {
await datasources.updateSchema(datasource)
notifications.success(`Datasource ${name} tables updated successfully.`)
unsaved = false
await tables.fetch()
} catch (err) {
notifications.error(`Error updating datasource schema: ${err}`)
@ -98,10 +95,6 @@
$goto(`../../table/${table._id}`)
}
function setUnsaved() {
unsaved = true
}
function openRelationshipModal(fromRelationship, toRelationship) {
selectedFromRelationship = fromRelationship || {}
selectedToRelationship = toRelationship || {}
@ -111,16 +104,6 @@
function openDisplayColumnModal() {
displayColumnModal.show()
}
$beforeUrlChange(() => {
if (unsaved) {
notifications.error(
"Unsaved changes. Please save your datasource configuration before leaving."
)
return false
}
return true
})
</script>
<Modal bind:this={relationshipModal}>
@ -164,7 +147,6 @@
<IntegrationConfigForm
schema={integration.datasource}
integration={datasource.config}
on:change={setUnsaved}
/>
</div>
{#if datasource.plus}

6
packages/builder/src/pages/builder/portal/settings/organisation.svelte

@ -37,7 +37,11 @@
async function uploadLogo(file) {
let data = new FormData()
data.append("file", file)
const res = await post("/api/global/configs/upload/settings/logo", data, {})
const res = await post(
"/api/admin/configs/upload/settings/logoUrl",
data,
{}
)
return await res.json()
}

11
packages/builder/src/stores/backend/datasources.js

@ -59,9 +59,16 @@ export function createDatasourcesStore() {
return json
},
save: async datasource => {
let url = "/api/datasources"
let response
if (datasource._id) {
response = await api.put(
`/api/datasources/${datasource._id}`,
datasource
)
} else {
response = await api.post("/api/datasources", datasource)
}
const response = await api.post(url, datasource)
const json = await response.json()
if (response.status !== 200) {

2
packages/cli/package.json

@ -1,6 +1,6 @@
{
"name": "@budibase/cli",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js",
"bin": {

8
packages/client/package.json

@ -1,6 +1,6 @@
{
"name": "@budibase/client",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"license": "MPL-2.0",
"module": "dist/budibase-client.js",
"main": "dist/budibase-client.js",
@ -18,9 +18,9 @@
"dev:builder": "rollup -cw"
},
"dependencies": {
"@budibase/bbui": "^0.9.105-alpha.19",
"@budibase/standard-components": "^0.9.105-alpha.19",
"@budibase/string-templates": "^0.9.105-alpha.19",
"@budibase/bbui": "^0.9.105-alpha.26",
"@budibase/standard-components": "^0.9.105-alpha.26",
"@budibase/string-templates": "^0.9.105-alpha.26",
"regexparam": "^1.3.0",
"shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5"

10
packages/server/package.json

@ -1,7 +1,7 @@
{
"name": "@budibase/server",
"email": "hi@budibase.com",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"description": "Budibase Web Server",
"main": "src/index.js",
"repository": {
@ -62,9 +62,9 @@
"author": "Budibase",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@budibase/auth": "^0.9.105-alpha.19",
"@budibase/client": "^0.9.105-alpha.19",
"@budibase/string-templates": "^0.9.105-alpha.19",
"@budibase/auth": "^0.9.105-alpha.26",
"@budibase/client": "^0.9.105-alpha.26",
"@budibase/string-templates": "^0.9.105-alpha.26",
"@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1",
@ -117,7 +117,7 @@
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4",
"@budibase/standard-components": "^0.9.105-alpha.19",
"@budibase/standard-components": "^0.9.105-alpha.26",
"@jest/test-sequencer": "^24.8.0",
"@types/bull": "^3.15.1",
"@types/jest": "^26.0.23",

22
packages/server/src/api/controllers/datasource.js

@ -57,6 +57,28 @@ exports.buildSchemaFromDb = async function (ctx) {
ctx.body = datasource
}
exports.update = async function (ctx) {
const db = new CouchDB(ctx.appId)
const datasourceId = ctx.params.datasourceId
const datasource = await db.get(datasourceId)
datasource.name = ctx.request.body.name
const response = await db.put(datasource)
datasource._rev = response.rev
// Drain connection pools when configuration is changed
if (datasource.source) {
const source = integrations[datasource.source]
if (source && source.pool) {
await source.pool.end()
}
}
ctx.status = 200
ctx.message = "Datasource saved successfully."
ctx.body = datasource
}
exports.save = async function (ctx) {
const db = new CouchDB(ctx.appId)
const plus = ctx.request.body.plus

5
packages/server/src/api/routes/datasource.js

@ -66,6 +66,11 @@ router
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
datasourceController.find
)
.put(
"/api/datasources/:datasourceId",
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
datasourceController.update
)
.post(
"/api/datasources/query",
authorized(PermissionTypes.TABLE, PermissionLevels.READ),

10
packages/server/src/db/client.js

@ -1,10 +1,11 @@
const PouchDB = require("pouchdb")
const { getCouchUrl } = require("@budibase/auth/db")
const replicationStream = require("pouchdb-replication-stream")
const allDbs = require("pouchdb-all-dbs")
const find = require("pouchdb-find")
const env = require("../environment")
const COUCH_DB_URL = env.COUCH_DB_URL || "http://localhost:10000/db/"
const COUCH_DB_URL = getCouchUrl() || "http://localhost:10000/db/"
PouchDB.plugin(replicationStream.plugin)
PouchDB.plugin(find)
@ -14,13 +15,6 @@ let POUCH_DB_DEFAULTS = {
prefix: COUCH_DB_URL,
}
if (env.COUCH_DB_USERNAME && env.COUCH_DB_PASSWORD) {
POUCH_DB_DEFAULTS.auth = {
username: env.COUCH_DB_USERNAME,
password: env.COUCH_DB_PASSWORD,
}
}
if (env.isTest()) {
PouchDB.plugin(require("pouchdb-adapter-memory"))
POUCH_DB_DEFAULTS = {

2
packages/server/src/environment.js

@ -24,8 +24,6 @@ module.exports = {
PORT: process.env.PORT,
JWT_SECRET: process.env.JWT_SECRET,
COUCH_DB_URL: process.env.COUCH_DB_URL,
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
MINIO_URL: process.env.MINIO_URL,
WORKER_URL: process.env.WORKER_URL,
SELF_HOSTED: process.env.SELF_HOSTED,

2
packages/server/src/utilities/index.js

@ -2,7 +2,7 @@ const env = require("../environment")
const { OBJ_STORE_DIRECTORY } = require("../constants")
const { sanitizeKey } = require("@budibase/auth/src/objectStore")
const BB_CDN = "https://cdn.app.budi.live/assets"
const BB_CDN = "https://cdn.budi.live"
exports.wait = ms => new Promise(resolve => setTimeout(resolve, ms))

4
packages/standard-components/package.json

@ -29,11 +29,11 @@
"keywords": [
"svelte"
],
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"license": "MIT",
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
"dependencies": {
"@budibase/bbui": "^0.9.105-alpha.19",
"@budibase/bbui": "^0.9.105-alpha.26",
"@spectrum-css/button": "^3.0.3",
"@spectrum-css/card": "^3.0.3",
"@spectrum-css/divider": "^1.0.3",

2
packages/string-templates/package.json

@ -1,6 +1,6 @@
{
"name": "@budibase/string-templates",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs",
"module": "dist/bundle.mjs",

6
packages/worker/package.json

@ -1,7 +1,7 @@
{
"name": "@budibase/worker",
"email": "hi@budibase.com",
"version": "0.9.105-alpha.19",
"version": "0.9.105-alpha.26",
"description": "Budibase background service",
"main": "src/index.js",
"repository": {
@ -23,8 +23,8 @@
"author": "Budibase",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@budibase/auth": "^0.9.105-alpha.19",
"@budibase/string-templates": "^0.9.105-alpha.19",
"@budibase/auth": "^0.9.105-alpha.26",
"@budibase/string-templates": "^0.9.105-alpha.26",
"@koa/router": "^8.0.0",
"@techpass/passport-openidconnect": "^0.3.0",
"aws-sdk": "^2.811.0",

10
packages/worker/src/db/index.js

@ -1,21 +1,15 @@
const PouchDB = require("pouchdb")
const allDbs = require("pouchdb-all-dbs")
const env = require("../environment")
const { getCouchUrl } = require("@budibase/auth/db")
// level option is purely for testing (development)
const COUCH_DB_URL = env.COUCH_DB_URL || "http://localhost:10000/db/"
const COUCH_DB_URL = getCouchUrl() || "http://localhost:10000/db/"
let POUCH_DB_DEFAULTS = {
prefix: COUCH_DB_URL,
}
if (env.COUCH_DB_USERNAME && env.COUCH_DB_PASSWORD) {
POUCH_DB_DEFAULTS.auth = {
username: env.COUCH_DB_USERNAME,
password: env.COUCH_DB_PASSWORD,
}
}
if (env.isTest()) {
PouchDB.plugin(require("pouchdb-adapter-memory"))
POUCH_DB_DEFAULTS = {

3
scripts/release_helm_chart.sh

@ -0,0 +1,3 @@
cd docs
helm package ../hosting/kubernetes/budibase
helm repo index . --url https://budibase.github.io/budibase

5
yarn.lock

@ -2448,6 +2448,11 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"
husky@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.1.tgz#579f4180b5da4520263e8713cc832942b48e1f1c"
integrity sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA==
iconv-lite@^0.4.24, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"

Loading…
Cancel
Save