diff --git a/CHANGELOG.md b/CHANGELOG.md index 73ec6ca3..7f58b40a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +- node class: add ability to add, modify, and delete node labels + ## 3.3.13 - docs: fix doc and add autobuild diff --git a/jenkinsapi/node.py b/jenkinsapi/node.py index cfeda98d..4faa34ca 100644 --- a/jenkinsapi/node.py +++ b/jenkinsapi/node.py @@ -390,6 +390,43 @@ def get_labels(self) -> str | None: """ return self.get_config_element("label") + def add_labels(self, labels: str | list) -> None: + """Adds new label(s) to a node""" + if isinstance(labels, str): + labels = labels.split() + current_labels = self.get_labels() or "" + current_labels_set = set(current_labels.split()) + updated_labels_set = current_labels_set.union(labels) + updated_labels = " ".join(sorted(updated_labels_set)) + self.set_config_element("label", updated_labels) + self.poll() + + def modify_labels(self, new_labels: str | list[str]) -> None: + """ + Replaces the current node labels with new label(s). + + :param new_labels: A string of space-separated labels or a list of labels to set. + """ + if isinstance(new_labels, list): + new_labels = " ".join(new_labels) + self.set_config_element("label", new_labels) + self.poll() + + def delete_labels(self, labels_to_remove: str | list[str]) -> None: + """ + Removes label(s) from the node. + + :param labels_to_remove: A string of space-separated labels or a list of labels to remove. + """ + if isinstance(labels_to_remove, str): + labels_to_remove = labels_to_remove.split() + current_labels = self.get_labels() or "" + current_labels_set = set(current_labels.split()) + updated_labels_set = current_labels_set.difference(labels_to_remove) + updated_labels = " ".join(sorted(updated_labels_set)) + self.set_config_element("label", updated_labels) + self.poll() + def get_num_executors(self) -> str: try: return self.get_config_element("numExecutors") diff --git a/jenkinsapi_tests/systests/test_nodes.py b/jenkinsapi_tests/systests/test_nodes.py index 2cdcce9b..e2114622 100644 --- a/jenkinsapi_tests/systests/test_nodes.py +++ b/jenkinsapi_tests/systests/test_nodes.py @@ -142,6 +142,87 @@ def test_get_node_labels(jenkins): del jenkins.nodes[node_name] +def test_add_node_labels(jenkins): + node_name = random_string() + extra_label = random_string() + node_labels = "LABEL1 LABEL2" + node_dict = { + "num_executors": 1, + "node_description": "Test Node with Labels", + "remote_fs": "/tmp", + "labels": node_labels, + "exclusive": True, + } + node = jenkins.nodes.create_node(node_name, node_dict) + node.add_labels(extra_label) + assert node.get_labels() == " ".join([node_labels, extra_label]) + + del jenkins.nodes[node_name] + + +def test_add_list_node_labels(jenkins): + node_name = random_string() + extra_labels = [random_string(), random_string()] + node_labels = "LABEL1 LABEL2" + node_dict = { + "num_executors": 1, + "node_description": "Test Node with Labels", + "remote_fs": "/tmp", + "labels": node_labels, + "exclusive": True, + } + node = jenkins.nodes.create_node(node_name, node_dict) + node.add_labels(extra_labels) + labels_on_node = node.get_labels().split(" ") + for label in extra_labels + node_labels.split(" "): + assert label in labels_on_node + + del jenkins.nodes[node_name] + + +def test_modify_node_labels(jenkins): + node_name = random_string() + extra_label = random_string() + node_labels = "LABEL1 LABEL2" + node_dict = { + "num_executors": 1, + "node_description": "Test Node with Labels", + "remote_fs": "/tmp", + "labels": node_labels, + "exclusive": True, + } + node = jenkins.nodes.create_node(node_name, node_dict) + node.modify_labels(extra_label) + assert node.get_labels() == extra_label + + del jenkins.nodes[node_name] + + +def test_delete_list_node_labels(jenkins): + node_name = random_string() + extra_labels = [random_string(), random_string()] + node_labels = "LABEL1 LABEL2" + node_dict = { + "num_executors": 1, + "node_description": "Test Node with Labels", + "remote_fs": "/tmp", + "labels": node_labels, + "exclusive": True, + } + node = jenkins.nodes.create_node(node_name, node_dict) + node.add_labels(extra_labels) + labels_on_node = node.get_labels().split(" ") + for label in extra_labels + node_labels.split(" "): + assert label in labels_on_node + node.delete_labels(extra_labels) + + labels_on_node = node.get_labels().split(" ") + for label in node_labels.split(" "): + assert label in labels_on_node + + del jenkins.nodes[node_name] + + def test_get_executors(jenkins): node_name = random_string() node_labels = "LABEL1 LABEL2"