From 846a6a02c4e3aaa7eb213be8cdc00db126722abe Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Tue, 4 Apr 2023 09:52:19 +0300 Subject: [PATCH] NAS-121156 / 23.10 / Add vaultwarden to community train (#1055) * Add vaultwarden to community train * add variable only when set * Update library/ix-dev/community/vaultwarden/values.yaml * Update library/ix-dev/community/vaultwarden/values.yaml * add NET_BIND_SERVICE * minor typo * use the new common * Update common * add upgrade_info.json * remove the capability, and bump to fixed version --- .../ix-dev/community/vaultwarden/Chart.lock | 6 + .../ix-dev/community/vaultwarden/Chart.yaml | 24 ++ .../ix-dev/community/vaultwarden/README.md | 18 ++ .../community/vaultwarden/app-readme.md | 18 ++ .../vaultwarden/charts/common-1.0.1.tgz | Bin 0 -> 53833 bytes .../vaultwarden/ci/additional-env-values.yaml | 17 ++ .../vaultwarden/ci/admin-values.yaml | 13 + .../vaultwarden/ci/basic-values.yaml | 10 + .../vaultwarden/ci/https-values.yaml | 100 ++++++ .../vaultwarden/ci/other-user-values.yaml | 14 + .../vaultwarden/ci/ws-disabled-values.yaml | 13 + .../ix-dev/community/vaultwarden/item.yaml | 4 + .../community/vaultwarden/questions.yaml | 285 ++++++++++++++++++ .../community/vaultwarden/templates/NOTES.txt | 1 + .../vaultwarden/templates/_configuration.tpl | 34 +++ .../vaultwarden/templates/_portal.tpl | 24 ++ .../vaultwarden/templates/_postgres.tpl | 48 +++ .../vaultwarden/templates/_vaultwarden.tpl | 119 ++++++++ .../vaultwarden/templates/common.yaml | 11 + .../community/vaultwarden/upgrade_info.json | 1 + .../community/vaultwarden/upgrade_strategy | 26 ++ .../ix-dev/community/vaultwarden/values.yaml | 39 +++ 22 files changed, 825 insertions(+) create mode 100644 library/ix-dev/community/vaultwarden/Chart.lock create mode 100644 library/ix-dev/community/vaultwarden/Chart.yaml create mode 100644 library/ix-dev/community/vaultwarden/README.md create mode 100644 library/ix-dev/community/vaultwarden/app-readme.md create mode 100644 library/ix-dev/community/vaultwarden/charts/common-1.0.1.tgz create mode 100644 library/ix-dev/community/vaultwarden/ci/additional-env-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/ci/admin-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/ci/basic-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/ci/https-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/ci/other-user-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/ci/ws-disabled-values.yaml create mode 100644 library/ix-dev/community/vaultwarden/item.yaml create mode 100644 library/ix-dev/community/vaultwarden/questions.yaml create mode 100644 library/ix-dev/community/vaultwarden/templates/NOTES.txt create mode 100644 library/ix-dev/community/vaultwarden/templates/_configuration.tpl create mode 100644 library/ix-dev/community/vaultwarden/templates/_portal.tpl create mode 100644 library/ix-dev/community/vaultwarden/templates/_postgres.tpl create mode 100644 library/ix-dev/community/vaultwarden/templates/_vaultwarden.tpl create mode 100644 library/ix-dev/community/vaultwarden/templates/common.yaml create mode 100644 library/ix-dev/community/vaultwarden/upgrade_info.json create mode 100755 library/ix-dev/community/vaultwarden/upgrade_strategy create mode 100644 library/ix-dev/community/vaultwarden/values.yaml diff --git a/library/ix-dev/community/vaultwarden/Chart.lock b/library/ix-dev/community/vaultwarden/Chart.lock new file mode 100644 index 0000000000..e17b6357c4 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.0.1 +digest: sha256:ec8784f128039af68613a8268208bde360d5b178f811c4a16c79a1650ca8be92 +generated: "2023-04-03T17:51:26.178586108+03:00" diff --git a/library/ix-dev/community/vaultwarden/Chart.yaml b/library/ix-dev/community/vaultwarden/Chart.yaml new file mode 100644 index 0000000000..bb085b9a73 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/Chart.yaml @@ -0,0 +1,24 @@ +name: vaultwarden +description: Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients. +annotations: + title: Vaultwarden +type: application +version: 1.0.0 +apiVersion: v2 +appVersion: '1.27.0' +kubeVersion: '>=1.16.0-0' +maintainers: + - name: truenas + url: https://www.truenas.com/ +dependencies: + - name: common + repository: file://../../../common + version: 1.0.1 +home: https://github.com/dani-garcia/vaultwarden +icon: https://raw.githubusercontent.com/dani-garcia/vaultwarden/main/src/static/images/vaultwarden-icon.png +sources: + - https://github.com/dani-garcia/vaultwarden + - https://github.com/truenas/charts/tree/master/community/vaultwarden +keywords: + - password + - manager diff --git a/library/ix-dev/community/vaultwarden/README.md b/library/ix-dev/community/vaultwarden/README.md new file mode 100644 index 0000000000..06e50608f5 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/README.md @@ -0,0 +1,18 @@ +# Vaultwarden + +[Vaultwarden](https://github.com/dani-garcia/vaultwarden) Alternative implementation of the `Bitwarden` server API written in Rust and compatible with upstream Bitwarden clients + +> During the installation process, a container will be launched with **root** privileges. This is required +> in order to apply the correct permissions to the `Vaultwarden` data directory. Afterward, the `Vaultwarden` container +> will run as a **non**-root user (default `568`). +> Same applies to the `postgres` container. This will run afterwards as a **non**-root user (`999`). +> On each upgrade, a container will be launched with **root** privileges in order to apply the correct +> permissions to the `postgres` **backups** directory. Container that performs the backup will run as a **non**-root user (`999`) afterwards. +> Keep in mind the permissions on the backup directory will be changed to `999:999` on **every** update. +> But will only be changed once for the `Vaultwarden` and `postgres` data directories. + +While the option to use `Rocket` for TLS is there, it is not +[recommended](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-HTTPS#via-rocket). +Instead, use a reverse proxy to handle TLS termination. + +Using `HTTPS` is **required** for the most of the features to work (correctly). diff --git a/library/ix-dev/community/vaultwarden/app-readme.md b/library/ix-dev/community/vaultwarden/app-readme.md new file mode 100644 index 0000000000..06e50608f5 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/app-readme.md @@ -0,0 +1,18 @@ +# Vaultwarden + +[Vaultwarden](https://github.com/dani-garcia/vaultwarden) Alternative implementation of the `Bitwarden` server API written in Rust and compatible with upstream Bitwarden clients + +> During the installation process, a container will be launched with **root** privileges. This is required +> in order to apply the correct permissions to the `Vaultwarden` data directory. Afterward, the `Vaultwarden` container +> will run as a **non**-root user (default `568`). +> Same applies to the `postgres` container. This will run afterwards as a **non**-root user (`999`). +> On each upgrade, a container will be launched with **root** privileges in order to apply the correct +> permissions to the `postgres` **backups** directory. Container that performs the backup will run as a **non**-root user (`999`) afterwards. +> Keep in mind the permissions on the backup directory will be changed to `999:999` on **every** update. +> But will only be changed once for the `Vaultwarden` and `postgres` data directories. + +While the option to use `Rocket` for TLS is there, it is not +[recommended](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-HTTPS#via-rocket). +Instead, use a reverse proxy to handle TLS termination. + +Using `HTTPS` is **required** for the most of the features to work (correctly). diff --git a/library/ix-dev/community/vaultwarden/charts/common-1.0.1.tgz b/library/ix-dev/community/vaultwarden/charts/common-1.0.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..aafa51055c4d34b8512f9dd930b77a00d776a495 GIT binary patch literal 53833 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≻w{&IXGP3|6Ivq*niL1 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 IC;$Kl0Ke7GT>t<8 literal 0 HcmV?d00001 diff --git a/library/ix-dev/community/vaultwarden/ci/additional-env-values.yaml b/library/ix-dev/community/vaultwarden/ci/additional-env-values.yaml new file mode 100644 index 0000000000..976eaff776 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/additional-env-values.yaml @@ -0,0 +1,17 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup + +vaultwardenConfig: + additionalEnvs: + - name: LOG_LEVEL + value: debug + - name: SIGNUPS_ALLOWED + value: false diff --git a/library/ix-dev/community/vaultwarden/ci/admin-values.yaml b/library/ix-dev/community/vaultwarden/ci/admin-values.yaml new file mode 100644 index 0000000000..c4654d5d26 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/admin-values.yaml @@ -0,0 +1,13 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup + +vaultwardenConfig: + adminToken: "super-long-secret-password" diff --git a/library/ix-dev/community/vaultwarden/ci/basic-values.yaml b/library/ix-dev/community/vaultwarden/ci/basic-values.yaml new file mode 100644 index 0000000000..845deffc82 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/basic-values.yaml @@ -0,0 +1,10 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup diff --git a/library/ix-dev/community/vaultwarden/ci/https-values.yaml b/library/ix-dev/community/vaultwarden/ci/https-values.yaml new file mode 100644 index 0000000000..588faf86a4 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/https-values.yaml @@ -0,0 +1,100 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup + +vaultwardenNetwork: + certificateID: 1 + domain: https://vault.example.com:30000 + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/library/ix-dev/community/vaultwarden/ci/other-user-values.yaml b/library/ix-dev/community/vaultwarden/ci/other-user-values.yaml new file mode 100644 index 0000000000..ed43f9bbf9 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/other-user-values.yaml @@ -0,0 +1,14 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup + +vaultwardenRunAs: + user: 1000 + group: 1000 diff --git a/library/ix-dev/community/vaultwarden/ci/ws-disabled-values.yaml b/library/ix-dev/community/vaultwarden/ci/ws-disabled-values.yaml new file mode 100644 index 0000000000..7c6d1015b2 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/ci/ws-disabled-values.yaml @@ -0,0 +1,13 @@ +vaultwardenStorage: + data: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/data + pgData: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgData + pgBackup: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/pgBackup + +vaultwardenNetwork: + wsEnabled: false diff --git a/library/ix-dev/community/vaultwarden/item.yaml b/library/ix-dev/community/vaultwarden/item.yaml new file mode 100644 index 0000000000..d7fad19236 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/item.yaml @@ -0,0 +1,4 @@ +icon: https://raw.githubusercontent.com/dani-garcia/vaultwarden/main/src/static/images/vaultwarden-icon.png +categories: + - password + - manager diff --git a/library/ix-dev/community/vaultwarden/questions.yaml b/library/ix-dev/community/vaultwarden/questions.yaml new file mode 100644 index 0000000000..2992f23a86 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/questions.yaml @@ -0,0 +1,285 @@ +groups: + - name: Vaultwarden Configuration + description: Configure Vaultwarden + - name: User and Group Configuration + description: Configure User and Group for Vaultwarden + - name: Network Configuration + description: Configure Network for Vaultwarden + - name: Storage Configuration + description: Configure Storage for Vaultwarden + - name: Resources Configuration + description: Configure Resources for Vaultwarden + +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_path" + admin_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_admin_path" + +questions: + - variable: vaultwardenConfig + label: "" + group: Vaultwarden Configuration + schema: + type: dict + attrs: + - variable: adminToken + label: Admin Token + description: Setting this, will enable the admin portal + schema: + type: string + private: true + max_length: 20 + default: "" + - variable: additionalEnvs + label: Additional Environment Variables + description: Configure additional environment variables for Vaultwarden. + schema: + type: list + default: [] + items: + - variable: env + label: Environment Variable + schema: + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + + - variable: vaultwardenRunAs + label: "" + group: User and Group Configuration + schema: + type: dict + attrs: + - variable: user + label: User ID + description: The user id that Vaultwarden will run as. + schema: + type: int + min: 1 + default: 568 + required: true + - variable: group + label: Group ID + description: The group id that Vaultwarden will run as. + schema: + type: int + min: 1 + default: 568 + required: true + + - variable: vaultwardenNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: webPort + label: Web Port + description: The port for the Vaultwarden Web UI. + schema: + type: int + default: 30000 + min: 9000 + max: 65535 + required: true + - variable: wsEnabled + label: Enable Websocket + schema: + type: boolean + default: true + - variable: wsPort + label: Websocket Port + description: The port for the Vaultwarden Websocket. + schema: + type: int + show_if: [["wsEnabled", "=", true]] + default: 30001 + min: 9000 + max: 65535 + required: true + - variable: hostNetwork + label: Host Network + description: | + Bind to the host network. It's recommended to keep this disabled.
+ schema: + type: boolean + default: false + - variable: domain + label: Domain + description: | + The domain to use for Vaultwarden
+ Format is: https://sub.domain.tld:port + schema: + type: string + default: "" + - variable: certificateID + label: Certificate + description: | + The certificate to use for Vaultwarden
+ Using the Rocket method for TLS setup is NOT recommended
+ Prefer a reverse proxy with a valid certificate
+ schema: + type: int + "null": true + $ref: + - "definitions/certificate" + + - variable: vaultwardenStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: data + label: Vaultwarden Data Storage + description: The path to store Vaultwarden attachments, icons, etc. + schema: + type: dict + attrs: + - variable: type + label: Type + schema: + type: string + required: true + default: ixVolume + enum: + - value: hostPath + description: Host Path + - value: ixVolume + description: ixVolume + - variable: datasetName + label: Dataset Name + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + hidden: true + immutable: true + default: data + $ref: + - "normalize/ixVolume" + - variable: hostPath + label: Host Path + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + immutable: true + required: true + - variable: pgData + label: Vaultwarden Postgres Data Storage + description: The path to store Vaultwarden Postgres Data. + schema: + type: dict + attrs: + - variable: type + label: Type + schema: + type: string + required: true + default: ixVolume + enum: + - value: hostPath + description: Host Path + - value: ixVolume + description: ixVolume + - variable: datasetName + label: Dataset Name + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + hidden: true + immutable: true + default: pgData + $ref: + - "normalize/ixVolume" + - variable: hostPath + label: Host Path + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + immutable: true + required: true + - variable: pgBackup + label: Vaultwarden Postgres Backup Storage + description: The path to store Vaultwarden Postgres Backup. + schema: + type: dict + attrs: + - variable: type + label: Type + schema: + type: string + required: true + default: ixVolume + enum: + - value: hostPath + description: Host Path + - value: ixVolume + description: ixVolume + - variable: datasetName + label: Dataset Name + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + hidden: true + immutable: true + default: pgBackup + $ref: + - "normalize/ixVolume" + - variable: hostPath + label: Host Path + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + immutable: true + required: true + + - variable: resources + label: "" + group: Resources Configuration + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for Vaultwarden. + schema: + type: string + default: 4000m + required: true + - variable: memory + label: Memory + description: Memory limit for Vaultwarden. + schema: + type: string + default: 8Gi + required: true diff --git a/library/ix-dev/community/vaultwarden/templates/NOTES.txt b/library/ix-dev/community/vaultwarden/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/library/ix-dev/community/vaultwarden/templates/_configuration.tpl b/library/ix-dev/community/vaultwarden/templates/_configuration.tpl new file mode 100644 index 0000000000..bd5cd15fdb --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/_configuration.tpl @@ -0,0 +1,34 @@ +{{- define "vaultwarden.configuration" -}} + + {{- if and .Values.vaultwardenNetwork.domain (not (hasPrefix "http" .Values.vaultwardenNetwork.domain)) -}} + {{- fail "Vaultwarden - Expected [Domain] to have the following format [http(s)://(sub).domain.tld(:port)]." -}} + {{- end -}} + + {{- $fullname := (include "ix.v1.common.lib.chart.names.fullname" $) -}} + + {{- $dbHost := (printf "%s-postgres" $fullname) -}} + {{- $dbUser := "vaultwarden" -}} + {{- $dbName := "vaultwarden" -}} + + {{- $dbPass := (randAlphaNum 32) -}} + {{- with (lookup "v1" "Secret" .Release.Namespace (printf "%s-postgres-creds" $fullname)) -}} + {{- $dbPass = ((index .data "POSTGRES_PASSWORD") | b64dec) -}} + {{- end -}} + + {{ $dbURL := (printf "postgres://%s:%s@%s:5432/%s?sslmode=disable" $dbUser $dbPass $dbHost $dbName) }} +secret: + postgres-creds: + enabled: true + data: + POSTGRES_USER: {{ $dbUser }} + POSTGRES_DB: {{ $dbName }} + POSTGRES_PASSWORD: {{ $dbPass }} + POSTGRES_HOST: {{ $dbHost }} + POSTGRES_URL: {{ $dbURL }} + {{ with .Values.vaultwardenConfig.adminToken }} + vaultwarden: + enabled: true + data: + ADMIN_TOKEN: {{ . | quote }} + {{ end }} +{{- end -}} diff --git a/library/ix-dev/community/vaultwarden/templates/_portal.tpl b/library/ix-dev/community/vaultwarden/templates/_portal.tpl new file mode 100644 index 0000000000..e723ae3d94 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/_portal.tpl @@ -0,0 +1,24 @@ +{{- define "vaultwarden.portal" -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: portal +data: + path: / + admin_path: /admin + port: {{ .Values.vaultwardenNetwork.webPort | quote }} + + {{ if or (hasPrefix "https://" .Values.vaultwardenNetwork.domain) .Values.vaultwardenNetwork.certificateID }} + protocol: https + {{ else }} + protocol: http + {{ end }} + + {{- $host := "$node_ip" -}} + {{ with .Values.vaultwardenNetwork.domain }} {{/* Trim protocol and trailing slash */}} + {{ $host = (. | trimPrefix "https://" | trimPrefix "http://" | trimSuffix "/") }} + {{ $host = mustRegexReplaceAll "(.*):[0-9]+" $host "${1}" }} + {{ end }} + host: {{ $host }} +{{- end -}} diff --git a/library/ix-dev/community/vaultwarden/templates/_postgres.tpl b/library/ix-dev/community/vaultwarden/templates/_postgres.tpl new file mode 100644 index 0000000000..d1fc9dba86 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/_postgres.tpl @@ -0,0 +1,48 @@ +{{- define "postgres.workload" -}} +{{/* Postgres Database */}} +workload: +{{- include "ix.v1.common.app.postgres" (dict "secretName" "postgres-creds" "resources" .Values.resources) | nindent 2 }} + +{{/* Service */}} +service: + postgres: + enabled: true + type: ClusterIP + targetSelector: postgres + ports: + postgres: + enabled: true + primary: true + port: 5432 + targetSelector: postgres +{{/* Persistence */}} +persistence: + postgresdata: + enabled: true + type: {{ .Values.vaultwardenStorage.pgData.type }} + datasetName: {{ .Values.vaultwardenStorage.pgData.datasetName | default "" }} + hostPath: {{ .Values.vaultwardenStorage.pgData.hostPath | default "" }} + targetSelector: + # Postgres pod + postgres: + # Postgres container + postgres: + mountPath: /var/lib/postgresql/data + # Permissions container, for postgres, container is named "permissions" + permissions: + mountPath: /mnt/directories/postgres_data + postgresbackup: + enabled: true + type: {{ .Values.vaultwardenStorage.pgBackup.type }} + datasetName: {{ .Values.vaultwardenStorage.pgBackup.datasetName | default "" }} + hostPath: {{ .Values.vaultwardenStorage.pgBackup.hostPath | default "" }} + targetSelector: + # Postgres backup pod + postgresbackup: + # Postgres backup container + postgresbackup: + mountPath: /postgres_backup + # Permissions container, for postgres, container is named "permissions" + permissions: + mountPath: /mnt/directories/postgres_backup +{{- end -}} diff --git a/library/ix-dev/community/vaultwarden/templates/_vaultwarden.tpl b/library/ix-dev/community/vaultwarden/templates/_vaultwarden.tpl new file mode 100644 index 0000000000..97f4c7a365 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/_vaultwarden.tpl @@ -0,0 +1,119 @@ +{{- define "vaultwarden.workload" -}} +workload: + vaultwarden: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ .Values.vaultwardenNetwork.hostNetwork }} + containers: + vaultwarden: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: {{ .Values.vaultwardenRunAs.user }} + runAsGroup: {{ .Values.vaultwardenRunAs.group }} + env: + ROCKET_PORT: {{ .Values.vaultwardenNetwork.webPort }} + WEBSOCKET_PORT: {{ .Values.vaultwardenNetwork.wsPort }} + WEBSOCKET_ENABLED: {{ .Values.vaultwardenNetwork.wsEnabled }} + DATABASE_URL: + secretKeyRef: + name: postgres-creds + key: POSTGRES_URL + {{ if .Values.vaultwardenConfig.adminToken }} + ADMIN_TOKEN: + secretKeyRef: + name: vaultwarden + key: ADMIN_TOKEN + {{ end }} + {{ if .Values.vaultwardenNetwork.certificateID }} + ROCKET_TLS: '{certs="/certs/public.crt",key="/certs/private.key"}' + {{ end }} + {{ with .Values.vaultwardenNetwork.domain }} + DOMAIN: {{ . }} + {{ end }} + {{ with .Values.vaultwardenConfig.additionalEnvs }} + {{ range $env := . }} + {{ $env.name }}: {{ $env.value }} + {{ end }} + {{ end }} + probes: + liveness: + enabled: true + type: exec + command: /healthcheck.sh + readiness: + enabled: true + type: exec + command: /healthcheck.sh + startup: + enabled: true + type: exec + command: /healthcheck.sh + initContainers: + {{- include "ix.v1.common.app.permissions" (dict "containerName" "01-permissions" + "UID" .Values.vaultwardenRunAs.user + "GID" .Values.vaultwardenRunAs.group + "type" "install") | nindent 8 }} + {{- include "ix.v1.common.app.postgresWait" (dict "name" "postgres-wait" + "secretName" "postgres-creds") | nindent 8 }} + +{{/* Service */}} +service: + vaultwarden: + enabled: true + primary: true + type: NodePort + targetSelector: vaultwarden + ports: + webui: + enabled: true + primary: true + port: {{ .Values.vaultwardenNetwork.webPort }} + nodePort: {{ .Values.vaultwardenNetwork.webPort }} + targetSelector: vaultwarden + ws: + enabled: {{ .Values.vaultwardenNetwork.wsEnabled }} + port: {{ .Values.vaultwardenNetwork.wsPort }} + nodePort: {{ .Values.vaultwardenNetwork.wsPort }} + targetSelector: vaultwarden + +{{/* Persistence */}} +persistence: + data: + enabled: true + type: {{ .Values.vaultwardenStorage.data.type }} + datasetName: {{ .Values.vaultwardenStorage.data.datasetName | default "" }} + hostPath: {{ .Values.vaultwardenStorage.data.hostPath | default "" }} + targetSelector: + vaultwarden: + vaultwarden: + mountPath: /data + 01-permissions: + mountPath: /mnt/directories/data + + {{- if .Values.vaultwardenNetwork.certificateID }} + cert: + enabled: true + type: secret + objectName: vaultwarden-cert + defaultMode: "0600" + items: + - key: tls.key + path: private.key + - key: tls.crt + path: public.crt + targetSelector: + vaultwarden: + vaultwarden: + mountPath: /certs + readOnly: true + +scaleCertificate: + vaultwarden-cert: + enabled: true + id: {{ .Values.vaultwardenNetwork.certificateID }} + {{- end -}} +{{- end -}} diff --git a/library/ix-dev/community/vaultwarden/templates/common.yaml b/library/ix-dev/community/vaultwarden/templates/common.yaml new file mode 100644 index 0000000000..a892f75b24 --- /dev/null +++ b/library/ix-dev/community/vaultwarden/templates/common.yaml @@ -0,0 +1,11 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "vaultwarden.configuration" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "vaultwarden.workload" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "postgres.workload" $ | fromYaml) -}} + +{{/* Create the configmap for portal manually*/}} +{{- include "vaultwarden.portal" $ -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/library/ix-dev/community/vaultwarden/upgrade_info.json b/library/ix-dev/community/vaultwarden/upgrade_info.json new file mode 100644 index 0000000000..767388094a --- /dev/null +++ b/library/ix-dev/community/vaultwarden/upgrade_info.json @@ -0,0 +1 @@ +{"filename": "values.yaml", "keys": ["image"]} diff --git a/library/ix-dev/community/vaultwarden/upgrade_strategy b/library/ix-dev/community/vaultwarden/upgrade_strategy new file mode 100755 index 0000000000..13d38b0f3c --- /dev/null +++ b/library/ix-dev/community/vaultwarden/upgrade_strategy @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +import json +import sys + +from catalog_update.upgrade_strategy import semantic_versioning + + +def newer_mapping(image_tags): + key = list(image_tags.keys())[0] + version = semantic_versioning(image_tags[key]) + if not version: + return {} + + return { + 'tags': {key: f'v{version}'}, + 'app_version': f'v{version}', + } + + +if __name__ == '__main__': + try: + versions_json = json.loads(sys.stdin.read()) + except ValueError: + raise ValueError('Invalid json specified') + + print(json.dumps(newer_mapping(versions_json))) diff --git a/library/ix-dev/community/vaultwarden/values.yaml b/library/ix-dev/community/vaultwarden/values.yaml new file mode 100644 index 0000000000..d188a7a6fd --- /dev/null +++ b/library/ix-dev/community/vaultwarden/values.yaml @@ -0,0 +1,39 @@ +image: + repository: vaultwarden/server + pullPolicy: IfNotPresent + tag: "1.28.1" + +resources: + limits: + cpu: 4000m + memory: 8Gi + +vaultwardenConfig: + adminToken: "" + additionalEnvs: [] + +vaultwardenNetwork: + webPort: 30000 + wsEnabled: true + wsPort: 30001 + hostNetwork: false + certificateID: "" + domain: "" + +vaultwardenRunAs: + user: 568 + group: 568 + +vaultwardenStorage: + data: + type: ixVolume + hostPath: "" + datasetName: data + pgData: + type: ixVolume + hostPath: "" + datasetName: pgData + pgBackup: + type: ixVolume + hostPath: "" + datasetName: pgBackup