Merge ~jose-phillips/charm-k8s-ingress:master into charm-k8s-ingress:master

Proposed by Jose Phillips
Status: Rejected
Rejected by: Haw Loeung
Proposed branch: ~jose-phillips/charm-k8s-ingress:master
Merge into: charm-k8s-ingress:master
Diff against target: 118 lines (+35/-1)
4 files modified
.gitignore (+1/-0)
config.yaml (+9/-0)
lib/charms/nginx_ingress_integrator/v0/ingress.py (+2/-0)
src/charm.py (+23/-1)
Reviewer Review Type Date Requested Status
Tom Haddon Needs Information
Review via email: mp+413495@code.launchpad.net

Commit message

Allow custom annotations on charms

with this patch you can apply custom annotations for the k8s nginx controller

Closes #1955596
fix bug #1955596

Description of the change

With this patch will allow custom annotations for the nginx controller

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.

294711c... by Jose Phillips

Removed a hardcoded custom annotation

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

So far we've avoided taking the path of allowing freeform annotations to be added. While allowing freeform changes like this offers more flexibility, it is a little more error prone and means the specific options aren't as well documented, so the charm author needs to know more about the specific options. As an example, you have the following in config.yaml:

'{"nginx.ingress.kubernetes.io/ssl-passthrough": "True", "nginx.ingress.kubernetes.io/proxy-http-version': "1.1"}'

But if each was a separate option it would be exposed as such in `lib/charms/nginx_ingress_integrator/v0/ingress.py`.

Can you provide a bit more background on which options you'd need to use and why?

review: Needs Information
Revision history for this message
Jose Phillips (jose-phillips) wrote :

i understand that every option can be more easily for users and developers but Annotations can came from another plugin or requirement.

we start needing some options like Client certificate etc but we also required cert-manager that is a complete annotation out of the scope of the kubernetes ingress documentantion example.
 "cert-manager.io/cluster-issuer" also another internal plugins annotations required for the application that we are developing.

closing this as a normal configuration will lock some developers that they can't use this charm for addons required on the ingress controller.

as the annotations are just key value i don't think can be a issue.

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

Hi Jose,

Sorry for the delay in updates here. I need to discuss this with some other people and should have a chance to do that next week. I'll update here once I have more information.

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

Adding this to the relation is a bit problematic for the reasons mentioned above:
- It's error prone (there's even a typo in the example you include in config.yaml :) ).
- The list of things the relation supports is no longer documented in a straightforward way because you can also do anything you want via this freeform option.
- You need to be careful of collisions between existing options and the custom annotations.
- If you add something to the relation as an explicit option which someone was previously specifying via custom annotations how do you deal with that?

Anything that we add to the relation ties us to supporting that for this charm as well as any other charms that implement this relation.

However, we could add it as config, which would mean your deployment scenario is supported, just not directly via the relation. If you're okay with that, please update the merge proposal to only implement this as config (if so we'll want to check someone isn't specifying something via custom annotations that they can specify via explicit config/relations, and we'll also want to update unit tests to cover this), and I'll re-review.

Unmerged commits

294711c... by Jose Phillips

Removed a hardcoded custom annotation

0fff935... by Jose Phillips

Allow custom relations on charms

with this patch you can apply custom annotations for the k8s nginx controller

Closes #1955596

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2index ca38d73..6d3c0ea 100644
3--- a/.gitignore
4+++ b/.gitignore
5@@ -4,3 +4,4 @@
6 .tox
7 .coverage
8 __pycache__
9+build
10\ No newline at end of file
11diff --git a/config.yaml b/config.yaml
12index 9e95591..8110a1d 100644
13--- a/config.yaml
14+++ b/config.yaml
15@@ -94,3 +94,12 @@ options:
16 default: ""
17 description: The name of the TLS secret to use. Leaving this empty will configure an ingress with TLS disabled.
18 type: string
19+ custom-annotations:
20+ default: ""
21+ description: >
22+ JSON dictionary containing the keys and values to set as annotation in the ingress resource.
23+ Please see: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
24+ Example:
25+ '{"nginx.ingress.kubernetes.io/ssl-passthrough": "True", "nginx.ingress.kubernetes.io/proxy-http-version': "1.1"}'
26+ type: string
27+
28\ No newline at end of file
29diff --git a/lib/charms/nginx_ingress_integrator/v0/ingress.py b/lib/charms/nginx_ingress_integrator/v0/ingress.py
30index 1871e20..1eb9ce7 100644
31--- a/lib/charms/nginx_ingress_integrator/v0/ingress.py
32+++ b/lib/charms/nginx_ingress_integrator/v0/ingress.py
33@@ -22,6 +22,7 @@ Import `IngressRequires` in your charm, with two required options:
34 - service-namespace
35 - session-cookie-max-age
36 - tls-secret-name
37+ - custom-annotations
38
39 See [the config section](https://charmhub.io/nginx-ingress-integrator/configure) for descriptions
40 of each, along with the required type.
41@@ -87,6 +88,7 @@ OPTIONAL_INGRESS_RELATION_FIELDS = {
42 "session-cookie-max-age",
43 "tls-secret-name",
44 "path-routes",
45+ "custom-annotations"
46 }
47
48
49diff --git a/src/charm.py b/src/charm.py
50index 38a5255..2661bc6 100755
51--- a/src/charm.py
52+++ b/src/charm.py
53@@ -3,6 +3,7 @@
54 # See LICENSE file for licensing details.
55
56 import logging
57+import json
58
59 import kubernetes.client
60
61@@ -176,6 +177,13 @@ class NginxIngressCharm(CharmBase):
62 """Return the tls-secret-name to use for k8s ingress (if any)."""
63 return self._get_config_or_relation_data("tls-secret-name", "")
64
65+ @property
66+ def _custom_annotations(self):
67+ """Return the custom annotations to use for k8s ingress (if any)."""
68+
69+ return self._get_config_or_relation_data("custom-annotations", "")
70+
71+
72 def k8s_auth(self):
73 """Authenticate to kubernetes."""
74 if self._authed:
75@@ -259,6 +267,10 @@ class NginxIngressCharm(CharmBase):
76 self._service_name.upper()
77 )
78 annotations["nginx.ingress.kubernetes.io/session-cookie-samesite"] = "Lax"
79+ if self._custom_annotations != "":
80+ values=json.loads(self._custom_annotations)
81+ for key , value in values.items():
82+ annotations[key] = value
83 if self._tls_secret_name:
84 spec.tls = [
85 kubernetes.client.V1IngressTLS(
86@@ -417,6 +429,11 @@ class NginxIngressCharm(CharmBase):
87 msg = "Ingress with service IP(s): {}".format(
88 ", ".join(self._report_service_ips())
89 )
90+
91+ except json.JSONDecodeError as e:
92+ logger.error("Error in custom-annotations: " + str(e))
93+ self.unit.status = BlockedStatus("Invalid JSON in custom-annotations")
94+ return
95 except kubernetes.client.exceptions.ApiException as e:
96 if e.status == 403:
97 logger.error(
98@@ -439,6 +456,11 @@ class NginxIngressCharm(CharmBase):
99 try:
100 self._remove_ingress()
101 self._remove_service()
102+
103+ except json.JSONDecodeError as e:
104+ logger.error("Error in custom-annotations: " + str(e))
105+ self.unit.status = BlockedStatus("Invalid JSON in custom-annotations")
106+ return
107 except kubernetes.client.exceptions.ApiException as e:
108 if e.status == 403:
109 logger.error(
110@@ -449,7 +471,7 @@ class NginxIngressCharm(CharmBase):
111 "Insufficient permissions, try: `juju trust {} --scope=cluster`".format(
112 self.app.name
113 )
114- )
115+ )
116 return
117 else:
118 raise

Subscribers

People subscribed via source and target branches