1
1
# Copyright 2021 Canonical Ltd.
2
2
# See LICENSE file for licensing details.
3
3
4
- """# KubernetesServicePatch Library.
5
-
6
- This library is designed to enable developers to more simply patch the Kubernetes Service created
7
- by Juju during the deployment of a sidecar charm. When sidecar charms are deployed, Juju creates a
8
- service named after the application in the namespace (named after the Juju model). This service by
9
- default contains a "placeholder" port, which is 65535/TCP.
10
-
11
- When modifying the default set of resources managed by Juju, one must consider the lifecycle of the
12
- charm. In this case, any modifications to the default service (created during deployment), will be
13
- overwritten during a charm upgrade.
14
-
15
- When initialised, this library binds a handler to the parent charm's `install` and `upgrade_charm`
16
- events which applies the patch to the cluster. This should ensure that the service ports are
17
- correct throughout the charm's life.
18
-
19
- The constructor simply takes a reference to the parent charm, and a list of
20
- [`lightkube`](https://github.com/gtsystem/lightkube) ServicePorts that each define a port for the
21
- service. For information regarding the `lightkube` `ServicePort` model, please visit the
22
- `lightkube` [docs](https://gtsystem.github.io/lightkube-models/1.23/models/core_v1/#serviceport).
23
-
24
- Optionally, a name of the service (in case service name needs to be patched as well), labels,
25
- selectors, and annotations can be provided as keyword arguments.
26
-
27
- ## Getting Started
28
-
29
- To get started using the library, you just need to fetch the library using `charmcraft`. **Note
30
- that you also need to add `lightkube` and `lightkube-models` to your charm's `requirements.txt`.**
31
-
32
- ```shell
33
- cd some-charm
34
- charmcraft fetch-lib charms.observability_libs.v1.kubernetes_service_patch
35
- cat << EOF >> requirements.txt
36
- lightkube
37
- lightkube-models
38
- EOF
39
- ```
40
-
41
- Then, to initialise the library:
42
-
43
- For `ClusterIP` services:
44
-
45
- ```python
46
- # ...
47
- from charms.observability_libs.v1.kubernetes_service_patch import KubernetesServicePatch
48
- from lightkube.models.core_v1 import ServicePort
49
-
50
- class SomeCharm(CharmBase):
51
- def __init__(self, *args):
52
- # ...
53
- port = ServicePort(443, name=f"{self.app.name}")
54
- self.service_patcher = KubernetesServicePatch(self, [port])
55
- # ...
56
- ```
57
-
58
- For `LoadBalancer`/`NodePort` services:
59
-
60
- ```python
61
- # ...
62
- from charms.observability_libs.v1.kubernetes_service_patch import KubernetesServicePatch
63
- from lightkube.models.core_v1 import ServicePort
64
-
65
- class SomeCharm(CharmBase):
66
- def __init__(self, *args):
67
- # ...
68
- port = ServicePort(443, name=f"{self.app.name}", targetPort=443, nodePort=30666)
69
- self.service_patcher = KubernetesServicePatch(
70
- self, [port], "LoadBalancer"
71
- )
72
- # ...
73
- ```
74
-
75
- Port protocols can also be specified. Valid protocols are `"TCP"`, `"UDP"`, and `"SCTP"`
76
-
77
- ```python
78
- # ...
79
- from charms.observability_libs.v1.kubernetes_service_patch import KubernetesServicePatch
80
- from lightkube.models.core_v1 import ServicePort
81
-
82
- class SomeCharm(CharmBase):
83
- def __init__(self, *args):
84
- # ...
85
- tcp = ServicePort(443, name=f"{self.app.name}-tcp", protocol="TCP")
86
- udp = ServicePort(443, name=f"{self.app.name}-udp", protocol="UDP")
87
- sctp = ServicePort(443, name=f"{self.app.name}-sctp", protocol="SCTP")
88
- self.service_patcher = KubernetesServicePatch(self, [tcp, udp, sctp])
89
- # ...
90
- ```
91
-
92
- Bound with custom events by providing `refresh_event` argument:
93
- For example, you would like to have a configurable port in your charm and want to apply
94
- service patch every time charm config is changed.
95
-
96
- ```python
97
- from charms.observability_libs.v1.kubernetes_service_patch import KubernetesServicePatch
98
- from lightkube.models.core_v1 import ServicePort
99
-
100
- class SomeCharm(CharmBase):
101
- def __init__(self, *args):
102
- # ...
103
- port = ServicePort(int(self.config["charm-config-port"]), name=f"{self.app.name}")
104
- self.service_patcher = KubernetesServicePatch(
105
- self,
106
- [port],
107
- refresh_event=self.on.config_changed
108
- )
109
- # ...
110
- ```
111
-
112
- Creating a new k8s lb service instead of patching the one created by juju
113
- Service name is optional. If not provided, it defaults to {app_name}-lb.
114
- If provided and equal to app_name, it also defaults to {app_name}-lb to prevent conflicts with the Juju default service.
115
- ```python
116
- from charms.observability_libs.v1.kubernetes_service_patch import KubernetesServicePatch
117
- from lightkube.models.core_v1 import ServicePort
118
-
119
- class SomeCharm(CharmBase):
120
- def __init__(self, *args):
121
- # ...
122
- port = ServicePort(int(self.config["charm-config-port"]), name=f"{self.app.name}")
123
- self.service_patcher = KubernetesServicePatch(
124
- self,
125
- [port],
126
- service_type="LoadBalancer",
127
- service_name="application-lb"
128
- )
129
- # ...
130
- ```
131
-
132
- Additionally, you may wish to use mocks in your charm's unit testing to ensure that the library
133
- does not try to make any API calls, or open any files during testing that are unlikely to be
134
- present, and could break your tests. The easiest way to do this is during your test `setUp`:
135
-
136
- ```python
137
- # ...
138
-
139
- @patch("charm.KubernetesServicePatch", lambda x, y: None)
140
- def setUp(self, *unused):
141
- self.harness = Harness(SomeCharm)
142
- # ...
143
- ```
4
+ """# [DEPRECATED!] KubernetesServicePatch Library.
5
+
6
+ The `kubernetes_service_patch` library is DEPRECATED and will be removed in October 2025.
7
+
8
+ For patching the Kubernetes service created by Juju during the deployment of a charm,
9
+ `ops.Unit.set_ports` functionality should be used instead.
10
+
144
11
"""
145
12
146
13
import logging
@@ -167,7 +34,7 @@ def setUp(self, *unused):
167
34
168
35
# Increment this PATCH version before using `charmcraft publish-lib` or reset
169
36
# to 0 if you are raising the major API version
170
- LIBPATCH = 12
37
+ LIBPATCH = 13
171
38
172
39
ServiceType = Literal ["ClusterIP" , "LoadBalancer" ]
173
40
@@ -205,6 +72,11 @@ def __init__(
205
72
will be observed to re-apply the patch (e.g. on port change).
206
73
The `install` and `upgrade-charm` events would be observed regardless.
207
74
"""
75
+ logger .warning (
76
+ "The ``kubernetes_service_patch v1`` library is DEPRECATED and will be removed "
77
+ "in October 2025. For patching the Kubernetes service created by Juju during "
78
+ "the deployment of a charm, ``ops.Unit.set_ports`` functionality should be used instead."
79
+ )
208
80
super ().__init__ (charm , "kubernetes-service-patch" )
209
81
self .charm = charm
210
82
self .service_name = service_name or self ._app
0 commit comments