summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2016-12-05 13:33:41 -0800
committerJoffrey F <joffrey@docker.com>2016-12-07 12:24:18 -0800
commitc239e4050425394b20970998d3c33776621a90a7 (patch)
treea5fbfa3280c716841cdf5269c105d8d8beb89402
parentd56b2d3dc87b3d12fad197fa2cd19f3ea3f7e5d1 (diff)
downloaddocker-py-c239e4050425394b20970998d3c33776621a90a7.tar.gz
Implement swarm node removalremove_node
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r--docker/api/swarm.py28
-rw-r--r--docker/models/nodes.py19
-rw-r--r--tests/integration/api_swarm_test.py17
3 files changed, 64 insertions, 0 deletions
diff --git a/docker/api/swarm.py b/docker/api/swarm.py
index 6a1b752..9a240a9 100644
--- a/docker/api/swarm.py
+++ b/docker/api/swarm.py
@@ -224,6 +224,33 @@ class SwarmApiMixin(object):
return self._result(self._get(url, params=params), True)
+ @utils.check_resource
+ @utils.minimum_version('1.24')
+ def remove_node(self, node_id, force=False):
+ """
+ Remove a node from the swarm.
+
+ Args:
+ node_id (string): ID of the node to be removed.
+ force (bool): Force remove an active node. Default: `False`
+
+ Raises:
+ :py:class:`docker.errors.NotFound`
+ If the node referenced doesn't exist in the swarm.
+
+ :py:class:`docker.errors.APIError`
+ If the server returns an error.
+ Returns:
+ `True` if the request was successful.
+ """
+ url = self._url('/nodes/{0}', node_id)
+ params = {
+ 'force': force
+ }
+ res = self._delete(url, params=params)
+ self._raise_for_status(res)
+ return True
+
@utils.minimum_version('1.24')
def update_node(self, node_id, version, node_spec=None):
"""
@@ -231,6 +258,7 @@ class SwarmApiMixin(object):
Args:
+ node_id (string): ID of the node to be updated.
version (int): The version number of the node object being
updated. This is required to avoid conflicting writes.
node_spec (dict): Configuration settings to update. Any values
diff --git a/docker/models/nodes.py b/docker/models/nodes.py
index 0887f99..8dd9350 100644
--- a/docker/models/nodes.py
+++ b/docker/models/nodes.py
@@ -41,6 +41,25 @@ class Node(Model):
"""
return self.client.api.update_node(self.id, self.version, node_spec)
+ def remove(self, force=False):
+ """
+ Remove this node from the swarm.
+
+ Args:
+ force (bool): Force remove an active node. Default: `False`
+
+ Returns:
+ `True` if the request was successful.
+
+ Raises:
+ :py:class:`docker.errors.NotFound`
+ If the node doesn't exist in the swarm.
+
+ :py:class:`docker.errors.APIError`
+ If the server returns an error.
+ """
+ return self.client.api.remove_node(self.id, force=force)
+
class NodeCollection(Collection):
"""Nodes on the Docker server."""
diff --git a/tests/integration/api_swarm_test.py b/tests/integration/api_swarm_test.py
index 24c566f..a10437b 100644
--- a/tests/integration/api_swarm_test.py
+++ b/tests/integration/api_swarm_test.py
@@ -159,3 +159,20 @@ class SwarmTest(BaseAPIIntegrationTest):
node_spec=orig_spec)
reverted_node = self.client.inspect_node(node['ID'])
assert orig_spec == reverted_node['Spec']
+
+ @requires_api_version('1.24')
+ def test_remove_main_node(self):
+ assert self.client.init_swarm('eth0')
+ nodes_list = self.client.nodes()
+ node_id = nodes_list[0]['ID']
+ with pytest.raises(docker.errors.NotFound):
+ self.client.remove_node('foobar01')
+ with pytest.raises(docker.errors.APIError) as e:
+ self.client.remove_node(node_id)
+
+ assert e.value.response.status_code == 500
+
+ with pytest.raises(docker.errors.APIError) as e:
+ self.client.remove_node(node_id, True)
+
+ assert e.value.response.status_code == 500