From 76b51a872716412838cf73eb907d84cca03b8b2a Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Mon, 15 May 2023 14:12:32 +0300 Subject: [PATCH] NAS-119345 / 23.10 / Add webdav (#1186) --- .github/workflows/charts_tests.yaml | 4 +- library/ix-dev/community/webdav/Chart.lock | 6 + library/ix-dev/community/webdav/Chart.yaml | 25 ++ library/ix-dev/community/webdav/README.md | 9 + library/ix-dev/community/webdav/app-readme.md | 9 + .../community/webdav/charts/common-1.0.7.tgz | Bin 0 -> 55245 bytes .../ci/http-basicauth-other-user-values.yaml | 33 +++ .../webdav/ci/http-basicauth-values.yaml | 29 +++ .../ci/http-noauth-other-user-values.yaml | 28 +++ .../webdav/ci/http-noauth-values.yaml | 24 ++ ...ttp_https-basicauth-other-user-values.yaml | 122 +++++++++ .../ci/http_https-basicauth-values.yaml | 118 +++++++++ .../http_https-noauth-other-user-values.yaml | 117 +++++++++ .../webdav/ci/http_https-noauth-values.yaml | 113 +++++++++ ...ttps-basicauth-other-user-values copy.yaml | 121 +++++++++ .../webdav/ci/https-basicauth-values.yaml | 117 +++++++++ .../ci/https-noauth-other-user-values.yaml | 116 +++++++++ .../webdav/ci/https-noauth-values.yaml | 112 +++++++++ library/ix-dev/community/webdav/item.yaml | 6 + library/ix-dev/community/webdav/metadata.yaml | 8 + .../ix-dev/community/webdav/questions.yaml | 235 ++++++++++++++++++ .../community/webdav/templates/NOTES.txt | 1 + .../webdav/templates/_configuration.tpl | 153 ++++++++++++ .../community/webdav/templates/_helper.tpl | 110 ++++++++ .../webdav/templates/_validation.tpl | 34 +++ .../community/webdav/templates/_webdav.tpl | 191 ++++++++++++++ .../community/webdav/templates/common.yaml | 7 + .../ix-dev/community/webdav/upgrade_info.json | 1 + .../ix-dev/community/webdav/upgrade_strategy | 31 +++ library/ix-dev/community/webdav/values.yaml | 27 ++ 30 files changed, 1905 insertions(+), 2 deletions(-) create mode 100644 library/ix-dev/community/webdav/Chart.lock create mode 100644 library/ix-dev/community/webdav/Chart.yaml create mode 100644 library/ix-dev/community/webdav/README.md create mode 100644 library/ix-dev/community/webdav/app-readme.md create mode 100644 library/ix-dev/community/webdav/charts/common-1.0.7.tgz create mode 100644 library/ix-dev/community/webdav/ci/http-basicauth-other-user-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http-basicauth-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http-noauth-other-user-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http-noauth-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http_https-basicauth-other-user-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http_https-basicauth-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http_https-noauth-other-user-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/http_https-noauth-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/https-basicauth-other-user-values copy.yaml create mode 100644 library/ix-dev/community/webdav/ci/https-basicauth-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/https-noauth-other-user-values.yaml create mode 100644 library/ix-dev/community/webdav/ci/https-noauth-values.yaml create mode 100644 library/ix-dev/community/webdav/item.yaml create mode 100644 library/ix-dev/community/webdav/metadata.yaml create mode 100644 library/ix-dev/community/webdav/questions.yaml create mode 100644 library/ix-dev/community/webdav/templates/NOTES.txt create mode 100644 library/ix-dev/community/webdav/templates/_configuration.tpl create mode 100644 library/ix-dev/community/webdav/templates/_helper.tpl create mode 100644 library/ix-dev/community/webdav/templates/_validation.tpl create mode 100644 library/ix-dev/community/webdav/templates/_webdav.tpl create mode 100644 library/ix-dev/community/webdav/templates/common.yaml create mode 100644 library/ix-dev/community/webdav/upgrade_info.json create mode 100644 library/ix-dev/community/webdav/upgrade_strategy create mode 100644 library/ix-dev/community/webdav/values.yaml diff --git a/.github/workflows/charts_tests.yaml b/.github/workflows/charts_tests.yaml index 6e4c4594f5..65b99e3e55 100644 --- a/.github/workflows/charts_tests.yaml +++ b/.github/workflows/charts_tests.yaml @@ -20,7 +20,7 @@ jobs: helm-version: - v3.9.4 - v3.10.3 - - v3.11.2 + - v3.11.3 steps: - name: Checkout uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 @@ -87,7 +87,7 @@ jobs: # We run tests on Helm version of latest SCALE release, SCALE nightly and manually defined "latest" helm-version: - v3.9.4 - - v3.11.2 + - v3.11.3 # We run tests on k3s version of latest SCALE release, SCALE nightly and manually defined "latest" k3s-version: - v1.25.3+k3s1 diff --git a/library/ix-dev/community/webdav/Chart.lock b/library/ix-dev/community/webdav/Chart.lock new file mode 100644 index 0000000000..e4e70f6c11 --- /dev/null +++ b/library/ix-dev/community/webdav/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.0.7 +digest: sha256:919bcf42446fc1748a1b77001ec0161bb7a72a198381794b716a6ebb459ac31b +generated: "2023-05-09T17:09:32.735505559+03:00" diff --git a/library/ix-dev/community/webdav/Chart.yaml b/library/ix-dev/community/webdav/Chart.yaml new file mode 100644 index 0000000000..5ea40088ae --- /dev/null +++ b/library/ix-dev/community/webdav/Chart.yaml @@ -0,0 +1,25 @@ +name: webdav +description: WebDAV is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers. +annotations: + title: WebDAv +type: application +version: 1.0.0 +apiVersion: v2 +appVersion: '1.1.3.2982' +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.0.7 +home: http://www.webdav.org/ +icon: http://www.webdav.org/images/webdav-logo.jpg +sources: + - http://www.webdav.org/ + - https://github.com/truenas/charts/tree/master/community/webdav +keywords: + - webdav + - file-sharing diff --git a/library/ix-dev/community/webdav/README.md b/library/ix-dev/community/webdav/README.md new file mode 100644 index 0000000000..fbc46c3c63 --- /dev/null +++ b/library/ix-dev/community/webdav/README.md @@ -0,0 +1,9 @@ +# WebDAV + +[WebDAV](http://webdav.org/) is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers. + +> When application is installed and `Fix Permissions` is selected on at least 1 share +> a container will be launched with **root** privileges. This is required in order to apply +> the correct permissions to the selected `WebDAV` shares/directories. +> Afterward, the `WebDAV` container will run as a **non**-root user (Default: `568`). +> Note that `chown` will only apply if the parent directory does not match the configured user and group. diff --git a/library/ix-dev/community/webdav/app-readme.md b/library/ix-dev/community/webdav/app-readme.md new file mode 100644 index 0000000000..58ff82094c --- /dev/null +++ b/library/ix-dev/community/webdav/app-readme.md @@ -0,0 +1,9 @@ +# WebDAV + +[WebDAV](http://webdav.org/) is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers. + +> When application is installed and `Fix Permissions` is selected on at least 1 share +> a container will be launched with **root** privileges. This is required in order to apply +> the correct permissions to the `WebDAV` shares/directories. +> Afterward, the `WebDAV` container will run as a **non**-root user (Default: `568`). +> `Chown` will only apply if the parent directory does not match the configured user and group. diff --git a/library/ix-dev/community/webdav/charts/common-1.0.7.tgz b/library/ix-dev/community/webdav/charts/common-1.0.7.tgz new file mode 100644 index 0000000000000000000000000000000000000000..ede171ae7b9b9f05a00863f9d24bab10c7022d39 GIT binary patch literal 55245 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 k + schema: + type: boolean + default: false + + - variable: webdavStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: shares + label: Shares + description: Shares for WebDAV. + schema: + type: list + default: [] + items: + - variable: shareEntry + label: Share Entry + schema: + type: dict + attrs: + - variable: enabled + label: Enable the share + description: Enable the share. + schema: + type: boolean + default: true + - variable: name + label: Share Name + description: | + The name of the share.
+ Also serves as the endpoint for the share.
+ Example: [share1] will be available at [http://:/share1] + schema: + type: string + required: true + - variable: description + label: Description + description: Share description. Only used for documentation. + schema: + type: string + - variable: hostPath + label: Host Path + description: The host path to use for the share. + schema: + type: hostpath + required: true + - variable: readOnly + label: Read Only + description: | + Enable read only access to the share.
+ This will disable write access to the share.
+ Data will be mounted as read only. + schema: + type: boolean + default: false + - variable: fixPermissions + label: Fix Permissions + description: | + Enable permission fix for the share.
+ This will fix the permissions of the share on startup.
+ This will change the owner of the share to the user and group specified in [User and Group Configuration]. + Note: This will still change permissions even if [Read Only] for the share is enabled. + schema: + type: boolean + default: false + + - 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 WebDAV. + schema: + type: string + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for WebDAV. + schema: + type: string + default: "8Gi" + required: true diff --git a/library/ix-dev/community/webdav/templates/NOTES.txt b/library/ix-dev/community/webdav/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/library/ix-dev/community/webdav/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/library/ix-dev/community/webdav/templates/_configuration.tpl b/library/ix-dev/community/webdav/templates/_configuration.tpl new file mode 100644 index 0000000000..1e8ac89e02 --- /dev/null +++ b/library/ix-dev/community/webdav/templates/_configuration.tpl @@ -0,0 +1,153 @@ +{{- define "webdav.configuration" -}} +{{- include "webdav.validation" $ }} + +{{- if ne .Values.webdavConfig.authType "none" }} +secret: + htauth: + enabled: true + data: + htauth: | + {{- include "webdav.htauth" $ | nindent 8 }} +{{- end }} + +configmap: + config: + enabled: true + data: + {{- if ne .Values.webdavConfig.authType "none" }} + htauth: | + {{- include "webdav.htauth" $ | nindent 8 }} + {{- end }} + + {{- if .Values.webdavNetwork.http }} + webdav.conf: | + {{- include "webdav.http.config" $ | nindent 8 }} + {{- end }} + + {{- if .Values.webdavNetwork.https }} + webdav-ssl.conf: | + {{- include "webdav.https.config" $ | nindent 8 }} + {{- end }} + + {{- $modulePath := "/usr/local/apache2/modules" }} + httpd.conf: | + # This path is a emptyDir in memory + PidFile "/usr/local/apache2/var/httpd.pid" + # The absolutely necessary modules + LoadModule authn_file_module {{ $modulePath }}/mod_authn_file.so + LoadModule authn_core_module {{ $modulePath }}/mod_authn_core.so + LoadModule authz_user_module {{ $modulePath }}/mod_authz_user.so + LoadModule authz_core_module {{ $modulePath }}/mod_authz_core.so + LoadModule alias_module {{ $modulePath }}/mod_alias.so + LoadModule mpm_event_module {{ $modulePath }}/mod_mpm_event.so + LoadModule auth_basic_module {{ $modulePath }}/mod_auth_basic.so + LoadModule auth_digest_module {{ $modulePath }}/mod_auth_digest.so + LoadModule setenvif_module {{ $modulePath }}/mod_setenvif.so + LoadModule dav_module {{ $modulePath }}/mod_dav.so + LoadModule dav_fs_module {{ $modulePath }}/mod_dav_fs.so + LoadModule allowmethods_module {{ $modulePath }}/mod_allowmethods.so + LoadModule ssl_module {{ $modulePath }}/mod_ssl.so + LoadModule socache_shmcb_module {{ $modulePath }}/mod_socache_shmcb.so + LoadModule unixd_module {{ $modulePath }}/mod_unixd.so + LoadModule rewrite_module {{ $modulePath }}/mod_rewrite.so + + # Still deciding whether or not to keep these modules or not + LoadModule authz_host_module {{ $modulePath }}/mod_authz_host.so + LoadModule authz_groupfile_module {{ $modulePath }}/mod_authz_groupfile.so + LoadModule access_compat_module {{ $modulePath }}/mod_access_compat.so + LoadModule reqtimeout_module {{ $modulePath }}/mod_reqtimeout.so + LoadModule filter_module {{ $modulePath }}/mod_filter.so + LoadModule mime_module {{ $modulePath }}/mod_mime.so + LoadModule env_module {{ $modulePath }}/mod_env.so + LoadModule headers_module {{ $modulePath }}/mod_headers.so + LoadModule status_module {{ $modulePath }}/mod_status.so + LoadModule autoindex_module {{ $modulePath }}/mod_autoindex.so + LoadModule dir_module {{ $modulePath }}/mod_dir.so + + ServerName localhost + + + DirectoryIndex disabled + + + + Require all denied + + + ErrorLog "/proc/self/fd/2" + LogLevel warn + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + CustomLog "/proc/self/fd/1" common + + + + ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" + + + + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + + TypesConfig /usr/local/apache2/conf/mime.types + + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + + # AddType application/x-gzip .tgz + + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + + # AddEncoding x-compress .Z + # AddEncoding x-gzip .gz .tgz + + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + + # AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + # AddHandler type-map var + + # Filters allow you to process content before it is sent to the client. + + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + + # AddType text/html .shtml + # AddOutputFilter INCLUDES .shtml + + + # Secure (SSL/TLS) connections + # Include etc/apache24/extra/httpd-ssl.conf + + # Note: The following must must be present to support + # starting without SSL on platforms with no /dev/random equivalent + # but a statically compiled-in mod_ssl. + + + SSLRandomSeed startup builtin + SSLRandomSeed connect builtin + SSLProtocol +TLSv1.2 +TLSv1.3 + + + Include /usr/local/apache2/conf/Includes/*.conf +{{- end -}} diff --git a/library/ix-dev/community/webdav/templates/_helper.tpl b/library/ix-dev/community/webdav/templates/_helper.tpl new file mode 100644 index 0000000000..d27d462db2 --- /dev/null +++ b/library/ix-dev/community/webdav/templates/_helper.tpl @@ -0,0 +1,110 @@ +{{/* Webdav HTTP Config */}} +{{- define "webdav.http.config" -}} +Listen {{ .Values.webdavNetwork.httpPort }} + + {{- include "webdav.health.config" $ | nindent 2 }} + {{- include "webdav.core.config" $ | nindent 2 }} + +{{- end -}} + +{{/* Webdav HTTPS Config */}} +{{- define "webdav.https.config" -}} +Listen {{ .Values.webdavNetwork.httpsPort }} + + {{- if not .Values.webdavNetwork.http }} + {{- include "webdav.health.config" $ | nindent 2 }} + {{- end }} + SSLEngine on + SSLCertificateFile "{{ include "webdav.path.cert.crt" $ }}" + SSLCertificateKeyFile "{{ include "webdav.path.cert.key" $ }} + SSLProtocol +TLSv1.2 +TLSv1.3 + SSLCipherSuite HIGH:MEDIUM + {{- include "webdav.core.config" $ | nindent 2 }} + +{{- end -}} + +{{/* WebDav Core Config */}} +{{- define "webdav.core.config" -}} +DavLockDB "/usr/local/apache2/var/DavLock" + +{{- if ne .Values.webdavConfig.authType "none" }} + {{- include "webdav.auth.config" $ | nindent 2 }} +{{- end }} + Dav On + IndexOptions Charset=utf-8 + AddDefaultCharset UTF-8 + AllowOverride None + Order allow,deny + Allow from all + Options Indexes FollowSymLinks + +{{- range .Values.webdavStorage.shares }} + {{- if .enabled }} +# WebDav Share - {{ .name }} +# Description: {{ .description }} +Alias /{{ .name }} "/{{ include "webdav.shares.prefix" $ }}/{{ .name }}" + + + {{- if .readOnly }} + + AllowMethods GET OPTIONS PROPFIND + + {{- end }} + {{- end }} +{{- end }} +# The following directives disable redirects on non-GET requests for +# a directory that does not include the trailing slash. This fixes a +# problem with several clients that do not appropriately handle +# redirects for folders with DAV methods. +BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully +BrowserMatch "MS FrontPage" redirect-carefully +BrowserMatch "^WebDrive" redirect-carefully +BrowserMatch "^WebDAVFS/1.[01234]" redirect-carefully +BrowserMatch "^gnome-vfs/1.0" redirect-carefully +BrowserMatch "^XML Spy" redirect-carefully +BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully +BrowserMatch " Konqueror/4" redirect-carefully +RequestReadTimeout handshake=0 header=20-40,MinRate=500 body=20,MinRate=500 +{{- end -}} + +{{/* Included when authType is not "none" */}} +{{- define "webdav.auth.config" -}} +AuthType {{ .Values.webdavConfig.authType }} +AuthName webdav +AuthUserFile "/etc/apache2/webdavht{{ .Values.webdavConfig.authType }}" +Require valid-user +{{- end -}} + +{{/* Included in one of the configs (webdav or webdav-ssl) + Used as a healthcheck endpoint */}} +{{- define "webdav.health.config" -}} + + RewriteEngine On + RewriteRule .* - [R=200] + +{{- end -}} + +{{/* Creates the basic auth password */}} +{{- define "webdav.htauth" -}} + {{- if eq .Values.webdavConfig.authType "basic" -}} + {{- htpasswd .Values.webdavConfig.username .Values.webdavConfig.password -}} + {{- end -}} +{{- end -}} + +{{/* Prints the crt path + Used in mountPath of the secret and on the webdav-ssl.conf */}} +{{- define "webdav.path.cert.crt" -}} + {{- print "/etc/certificates/tls.crt" -}} +{{- end -}} + +{{/* Prints the key path + Used in mountPath of the secret and on the webdav-ssl.conf */}} +{{- define "webdav.path.cert.key" -}} + {{- print "/etc/certificates/tls.key" -}} +{{- end -}} + +{{/* Prints the shares base path inside the container + Used in mountPath of the volume and on the webdav*.conf */}} +{{- define "webdav.shares.prefix" -}} + {{- print "shares" -}} +{{- end -}} diff --git a/library/ix-dev/community/webdav/templates/_validation.tpl b/library/ix-dev/community/webdav/templates/_validation.tpl new file mode 100644 index 0000000000..171c9c0855 --- /dev/null +++ b/library/ix-dev/community/webdav/templates/_validation.tpl @@ -0,0 +1,34 @@ +{{- define "webdav.validation" -}} + + {{- $authTypes := (list "none" "basic") -}} + {{- if not (mustHas .Values.webdavConfig.authType $authTypes) -}} + {{- fail (printf "WebDAV - Expected [Auth Type] to be one of [%v], but got [%v]" (join ", " $authTypes) .Values.webdavConfig.authType) -}} + {{- end -}} + + {{- if eq .Values.webdavConfig.authType "basic" -}} + {{- if not .Values.webdavConfig.username -}} + {{- fail "WebDAV - Expected [Username] to be configured when [Auth Type] is set to [Basic Auth]" -}} + {{- end -}} + {{- if not .Values.webdavConfig.password -}} + {{- fail "WebDAV - Expected [Password] to be configured when [Auth Type] is set to [Basic Auth]" -}} + {{- end -}} + {{- end -}} + + {{- if and (not .Values.webdavNetwork.http) (not .Values.webdavNetwork.https) -}} + {{- fail "WebDAV - Expected at least one protocol [HTTP, HTTPS] to be enabled" -}} + {{- end -}} + + {{- if and .Values.webdavNetwork.https (not .Values.webdavNetwork.certificateID) -}} + {{- fail "WebDAV - Expected a certificate to be configured when HTTPS is enabled" -}} + {{- end -}} + + {{- if not .Values.webdavStorage.shares -}} + {{- fail "WebDAV - Expected at least 1 [Share] to be configured" -}} + {{- end -}} + + {{- range .Values.webdavStorage.shares -}} + {{- if not (mustRegexMatch "^[a-zA-Z0-9_-]+$" .name) -}} + {{- fail "WebDAV - Expected [Share] name to only consist of [Letters(a-z, A-Z), Numbers(0-9), Underscores(_), Dashes(-)]" -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/library/ix-dev/community/webdav/templates/_webdav.tpl b/library/ix-dev/community/webdav/templates/_webdav.tpl new file mode 100644 index 0000000000..0595382d2e --- /dev/null +++ b/library/ix-dev/community/webdav/templates/_webdav.tpl @@ -0,0 +1,191 @@ +{{- define "webdav.workload" -}} +workload: + webdav: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ .Values.webdavNetwork.hostNetwork }} + securityContext: + fsGroup: {{ .Values.webdavRunAs.group }} + containers: + webdav: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: {{ .Values.webdavRunAs.user }} + runAsGroup: {{ .Values.webdavRunAs.group }} + envList: + {{ with .Values.webdavConfig.additionalEnvs }} + {{ range $env := . }} + - name: {{ $env.name }} + value: {{ $env.value }} + {{ end }} + {{ end }} + {{ $port := .Values.webdavNetwork.httpPort }} + {{ $scheme := "http" }} + {{ if not .Values.webdavNetwork.http }} + {{ $port = .Values.webdavNetwork.httpsPort }} + {{ $scheme = "https" }} + {{ end }} + probes: + liveness: + enabled: true + type: {{ $scheme }} + path: /health + port: {{ $port }} + {{ if eq .Values.webdavConfig.authType "basic" }} + httpHeaders: + Authorization: Basic {{ (printf "%s:%s" .Values.webdavConfig.username .Values.webdavConfig.password) | b64enc }} + {{ end }} + readiness: + enabled: true + type: {{ $scheme }} + path: /health + port: {{ $port }} + {{ if eq .Values.webdavConfig.authType "basic" }} + httpHeaders: + Authorization: Basic {{ (printf "%s:%s" .Values.webdavConfig.username .Values.webdavConfig.password) | b64enc }} + {{ end }} + startup: + enabled: true + type: {{ $scheme }} + path: /health + port: {{ $port }} + {{ if eq .Values.webdavConfig.authType "basic" }} + httpHeaders: + Authorization: Basic {{ (printf "%s:%s" .Values.webdavConfig.username .Values.webdavConfig.password) | b64enc }} + {{ end }} + initContainers: + {{- include "ix.v1.common.app.permissions" (dict "containerName" "01-permissions" + "UID" .Values.webdavRunAs.user + "GID" .Values.webdavRunAs.group + "mode" "check" + "type" "init") | nindent 8 }} + +{{/* Service */}} +service: + webdav: + enabled: true + primary: true + type: NodePort + targetSelector: webdav + ports: + http: + enabled: {{ .Values.webdavNetwork.http }} + primary: true + port: {{ .Values.webdavNetwork.httpPort }} + nodePort: {{ .Values.webdavNetwork.httpPort }} + targetSelector: webdav + https: + enabled: {{ .Values.webdavNetwork.https }} + primary: {{ not .Values.webdavNetwork.http }} + port: {{ .Values.webdavNetwork.httpsPort }} + nodePort: {{ .Values.webdavNetwork.httpsPort }} + targetSelector: webdav + +{{/* Persistence */}} +persistence: + httpd-conf: + enabled: true + type: configmap + objectName: config + targetSelector: + webdav: + webdav: + mountPath: /usr/local/apache2/conf/httpd.conf + subPath: httpd.conf + readOnly: true + webdav-conf: + # Mount config only if http is enabled + enabled: {{ .Values.webdavNetwork.http }} + type: configmap + objectName: config + targetSelector: + webdav: + webdav: + mountPath: /usr/local/apache2/conf/Includes/webdav.conf + readOnly: true + subPath: webdav.conf + webdav-ssl-conf: + # Mount config only if https is enabled + enabled: {{ .Values.webdavNetwork.https }} + type: configmap + objectName: config + targetSelector: + webdav: + webdav: + mountPath: /usr/local/apache2/conf/Includes/webdav-ssl.conf + subPath: webdav-ssl.conf + readOnly: true + htauth: + # Mount config only if auth is enabled + enabled: {{ ne .Values.webdavConfig.authType "none" }} + type: secret + objectName: htauth + targetSelector: + webdav: + webdav: + mountPath: /etc/apache2/webdavht{{ .Values.webdavConfig.authType }} + subPath: htauth + readOnly: true + apachelock: + # Stores PID file and DavLockDB file + enabled: true + type: emptyDir + medium: Memory + #TODO: Is this enough? + size: 100Mi + targetSelector: + webdav: + webdav: + mountPath: /usr/local/apache2/var + {{ range $idx, $storage := .Values.webdavStorage.shares }} + {{ printf "webdav-%v" (int $idx) }}: + enabled: {{ $storage.enabled }} + type: hostPath + hostPath: {{ $storage.hostPath }} + targetSelector: + webdav: + webdav: + # This path is used in the Alias directive in the webdav.conf + mountPath: /{{ include "webdav.shares.prefix" $ }}/{{ $storage.name }} + readOnly: {{ $storage.readOnly }} + {{ if $storage.fixPermissions }} + 01-permissions: + mountPath: /mnt/directories/{{ $storage.name }} + readOnly: false + {{ end }} + {{ end }} +{{ if .Values.webdavNetwork.certificateID }} + {{/* Mount Certificate */}} + tls-crt: + enabled: true + type: secret + objectName: webdav-cert + defaultMode: "0600" + targetSelector: + webdav: + webdav: + mountPath: {{ include "webdav.path.cert.crt" $ }} + subPath: tls.crt + readOnly: true + tls-key: + enabled: true + type: secret + objectName: webdav-cert + defaultMode: "0600" + targetSelector: + webdav: + webdav: + mountPath: {{ include "webdav.path.cert.key" $ }} + subPath: tls.key + readOnly: true +{{/* Certificate Secret */}} +scaleCertificate: + webdav-cert: + enabled: true + id: {{ .Values.webdavNetwork.certificateID }} +{{ end }} +{{- end -}} diff --git a/library/ix-dev/community/webdav/templates/common.yaml b/library/ix-dev/community/webdav/templates/common.yaml new file mode 100644 index 0000000000..434a82b156 --- /dev/null +++ b/library/ix-dev/community/webdav/templates/common.yaml @@ -0,0 +1,7 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "webdav.configuration" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "webdav.workload" $ | fromYaml) -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/library/ix-dev/community/webdav/upgrade_info.json b/library/ix-dev/community/webdav/upgrade_info.json new file mode 100644 index 0000000000..767388094a --- /dev/null +++ b/library/ix-dev/community/webdav/upgrade_info.json @@ -0,0 +1 @@ +{"filename": "values.yaml", "keys": ["image"]} diff --git a/library/ix-dev/community/webdav/upgrade_strategy b/library/ix-dev/community/webdav/upgrade_strategy new file mode 100644 index 0000000000..41e9448b21 --- /dev/null +++ b/library/ix-dev/community/webdav/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'[0-9]+\.[0-9]+\.[0-9]+') + + +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/webdav/values.yaml b/library/ix-dev/community/webdav/values.yaml new file mode 100644 index 0000000000..57a8d90c1b --- /dev/null +++ b/library/ix-dev/community/webdav/values.yaml @@ -0,0 +1,27 @@ +image: + repository: httpd + pullPolicy: IfNotPresent + tag: '2.4.57' + +resources: + limits: + cpu: 4000m + memory: 8Gi + +webdavConfig: + authType: none + username: '' + password: '' + additionalEnvs: [] +webdavNetwork: + hostNetwork: false + http: true + httpPort: 30000 + https: false + httpsPort: 30001 + certificateID: 0 +webdavRunAs: + user: 568 + group: 568 +webdavStorage: + shares: []