From f780a02ed7627ae812e16a91981bd17f3f910a42 Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:37:44 +0300 Subject: [PATCH] Add `2FAuth` to `community` train (#1571) * initial commit * add some templates * fix config * add metadata and ci values * expose more config * add values * fix lint * add ui * add validation * whops * update description * formatting * rename app --- .../community/twofactor-auth/Chart.lock | 6 + .../community/twofactor-auth/Chart.yaml | 27 ++ .../ix-dev/community/twofactor-auth/README.md | 8 + .../community/twofactor-auth/app-readme.md | 8 + .../twofactor-auth/charts/common-1.1.1.tgz | Bin 0 -> 61735 bytes .../twofactor-auth/ci/basic-values.yaml | 7 + .../twofactor-auth/ci/extra-values.yaml | 28 ++ .../twofactor-auth/ci/hostNet-values.yaml | 8 + .../ix-dev/community/twofactor-auth/item.yaml | 8 + .../community/twofactor-auth/metadata.yaml | 8 + .../community/twofactor-auth/questions.yaml | 298 ++++++++++++++++++ .../twofactor-auth/templates/NOTES.txt | 1 + .../twofactor-auth/templates/_2fauth.tpl | 52 +++ .../templates/_configuration.tpl | 37 +++ .../twofactor-auth/templates/_persistence.tpl | 34 ++ .../twofactor-auth/templates/_portal.tpl | 35 ++ .../twofactor-auth/templates/_service.tpl | 16 + .../twofactor-auth/templates/_validation.tpl | 13 + .../twofactor-auth/templates/common.yaml | 14 + .../twofactor-auth/upgrade_info.json | 1 + .../community/twofactor-auth/upgrade_strategy | 31 ++ .../community/twofactor-auth/values.yaml | 30 ++ 22 files changed, 670 insertions(+) create mode 100644 library/ix-dev/community/twofactor-auth/Chart.lock create mode 100644 library/ix-dev/community/twofactor-auth/Chart.yaml create mode 100644 library/ix-dev/community/twofactor-auth/README.md create mode 100644 library/ix-dev/community/twofactor-auth/app-readme.md create mode 100644 library/ix-dev/community/twofactor-auth/charts/common-1.1.1.tgz create mode 100644 library/ix-dev/community/twofactor-auth/ci/basic-values.yaml create mode 100644 library/ix-dev/community/twofactor-auth/ci/extra-values.yaml create mode 100644 library/ix-dev/community/twofactor-auth/ci/hostNet-values.yaml create mode 100644 library/ix-dev/community/twofactor-auth/item.yaml create mode 100644 library/ix-dev/community/twofactor-auth/metadata.yaml create mode 100644 library/ix-dev/community/twofactor-auth/questions.yaml create mode 100644 library/ix-dev/community/twofactor-auth/templates/NOTES.txt create mode 100644 library/ix-dev/community/twofactor-auth/templates/_2fauth.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/_configuration.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/_persistence.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/_portal.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/_service.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/_validation.tpl create mode 100644 library/ix-dev/community/twofactor-auth/templates/common.yaml create mode 100644 library/ix-dev/community/twofactor-auth/upgrade_info.json create mode 100755 library/ix-dev/community/twofactor-auth/upgrade_strategy create mode 100644 library/ix-dev/community/twofactor-auth/values.yaml diff --git a/library/ix-dev/community/twofactor-auth/Chart.lock b/library/ix-dev/community/twofactor-auth/Chart.lock new file mode 100644 index 0000000000..411f496709 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.1.1 +digest: sha256:a7dbe3e4d42dbcd4325776e5e01a1d630c7f185f79e7ebf22b1b9cc80f56eed7 +generated: "2023-09-25T15:07:14.962982648+03:00" diff --git a/library/ix-dev/community/twofactor-auth/Chart.yaml b/library/ix-dev/community/twofactor-auth/Chart.yaml new file mode 100644 index 0000000000..c6b740e4bc --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/Chart.yaml @@ -0,0 +1,27 @@ +name: twofactor-auth +description: 2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. +annotations: + title: 2FAuth +type: application +version: 1.0.0 +apiVersion: v2 +appVersion: 4.2.2 +kubeVersion: '>=1.16.0-0' +maintainers: + - name: truenas + url: https://www.truenas.com/ + email: dev@ixsystems.com +dependencies: + - name: common + repository: file://../../../common + version: 1.1.1 +home: https://docs.2fauth.app/ +icon: https://docs.2fauth.app/static/2fauth_light.png +sources: + - https://github.com/Bubka/2FAuth + - https://github.com/truenas/charts/tree/master/library/ix-dev/community/2fauth + - https://hub.docker.com/r/2fauth/2fauth/ +keywords: + - security + - 2fa + - otp diff --git a/library/ix-dev/community/twofactor-auth/README.md b/library/ix-dev/community/twofactor-auth/README.md new file mode 100644 index 0000000000..84e16725b0 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/README.md @@ -0,0 +1,8 @@ +# 2FAuth + +[2FAuth](https://docs.2fauth.app/) is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. + +> When application is installed, a container will be launched with **root** privileges. +> This is required in order to apply the correct permissions to the `2FAuth` directories. +> Afterward, the `2FAuth` container will run as a **non**-root user (`1000`). +> All mounted storage(s) will be `chown`ed only if the parent directory does not match the configured user. diff --git a/library/ix-dev/community/twofactor-auth/app-readme.md b/library/ix-dev/community/twofactor-auth/app-readme.md new file mode 100644 index 0000000000..84e16725b0 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/app-readme.md @@ -0,0 +1,8 @@ +# 2FAuth + +[2FAuth](https://docs.2fauth.app/) is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. + +> When application is installed, a container will be launched with **root** privileges. +> This is required in order to apply the correct permissions to the `2FAuth` directories. +> Afterward, the `2FAuth` container will run as a **non**-root user (`1000`). +> All mounted storage(s) will be `chown`ed only if the parent directory does not match the configured user. diff --git a/library/ix-dev/community/twofactor-auth/charts/common-1.1.1.tgz b/library/ix-dev/community/twofactor-auth/charts/common-1.1.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..12d4db527305b8c32f96df78375cdfe618b86f66 GIT binary patch literal 61735 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ℜ@AduI<08c*fgoH{S`nkMwG%KI)`i&fFLMd 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
j7s=v)K8M3a2L(h&=e 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 z zL4`RbrJ%F-QjFIJ4@CeyY7G-b)W$n-BFUA!KO0_=Zwl;F{*G`FgeN_rkJGMBft!ZJ z@srdAUKH@Z?%n%zH_FmOw$;`3P!U?;ct~pjTR`H47bscXn#9j{u zMERlQWve`-U?ls*oeks@fJMad2zY>DI0i9HG9tE3^Ps~>uLFjSjVK#h9`Z(v#SLZMcae3*awnS;jYZMF8{trsgR%JYYq$x$Z7hSIld zGgA4}HLd94L-sgmicLbd7bs^Fl9Uj-#aj9B<;JRFNh(+>8@g2xZCiIM6Lxj`lOW*d zH<_y^Kb}Rz&}H^U7^*#a%_TR1Gni0;h-}w&3&mb-4A+v@phLF| zYM`cOtx7|;oK!`0Fm&r#MvHZeH9HFYc{~P$PC>t2Dx0Qm@jA~gPH{9tx68!KHkSOi zCG`D1c}`&}&#&q1k*XK2Q&R`q`dpua ztLxn5!aAHiVDPZZ)Ujs$&~9Es)W1rmB>#W7_}aG*SY!OxN%8#m;PCixkpI_Fr2PNk z;%irdUz7HqB@}E&ncaBy+oNEfZHON(zP7|m@-Bw6;67w)ow7!uvOt-TSQ;sllF9E( zf1dYhs0O5lGUrPA6B~TZx?uKY4%O;O2_&qcdH}4*bFT9G`5c#RIEpnhGGB6P_$K;t zl-xt;otEg7{buNL)rxV+PtG#WqMfk41H3L6&>Mdh$8)zZ1zsG(D1e*?VwPgSJvA6#TGb={>gjE^dFa}C%^pyzMj3&6e0Zh`7a5aiI<{#6d=#>@!}1w3T%pO zhpi5`b_>T_!#UFnmK^`rW6XcOH1dC?_^$^Cli~blEoBQ_+QQpzGutvK*8{dVY$%e=XU0*6EU@cp+OeDf%lZV3vLMGqK=E zX!;gdjph6R|7l`;*rRqffqZ>yunNo`s#77cho&1@y!|@w3a&EZX!Gjn()l|5Zs;%= z>QJsE7TqmX@gK$TF`Xj_QIz>zr0_8njSSr1OO`zU$J~D22sgg7i=J4)CjXD4NiqJ@ z(ZP`adp%_fsL@`*;HR*Eyijr|(RybSpDx_yb6NI?O_+UEVV@95 z{Sr)qm>a;dsmk%F=m?5`^%f|6y1*gw8z)|;j^r#1a;=RnSqSpW)bsDg;DQ-_ykB~u zxFDvjy0UH25o8R^V(5r{=BJvDShi+p-=-tZmBgzq^p}0wrJ9aBfzjE;{oxp#UECkH zG5DzI2!Vtk9G%RVoYOS7R-Ia+HQ>qSMyDZyQF?YU2In}kGa0bz2tQhMd{MoVq6Ngu z^b-0w3JB-3QB*m#nmQt?WAcdXf}wYNyFVQt?(LPkRnrl9ZgF;DGi@skJc`yGO#!5G zkBXkQBc=CZ2a~n6m7hvY zN0_AGTqzmh+KB{DW9~@t8)>&{(Yl$WkPn6kA7e~lAfq=#IH+)-dIf?lC638D)^aUB z%v7u*=s}KsU81P*W0*<~=+7ms${X@4nSz78?^}u;O4nkN|JAb6Qyca2|K#BCsCfQ+ zc)0&|kpI_Fwtxt@x{CPU&MweYYSX{Jg52+=vVxkSn;D~Rc@4SXOGW42+C$yi>e5td zvY(q%c6833)Jv&mcP-v+Z6sDF4OH8{ zcKaw+FExNwrAf-(ZEXN+Dz!7L%2fBI;Hm|zF=EPk0V`V;zX)nIfYrno5%0D%a4r{D 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 I!~g;a0Pn(n$N&HU literal 0 HcmV?d00001 diff --git a/library/ix-dev/community/twofactor-auth/ci/basic-values.yaml b/library/ix-dev/community/twofactor-auth/ci/basic-values.yaml new file mode 100644 index 0000000000..be865be020 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/ci/basic-values.yaml @@ -0,0 +1,7 @@ +twofauthNetwork: + webPort: 31000 + +twofauthStorage: + config: + type: hostPath + hostPath: /mnt/{{ .Release.Namespace }}/config diff --git a/library/ix-dev/community/twofactor-auth/ci/extra-values.yaml b/library/ix-dev/community/twofactor-auth/ci/extra-values.yaml new file mode 100644 index 0000000000..240385d0fd --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/ci/extra-values.yaml @@ -0,0 +1,28 @@ +twofauthConfig: + authenticationGuard: reverse-proxy-guard + authProxyHeaderUser: X-Forwarded-User + authProxyHeaderEmail: X-Forwarded-Email + webauthnUserVerification: required + trustedProxies: + - "*" + additionalEnvs: + - name: LOG_LEVEL + value: notice + - name: IS_DEMO_APP + value: "true" + + +twofauthNetwork: + webPort: 31000 + +twofauthStorage: + config: + type: hostPath + hostPath: /mnt/{{ .Release.Namespace }}/config + additionalStorages: + - type: hostPath + hostPath: /mnt/{{ .Release.Namespace }}/data1 + mountPath: /data1 + - type: hostPath + hostPath: /mnt/{{ .Release.Namespace }}/data2 + mountPath: /data2 diff --git a/library/ix-dev/community/twofactor-auth/ci/hostNet-values.yaml b/library/ix-dev/community/twofactor-auth/ci/hostNet-values.yaml new file mode 100644 index 0000000000..4eb327505f --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/ci/hostNet-values.yaml @@ -0,0 +1,8 @@ +twofauthNetwork: + webPort: 30000 + hostNetwork: true + +twofauthStorage: + config: + type: hostPath + hostPath: /mnt/{{ .Release.Namespace }}/config diff --git a/library/ix-dev/community/twofactor-auth/item.yaml b/library/ix-dev/community/twofactor-auth/item.yaml new file mode 100644 index 0000000000..e1cf6ee140 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/item.yaml @@ -0,0 +1,8 @@ +icon_url: https://docs.2fauth.app/static/2fauth_light.png +categories: + - security +screenshots: + - https://docs.2fauth.app/static/2fauth_screenshots_dark.png +tags: + - 2fa + - otp diff --git a/library/ix-dev/community/twofactor-auth/metadata.yaml b/library/ix-dev/community/twofactor-auth/metadata.yaml new file mode 100644 index 0000000000..8b1b61e6bb --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/metadata.yaml @@ -0,0 +1,8 @@ +runAsContext: + - userName: twofauth + groupName: twofauthreadarr + gid: 1000 + uid: 1000 + description: 2FAuth runs as a non-root user. +capabilities: [] +hostMounts: [] diff --git a/library/ix-dev/community/twofactor-auth/questions.yaml b/library/ix-dev/community/twofactor-auth/questions.yaml new file mode 100644 index 0000000000..8c666f8387 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/questions.yaml @@ -0,0 +1,298 @@ +groups: + - name: 2FAuth Configuration + description: Configure 2FAuth + - name: Network Configuration + description: Configure Network for 2FAuth + - name: Storage Configuration + description: Configure Storage for 2FAuth + - name: Resources Configuration + description: Configure Resources for 2FAuth + +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" + +questions: + - variable: twofauthConfig + label: "" + group: 2FAuth Configuration + schema: + type: dict + attrs: + - variable: appName + label: App Name + description: The name of the 2FAuth. + schema: + type: string + default: "2FAuth" + required: true + - variable: appUrl + label: App URL + description: | + The URL that 2FAuth will be accessible from.
+ Example:
+ http://server.ip:30081
+ https://2fauth.example.com + schema: + type: uri + default: "" + required: true + - variable: siteOwnerEmail + label: Site Owner Email + description: The email address of the site owner. + schema: + type: string + default: "" + required: true + - variable: authenticationGuard + label: Authentication Guard + description: | + When using 'reverse-proxy-guard' 2FAuth only look for the dedicated headers and skip all + other built-in authentication checks. That means your proxy is fully responsible of the + authentication process, 2FAuth will trust him as long as headers are presents. + schema: + type: string + default: "web-guard" + required: true + enum: + - value: "web-guard" + description: Web Guard + - value: "reverse-proxy-guard" + description: Reverse Proxy Guard + - variable: authProxyHeaderUser + label: Authentication Proxy Header User + description: | + Name of the HTTP headers sent by the reverse proxy that identifies the authenticated + user at proxy level. Check your proxy documentation to find out how these headers are named. + schema: + type: string + default: "" + show_if: [["authenticationGuard", "=", "reverse-proxy-guard"]] + required: true + - variable: authProxyHeaderEmail + label: Authentication Proxy Header Email + description: | + Name of the HTTP headers sent by the reverse proxy that identifies the authenticated + user at proxy level. Check your proxy documentation to find out how these headers are named. + schema: + type: string + default: "" + show_if: [["authenticationGuard", "=", "reverse-proxy-guard"]] + required: true + - variable: webauthnUserVerification + label: WebAuthn User Verification + description: | + Most authenticators and smartphones will ask the user to actively verify + themselves for log in. For example, through a touch plus pin code, + password entry, or biometric recognition (e.g., presenting a fingerprint). + The intent is to distinguish one user from any other. + schema: + type: string + default: "preferred" + required: true + enum: + - value: "preferred" + description: Preferred + - value: "required" + description: Required + - value: "discouraged" + description: Discouraged + - variable: trustedProxies + label: Trusted Proxies + description: The list of proxies IP to trust + schema: + type: list + default: [] + items: + - variable: trustedProxy + label: Trusted Proxy + schema: + type: string + required: true + - variable: additionalEnvs + label: Additional Environment Variables + description: Configure additional environment variables for 2FAuth. + 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: twofauthNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: webPort + label: Web Port + description: The port for the 2FAuth Web UI. + schema: + type: int + default: 30081 + 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: twofauthStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: config + label: 2FAuth Config Storage + description: The path to store 2FAuth Configuration. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + default: "ixVolume" + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - variable: datasetName + label: Dataset Name + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + hidden: true + immutable: true + default: "config" + $ref: + - "normalize/ixVolume" + - variable: hostPath + label: Host Path + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + immutable: true + required: true + - variable: additionalStorages + label: Additional Storage + description: Additional storage for 2FAuth. + schema: + type: list + default: [] + items: + - variable: storageEntry + label: Storage Entry + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + default: "ixVolume" + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - variable: mountPath + label: Mount Path + description: The path inside the container to mount the storage. + schema: + type: path + required: true + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + required: true + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + immutable: true + default: "storage_entry" + $ref: + - "normalize/ixVolume" + + - variable: resources + group: Resources Configuration + label: "" + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for 2FAuth. + schema: + type: string + max_length: 6 + valid_chars: '^(0\.[1-9]|[1-9][0-9]*)(\.[0-9]|m?)$' + valid_chars_error: | + Valid CPU limit formats are
+ - Plain Integer - eg. 1
+ - Float - eg. 0.5
+ - Milicpu - eg. 500m + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for 2FAuth. + schema: + type: string + max_length: 12 + valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$' + valid_chars_error: | + Valid Memory limit formats are
+ - Suffixed with E/P/T/G/M/K - eg. 1G
+ - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi
+ - Plain Integer in bytes - eg. 1024
+ - Exponent - eg. 134e6 + default: "8Gi" + required: true diff --git a/library/ix-dev/community/twofactor-auth/templates/NOTES.txt b/library/ix-dev/community/twofactor-auth/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/library/ix-dev/community/twofactor-auth/templates/_2fauth.tpl b/library/ix-dev/community/twofactor-auth/templates/_2fauth.tpl new file mode 100644 index 0000000000..76d64a4630 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_2fauth.tpl @@ -0,0 +1,52 @@ +{{- define "twofauth.workload" -}} +workload: + twofauth: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ .Values.twofauthNetwork.hostNetwork }} + containers: + twofauth: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: false + envFrom: + - secretRef: + name: twofauth-creds + - configMapRef: + name: twofauth-config + {{ with .Values.twofauthConfig.additionalEnvs }} + envList: + {{ range $env := . }} + - name: {{ $env.name }} + value: {{ $env.value }} + {{ end }} + {{ end }} + probes: + liveness: + enabled: true + type: http + port: 8000 + path: /infos + readiness: + enabled: true + type: http + port: 8000 + path: /infos + startup: + enabled: true + type: http + port: 8000 + path: /infos + initContainers: + {{- include "ix.v1.common.app.permissions" (dict "containerName" "01-permissions" + "UID" 1000 + "GID" 1000 + "mode" "check" + "type" "init") | nindent 8 }} +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/_configuration.tpl b/library/ix-dev/community/twofactor-auth/templates/_configuration.tpl new file mode 100644 index 0000000000..a4c60159d2 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_configuration.tpl @@ -0,0 +1,37 @@ +{{- define "twofauth.configuration" -}} + + {{- $fullname := (include "ix.v1.common.lib.chart.names.fullname" $) -}} + + {{- $appKey := (randAlphaNum 32) -}} + {{- with (lookup "v1" "Secret" .Release.Namespace (printf "%s-twofauth-creds" $fullname)) -}} + {{- $appKey = ((index .data "APP_KEY") | b64dec) -}} + {{- end }} + +secret: + twofauth-creds: + enabled: true + data: + APP_KEY: {{ $appKey }} + +configmap: + twofauth-config: + enabled: true + data: + # When this is set to production, it initialize automatically + # Because it waits for user input in the console. + APP_ENV: local + # It is symlinked to /2fauth/database.sqlite + DB_DATABASE: /srv/database/database.sqlite + APP_NAME: {{ .Values.twofauthConfig.appName }} + APP_URL: {{ .Values.twofauthConfig.appUrl }} + SITE_OWNER: {{ .Values.twofauthConfig.siteOwnerEmail }} + AUTHENTICATION_GUARD: {{ .Values.twofauthConfig.authenticationGuard }} + {{- if eq .Values.twofauthConfig.authenticationGuard "reverse-proxy-guard" }} + AUTH_PROXY_HEADER_FOR_USER: {{ .Values.twofauthConfig.authProxyHeaderUser }} + AUTH_PROXY_HEADER_FOR_EMAIL: {{ .Values.twofauthConfig.authProxyHeaderEmail }} + {{- end }} + WEBAUTHN_USER_VERIFICATION: {{ .Values.twofauthConfig.webauthnUserVerification }} + {{- with .Values.twofauthConfig.trustedProxies }} + TRUSTED_PROXIES: {{ join "," . | quote }} + {{- end -}} +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/_persistence.tpl b/library/ix-dev/community/twofactor-auth/templates/_persistence.tpl new file mode 100644 index 0000000000..b6014a1b81 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_persistence.tpl @@ -0,0 +1,34 @@ +{{- define "twofauth.persistence" -}} +persistence: + config: + enabled: true + type: {{ .Values.twofauthStorage.config.type }} + datasetName: {{ .Values.twofauthStorage.config.datasetName | default "" }} + hostPath: {{ .Values.twofauthStorage.config.hostPath | default "" }} + targetSelector: + twofauth: + twofauth: + mountPath: /2fauth + 01-permissions: + mountPath: /mnt/directories/2fauth + tmp: + enabled: true + type: emptyDir + targetSelector: + twofauth: + twofauth: + mountPath: /tmp + {{- range $idx, $storage := .Values.twofauthStorage.additionalStorages }} + {{ printf "twofauth-%v" (int $idx) }}: + enabled: true + type: {{ $storage.type }} + datasetName: {{ $storage.datasetName | default "" }} + hostPath: {{ $storage.hostPath | default "" }} + targetSelector: + twofauth: + twofauth: + mountPath: {{ $storage.mountPath }} + 01-permissions: + mountPath: /mnt/directories{{ $storage.mountPath }} + {{- end }} +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/_portal.tpl b/library/ix-dev/community/twofactor-auth/templates/_portal.tpl new file mode 100644 index 0000000000..aa801e1743 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_portal.tpl @@ -0,0 +1,35 @@ +{{- define "twofauth.portal" -}} + {{- $host := "$node_ip" -}} + {{- $port := "" -}} + {{- $protocol := "http" -}} + {{- if hasPrefix "https://" .Values.twofauthConfig.appUrl -}} + {{- $protocol = "https" -}} + {{- end -}} + + {{- with .Values.twofauthConfig.appUrl -}} {{/* Trim protocol and trailing slash */}} + {{- $host = . | trimPrefix "https://" | trimPrefix "http://" | trimSuffix "/" -}} + + {{- if contains ":" $host -}} + {{- $port = (split ":" $host)._1 -}} + {{- $host = (split ":" $host)._0 -}} + {{- end -}} + + {{- if not $port -}} + {{- if eq $protocol "https" -}} + {{- $port = "443" -}} + {{- else -}} + {{- $port = "80" -}} + {{- end -}} + {{- end -}} + {{- end }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: portal +data: + path: "/" + port: {{ $port | quote }} + protocol: {{ $protocol }} + host: {{ $host }} +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/_service.tpl b/library/ix-dev/community/twofactor-auth/templates/_service.tpl new file mode 100644 index 0000000000..b034bef6a0 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_service.tpl @@ -0,0 +1,16 @@ +{{- define "twofauth.service" -}} +service: + twofauth: + enabled: true + primary: true + type: NodePort + targetSelector: twofauth + ports: + webui: + enabled: true + primary: true + port: {{ .Values.twofauthNetwork.webPort }} + nodePort: {{ .Values.twofauthNetwork.webPort }} + targetPort: 8000 + targetSelector: twofauth +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/_validation.tpl b/library/ix-dev/community/twofactor-auth/templates/_validation.tpl new file mode 100644 index 0000000000..ab896ca723 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/_validation.tpl @@ -0,0 +1,13 @@ +{{- define "twofauth.validation" -}} + {{- if eq .Values.twofauthConfig.authenticationGuard "reverse-proxy-guard" -}} + + {{- if not .Values.twofauthConfig.authProxyHeaderUser -}} + {{- fail "[Auth Proxy Header User] is required when using reverse-proxy-guard" -}} + {{- end -}} + + {{- if not .Values.twofauthConfig.authProxyHeaderEmail -}} + {{- fail "[Auth Proxy Header Email] is required when using reverse-proxy-guard" -}} + {{- end -}} + + {{- end }} +{{- end -}} diff --git a/library/ix-dev/community/twofactor-auth/templates/common.yaml b/library/ix-dev/community/twofactor-auth/templates/common.yaml new file mode 100644 index 0000000000..3ef1dc4d21 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/templates/common.yaml @@ -0,0 +1,14 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{- include "twofauth.validation" $ -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "twofauth.configuration" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "twofauth.persistence" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "twofauth.service" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "twofauth.workload" $ | fromYaml) -}} + +{{/* Create the configmap for portal manually*/}} +{{- include "twofauth.portal" $ -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/library/ix-dev/community/twofactor-auth/upgrade_info.json b/library/ix-dev/community/twofactor-auth/upgrade_info.json new file mode 100644 index 0000000000..767388094a --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/upgrade_info.json @@ -0,0 +1 @@ +{"filename": "values.yaml", "keys": ["image"]} diff --git a/library/ix-dev/community/twofactor-auth/upgrade_strategy b/library/ix-dev/community/twofactor-auth/upgrade_strategy new file mode 100755 index 0000000000..af685230a1 --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/upgrade_strategy @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import json +import re +import sys + +from catalog_update.upgrade_strategy import semantic_versioning + + +RE_STABLE_VERSION = re.compile(r'\d+\.\d+\.\d+') + + +def newer_mapping(image_tags): + key = list(image_tags.keys())[0] + tags = {t: t for t in image_tags[key] if RE_STABLE_VERSION.fullmatch(t)} + version = semantic_versioning(list(tags)) + if not version: + return {} + + return { + 'tags': {key: tags[version]}, + 'app_version': 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/twofactor-auth/values.yaml b/library/ix-dev/community/twofactor-auth/values.yaml new file mode 100644 index 0000000000..921059672b --- /dev/null +++ b/library/ix-dev/community/twofactor-auth/values.yaml @@ -0,0 +1,30 @@ +image: + repository: 2fauth/2fauth + pullPolicy: IfNotPresent + tag: 4.2.2 + +resources: + limits: + cpu: 4000m + memory: 8Gi + +twofauthConfig: + appName: 2FAuth + appUrl: http://localhost:30081 + siteOwnerEmail: 'admin@example.com' + authenticationGuard: web-guard + authProxyHeaderUser: '' + authProxyHeaderEmail: '' + webauthnUserVerification: preferred + trustedProxies: [] + additionalEnvs: [] + +twofauthNetwork: + webPort: 30081 + hostNetwork: false + +twofauthStorage: + config: + type: ixVolume + datasetName: config + additionalStorages: []