summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--designateclient/cli/base.py4
-rw-r--r--designateclient/cli/domains.py20
-rw-r--r--designateclient/cli/records.py31
-rw-r--r--designateclient/tests/test_utils.py64
-rw-r--r--designateclient/utils.py22
-rw-r--r--test-requirements.txt1
6 files changed, 123 insertions, 19 deletions
diff --git a/designateclient/cli/base.py b/designateclient/cli/base.py
index 3fb3323..b01ae0d 100644
--- a/designateclient/cli/base.py
+++ b/designateclient/cli/base.py
@@ -82,6 +82,10 @@ class Command(CliffCommand):
results = self.execute(parsed_args)
return self.post_execute(results)
+ def find_resourceid_by_name_or_id(self, resource_plural, name_or_id):
+ resource_client = getattr(self.client, resource_plural)
+ return utils.find_resourceid_by_name_or_id(resource_client, name_or_id)
+
class ListCommand(Command, Lister):
columns = None
diff --git a/designateclient/cli/domains.py b/designateclient/cli/domains.py
index fed6e3a..f848e1e 100644
--- a/designateclient/cli/domains.py
+++ b/designateclient/cli/domains.py
@@ -37,12 +37,13 @@ class GetDomainCommand(base.GetCommand):
def get_parser(self, prog_name):
parser = super(GetDomainCommand, self).get_parser(prog_name)
- parser.add_argument('id', help="Domain ID")
+ parser.add_argument('id', help="Domain ID or Name")
return parser
def execute(self, parsed_args):
- return self.client.domains.get(parsed_args.id)
+ id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
+ return self.client.domains.get(id)
class CreateDomainCommand(base.CreateCommand):
@@ -79,7 +80,7 @@ class UpdateDomainCommand(base.UpdateCommand):
def get_parser(self, prog_name):
parser = super(UpdateDomainCommand, self).get_parser(prog_name)
- parser.add_argument('id', help="Domain ID")
+ parser.add_argument('id', help="Domain ID or Name")
parser.add_argument('--name', help="Domain Name")
parser.add_argument('--email', help="Domain Email")
parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)")
@@ -91,7 +92,8 @@ class UpdateDomainCommand(base.UpdateCommand):
def execute(self, parsed_args):
# TODO(kiall): API needs updating.. this get is silly
- domain = self.client.domains.get(parsed_args.id)
+ id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
+ domain = self.client.domains.get(id)
if parsed_args.name:
domain.name = parsed_args.name
@@ -116,12 +118,13 @@ class DeleteDomainCommand(base.DeleteCommand):
def get_parser(self, prog_name):
parser = super(DeleteDomainCommand, self).get_parser(prog_name)
- parser.add_argument('id', help="Domain ID")
+ parser.add_argument('id', help="Domain ID or Name")
return parser
def execute(self, parsed_args):
- return self.client.domains.delete(parsed_args.id)
+ id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
+ return self.client.domains.delete(id)
class ListDomainServersCommand(base.ListCommand):
@@ -132,9 +135,10 @@ class ListDomainServersCommand(base.ListCommand):
def get_parser(self, prog_name):
parser = super(ListDomainServersCommand, self).get_parser(prog_name)
- parser.add_argument('id', help="Domain ID")
+ parser.add_argument('id', help="Domain ID or Name")
return parser
def execute(self, parsed_args):
- return self.client.domains.list_domain_servers(parsed_args.id)
+ id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
+ return self.client.domains.list_domain_servers(id)
diff --git a/designateclient/cli/records.py b/designateclient/cli/records.py
index ef8b6af..9e94137 100644
--- a/designateclient/cli/records.py
+++ b/designateclient/cli/records.py
@@ -30,12 +30,14 @@ class ListRecordsCommand(base.ListCommand):
def get_parser(self, prog_name):
parser = super(ListRecordsCommand, self).get_parser(prog_name)
- parser.add_argument('domain_id', help="Domain ID")
+ parser.add_argument('domain_id', help="Domain ID or Name")
return parser
def execute(self, parsed_args):
- return self.client.records.list(parsed_args.domain_id)
+ domain_id = self.find_resourceid_by_name_or_id(
+ 'domains', parsed_args.domain_id)
+ return self.client.records.list(domain_id)
class GetRecordCommand(base.GetCommand):
@@ -44,13 +46,15 @@ class GetRecordCommand(base.GetCommand):
def get_parser(self, prog_name):
parser = super(GetRecordCommand, self).get_parser(prog_name)
- parser.add_argument('domain_id', help="Domain ID")
+ parser.add_argument('domain_id', help="Domain ID or Name")
parser.add_argument('id', help="Record ID")
return parser
def execute(self, parsed_args):
- return self.client.records.get(parsed_args.domain_id, parsed_args.id)
+ domain_id = self.find_resourceid_by_name_or_id(
+ 'domains', parsed_args.domain_id)
+ return self.client.records.get(domain_id, parsed_args.id)
class CreateRecordCommand(base.CreateCommand):
@@ -59,7 +63,7 @@ class CreateRecordCommand(base.CreateCommand):
def get_parser(self, prog_name):
parser = super(CreateRecordCommand, self).get_parser(prog_name)
- parser.add_argument('domain_id', help="Domain ID")
+ parser.add_argument('domain_id', help="Domain ID or Name")
parser.add_argument('--name', help="Record Name", required=True)
parser.add_argument('--type', help="Record Type", required=True)
parser.add_argument('--data', help="Record Data", required=True)
@@ -85,7 +89,9 @@ class CreateRecordCommand(base.CreateCommand):
if parsed_args.description:
record.description = parsed_args.description
- return self.client.records.create(parsed_args.domain_id, record)
+ domain_id = self.find_resourceid_by_name_or_id(
+ 'domains', parsed_args.domain_id)
+ return self.client.records.create(domain_id, record)
class UpdateRecordCommand(base.UpdateCommand):
@@ -94,7 +100,7 @@ class UpdateRecordCommand(base.UpdateCommand):
def get_parser(self, prog_name):
parser = super(UpdateRecordCommand, self).get_parser(prog_name)
- parser.add_argument('domain_id', help="Domain ID")
+ parser.add_argument('domain_id', help="Domain ID or Name")
parser.add_argument('id', help="Record ID")
parser.add_argument('--name', help="Record Name")
parser.add_argument('--type', help="Record Type")
@@ -144,7 +150,9 @@ class UpdateRecordCommand(base.UpdateCommand):
elif parsed_args.description:
record.description = parsed_args.description
- return self.client.records.update(parsed_args.domain_id, record)
+ domain_id = self.find_resourceid_by_name_or_id(
+ 'domains', parsed_args.domain_id)
+ return self.client.records.update(domain_id, record)
class DeleteRecordCommand(base.DeleteCommand):
@@ -153,11 +161,12 @@ class DeleteRecordCommand(base.DeleteCommand):
def get_parser(self, prog_name):
parser = super(DeleteRecordCommand, self).get_parser(prog_name)
- parser.add_argument('domain_id', help="Domain ID")
+ parser.add_argument('domain_id', help="Domain ID or Name")
parser.add_argument('id', help="Record ID")
return parser
def execute(self, parsed_args):
- return self.client.records.delete(parsed_args.domain_id,
- parsed_args.id)
+ domain_id = self.find_resourceid_by_name_or_id(
+ 'domains', parsed_args.domain_id)
+ return self.client.records.delete(domain_id, parsed_args.id)
diff --git a/designateclient/tests/test_utils.py b/designateclient/tests/test_utils.py
new file mode 100644
index 0000000..359d0e1
--- /dev/null
+++ b/designateclient/tests/test_utils.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2015 Thales Services SAS
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import uuid
+
+import mock
+
+
+from designateclient import exceptions
+from designateclient.tests import base
+from designateclient import utils
+
+
+LIST_MOCK_RESPONSE = [
+ {'id': '13579bdf-0000-0000-abcd-000000000001', 'name': 'abcd'},
+ {'id': '13579bdf-0000-0000-baba-000000000001', 'name': 'baba'},
+ {'id': '13579bdf-0000-0000-baba-000000000002', 'name': 'baba'},
+]
+
+
+class UtilsTestCase(base.TestCase):
+
+ def _find_resourceid_by_name_or_id(self, name_or_id, by_name=False):
+ resource_client = mock.Mock()
+ resource_client.list.return_value = LIST_MOCK_RESPONSE
+ resourceid = utils.find_resourceid_by_name_or_id(
+ resource_client, name_or_id)
+ self.assertEqual(by_name, resource_client.list.called)
+ return resourceid
+
+ def test_find_resourceid_with_hyphen_uuid(self):
+ expected = str(uuid.uuid4())
+ observed = self._find_resourceid_by_name_or_id(expected)
+ self.assertEqual(expected, observed)
+
+ def test_find_resourceid_with_nonhyphen_uuid(self):
+ expected = str(uuid.uuid4())
+ fakeid = expected.replace('-', '')
+ observed = self._find_resourceid_by_name_or_id(fakeid)
+ self.assertEqual(expected, observed)
+
+ def test_find_resourceid_with_unique_resource(self):
+ observed = self._find_resourceid_by_name_or_id('abcd', by_name=True)
+ self.assertEqual('13579bdf-0000-0000-abcd-000000000001', observed)
+
+ def test_find_resourceid_with_nonexistent_resource(self):
+ self.assertRaises(exceptions.ResourceNotFound,
+ self._find_resourceid_by_name_or_id,
+ 'taz', by_name=True)
+
+ def test_find_resourceid_with_multiple_resources(self):
+ self.assertRaises(exceptions.NoUniqueMatch,
+ self._find_resourceid_by_name_or_id,
+ 'baba', by_name=True)
diff --git a/designateclient/utils.py b/designateclient/utils.py
index e2414a7..dfba0a8 100644
--- a/designateclient/utils.py
+++ b/designateclient/utils.py
@@ -16,6 +16,7 @@
import json
import os
+import uuid
from keystoneclient.auth.identity import generic
@@ -141,3 +142,24 @@ def get_session(auth_url, endpoint, domain_id, domain_name, project_id,
session.all_tenants = all_tenants
return session
+
+
+def find_resourceid_by_name_or_id(resource_client, name_or_id):
+ """Find resource id from its id or name."""
+ try:
+ # Try to return a uuid
+ return str(uuid.UUID(name_or_id))
+ except ValueError:
+ # Not a uuid => asume it is resource name
+ pass
+
+ resources = resource_client.list()
+ candidate_ids = [r['id'] for r in resources if r.get('name') == name_or_id]
+ if not candidate_ids:
+ raise exceptions.ResourceNotFound(
+ 'Could not find resource with name "%s"' % name_or_id)
+ elif len(candidate_ids) > 1:
+ str_ids = ','.join(candidate_ids)
+ raise exceptions.NoUniqueMatch(
+ 'Multiple resources with name "%s": %s' % (name_or_id, str_ids))
+ return candidate_ids[0]
diff --git a/test-requirements.txt b/test-requirements.txt
index bd75774..7ec707c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -4,6 +4,7 @@
# Hacking already pins down pep8, pyflakes and flake8
hacking>=0.9.2,<0.10
coverage>=3.6
+mock>=1.0
discover
oslotest>=1.5.1
python-subunit>=0.0.18