Skip to content
This repository was archived by the owner on Jan 20, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dockercloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from dockercloud.api.exceptions import ApiError, AuthError, ObjectNotFound, NonUniqueIdentifier
from dockercloud.api.utils import Utils
from dockercloud.api.events import Events
from dockercloud.api.swarm import Swarm
from dockercloud.api.nodeaz import AZ

__version__ = '1.0.9'
Expand Down
2 changes: 1 addition & 1 deletion dockercloud/api/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def send_request(method, path, inject_header=True, **kwargs):
# Try to parse the response.
try:
json = response.json()
if response.headers and inject_header:
if response.headers and inject_header and response.headers.get("X-DockerCloud-Action-URI"):
json["dockercloud_action_uri"] = response.headers.get("X-DockerCloud-Action-URI", "")
except TypeError:
raise ApiError("JSON Parse Error (%s %s). Response: %s" % (method, url, response.text))
Expand Down
8 changes: 8 additions & 0 deletions dockercloud/api/swarm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from __future__ import absolute_import

from .base import Mutable


class Swarm(Mutable):
subsystem = "infra"
endpoint = "/swarm"
28 changes: 28 additions & 0 deletions dockercloud/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .nodecluster import NodeCluster
from .service import Service
from .stack import Stack
from .swarm import Swarm


def is_uuid4(identifier):
Expand Down Expand Up @@ -191,3 +192,30 @@ def fetch_remote_action(identifier, raise_exceptions=True):
if not raise_exceptions:
return e
raise e

@staticmethod
def fetch_remote_swarm(identifier, raise_exceptions=True):
try:
terms = identifier.split("/", 1)
if len(terms) == 1:
namespace = ""
name = identifier
else:
namespace = terms[0]
name = terms[1]
try:
return Swarm.fetch(name, namespace=namespace)
except Exception:
objects_same_identifier = Swarm.list(name__startswith=name, namespace=namespace)
if len(objects_same_identifier) == 1:
swarm_id = objects_same_identifier[0].swarm_id
return Swarm.fetch(swarm_id, namespace=namespace)
elif len(objects_same_identifier) == 0:
raise ObjectNotFound("Cannot find a swarm cluster with name '%s'" % identifier)
raise NonUniqueIdentifier(
"More than one action has the same identifier, please use swarm id")

except (NonUniqueIdentifier, ObjectNotFound) as e:
if not raise_exceptions:
return e
raise e
31 changes: 31 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,34 @@ def test_fetch_remote_nodecluster(self, mock_fetch, mock_list):
mock_list.side_effect = [ApiError, ApiError]
self.assertRaises(ApiError, dockercloud.Utils.fetch_remote_nodecluster, 'uuid_or_name', True)
self.assertRaises(ApiError, dockercloud.Utils.fetch_remote_nodecluster, 'uuid_or_name', False)

@mock.patch('dockercloud.Swarm.list')
@mock.patch('dockercloud.Swarm.fetch')
def test_fetch_remote_swarm(self, mock_fetch, mock_list):
# test the identifier w/ and w/o namespace
mock_fetch.return_value = 'returned'
self.assertEqual(dockercloud.Utils.fetch_remote_swarm('abc', True), 'returned')
mock_fetch.assert_called_with("abc", namespace="")

self.assertEqual(dockercloud.Utils.fetch_remote_swarm('tifayuki/abc', True), 'returned')
mock_fetch.assert_called_with("abc", namespace="tifayuki")

self.assertEqual(dockercloud.Utils.fetch_remote_swarm('tifayuki/abc/xyz', True), 'returned')
mock_fetch.assert_called_with("abc/xyz", namespace="tifayuki")

# test no swarm found
mock_fetch.side_effect = ObjectNotFound
self.assertRaises(ObjectNotFound, dockercloud.Utils.fetch_remote_swarm, 'swarm_id', True)
self.assertIsInstance(dockercloud.Utils.fetch_remote_swarm('swarm_id', False), ObjectNotFound)

# test multi-swarm found
mock_fetch.return_value = 'returned'
mock_list.side_effect = [['swarm1', 'swarm2'], []]
self.assertRaises(NonUniqueIdentifier, dockercloud.Utils.fetch_remote_swarm, 'swarm_id', True)
mock_list.side_effect = [['swarm1', 'swarm2'], []]
self.assertIsInstance(dockercloud.Utils.fetch_remote_swarm('swarm_id', False), NonUniqueIdentifier)

# test api error
mock_list.side_effect = [ApiError, ApiError]
self.assertRaises(ApiError, dockercloud.Utils.fetch_remote_swarm, 'swarm_id', True)
self.assertRaises(ApiError, dockercloud.Utils.fetch_remote_swarm, 'swarm_id', False)