From 07d9fbf7a2acb8bdf8c0c53eb28bbe74c99636ce Mon Sep 17 00:00:00 2001
From: Sheogorath <sheogorath@shivering-isles.com>
Date: Thu, 25 Jan 2024 00:45:58 +0100
Subject: [PATCH] chore(mok): Move dovecot config to helm chart

This patch moves the dovecot config from the container build to the helm
chart which allows to use templating with values that are configured at
runtime. This should provide more flexibility and standardizes the
dovecot container further.
---
 charts/mok/Chart.yaml                         |   2 +-
 charts/mok/README.md                          |   6 +-
 charts/mok/templates/dovecot-config.yaml      | 135 +++++++++++++++
 charts/mok/templates/dovecot.yaml             |   7 +
 .../tests/__snapshot__/dovecot_test.yaml.snap | 156 +++++++++++++++++-
 charts/mok/tests/dovecot_test.yaml            |   1 +
 charts/mok/values.yaml                        |   2 +-
 images/dovecot/.release                       |   2 +-
 images/dovecot/Earthfile                      |   2 -
 images/dovecot/README.md                      |  11 --
 images/dovecot/config/dovecot.conf            | 126 --------------
 11 files changed, 300 insertions(+), 150 deletions(-)
 create mode 100644 charts/mok/templates/dovecot-config.yaml
 delete mode 100644 images/dovecot/config/dovecot.conf

diff --git a/charts/mok/Chart.yaml b/charts/mok/Chart.yaml
index 3a1066f8d..7ab775d4c 100644
--- a/charts/mok/Chart.yaml
+++ b/charts/mok/Chart.yaml
@@ -3,7 +3,7 @@ name: mok
 description: |
   Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that runs without a database server on Kubernetes, taking advantage of configmaps and secret.
 type: application
-version: 0.11.1
+version: 0.12.0
 sources:
   - https://de.postfix.org/ftpmirror/index.html
   - https://github.com/dovecot/core
diff --git a/charts/mok/README.md b/charts/mok/README.md
index f41007ea3..8e3bc8f30 100644
--- a/charts/mok/README.md
+++ b/charts/mok/README.md
@@ -1,6 +1,6 @@
 # mok
 
-![Version: 0.11.1](https://img.shields.io/badge/Version-0.11.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
+![Version: 0.12.0](https://img.shields.io/badge/Version-0.12.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
 
 Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that runs without a database server on Kubernetes, taking advantage of configmaps and secret.
 
@@ -23,7 +23,7 @@ Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that run
 | dovecot.affinity | object | `{}` |  |
 | dovecot.image.pullPolicy | string | `"IfNotPresent"` |  |
 | dovecot.image.repository | string | `"quay.io/shivering-isles/dovecot"` | dovecot container image |
-| dovecot.image.tag | string | `"0.3.2"` | Overrides the image tag whose default is "latest" |
+| dovecot.image.tag | string | `"0.4.0"` | Overrides the image tag whose default is "latest" |
 | dovecot.imagePullSecrets | list | `[]` | pull secret to access the afore defined image |
 | dovecot.nodeSelector | object | `{}` |  |
 | dovecot.podAnnotations | object | `{}` |  |
@@ -93,4 +93,4 @@ Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that run
 | serviceAccount.name | string | `""` |  |
 
 ----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0)
diff --git a/charts/mok/templates/dovecot-config.yaml b/charts/mok/templates/dovecot-config.yaml
new file mode 100644
index 000000000..7d0e521ec
--- /dev/null
+++ b/charts/mok/templates/dovecot-config.yaml
@@ -0,0 +1,135 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "mok.fullname" . }}-dovecot
+  labels:
+    {{- include "mok.labels" . | nindent 4 }}
+    app.kubernetes.io/component: dovecot
+data:
+  dovecot.conf: |
+    auth_mechanisms = plain login
+    disable_plaintext_auth = no
+    info_log_path = /dev/stdout
+    log_path = /dev/stderr
+
+    ## Mailbox location
+
+    mail_gid = vmail
+    mail_home = /srv/mail/mailboxes/%d/%n
+    mail_location = maildir:~/mail:LAYOUT=fs
+    mail_privileged_group = vmail
+    mail_uid = vmail
+
+    ## Sieve
+
+    managesieve_notify_capability = mailto
+    managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext imapsieve vnd.dovecot.imapsieve
+
+    ## Inbox
+
+    namespace inbox {
+      inbox = yes
+      location =
+      mailbox Drafts {
+        auto = subscribe
+        special_use = \Drafts
+      }
+      mailbox Sent {
+        auto = subscribe
+        special_use = \Sent
+      }
+      mailbox Spam {
+        auto = subscribe
+        special_use = \Junk
+      }
+      mailbox Trash {
+        auto = subscribe
+        special_use = \Trash
+      }
+      prefix =
+    }
+
+    ## Authentication
+
+    passdb {
+      args = scheme=ARGON2ID /srv/passdb/passwd
+      driver = passwd-file
+    }
+
+    ## Plugins
+
+    plugin {
+      imapsieve_mailbox1_before = file:/srv/mail/sieve/global/learn-spam.sieve
+      imapsieve_mailbox1_causes = COPY
+      imapsieve_mailbox1_name = Spam
+      imapsieve_mailbox2_before = file:/srv/mail/sieve/global/learn-ham.sieve
+      imapsieve_mailbox2_causes = COPY
+      imapsieve_mailbox2_from = Spam
+      imapsieve_mailbox2_name = *
+      quota = maildir:User quota
+      quota_exceeded_message = User %u has exhausted allowed storage space.
+      sieve = file:/srv/mail/sieve/%d/%n/scripts;active=/srv/mail/sieve/%d/%n/active-script.sieve
+      sieve_before = /srv/mail/sieve/global/spam-global.sieve
+      sieve_global_extensions = +vnd.dovecot.pipe
+      sieve_pipe_bin_dir = /usr/bin
+      sieve_plugins = sieve_imapsieve sieve_extprograms
+    }
+
+    ## Services
+
+    protocols = imap lmtp sieve
+    service auth {
+      inet_listener {
+        port = 12345
+      }
+      vsz_limit = 2 G
+    }
+    service imap-login {
+      inet_listener imap {
+        port = 143
+      }
+    }
+    service lmtp {
+      inet_listener lmtp {
+        port = 24
+      }
+    }
+    service managesieve-login {
+      inet_listener sieve {
+        port = 4190
+      }
+    }
+    service stats {
+      inet_listener http {
+        port = 9090
+      }
+    }
+
+    ## TLS
+
+    ssl = required
+    ssl_cert = </srv/tls/tls.crt
+    ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
+    ssl_key = </srv/tls/tls.key
+    ssl_prefer_server_ciphers = yes
+
+    ## Users
+
+    userdb {
+      args = uid=5000 gid=5000 home=/srv/mail/mailboxes/%d/%n allow_all_users=yes
+      driver = static
+    }
+
+    verbose_proctitle = yes
+
+    ## Protocols
+
+    protocol imap {
+      imap_idle_notify_interval = 5 mins
+      mail_max_userip_connections = 20
+      mail_plugins = " quota imap_quota imap_sieve"
+    }
+    protocol lmtp {
+      mail_plugins = " sieve"
+      postmaster_address = postmaster@mysystems.tld
+    }
diff --git a/charts/mok/templates/dovecot.yaml b/charts/mok/templates/dovecot.yaml
index 9950dda22..5cf3739c7 100644
--- a/charts/mok/templates/dovecot.yaml
+++ b/charts/mok/templates/dovecot.yaml
@@ -115,6 +115,10 @@ spec:
             - name: tls
               mountPath: "/srv/tls/"
               readOnly: true
+            - name: config
+              mountPath: /etc/dovecot/dovecot.conf
+              subPath: dovecot.conf
+              readOnly: true
       {{- with .Values.dovecot.nodeSelector }}
       nodeSelector:
         {{- toYaml . | nindent 8 }}
@@ -128,6 +132,9 @@ spec:
         {{- toYaml . | nindent 8 }}
       {{- end }}
       volumes:
+        - name: config
+          configMap:
+            name: {{ include "mok.fullname" . }}-dovecot
         - name: vmail
           persistentVolumeClaim:
             claimName: {{ include "mok.fullname" . }}-dovecot-vmail
diff --git a/charts/mok/tests/__snapshot__/dovecot_test.yaml.snap b/charts/mok/tests/__snapshot__/dovecot_test.yaml.snap
index dedef7148..96a8af42e 100644
--- a/charts/mok/tests/__snapshot__/dovecot_test.yaml.snap
+++ b/charts/mok/tests/__snapshot__/dovecot_test.yaml.snap
@@ -1,5 +1,144 @@
 should match snapshot:
   1: |
+    apiVersion: v1
+    data:
+      dovecot.conf: |
+        auth_mechanisms = plain login
+        disable_plaintext_auth = no
+        info_log_path = /dev/stdout
+        log_path = /dev/stderr
+
+        ## Mailbox location
+
+        mail_gid = vmail
+        mail_home = /srv/mail/mailboxes/%d/%n
+        mail_location = maildir:~/mail:LAYOUT=fs
+        mail_privileged_group = vmail
+        mail_uid = vmail
+
+        ## Sieve
+
+        managesieve_notify_capability = mailto
+        managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext imapsieve vnd.dovecot.imapsieve
+
+        ## Inbox
+
+        namespace inbox {
+          inbox = yes
+          location =
+          mailbox Drafts {
+            auto = subscribe
+            special_use = \Drafts
+          }
+          mailbox Sent {
+            auto = subscribe
+            special_use = \Sent
+          }
+          mailbox Spam {
+            auto = subscribe
+            special_use = \Junk
+          }
+          mailbox Trash {
+            auto = subscribe
+            special_use = \Trash
+          }
+          prefix =
+        }
+
+        ## Authentication
+
+        passdb {
+          args = scheme=ARGON2ID /srv/passdb/passwd
+          driver = passwd-file
+        }
+
+        ## Plugins
+
+        plugin {
+          imapsieve_mailbox1_before = file:/srv/mail/sieve/global/learn-spam.sieve
+          imapsieve_mailbox1_causes = COPY
+          imapsieve_mailbox1_name = Spam
+          imapsieve_mailbox2_before = file:/srv/mail/sieve/global/learn-ham.sieve
+          imapsieve_mailbox2_causes = COPY
+          imapsieve_mailbox2_from = Spam
+          imapsieve_mailbox2_name = *
+          quota = maildir:User quota
+          quota_exceeded_message = User %u has exhausted allowed storage space.
+          sieve = file:/srv/mail/sieve/%d/%n/scripts;active=/srv/mail/sieve/%d/%n/active-script.sieve
+          sieve_before = /srv/mail/sieve/global/spam-global.sieve
+          sieve_global_extensions = +vnd.dovecot.pipe
+          sieve_pipe_bin_dir = /usr/bin
+          sieve_plugins = sieve_imapsieve sieve_extprograms
+        }
+
+        ## Services
+
+        protocols = imap lmtp sieve
+        service auth {
+          inet_listener {
+            port = 12345
+          }
+          vsz_limit = 2 G
+        }
+        service imap-login {
+          inet_listener imap {
+            port = 143
+          }
+        }
+        service lmtp {
+          inet_listener lmtp {
+            port = 24
+          }
+        }
+        service managesieve-login {
+          inet_listener sieve {
+            port = 4190
+          }
+        }
+        service stats {
+          inet_listener http {
+            port = 9090
+          }
+        }
+
+        ## TLS
+
+        ssl = required
+        ssl_cert = </srv/tls/tls.crt
+        ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
+        ssl_key = </srv/tls/tls.key
+        ssl_prefer_server_ciphers = yes
+
+        ## Users
+
+        userdb {
+          args = uid=5000 gid=5000 home=/srv/mail/mailboxes/%d/%n allow_all_users=yes
+          driver = static
+        }
+
+        verbose_proctitle = yes
+
+        ## Protocols
+
+        protocol imap {
+          imap_idle_notify_interval = 5 mins
+          mail_max_userip_connections = 20
+          mail_plugins = " quota imap_quota imap_sieve"
+        }
+        protocol lmtp {
+          mail_plugins = " sieve"
+          postmaster_address = postmaster@mysystems.tld
+        }
+    kind: ConfigMap
+    metadata:
+      labels:
+        app.kubernetes.io/component: dovecot
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mok
+        helm.sh/chart: mok-1.2.3
+      name: RELEASE-NAME-mok-dovecot
+  2: |
     apiVersion: v1
     kind: Service
     metadata:
@@ -32,7 +171,7 @@ should match snapshot:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/name: mok
       type: LoadBalancer
-  2: |
+  3: |
     apiVersion: v1
     kind: Service
     metadata:
@@ -56,7 +195,7 @@ should match snapshot:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/name: mok
       type: ClusterIP
-  3: |
+  4: |
     apiVersion: apps/v1
     kind: Deployment
     metadata:
@@ -135,10 +274,17 @@ should match snapshot:
                 - mountPath: /srv/tls/
                   name: tls
                   readOnly: true
+                - mountPath: /etc/dovecot/dovecot.conf
+                  name: config
+                  readOnly: true
+                  subPath: dovecot.conf
           securityContext: {}
           serviceAccountName: RELEASE-NAME-mok
           terminationGracePeriodSeconds: 300
           volumes:
+            - configMap:
+                name: RELEASE-NAME-mok-dovecot
+              name: config
             - name: vmail
               persistentVolumeClaim:
                 claimName: RELEASE-NAME-mok-dovecot-vmail
@@ -148,7 +294,7 @@ should match snapshot:
             - name: tls
               secret:
                 secretName: example-tls
-  4: |
+  5: |
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
@@ -166,7 +312,7 @@ should match snapshot:
         requests:
           storage: 5Gi
       volumeMode: Filesystem
-  5: |
+  6: |
     apiVersion: v1
     kind: Secret
     metadata:
@@ -180,7 +326,7 @@ should match snapshot:
     stringData:
       passwd: ""
     type: Opaque
-  6: |
+  7: |
     apiVersion: v1
     kind: Secret
     metadata:
diff --git a/charts/mok/tests/dovecot_test.yaml b/charts/mok/tests/dovecot_test.yaml
index 7b4f890d8..a11892df5 100644
--- a/charts/mok/tests/dovecot_test.yaml
+++ b/charts/mok/tests/dovecot_test.yaml
@@ -1,5 +1,6 @@
 suite: Dovecot
 templates:
+  - dovecot-config.yaml
   - dovecot.yaml
   - persistentvolumeclaim.yaml
   - secret.yaml
diff --git a/charts/mok/values.yaml b/charts/mok/values.yaml
index dac8e6b27..e5e10135b 100644
--- a/charts/mok/values.yaml
+++ b/charts/mok/values.yaml
@@ -126,7 +126,7 @@ dovecot:
     repository: quay.io/shivering-isles/dovecot
     pullPolicy: IfNotPresent
     # -- Overrides the image tag whose default is "latest"
-    tag: "0.3.2"
+    tag: "0.4.0"
 
   # -- pull secret to access the afore defined image
   imagePullSecrets: []
diff --git a/images/dovecot/.release b/images/dovecot/.release
index c0fd37de2..9ecf65833 100644
--- a/images/dovecot/.release
+++ b/images/dovecot/.release
@@ -1 +1 @@
-release=0.3.2
+release=0.4.0
diff --git a/images/dovecot/Earthfile b/images/dovecot/Earthfile
index afb3bf13a..d79209b7b 100644
--- a/images/dovecot/Earthfile
+++ b/images/dovecot/Earthfile
@@ -19,8 +19,6 @@ container:
         dovecot-pigeonhole-plugin \
         dovecot-lmtpd
 
-    COPY config/dovecot.conf /etc/dovecot/
-
     ENV USER=vmail
     ENV UID=5000
     ENV GID=5000
diff --git a/images/dovecot/README.md b/images/dovecot/README.md
index bcc8cad94..cff0a6009 100644
--- a/images/dovecot/README.md
+++ b/images/dovecot/README.md
@@ -3,17 +3,6 @@ dovecot
 
 Simple dovecot container, build with the intend to be used in combination with Kubernetes. This means the image on its own might not be useful. It doesn't come with external database backend.
 
-Expectations
----
-
-This container image expects some paths to be in place:
-
-|Path | Usage |
-|-----|-------|
-|`/srv/mail/mailboxes/`|Storage for recieved emails|
-|`/srv/passdb/`|Password database storage using `passwd` backend|
-|`/srv/tls/`|TLS key and certificate used for TLS enabled services|
-
 References
 ---
 
diff --git a/images/dovecot/config/dovecot.conf b/images/dovecot/config/dovecot.conf
deleted file mode 100644
index fda92e08d..000000000
--- a/images/dovecot/config/dovecot.conf
+++ /dev/null
@@ -1,126 +0,0 @@
-auth_mechanisms = plain login
-disable_plaintext_auth = no
-info_log_path = /dev/stdout
-log_path = /dev/stderr
-
-## Mailbox location
-
-mail_gid = vmail
-mail_home = /srv/mail/mailboxes/%d/%n
-mail_location = maildir:~/mail:LAYOUT=fs
-mail_privileged_group = vmail
-mail_uid = vmail
-
-## Sieve
-
-managesieve_notify_capability = mailto
-managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext imapsieve vnd.dovecot.imapsieve
-
-## Inbox
-
-namespace inbox {
-  inbox = yes
-  location =
-  mailbox Drafts {
-    auto = subscribe
-    special_use = \Drafts
-  }
-  mailbox Sent {
-    auto = subscribe
-    special_use = \Sent
-  }
-  mailbox Spam {
-    auto = subscribe
-    special_use = \Junk
-  }
-  mailbox Trash {
-    auto = subscribe
-    special_use = \Trash
-  }
-  prefix =
-}
-
-## Authentication
-
-passdb {
-  args = scheme=ARGON2ID /srv/passdb/passwd
-  driver = passwd-file
-}
-
-## Plugins
-
-plugin {
-  imapsieve_mailbox1_before = file:/srv/mail/sieve/global/learn-spam.sieve
-  imapsieve_mailbox1_causes = COPY
-  imapsieve_mailbox1_name = Spam
-  imapsieve_mailbox2_before = file:/srv/mail/sieve/global/learn-ham.sieve
-  imapsieve_mailbox2_causes = COPY
-  imapsieve_mailbox2_from = Spam
-  imapsieve_mailbox2_name = *
-  quota = maildir:User quota
-  quota_exceeded_message = User %u has exhausted allowed storage space.
-  sieve = file:/srv/mail/sieve/%d/%n/scripts;active=/srv/mail/sieve/%d/%n/active-script.sieve
-  sieve_before = /srv/mail/sieve/global/spam-global.sieve
-  sieve_global_extensions = +vnd.dovecot.pipe
-  sieve_pipe_bin_dir = /usr/bin
-  sieve_plugins = sieve_imapsieve sieve_extprograms
-}
-
-## Services
-
-protocols = imap lmtp sieve
-service auth {
-  inet_listener {
-    port = 12345
-  }
-  vsz_limit = 2 G
-}
-service imap-login {
-  inet_listener imap {
-    port = 143
-  }
-}
-service lmtp {
-  inet_listener lmtp {
-    port = 24
-  }
-}
-service managesieve-login {
-  inet_listener sieve {
-    port = 4190
-  }
-}
-service stats {
-  inet_listener http {
-    port = 9090
-  }
-}
-
-## TLS
-
-ssl = required
-ssl_cert = </srv/tls/tls.crt
-ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
-ssl_key = </srv/tls/tls.key
-ssl_prefer_server_ciphers = yes
-
-## Users
-
-userdb {
-  args = uid=5000 gid=5000 home=/srv/mail/mailboxes/%d/%n allow_all_users=yes
-  driver = static
-}
-
-verbose_proctitle = yes
-
-## Protocols
-
-protocol imap {
-  imap_idle_notify_interval = 5 mins
-  mail_max_userip_connections = 20
-  mail_plugins = " quota imap_quota imap_sieve"
-}
-protocol lmtp {
-  mail_plugins = " sieve"
-  postmaster_address = postmaster@mysystems.tld
-}
-- 
GitLab