Merge ~pjdc/charm-k8s-mattermost/+git/charm-k8s-mattermost:tls-ingress into charm-k8s-mattermost:master

Proposed by Paul Collins
Status: Merged
Approved by: Paul Collins
Approved revision: 9d239270fd5c6b29ea4634da2973cd009dda2894
Merged at revision: d855a543029c60512cba58eed2684fd0989f6634
Proposed branch: ~pjdc/charm-k8s-mattermost/+git/charm-k8s-mattermost:tls-ingress
Merge into: charm-k8s-mattermost:master
Prerequisite: ~pjdc/charm-k8s-mattermost/+git/charm-k8s-mattermost:siteurl
Diff against target: 169 lines (+91/-28)
2 files modified
config.yaml (+7/-4)
src/charm.py (+84/-24)
Reviewer Review Type Date Requested Status
Paul Collins me Approve
Stuart Bishop (community) Approve
Canonical IS Reviewers Pending
Review via email: mp+384520@code.launchpad.net

Commit message

create ingress ourselves so that we can enable TLS

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Stuart Bishop (stub) wrote :

Looks good. Needs a minor tweak to simplify some code, and consideration on if we actually want mattermost_port to be configurable. Is there any reason to choose non-default ports except to confuse people?

review: Approve
Revision history for this message
Tom Haddon (mthaddon) wrote :

One comment about non-leader status

Revision history for this message
Paul Collins (pjdc) :
Revision history for this message
Paul Collins (pjdc) wrote :

self-approving due to rebase

review: Approve (me)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision d855a543029c60512cba58eed2684fd0989f6634

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/config.yaml b/config.yaml
index 733c53d..1bb6bca 100644
--- a/config.yaml
+++ b/config.yaml
@@ -1,8 +1,4 @@
1options:1options:
2 mattermost_port:
3 type: int
4 description: The port number for Mattermost to listen to.
5 default: 8000
6 open_server:2 open_server:
7 type: boolean3 type: boolean
8 description: Allows users to sign up from the root page without an invite4 description: Allows users to sign up from the root page without an invite
@@ -14,3 +10,10 @@ options:
1410
15 For more information, see https://docs.mattermost.com/administration/config-settings.html#site-url11 For more information, see https://docs.mattermost.com/administration/config-settings.html#site-url
16 default: ''12 default: ''
13 tls_secret_name:
14 type: string
15 description: |
16 The name of the Kubernetes secret to be associated with the ingress resource.
17
18 This setting is ignored unless site_url begins with "https".
19 default: ''
diff --git a/src/charm.py b/src/charm.py
index 230651c..5aae587 100755
--- a/src/charm.py
+++ b/src/charm.py
@@ -3,6 +3,8 @@
3import sys3import sys
4sys.path.append('lib') # noqa: E4024sys.path.append('lib') # noqa: E402
55
6from urllib.parse import urlparse
7
6from ops.charm import (8from ops.charm import (
7 CharmBase,9 CharmBase,
8 CharmEvents,10 CharmEvents,
@@ -26,6 +28,7 @@ import logging
26logger = logging.getLogger()28logger = logging.getLogger()
2729
2830
31CONTAINER_PORT = 8000
29DATABASE_NAME = 'mattermost'32DATABASE_NAME = 'mattermost'
3033
3134
@@ -97,22 +100,27 @@ class MattermostK8sCharm(CharmBase):
97100
98 # TODO(pjdc): Emit event when we add support for read replicas.101 # TODO(pjdc): Emit event when we add support for read replicas.
99102
100 def configure_pod(self, event):103 def _make_pod_spec(self):
101 if not self.state.db_uri:104 mattermost_image_details = self.mattermost_image.fetch()
102 self.model.unit.status = WaitingStatus('Waiting for database relation')105 pod_spec = {
103 event.defer()106 'version': 2, # otherwise resources are ignored
104 return107 'containers': [{
108 'name': self.app.name,
109 'imageDetails': mattermost_image_details,
110 'ports': [{
111 'containerPort': CONTAINER_PORT,
112 'protocol': 'TCP',
113 }],
114 'config': self._make_pod_config(),
115 }]
116 }
105117
106 if not self.framework.model.unit.is_leader():118 return pod_spec
107 self.model.unit.status = WaitingStatus('Not a leader')
108 return
109119
110 mattermost_image_details = self.mattermost_image.fetch()120 def _make_pod_config(self):
111 self.model.unit.status = MaintenanceStatus('Configuring pod')
112 config = self.model.config121 config = self.model.config
113
114 pod_config = {122 pod_config = {
115 'MATTERMOST_HTTPD_LISTEN_PORT': int(config['mattermost_port']),123 'MATTERMOST_HTTPD_LISTEN_PORT': CONTAINER_PORT,
116 'MM_SQLSETTINGS_DATASOURCE': self.state.db_uri,124 'MM_SQLSETTINGS_DATASOURCE': self.state.db_uri,
117 'MM_ENABLEOPENSERVER': config['open_server'],125 'MM_ENABLEOPENSERVER': config['open_server'],
118 }126 }
@@ -120,19 +128,71 @@ class MattermostK8sCharm(CharmBase):
120 if config['site_url']:128 if config['site_url']:
121 pod_config['MM_SERVICESETTINGS_SITEURL'] = config['site_url']129 pod_config['MM_SERVICESETTINGS_SITEURL'] = config['site_url']
122130
123 self.model.pod.set_spec({131 return pod_config
124 'containers': [{132
125 'name': self.framework.model.app.name,133 def _make_k8s_resources(self):
126 'imageDetails': mattermost_image_details,134 site_url = self.model.config['site_url']
127 'ports': [{135 if not site_url:
128 'containerPort': int(self.framework.model.config['mattermost_port']),136 return None
129 'protocol': 'TCP',137 parsed = urlparse(site_url)
130 }],138
131 'config': pod_config,139 if parsed.scheme.startswith('http'):
132 }]140 ingress = {
133 })141 "name": self.app.name,
142 "spec": {
143 "rules": [{
144 "host": parsed.hostname,
145 "http": {
146 "paths": [{
147 "path": "/",
148 "backend": {
149 "serviceName": self.app.name,
150 "servicePort": CONTAINER_PORT,
151 }
152 }]
153 }
154 }]
155 }
156 }
157 if parsed.scheme == 'https':
158 ingress['spec']['tls'] = [
159 {
160 'hosts': [parsed.hostname],
161 }
162 ]
163 tls_secret_name = self.model.config['tls_secret_name']
164 if tls_secret_name:
165 ingress['spec']['tls'][0]['secretName'] = tls_secret_name
166
167 return {
168 "kubernetesResources": {
169 "ingressResources": [ingress],
170 }
171 }
172
173 def configure_pod(self, event):
174 if not self.state.db_uri:
175 self.unit.status = WaitingStatus('Waiting for database relation')
176 event.defer()
177 return
178
179 if not self.unit.is_leader():
180 self.unit.status = ActiveStatus()
181 return
182
183 self.unit.status = MaintenanceStatus('Configuring pod')
184
185 pod_spec = self._make_pod_spec()
186
187 # Due to https://github.com/canonical/operator/issues/293 we
188 # can't use pod.set_spec's k8s_resources argument.
189 k8s_resources = self._make_k8s_resources()
190 if k8s_resources:
191 pod_spec.update(k8s_resources)
192
193 self.model.pod.set_spec(pod_spec)
134 self.state.is_started = True194 self.state.is_started = True
135 self.model.unit.status = ActiveStatus()195 self.unit.status = ActiveStatus()
136196
137197
138if __name__ == '__main__':198if __name__ == '__main__':

Subscribers

People subscribed via source and target branches