11# Copyright 2021 Canonical Ltd.
22# See LICENSE file for licensing details.
33
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+
14411"""
14512
14613import logging
@@ -167,7 +34,7 @@ def setUp(self, *unused):
16734
16835# Increment this PATCH version before using `charmcraft publish-lib` or reset
16936# to 0 if you are raising the major API version
170- LIBPATCH = 12
37+ LIBPATCH = 13
17138
17239ServiceType = Literal ["ClusterIP" , "LoadBalancer" ]
17340
@@ -205,6 +72,11 @@ def __init__(
20572 will be observed to re-apply the patch (e.g. on port change).
20673 The `install` and `upgrade-charm` events would be observed regardless.
20774 """
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+ )
20880 super ().__init__ (charm , "kubernetes-service-patch" )
20981 self .charm = charm
21082 self .service_name = service_name or self ._app
0 commit comments