Skip to content

Commit

Permalink
the snaps set the node-role labels, the charm only now worries about …
Browse files Browse the repository at this point in the history
…custom labels (#34)
  • Loading branch information
addyess authored Mar 4, 2024
1 parent a241e92 commit a32b33a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Since the same charm code is executed on the worker and control-plane, in some u

This repo uses `pytest` and `pytest-operator` to execute functional/integration tests against the charm files. The integration tests are defined in `./tests/integration`. Because this repo consists of two charms, the integration tests will build two charm files automatically without you doing anything. If you want to use specific charm files, just make sure the `.charm` files are in the top-level paths and the integration tests will find them if they are named appropriately (eg `./k8s-worker_*.charm` or `k8s_*.charm`). The charms are deployed according to the bundle defined in `./tests/integration/test-bundle.yaml`.

It's required you have a bootstrapped [juju machine controller](https://juju.is/docs/juju/manage-controllers) available. Usually, one prefers to have a controller available from their development machine to a supported cloud like `lxd` or `aws`. You can test if the controller is available by runnning:
It's required you have a bootstrapped [juju machine controller](https://juju.is/docs/juju/manage-controllers) available. Usually, one prefers to have a controller available from their development machine to a supported cloud like `lxd` or `aws`. You can test if the controller is available by running:

```shell
juju status -m controller
Expand Down Expand Up @@ -117,6 +117,6 @@ tox run -e integration-tests -- --positional --arguments
`-k regex-pattern`: run a specific set of matching tests names ignore other passing tests
Remember that cloud costs could be incurred for every machine -- so be sure to clean up your models on clouds if you instruct pytest-operator to not clean up the models.

See [pytest-operator](https://github.com/charmed-kubernetes/pytest-operator/blob/main/docs/reference.md) and [pytest](https://docs.pytest.org/en/7.1.x/contents.html) for more documenation on `pytest` arguments
See [pytest-operator](https://github.com/charmed-kubernetes/pytest-operator/blob/main/docs/reference.md) and [pytest](https://docs.pytest.org/en/7.1.x/contents.html) for more documentation on `pytest` arguments


2 changes: 1 addition & 1 deletion charms/worker/k8s/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ config:
type: string
description: Snap channel of the k8s snap
labels:
default: "node-role.kubernetes.io/control-plane="
default: ""
type: string
description: |
Labels can be used to organize and to select subsets of nodes in the
Expand Down
8 changes: 5 additions & 3 deletions charms/worker/k8s/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ def __init__(self, *args):
self.reconciler = Reconciler(self, self._reconcile)
self.distributor = TokenDistributor(self, self.get_node_name(), self.api_manager)
self.collector = TokenCollector(self, self.get_node_name())
self.labeler = LabelMaker(
self, kubeconfig_path=self._source_kubeconfig, kubectl=KUBECTL_PATH
)
self._stored.set_default(removing=False)

self.cos_agent = COSAgentProvider(
Expand Down Expand Up @@ -438,9 +441,8 @@ def _apply_node_labels(self):
"""Apply labels to the node."""
status.add(ops.MaintenanceStatus("Apply Node Labels"))
node = self.get_node_name()
labeler = LabelMaker(self, kubeconfig_path=self._source_kubeconfig, kubectl=KUBECTL_PATH)
if labeler.active_labels() is not None:
labeler.apply_node_labels()
if self.labeler.active_labels() is not None:
self.labeler.apply_node_labels()
log.info("Node %s labelled successfully", node)
else:
log.info("Node %s not yet labelled", node)
Expand Down
35 changes: 27 additions & 8 deletions tests/integration/test_k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import logging

import pytest
from juju import model
from juju import application, model
from tenacity import retry, stop_after_attempt, wait_fixed

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -83,16 +83,35 @@ async def test_nodes_ready(kubernetes_cluster: model.Model):
await ready_nodes(k8s.units[0], expected_nodes)


async def test_nodes_labelled(kubernetes_cluster):
async def test_nodes_labelled(request, kubernetes_cluster: model.Model):
"""Test the charms label the nodes appropriately."""
k8s = kubernetes_cluster.applications["k8s"]
worker = kubernetes_cluster.applications["k8s-worker"]
testname: str = request.node.name
k8s: application.Application = kubernetes_cluster.applications["k8s"]
worker: application.Application = kubernetes_cluster.applications["k8s-worker"]
label_config = {"labels": f"{testname}="}
await asyncio.gather(k8s.set_config(label_config), worker.set_config(label_config))
await kubernetes_cluster.wait_for_idle(status="active", timeout=5 * 60)

try:
nodes = await get_nodes(k8s.units[0])
labelled = [n for n in nodes if testname in n["metadata"]["labels"]]
juju_nodes = [n for n in nodes if "juju-charm" in n["metadata"]["labels"]]
assert len(k8s.units + worker.units) == len(
labelled
), "Not all nodes labeled with custom-label"
assert len(k8s.units + worker.units) == len(
juju_nodes
), "Not all nodes labeled as juju-charms"
finally:
await asyncio.gather(
k8s.reset_config(list(label_config)), worker.reset_config(list(label_config))
)

await kubernetes_cluster.wait_for_idle(status="active", timeout=5 * 60)
nodes = await get_nodes(k8s.units[0])
control_plane_label = "node-role.kubernetes.io/control-plane"
control_plane = [n for n in nodes if control_plane_label in n["metadata"]["labels"]]
assert len(k8s.units) == len(control_plane), "Not all control-plane nodes labeled"
labelled = [n for n in nodes if testname in n["metadata"]["labels"]]
juju_nodes = [n for n in nodes if "juju-charm" in n["metadata"]["labels"]]
assert len(k8s.units + worker.units) == len(juju_nodes), "Not all nodes labeled as juju-charms"
assert 0 == len(labelled), "Not all nodes labeled with custom-label"


@pytest.mark.abort_on_fail
Expand Down

0 comments on commit a32b33a

Please sign in to comment.