summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/api/object_store_v1.py3
-rw-r--r--openstackclient/common/clientmanager.py73
-rw-r--r--openstackclient/common/quota.py2
-rw-r--r--openstackclient/compute/v2/hypervisor_stats.py3
-rw-r--r--openstackclient/compute/v2/server.py2
-rw-r--r--openstackclient/identity/client.py1
-rw-r--r--openstackclient/identity/common.py41
-rw-r--r--openstackclient/network/v2/subnet_pool.py1
-rw-r--r--openstackclient/object/v1/container.py1
-rw-r--r--openstackclient/tests/api/fakes.py2
-rw-r--r--openstackclient/tests/api/test_image_v1.py2
-rw-r--r--openstackclient/tests/api/test_image_v2.py2
-rw-r--r--openstackclient/tests/api/test_object_store_v1.py2
-rw-r--r--openstackclient/tests/common/test_availability_zone.py1
-rw-r--r--openstackclient/tests/common/test_extension.py5
-rw-r--r--openstackclient/tests/common/test_parseractions.py2
-rw-r--r--openstackclient/tests/common/test_quota.py7
-rw-r--r--openstackclient/tests/compute/v2/fakes.py4
-rw-r--r--openstackclient/tests/compute/v2/test_agent.py2
-rw-r--r--openstackclient/tests/compute/v2/test_flavor.py62
-rw-r--r--openstackclient/tests/compute/v2/test_server.py50
-rw-r--r--openstackclient/tests/fakes.py2
-rw-r--r--openstackclient/tests/identity/v2_0/test_endpoint.py3
-rw-r--r--openstackclient/tests/identity/v2_0/test_service.py47
-rw-r--r--openstackclient/tests/identity/v3/fakes.py103
-rw-r--r--openstackclient/tests/identity/v3/test_credential.py292
-rw-r--r--openstackclient/tests/identity/v3/test_identity_provider.py1
-rw-r--r--openstackclient/tests/identity/v3/test_mappings.py1
-rw-r--r--openstackclient/tests/identity/v3/test_service.py34
-rw-r--r--openstackclient/tests/identity/v3/test_user.py1
-rw-r--r--openstackclient/tests/image/v2/test_image.py117
-rw-r--r--openstackclient/tests/network/v2/test_address_scope.py2
-rw-r--r--openstackclient/tests/object/v1/fakes.py1
-rw-r--r--openstackclient/tests/utils.py3
-rw-r--r--openstackclient/tests/volume/v1/test_volume.py51
-rw-r--r--openstackclient/tests/volume/v2/test_snapshot.py34
-rw-r--r--openstackclient/tests/volume/v2/test_type.py61
-rw-r--r--openstackclient/tests/volume/v2/test_volume.py151
-rw-r--r--openstackclient/volume/client.py1
-rw-r--r--openstackclient/volume/v2/snapshot.py17
-rw-r--r--openstackclient/volume/v2/volume.py17
-rw-r--r--openstackclient/volume/v2/volume_type.py20
42 files changed, 833 insertions, 394 deletions
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py
index ae49922d..faa55118 100644
--- a/openstackclient/api/object_store_v1.py
+++ b/openstackclient/api/object_store_v1.py
@@ -17,11 +17,10 @@ import io
import logging
import os
+from osc_lib import utils
import six
from six.moves import urllib
-from osc_lib import utils
-
from openstackclient.api import api
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 9e4b9c93..2105a497 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -19,8 +19,6 @@ import logging
import pkg_resources
import sys
-from keystoneauth1.loading import base
-from osc_lib.api import auth
from osc_lib import clientmanager
@@ -31,77 +29,6 @@ PLUGIN_MODULES = []
USER_AGENT = 'python-openstackclient'
-# NOTE(dtroyer): Bringing back select_auth_plugin() and build_auth_params()
-# temporarily because osc-lib 0.3.0 removed it a wee bit early
-def select_auth_plugin(options):
- """Pick an auth plugin based on --os-auth-type or other options"""
-
- auth_plugin_name = None
-
- # Do the token/url check first as this must override the default
- # 'password' set by os-client-config
- # Also, url and token are not copied into o-c-c's auth dict (yet?)
- if options.auth.get('url') and options.auth.get('token'):
- # service token authentication
- auth_plugin_name = 'token_endpoint'
- elif options.auth_type in auth.PLUGIN_LIST:
- # A direct plugin name was given, use it
- auth_plugin_name = options.auth_type
- elif options.auth.get('username'):
- if options.identity_api_version == '3':
- auth_plugin_name = 'v3password'
- elif options.identity_api_version.startswith('2'):
- auth_plugin_name = 'v2password'
- else:
- # let keystoneauth figure it out itself
- auth_plugin_name = 'password'
- elif options.auth.get('token'):
- if options.identity_api_version == '3':
- auth_plugin_name = 'v3token'
- elif options.identity_api_version.startswith('2'):
- auth_plugin_name = 'v2token'
- else:
- # let keystoneauth figure it out itself
- auth_plugin_name = 'token'
- else:
- # The ultimate default is similar to the original behaviour,
- # but this time with version discovery
- auth_plugin_name = 'password'
- LOG.debug("Auth plugin %s selected", auth_plugin_name)
- return auth_plugin_name
-
-
-def build_auth_params(auth_plugin_name, cmd_options):
- if auth_plugin_name:
- LOG.debug('auth_type: %s', auth_plugin_name)
- auth_plugin_loader = base.get_plugin_loader(auth_plugin_name)
- auth_params = {
- opt.dest: opt.default
- for opt in base.get_plugin_options(auth_plugin_name)
- }
- auth_params.update(dict(cmd_options.auth))
- # grab tenant from project for v2.0 API compatibility
- if auth_plugin_name.startswith("v2"):
- if 'project_id' in auth_params:
- auth_params['tenant_id'] = auth_params['project_id']
- del auth_params['project_id']
- if 'project_name' in auth_params:
- auth_params['tenant_name'] = auth_params['project_name']
- del auth_params['project_name']
- else:
- LOG.debug('no auth_type')
- # delay the plugin choice, grab every option
- auth_plugin_loader = None
- auth_params = dict(cmd_options.auth)
- plugin_options = set(
- [o.replace('-', '_') for o in auth.get_options_list()]
- )
- for option in plugin_options:
- LOG.debug('fetching option %s', option)
- auth_params[option] = getattr(cmd_options.auth, option, None)
- return (auth_plugin_loader, auth_params)
-
-
class ClientManager(clientmanager.ClientManager):
"""Manages access to API clients, including authentication
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 3c12c366..5d53171c 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -38,6 +38,8 @@ COMPUTE_QUOTAS = {
'key_pairs': 'key-pairs',
'metadata_items': 'properties',
'ram': 'ram',
+ 'server_groups': 'server-groups',
+ 'server_group_members': 'server-group-members',
}
VOLUME_QUOTAS = {
diff --git a/openstackclient/compute/v2/hypervisor_stats.py b/openstackclient/compute/v2/hypervisor_stats.py
index a70f0ce1..c6fd2992 100644
--- a/openstackclient/compute/v2/hypervisor_stats.py
+++ b/openstackclient/compute/v2/hypervisor_stats.py
@@ -14,9 +14,8 @@
"""Hypervisor Stats action implementations"""
-import six
-
from osc_lib.command import command
+import six
class ShowHypervisorStats(command.ShowOne):
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 16c86bd9..3e6903b7 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -260,7 +260,7 @@ class AddServerSecurityGroup(command.Command):
parsed_args.group,
)
- server.add_security_group(security_group.name)
+ server.add_security_group(security_group.id)
class AddServerVolume(command.Command):
diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py
index d932b970..0c609313 100644
--- a/openstackclient/identity/client.py
+++ b/openstackclient/identity/client.py
@@ -21,6 +21,7 @@ from osc_lib import utils
from openstackclient.i18n import _
+
LOG = logging.getLogger(__name__)
DEFAULT_API_VERSION = '3'
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index 379f4114..1e40f396 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -30,21 +30,32 @@ def find_service(identity_client, name_type_or_id):
"""Find a service by id, name or type."""
try:
- # search for the usual ID or name
- return utils.find_resource(identity_client.services, name_type_or_id)
- except exceptions.CommandError:
- try:
- # search for service type
- return identity_client.services.find(type=name_type_or_id)
- # FIXME(dtroyer): This exception should eventually come from
- # common client exceptions
- except identity_exc.NotFound:
- msg = _("No service with a type, name or ID of '%s' exists.")
- raise exceptions.CommandError(msg % name_type_or_id)
- except identity_exc.NoUniqueMatch:
- msg = _("Multiple service matches found for '%s', "
- "use an ID to be more specific.")
- raise exceptions.CommandError(msg % name_type_or_id)
+ # search for service id
+ return identity_client.services.get(name_type_or_id)
+ except identity_exc.NotFound:
+ # ignore NotFound exception, raise others
+ pass
+
+ try:
+ # search for service name
+ return identity_client.services.find(name=name_type_or_id)
+ except identity_exc.NotFound:
+ pass
+ except identity_exc.NoUniqueMatch:
+ msg = _("Multiple service matches found for '%s', "
+ "use an ID to be more specific.")
+ raise exceptions.CommandError(msg % name_type_or_id)
+
+ try:
+ # search for service type
+ return identity_client.services.find(type=name_type_or_id)
+ except identity_exc.NotFound:
+ msg = _("No service with a type, name or ID of '%s' exists.")
+ raise exceptions.CommandError(msg % name_type_or_id)
+ except identity_exc.NoUniqueMatch:
+ msg = _("Multiple service matches found for '%s', "
+ "use an ID to be more specific.")
+ raise exceptions.CommandError(msg % name_type_or_id)
def _get_token_resource(client, resource, parsed_name):
diff --git a/openstackclient/network/v2/subnet_pool.py b/openstackclient/network/v2/subnet_pool.py
index ed2bb0ef..d3fab8ac 100644
--- a/openstackclient/network/v2/subnet_pool.py
+++ b/openstackclient/network/v2/subnet_pool.py
@@ -13,7 +13,6 @@
"""Subnet pool action implementations"""
import copy
-
import logging
from osc_lib.cli import parseractions
diff --git a/openstackclient/object/v1/container.py b/openstackclient/object/v1/container.py
index 2b021ec2..f00cc150 100644
--- a/openstackclient/object/v1/container.py
+++ b/openstackclient/object/v1/container.py
@@ -15,7 +15,6 @@
"""Container v1 action implementations"""
-
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import utils
diff --git a/openstackclient/tests/api/fakes.py b/openstackclient/tests/api/fakes.py
index e285a61c..8d1d88ff 100644
--- a/openstackclient/tests/api/fakes.py
+++ b/openstackclient/tests/api/fakes.py
@@ -13,9 +13,9 @@
"""API Test Fakes"""
+from keystoneauth1 import session
from requests_mock.contrib import fixture
-from keystoneauth1 import session
from openstackclient.tests import utils
diff --git a/openstackclient/tests/api/test_image_v1.py b/openstackclient/tests/api/test_image_v1.py
index f3479756..f8ad6692 100644
--- a/openstackclient/tests/api/test_image_v1.py
+++ b/openstackclient/tests/api/test_image_v1.py
@@ -13,9 +13,9 @@
"""Image v1 API Library Tests"""
+from keystoneauth1 import session
from requests_mock.contrib import fixture
-from keystoneauth1 import session
from openstackclient.api import image_v1
from openstackclient.tests import utils
diff --git a/openstackclient/tests/api/test_image_v2.py b/openstackclient/tests/api/test_image_v2.py
index 77063997..28b0d580 100644
--- a/openstackclient/tests/api/test_image_v2.py
+++ b/openstackclient/tests/api/test_image_v2.py
@@ -13,9 +13,9 @@
"""Image v2 API Library Tests"""
+from keystoneauth1 import session
from requests_mock.contrib import fixture
-from keystoneauth1 import session
from openstackclient.api import image_v2
from openstackclient.tests import utils
diff --git a/openstackclient/tests/api/test_object_store_v1.py b/openstackclient/tests/api/test_object_store_v1.py
index 8cc3a927..e6ac203d 100644
--- a/openstackclient/tests/api/test_object_store_v1.py
+++ b/openstackclient/tests/api/test_object_store_v1.py
@@ -15,9 +15,9 @@
import mock
+from keystoneauth1 import session
from requests_mock.contrib import fixture
-from keystoneauth1 import session
from openstackclient.api import object_store_v1 as object_store
from openstackclient.tests import utils
diff --git a/openstackclient/tests/common/test_availability_zone.py b/openstackclient/tests/common/test_availability_zone.py
index feecaf55..014ab8bc 100644
--- a/openstackclient/tests/common/test_availability_zone.py
+++ b/openstackclient/tests/common/test_availability_zone.py
@@ -12,6 +12,7 @@
#
import mock
+
import six
from openstackclient.common import availability_zone
diff --git a/openstackclient/tests/common/test_extension.py b/openstackclient/tests/common/test_extension.py
index 17a3b492..10023aa6 100644
--- a/openstackclient/tests/common/test_extension.py
+++ b/openstackclient/tests/common/test_extension.py
@@ -14,12 +14,11 @@
import mock
from openstackclient.common import extension
-from openstackclient.tests import fakes
-from openstackclient.tests import utils
-
from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
from openstackclient.tests.network.v2 import fakes as network_fakes
+from openstackclient.tests import utils
from openstackclient.tests.volume.v2 import fakes as volume_fakes
diff --git a/openstackclient/tests/common/test_parseractions.py b/openstackclient/tests/common/test_parseractions.py
index 60d4a8cf..3038701f 100644
--- a/openstackclient/tests/common/test_parseractions.py
+++ b/openstackclient/tests/common/test_parseractions.py
@@ -49,7 +49,7 @@ class TestKeyValueAction(utils.TestCase):
actual = getattr(results, 'property', {})
# All should pass through unmolested
expect = {'red': '', 'green': '100%', 'blue': '50%', 'format': '#rgb'}
- self.assertDictEqual(expect, actual)
+ self.assertEqual(expect, actual)
def test_error_values(self):
self.assertRaises(
diff --git a/openstackclient/tests/common/test_quota.py b/openstackclient/tests/common/test_quota.py
index c9ec5599..16fa35f6 100644
--- a/openstackclient/tests/common/test_quota.py
+++ b/openstackclient/tests/common/test_quota.py
@@ -11,7 +11,6 @@
# under the License.
import copy
-
import mock
from openstackclient.common import quota
@@ -116,6 +115,8 @@ class TestQuotaSet(TestQuota):
'--properties', str(compute_fakes.property_num),
'--secgroup-rules', str(compute_fakes.secgroup_rule_num),
'--secgroups', str(compute_fakes.secgroup_num),
+ '--server-groups', str(compute_fakes.servgroup_num),
+ '--server-group-members', str(compute_fakes.servgroup_members_num),
identity_fakes.project_name,
]
verifylist = [
@@ -132,6 +133,8 @@ class TestQuotaSet(TestQuota):
('metadata_items', compute_fakes.property_num),
('security_group_rules', compute_fakes.secgroup_rule_num),
('security_groups', compute_fakes.secgroup_num),
+ ('server_groups', compute_fakes.servgroup_num),
+ ('server_group_members', compute_fakes.servgroup_members_num),
('project', identity_fakes.project_name),
]
@@ -154,6 +157,8 @@ class TestQuotaSet(TestQuota):
'metadata_items': compute_fakes.property_num,
'security_group_rules': compute_fakes.secgroup_rule_num,
'security_groups': compute_fakes.secgroup_num,
+ 'server_groups': compute_fakes.servgroup_num,
+ 'server_group_members': compute_fakes.servgroup_members_num,
}
self.quotas_mock.update.assert_called_with(
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index b4243a22..85c11c94 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -36,6 +36,8 @@ instance_num = 10
property_num = 128
secgroup_rule_num = 20
secgroup_num = 10
+servgroup_num = 10
+servgroup_members_num = 10
project_name = 'project_test'
QUOTA = {
'project': project_name,
@@ -51,6 +53,8 @@ QUOTA = {
'properties': property_num,
'secgroup_rules': secgroup_rule_num,
'secgroups': secgroup_num,
+ 'server-groups': servgroup_num,
+ 'server-group-members': servgroup_members_num
}
QUOTA_columns = tuple(sorted(QUOTA))
diff --git a/openstackclient/tests/compute/v2/test_agent.py b/openstackclient/tests/compute/v2/test_agent.py
index 7695ee41..07265bb0 100644
--- a/openstackclient/tests/compute/v2/test_agent.py
+++ b/openstackclient/tests/compute/v2/test_agent.py
@@ -14,8 +14,8 @@
#
import mock
-
from mock import call
+
from osc_lib import exceptions
from openstackclient.compute.v2 import agent
diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py
index 40cd17c1..d326ea8a 100644
--- a/openstackclient/tests/compute/v2/test_flavor.py
+++ b/openstackclient/tests/compute/v2/test_flavor.py
@@ -13,7 +13,6 @@
# under the License.
#
-import copy
import mock
from mock import call
@@ -22,7 +21,6 @@ from osc_lib import utils
from openstackclient.compute.v2 import flavor
from openstackclient.tests.compute.v2 import fakes as compute_fakes
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
from openstackclient.tests import utils as tests_utils
@@ -48,7 +46,7 @@ class TestFlavorCreate(TestFlavor):
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'links': 'flavor-links'})
-
+ project = identity_fakes.FakeProject.create_one_project()
columns = (
'OS-FLV-DISABLED:disabled',
'OS-FLV-EXT-DATA:ephemeral',
@@ -80,11 +78,7 @@ class TestFlavorCreate(TestFlavor):
super(TestFlavorCreate, self).setUp()
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
self.flavors_mock.create.return_value = self.flavor
self.cmd = flavor.CreateFlavor(self.app, None)
@@ -174,7 +168,7 @@ class TestFlavorCreate(TestFlavor):
'--vcpus', str(self.flavor.vcpus),
'--rxtx-factor', str(self.flavor.rxtx_factor),
'--private',
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
'--property', 'key1=value1',
'--property', 'key2=value2',
self.flavor.name,
@@ -188,7 +182,7 @@ class TestFlavorCreate(TestFlavor):
('vcpus', self.flavor.vcpus),
('rxtx_factor', self.flavor.rxtx_factor),
('public', False),
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('property', {'key1': 'value1', 'key2': 'value2'}),
('name', self.flavor.name),
]
@@ -209,7 +203,7 @@ class TestFlavorCreate(TestFlavor):
self.flavors_mock.create.assert_called_once_with(*args)
self.flavor_access_mock.add_tenant_access.assert_called_with(
self.flavor.id,
- identity_fakes.project_id,
+ self.project.id,
)
self.flavor.set_keys.assert_called_with(
{'key1': 'value1', 'key2': 'value2'})
@@ -219,11 +213,11 @@ class TestFlavorCreate(TestFlavor):
def test_public_flavor_create_with_project(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
self.flavor.name,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('name', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -507,6 +501,7 @@ class TestFlavorSet(TestFlavor):
# Return value of self.flavors_mock.find().
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'os-flavor-access:is_public': False})
+ project = identity_fakes.FakeProject.create_one_project()
def setUp(self):
super(TestFlavorSet, self).setUp()
@@ -514,11 +509,7 @@ class TestFlavorSet(TestFlavor):
self.flavors_mock.find.return_value = self.flavor
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
self.cmd = flavor.SetFlavor(self.app, None)
def test_flavor_set_property(self):
@@ -540,11 +531,11 @@ class TestFlavorSet(TestFlavor):
def test_flavor_set_project(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
self.flavor.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -555,7 +546,7 @@ class TestFlavorSet(TestFlavor):
is_public=None)
self.flavor_access_mock.add_tenant_access.assert_called_with(
self.flavor.id,
- identity_fakes.project_id,
+ self.project.id,
)
self.flavor.set_keys.assert_not_called()
self.assertIsNone(result)
@@ -574,10 +565,10 @@ class TestFlavorSet(TestFlavor):
def test_flavor_set_no_flavor(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
@@ -587,11 +578,11 @@ class TestFlavorSet(TestFlavor):
self.flavors_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
'unexist_flavor',
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('flavor', 'unexist_flavor'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -729,6 +720,7 @@ class TestFlavorUnset(TestFlavor):
# Return value of self.flavors_mock.find().
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'os-flavor-access:is_public': False})
+ project = identity_fakes.FakeProject.create_one_project()
def setUp(self):
super(TestFlavorUnset, self).setUp()
@@ -736,11 +728,7 @@ class TestFlavorUnset(TestFlavor):
self.flavors_mock.find.return_value = self.flavor
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
self.cmd = flavor.UnsetFlavor(self.app, None)
def test_flavor_unset_property(self):
@@ -763,11 +751,11 @@ class TestFlavorUnset(TestFlavor):
def test_flavor_unset_project(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
self.flavor.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -779,7 +767,7 @@ class TestFlavorUnset(TestFlavor):
is_public=None)
self.flavor_access_mock.remove_tenant_access.assert_called_with(
self.flavor.id,
- identity_fakes.project_id,
+ self.project.id,
)
self.flavor.unset_keys.assert_not_called()
self.assertIsNone(result)
@@ -798,10 +786,10 @@ class TestFlavorUnset(TestFlavor):
def test_flavor_unset_no_flavor(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
@@ -811,11 +799,11 @@ class TestFlavorUnset(TestFlavor):
self.flavors_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
'unexist_flavor',
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('flavor', 'unexist_flavor'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py
index 9c89c6af..a98398ee 100644
--- a/openstackclient/tests/compute/v2/test_server.py
+++ b/openstackclient/tests/compute/v2/test_server.py
@@ -168,6 +168,54 @@ class TestServerAddFloatingIP(TestServer):
self.assertIsNone(result)
+class TestServerAddSecurityGroup(TestServer):
+
+ def setUp(self):
+ super(TestServerAddSecurityGroup, self).setUp()
+
+ self.security_group = \
+ compute_fakes.FakeSecurityGroup.create_one_security_group()
+ # This is the return value for utils.find_resource() for security group
+ self.security_groups_mock.get.return_value = self.security_group
+
+ attrs = {
+ 'security_groups': [{'name': self.security_group.id}]
+ }
+ methods = {
+ 'add_security_group': None,
+ }
+
+ self.server = compute_fakes.FakeServer.create_one_server(
+ attrs=attrs,
+ methods=methods
+ )
+ # This is the return value for utils.find_resource() for server
+ self.servers_mock.get.return_value = self.server
+
+ # Get the command object to test
+ self.cmd = server.AddServerSecurityGroup(self.app, None)
+
+ def test_server_add_security_group(self):
+ arglist = [
+ self.server.id,
+ self.security_group.id
+ ]
+ verifylist = [
+ ('server', self.server.id),
+ ('group', self.security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.security_groups_mock.get.assert_called_with(
+ self.security_group.id,
+ )
+ self.servers_mock.get.assert_called_with(self.server.id)
+ self.server.add_security_group.assert_called_with(
+ self.security_group.id,
+ )
+ self.assertIsNone(result)
+
+
class TestServerCreate(TestServer):
columns = (
@@ -1793,4 +1841,4 @@ class TestServerGeneral(TestServer):
server_detail.pop('networks')
# Check the results.
- self.assertDictEqual(info, server_detail)
+ self.assertEqual(info, server_detail)
diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py
index d0cab019..786cd6d4 100644
--- a/openstackclient/tests/fakes.py
+++ b/openstackclient/tests/fakes.py
@@ -15,11 +15,11 @@
import json
import mock
-import six
import sys
from keystoneauth1 import fixture
import requests
+import six
AUTH_TOKEN = "foobar"
diff --git a/openstackclient/tests/identity/v2_0/test_endpoint.py b/openstackclient/tests/identity/v2_0/test_endpoint.py
index b2b6d0f1..26ec654d 100644
--- a/openstackclient/tests/identity/v2_0/test_endpoint.py
+++ b/openstackclient/tests/identity/v2_0/test_endpoint.py
@@ -103,9 +103,6 @@ class TestEndpointDelete(TestEndpoint):
super(TestEndpointDelete, self).setUp()
self.endpoints_mock.get.return_value = self.fake_endpoint
-
- self.services_mock.get.return_value = self.fake_service
-
self.endpoints_mock.delete.return_value = None
# Get the command object to test
diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py
index 318fa83d..7efd2a60 100644
--- a/openstackclient/tests/identity/v2_0/test_service.py
+++ b/openstackclient/tests/identity/v2_0/test_service.py
@@ -13,6 +13,9 @@
# under the License.
#
+from keystoneclient import exceptions as identity_exc
+from osc_lib import exceptions
+
from openstackclient.identity.v2_0 import service
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
@@ -170,7 +173,8 @@ class TestServiceDelete(TestService):
def setUp(self):
super(TestServiceDelete, self).setUp()
- self.services_mock.get.return_value = self.fake_service
+ self.services_mock.get.side_effect = identity_exc.NotFound(None)
+ self.services_mock.find.return_value = self.fake_service
self.services_mock.delete.return_value = None
# Get the command object to test
@@ -253,20 +257,23 @@ class TestServiceList(TestService):
class TestServiceShow(TestService):
+ fake_service_s = identity_fakes.FakeService.create_one_service()
+
def setUp(self):
super(TestServiceShow, self).setUp()
- self.services_mock.get.return_value = self.fake_service
+ self.services_mock.get.side_effect = identity_exc.NotFound(None)
+ self.services_mock.find.return_value = self.fake_service_s
# Get the command object to test
self.cmd = service.ShowService(self.app, None)
def test_service_show(self):
arglist = [
- self.fake_service.name,
+ self.fake_service_s.name,
]
verifylist = [
- ('service', self.fake_service.name),
+ ('service', self.fake_service_s.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -275,17 +282,35 @@ class TestServiceShow(TestService):
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
- # ServiceManager.get(id)
- self.services_mock.get.assert_called_with(
- self.fake_service.name,
+ # ServiceManager.find(id)
+ self.services_mock.find.assert_called_with(
+ name=self.fake_service_s.name,
)
collist = ('description', 'id', 'name', 'type')
self.assertEqual(collist, columns)
datalist = (
- self.fake_service.description,
- self.fake_service.id,
- self.fake_service.name,
- self.fake_service.type,
+ self.fake_service_s.description,
+ self.fake_service_s.id,
+ self.fake_service_s.name,
+ self.fake_service_s.type,
)
self.assertEqual(datalist, data)
+
+ def test_service_show_nounique(self):
+ self.services_mock.find.side_effect = identity_exc.NoUniqueMatch(None)
+ arglist = [
+ 'nounique_service',
+ ]
+ verifylist = [
+ ('service', 'nounique_service'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual(
+ "Multiple service matches found for 'nounique_service',"
+ " use an ID to be more specific.", str(e))
diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py
index df532df4..bad15b6c 100644
--- a/openstackclient/tests/identity/v3/fakes.py
+++ b/openstackclient/tests/identity/v3/fakes.py
@@ -198,8 +198,6 @@ SERVICE_WITHOUT_NAME = {
'links': base_url + 'services/' + service_id,
}
-credential_id = 'c-123'
-
endpoint_id = 'e-123'
endpoint_url = 'http://127.0.0.1:35357'
endpoint_region = 'RegionOne'
@@ -639,3 +637,104 @@ class FakeDomain(object):
domain = fakes.FakeResource(info=copy.deepcopy(domain_info),
loaded=True)
return domain
+
+
+class FakeCredential(object):
+ """Fake one or more credential."""
+
+ @staticmethod
+ def create_one_credential(attrs=None):
+ """Create a fake credential.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with id, type, and so on
+ """
+
+ attrs = attrs or {}
+
+ # set default attributes.
+ credential_info = {
+ 'id': 'credential-id-' + uuid.uuid4().hex,
+ 'type': 'cert',
+ 'user_id': 'user-id-' + uuid.uuid4().hex,
+ 'blob': 'credential-data-' + uuid.uuid4().hex,
+ 'project_id': 'project-id-' + uuid.uuid4().hex,
+ 'links': 'links-' + uuid.uuid4().hex,
+ }
+ credential_info.update(attrs)
+
+ credential = fakes.FakeResource(
+ info=copy.deepcopy(credential_info), loaded=True)
+ return credential
+
+ @staticmethod
+ def create_credentials(attrs=None, count=2):
+ """Create multiple fake credentials.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of credentials to fake
+ :return:
+ A list of FakeResource objects faking the credentials
+ """
+ credentials = []
+ for i in range(0, count):
+ credential = FakeCredential.create_one_credential(attrs)
+ credentials.append(credential)
+
+ return credentials
+
+ @staticmethod
+ def get_credentials(credentials=None, count=2):
+ """Get an iterable MagicMock object with a list of faked credentials.
+
+ If credentials list is provided, then initialize the Mock object with
+ the list. Otherwise create one.
+
+ :param List credentials:
+ A list of FakeResource objects faking credentials
+ :param Integer count:
+ The number of credentials to be faked
+ :return
+ An iterable Mock object with side_effect set to a list of faked
+ credentials
+ """
+ if credentials is None:
+ credentials = FakeCredential.create_credentials(count)
+
+ return mock.MagicMock(side_effect=credentials)
+
+
+class FakeUser(object):
+ """Fake one or more user."""
+
+ @staticmethod
+ def create_one_user(attrs=None):
+ """Create a fake user.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with id, name, and so on
+ """
+
+ attrs = attrs or {}
+
+ # set default attributes.
+ user_info = {
+ 'id': 'user-id-' + uuid.uuid4().hex,
+ 'name': 'user-name-' + uuid.uuid4().hex,
+ 'default_project_id': 'project-' + uuid.uuid4().hex,
+ 'email': 'user-email-' + uuid.uuid4().hex,
+ 'enabled': True,
+ 'domain_id': 'domain-id' + uuid.uuid4().hex,
+ 'links': 'links-' + uuid.uuid4().hex,
+ }
+ user_info.update(attrs)
+
+ user = fakes.FakeResource(info=copy.deepcopy(user_info),
+ loaded=True)
+ return user
diff --git a/openstackclient/tests/identity/v3/test_credential.py b/openstackclient/tests/identity/v3/test_credential.py
index d8866124..b272087d 100644
--- a/openstackclient/tests/identity/v3/test_credential.py
+++ b/openstackclient/tests/identity/v3/test_credential.py
@@ -10,7 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+import mock
+from mock import call
+
+from osc_lib import exceptions
from openstackclient.identity.v3 import credential
from openstackclient.tests.identity.v3 import fakes as identity_fakes
@@ -18,16 +21,6 @@ from openstackclient.tests import utils
class TestCredential(identity_fakes.TestIdentityv3):
- data = {
- "access": "abc123",
- "secret": "hidden-message",
- "trust_id": None
- }
-
- def __init__(self, *args):
- super(TestCredential, self).__init__(*args)
-
- self.json_data = json.dumps(self.data)
def setUp(self):
super(TestCredential, self).setUp()
@@ -45,15 +38,221 @@ class TestCredential(identity_fakes.TestIdentityv3):
self.projects_mock.reset_mock()
+class TestCredentialCreate(TestCredential):
+
+ user = identity_fakes.FakeUser.create_one_user()
+ project = identity_fakes.FakeProject.create_one_project()
+ columns = (
+ 'blob',
+ 'id',
+ 'project_id',
+ 'type',
+ 'user_id',
+ )
+
+ def setUp(self):
+ super(TestCredentialCreate, self).setUp()
+
+ self.credential = identity_fakes.FakeCredential.create_one_credential(
+ attrs={'user_id': self.user.id, 'project_id': self.project.id})
+ self.credentials_mock.create.return_value = self.credential
+ self.users_mock.get.return_value = self.user
+ self.projects_mock.get.return_value = self.project
+ self.data = (
+ self.credential.blob,
+ self.credential.id,
+ self.credential.project_id,
+ self.credential.type,
+ self.credential.user_id,
+ )
+
+ self.cmd = credential.CreateCredential(self.app, None)
+
+ def test_credential_create_no_options(self):
+ arglist = [
+ self.credential.user_id,
+ self.credential.blob,
+ ]
+ verifylist = [
+ ('user', self.credential.user_id),
+ ('data', self.credential.blob),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'user': self.credential.user_id,
+ 'type': self.credential.type,
+ 'blob': self.credential.blob,
+ 'project': None,
+ }
+ self.credentials_mock.create.assert_called_once_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_credential_create_with_options(self):
+ arglist = [
+ self.credential.user_id,
+ self.credential.blob,
+ '--type', self.credential.type,
+ '--project', self.credential.project_id,
+ ]
+ verifylist = [
+ ('user', self.credential.user_id),
+ ('data', self.credential.blob),
+ ('type', self.credential.type),
+ ('project', self.credential.project_id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ kwargs = {
+ 'user': self.credential.user_id,
+ 'type': self.credential.type,
+ 'blob': self.credential.blob,
+ 'project': self.credential.project_id,
+ }
+ self.credentials_mock.create.assert_called_once_with(
+ **kwargs
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_credential_create_with_invalid_type(self):
+ arglist = [
+ self.credential.user_id,
+ self.credential.blob,
+ '--type', 'invalid_type',
+ ]
+ verifylist = [
+ ('user', self.credential.user_id),
+ ('data', self.credential.blob),
+ ('type', 'invalid_type'),
+ ]
+ self.assertRaises(utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+
+class TestCredentialDelete(TestCredential):
+
+ credentials = identity_fakes.FakeCredential.create_credentials(count=2)
+
+ def setUp(self):
+ super(TestCredentialDelete, self).setUp()
+
+ self.credentials_mock.delete.return_value = None
+
+ # Get the command object to test
+ self.cmd = credential.DeleteCredential(self.app, None)
+
+ def test_credential_delete(self):
+ arglist = [
+ self.credentials[0].id,
+ ]
+ verifylist = [
+ ('credential', [self.credentials[0].id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.credentials_mock.delete.assert_called_with(
+ self.credentials[0].id,
+ )
+ self.assertIsNone(result)
+
+ def test_credential_multi_delete(self):
+ arglist = []
+ for c in self.credentials:
+ arglist.append(c.id)
+ verifylist = [
+ ('credential', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for c in self.credentials:
+ calls.append(call(c.id))
+ self.credentials_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_credential_multi_delete_with_exception(self):
+ arglist = [
+ self.credentials[0].id,
+ 'unexist_credential',
+ ]
+ verifylist = [
+ ('credential', [self.credentials[0].id, 'unexist_credential'])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ delete_mock_result = [None, exceptions.CommandError]
+ self.credentials_mock.delete = (
+ mock.MagicMock(side_effect=delete_mock_result)
+ )
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 credential failed to delete.', str(e))
+
+ self.credentials_mock.delete.assert_any_call(self.credentials[0].id)
+ self.credentials_mock.delete.assert_any_call('unexist_credential')
+
+
+class TestCredentialList(TestCredential):
+
+ credential = identity_fakes.FakeCredential.create_one_credential()
+
+ columns = ('ID', 'Type', 'User ID', 'Data', 'Project ID')
+ data = ((
+ credential.id,
+ credential.type,
+ credential.user_id,
+ credential.blob,
+ credential.project_id,
+ ), )
+
+ def setUp(self):
+ super(TestCredentialList, self).setUp()
+
+ self.credentials_mock.list.return_value = [self.credential]
+
+ # Get the command object to test
+ self.cmd = credential.ListCredential(self.app, None)
+
+ def test_domain_list_no_options(self):
+ arglist = []
+ verifylist = []
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.credentials_mock.list.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, tuple(data))
+
+
class TestCredentialSet(TestCredential):
+ credential = identity_fakes.FakeCredential.create_one_credential()
+
def setUp(self):
super(TestCredentialSet, self).setUp()
self.cmd = credential.SetCredential(self.app, None)
def test_credential_set_no_options(self):
arglist = [
- identity_fakes.credential_id,
+ self.credential.id,
]
self.assertRaises(utils.ParserException,
@@ -62,8 +261,8 @@ class TestCredentialSet(TestCredential):
def test_credential_set_missing_user(self):
arglist = [
'--type', 'ec2',
- '--data', self.json_data,
- identity_fakes.credential_id,
+ '--data', self.credential.blob,
+ self.credential.id,
]
self.assertRaises(utils.ParserException,
@@ -71,9 +270,9 @@ class TestCredentialSet(TestCredential):
def test_credential_set_missing_type(self):
arglist = [
- '--user', identity_fakes.user_name,
- '--data', self.json_data,
- identity_fakes.credential_id,
+ '--user', self.credential.user_id,
+ '--data', self.credential.blob,
+ self.credential.id,
]
self.assertRaises(utils.ParserException,
@@ -81,9 +280,9 @@ class TestCredentialSet(TestCredential):
def test_credential_set_missing_data(self):
arglist = [
- '--user', identity_fakes.user_name,
+ '--user', self.credential.user_id,
'--type', 'ec2',
- identity_fakes.credential_id,
+ self.credential.id,
]
self.assertRaises(utils.ParserException,
@@ -91,10 +290,10 @@ class TestCredentialSet(TestCredential):
def test_credential_set_valid(self):
arglist = [
- '--user', identity_fakes.user_name,
+ '--user', self.credential.user_id,
'--type', 'ec2',
- '--data', self.json_data,
- identity_fakes.credential_id,
+ '--data', self.credential.blob,
+ self.credential.id,
]
parsed_args = self.check_parser(self.cmd, arglist, [])
@@ -104,14 +303,55 @@ class TestCredentialSet(TestCredential):
def test_credential_set_valid_with_project(self):
arglist = [
- '--user', identity_fakes.user_name,
+ '--user', self.credential.user_id,
'--type', 'ec2',
- '--data', self.json_data,
- '--project', identity_fakes.project_name,
- identity_fakes.credential_id,
+ '--data', self.credential.blob,
+ '--project', self.credential.project_id,
+ self.credential.id,
]
parsed_args = self.check_parser(self.cmd, arglist, [])
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
+
+
+class TestCredentialShow(TestCredential):
+
+ columns = (
+ 'blob',
+ 'id',
+ 'project_id',
+ 'type',
+ 'user_id',
+ )
+
+ def setUp(self):
+ super(TestCredentialShow, self).setUp()
+
+ self.credential = identity_fakes.FakeCredential.create_one_credential()
+ self.credentials_mock.get.return_value = self.credential
+ self.data = (
+ self.credential.blob,
+ self.credential.id,
+ self.credential.project_id,
+ self.credential.type,
+ self.credential.user_id,
+ )
+
+ self.cmd = credential.ShowCredential(self.app, None)
+
+ def test_credential_show(self):
+ arglist = [
+ self.credential.id,
+ ]
+ verifylist = [
+ ('credential', self.credential.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.credentials_mock.get.assert_called_once_with(self.credential.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/identity/v3/test_identity_provider.py b/openstackclient/tests/identity/v3/test_identity_provider.py
index 1ec61052..b5d784ef 100644
--- a/openstackclient/tests/identity/v3/test_identity_provider.py
+++ b/openstackclient/tests/identity/v3/test_identity_provider.py
@@ -13,7 +13,6 @@
# under the License.
import copy
-
import mock
from openstackclient.identity.v3 import identity_provider
diff --git a/openstackclient/tests/identity/v3/test_mappings.py b/openstackclient/tests/identity/v3/test_mappings.py
index 6aa1a6e5..09a383eb 100644
--- a/openstackclient/tests/identity/v3/test_mappings.py
+++ b/openstackclient/tests/identity/v3/test_mappings.py
@@ -13,7 +13,6 @@
# under the License.
import copy
-
import mock
from osc_lib import exceptions
diff --git a/openstackclient/tests/identity/v3/test_service.py b/openstackclient/tests/identity/v3/test_service.py
index a1f85adc..65d8ebd7 100644
--- a/openstackclient/tests/identity/v3/test_service.py
+++ b/openstackclient/tests/identity/v3/test_service.py
@@ -15,6 +15,9 @@
import copy
+from keystoneclient import exceptions as identity_exc
+from osc_lib import exceptions
+
from openstackclient.identity.v3 import service
from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
@@ -185,7 +188,8 @@ class TestServiceDelete(TestService):
def setUp(self):
super(TestServiceDelete, self).setUp()
- self.services_mock.get.return_value = fakes.FakeResource(
+ self.services_mock.get.side_effect = identity_exc.NotFound(None)
+ self.services_mock.find.return_value = fakes.FakeResource(
None,
copy.deepcopy(identity_fakes.SERVICE),
loaded=True,
@@ -282,7 +286,8 @@ class TestServiceSet(TestService):
def setUp(self):
super(TestServiceSet, self).setUp()
- self.services_mock.get.return_value = fakes.FakeResource(
+ self.services_mock.get.side_effect = identity_exc.NotFound(None)
+ self.services_mock.find.return_value = fakes.FakeResource(
None,
copy.deepcopy(identity_fakes.SERVICE),
loaded=True,
@@ -460,7 +465,8 @@ class TestServiceShow(TestService):
def setUp(self):
super(TestServiceShow, self).setUp()
- self.services_mock.get.return_value = fakes.FakeResource(
+ self.services_mock.get.side_effect = identity_exc.NotFound(None)
+ self.services_mock.find.return_value = fakes.FakeResource(
None,
copy.deepcopy(identity_fakes.SERVICE),
loaded=True,
@@ -484,8 +490,8 @@ class TestServiceShow(TestService):
columns, data = self.cmd.take_action(parsed_args)
# ServiceManager.get(id)
- self.services_mock.get.assert_called_with(
- identity_fakes.service_name,
+ self.services_mock.find.assert_called_with(
+ name=identity_fakes.service_name
)
collist = ('description', 'enabled', 'id', 'name', 'type')
@@ -498,3 +504,21 @@ class TestServiceShow(TestService):
identity_fakes.service_type,
)
self.assertEqual(datalist, data)
+
+ def test_service_show_nounique(self):
+ self.services_mock.find.side_effect = identity_exc.NoUniqueMatch(None)
+ arglist = [
+ 'nounique_service',
+ ]
+ verifylist = [
+ ('service', 'nounique_service'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual(
+ "Multiple service matches found for 'nounique_service',"
+ " use an ID to be more specific.", str(e))
diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py
index c4fb1521..7b99a4cb 100644
--- a/openstackclient/tests/identity/v3/test_user.py
+++ b/openstackclient/tests/identity/v3/test_user.py
@@ -15,7 +15,6 @@
import contextlib
import copy
-
import mock
from openstackclient.identity.v3 import user
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index c6b83bc5..2b116b4e 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -16,14 +16,12 @@
import copy
import mock
-import warlock
-
from glanceclient.v2 import schemas
from osc_lib import exceptions
from osc_lib import utils as common_utils
+import warlock
from openstackclient.image.v2 import image
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
@@ -58,23 +56,18 @@ class TestImage(image_fakes.TestImagev2):
class TestImageCreate(TestImage):
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+
def setUp(self):
super(TestImageCreate, self).setUp()
self.new_image = image_fakes.FakeImage.create_one_image()
self.images_mock.create.return_value = self.new_image
- self.project_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.project_mock.get.return_value = self.project
- self.domain_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
- )
+ self.domain_mock.get.return_value = self.domain
# This is the return value for utils.find_resource()
self.images_mock.get.return_value = copy.deepcopy(
@@ -145,7 +138,7 @@ class TestImageCreate(TestImage):
('--private'
if self.new_image.visibility == 'private' else '--public'),
'--project', self.new_image.owner,
- '--project-domain', identity_fakes.domain_id,
+ '--project-domain', self.domain.id,
self.new_image.name,
]
verifylist = [
@@ -158,7 +151,7 @@ class TestImageCreate(TestImage):
('public', self.new_image.visibility == 'public'),
('private', self.new_image.visibility == 'private'),
('project', self.new_image.owner),
- ('project_domain', identity_fakes.domain_id),
+ ('project_domain', self.domain.id),
('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -175,7 +168,7 @@ class TestImageCreate(TestImage):
disk_format='fs',
min_disk=10,
min_ram=4,
- owner=identity_fakes.project_id,
+ owner=self.project.id,
protected=self.new_image.protected,
visibility=self.new_image.visibility,
)
@@ -346,10 +339,12 @@ class TestImageCreate(TestImage):
class TestAddProjectToImage(TestImage):
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
_image = image_fakes.FakeImage.create_one_image()
new_member = image_fakes.FakeImage.create_one_image_member(
attrs={'image_id': _image.id,
- 'member_id': identity_fakes.project_id}
+ 'member_id': project.id}
)
columns = (
@@ -360,8 +355,8 @@ class TestAddProjectToImage(TestImage):
datalist = (
_image.id,
- identity_fakes.project_id,
- new_member.status
+ new_member.member_id,
+ new_member.status,
)
def setUp(self):
@@ -372,27 +367,19 @@ class TestAddProjectToImage(TestImage):
# Update the image_id in the MEMBER dict
self.image_members_mock.create.return_value = self.new_member
- self.project_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
- self.domain_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
- )
+ self.project_mock.get.return_value = self.project
+ self.domain_mock.get.return_value = self.domain
# Get the command object to test
self.cmd = image.AddProjectToImage(self.app, None)
def test_add_project_to_image_no_option(self):
arglist = [
self._image.id,
- identity_fakes.project_id,
+ self.project.id,
]
verifylist = [
('image', self._image.id),
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -402,7 +389,7 @@ class TestAddProjectToImage(TestImage):
columns, data = self.cmd.take_action(parsed_args)
self.image_members_mock.create.assert_called_with(
self._image.id,
- identity_fakes.project_id
+ self.project.id
)
self.assertEqual(self.columns, columns)
@@ -411,13 +398,13 @@ class TestAddProjectToImage(TestImage):
def test_add_project_to_image_with_option(self):
arglist = [
self._image.id,
- identity_fakes.project_id,
- '--project-domain', identity_fakes.domain_id,
+ self.project.id,
+ '--project-domain', self.domain.id,
]
verifylist = [
('image', self._image.id),
- ('project', identity_fakes.project_id),
- ('project_domain', identity_fakes.domain_id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -427,7 +414,7 @@ class TestAddProjectToImage(TestImage):
columns, data = self.cmd.take_action(parsed_args)
self.image_members_mock.create.assert_called_with(
self._image.id,
- identity_fakes.project_id
+ self.project.id
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
@@ -755,6 +742,9 @@ class TestImageList(TestImage):
class TestRemoveProjectImage(TestImage):
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+
def setUp(self):
super(TestRemoveProjectImage, self).setUp()
@@ -762,16 +752,8 @@ class TestRemoveProjectImage(TestImage):
# This is the return value for utils.find_resource()
self.images_mock.get.return_value = self._image
- self.project_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
- self.domain_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
- )
+ self.project_mock.get.return_value = self.project
+ self.domain_mock.get.return_value = self.domain
self.image_members_mock.delete.return_value = None
# Get the command object to test
self.cmd = image.RemoveProjectImage(self.app, None)
@@ -779,11 +761,11 @@ class TestRemoveProjectImage(TestImage):
def test_remove_project_image_no_options(self):
arglist = [
self._image.id,
- identity_fakes.project_id,
+ self.project.id,
]
verifylist = [
('image', self._image.id),
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -791,20 +773,20 @@ class TestRemoveProjectImage(TestImage):
self.image_members_mock.delete.assert_called_with(
self._image.id,
- identity_fakes.project_id,
+ self.project.id,
)
self.assertIsNone(result)
def test_remove_project_image_with_options(self):
arglist = [
self._image.id,
- identity_fakes.project_id,
- '--project-domain', identity_fakes.domain_id,
+ self.project.id,
+ '--project-domain', self.domain.id,
]
verifylist = [
('image', self._image.id),
- ('project', identity_fakes.project_id),
- ('project_domain', identity_fakes.domain_id),
+ ('project', self.project.id),
+ ('project_domain', self.domain.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -812,13 +794,16 @@ class TestRemoveProjectImage(TestImage):
self.image_members_mock.delete.assert_called_with(
self._image.id,
- identity_fakes.project_id,
+ self.project.id,
)
self.assertIsNone(result)
class TestImageSet(TestImage):
+ project = identity_fakes.FakeProject.create_one_project()
+ domain = identity_fakes.FakeDomain.create_one_domain()
+
def setUp(self):
super(TestImageSet, self).setUp()
# Set up the schema
@@ -827,17 +812,9 @@ class TestImageSet(TestImage):
schemas.SchemaBasedModel,
)
- self.project_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.project_mock.get.return_value = self.project
- self.domain_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.DOMAIN),
- loaded=True,
- )
+ self.domain_mock.get.return_value = self.domain
self.images_mock.get.return_value = self.model(**image_fakes.IMAGE)
self.images_mock.update.return_value = self.model(**image_fakes.IMAGE)
@@ -864,8 +841,8 @@ class TestImageSet(TestImage):
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
- '--project', identity_fakes.project_name,
- '--project-domain', identity_fakes.domain_id,
+ '--project', self.project.name,
+ '--project-domain', self.domain.id,
image_fakes.image_id,
]
verifylist = [
@@ -874,8 +851,8 @@ class TestImageSet(TestImage):
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
- ('project', identity_fakes.project_name),
- ('project_domain', identity_fakes.domain_id),
+ ('project', self.project.name),
+ ('project_domain', self.domain.id),
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -884,7 +861,7 @@ class TestImageSet(TestImage):
kwargs = {
'name': 'new-name',
- 'owner': identity_fakes.project_id,
+ 'owner': self.project.id,
'min_disk': 2,
'min_ram': 4,
'container_format': 'ovf',
diff --git a/openstackclient/tests/network/v2/test_address_scope.py b/openstackclient/tests/network/v2/test_address_scope.py
index 502516f9..342cf49b 100644
--- a/openstackclient/tests/network/v2/test_address_scope.py
+++ b/openstackclient/tests/network/v2/test_address_scope.py
@@ -12,8 +12,8 @@
#
import mock
-
from mock import call
+
from osc_lib import exceptions
from openstackclient.network.v2 import address_scope
diff --git a/openstackclient/tests/object/v1/fakes.py b/openstackclient/tests/object/v1/fakes.py
index b9e86db7..6c367111 100644
--- a/openstackclient/tests/object/v1/fakes.py
+++ b/openstackclient/tests/object/v1/fakes.py
@@ -14,6 +14,7 @@
#
from keystoneauth1 import session
+
from openstackclient.api import object_store_v1 as object_store
from openstackclient.tests import utils
diff --git a/openstackclient/tests/utils.py b/openstackclient/tests/utils.py
index 8dead718..f3ab5ea6 100644
--- a/openstackclient/tests/utils.py
+++ b/openstackclient/tests/utils.py
@@ -14,9 +14,8 @@
# under the License.
#
-import os
-
import fixtures
+import os
import testtools
from openstackclient.tests import fakes
diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py
index 380bc632..e41c2a72 100644
--- a/openstackclient/tests/volume/v1/test_volume.py
+++ b/openstackclient/tests/volume/v1/test_volume.py
@@ -50,6 +50,9 @@ class TestVolume(volume_fakes.TestVolumev1):
class TestVolumeCreate(TestVolume):
+ project = identity_fakes.FakeProject.create_one_project()
+ user = identity_fakes.FakeUser.create_one_user()
+
columns = (
'attach_status',
'availability_zone',
@@ -168,28 +171,20 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_user_project_id(self):
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Return a user
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.user
arglist = [
'--size', str(volume_fakes.volume_size),
- '--project', identity_fakes.project_id,
- '--user', identity_fakes.user_id,
+ '--project', self.project.id,
+ '--user', self.user.id,
volume_fakes.volume_name,
]
verifylist = [
('size', volume_fakes.volume_size),
- ('project', identity_fakes.project_id),
- ('user', identity_fakes.user_id),
+ ('project', self.project.id),
+ ('user', self.user.id),
('name', volume_fakes.volume_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -211,8 +206,8 @@ class TestVolumeCreate(TestVolume):
volume_fakes.volume_name,
None,
None,
- identity_fakes.user_id,
- identity_fakes.project_id,
+ self.user.id,
+ self.project.id,
None,
None,
None,
@@ -223,28 +218,20 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_user_project_name(self):
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Return a user
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.user
arglist = [
'--size', str(volume_fakes.volume_size),
- '--project', identity_fakes.project_name,
- '--user', identity_fakes.user_name,
+ '--project', self.project.name,
+ '--user', self.user.name,
volume_fakes.volume_name,
]
verifylist = [
('size', volume_fakes.volume_size),
- ('project', identity_fakes.project_name),
- ('user', identity_fakes.user_name),
+ ('project', self.project.name),
+ ('user', self.user.name),
('name', volume_fakes.volume_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -266,8 +253,8 @@ class TestVolumeCreate(TestVolume):
volume_fakes.volume_name,
None,
None,
- identity_fakes.user_id,
- identity_fakes.project_id,
+ self.user.id,
+ self.project.id,
None,
None,
None,
diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py
index 04e0285e..3eb740ba 100644
--- a/openstackclient/tests/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/volume/v2/test_snapshot.py
@@ -12,6 +12,7 @@
# under the License.
#
+import argparse
import mock
from mock import call
@@ -260,16 +261,33 @@ class TestSnapshotList(TestSnapshot):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+
+ self.snapshots_mock.list.assert_called_once_with(
+ limit=None, marker=None, search_opts={'all_tenants': False})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_snapshot_list_with_options(self):
- arglist = ["--long"]
- verifylist = [("long", True), ('all_projects', False)]
+ arglist = [
+ "--long",
+ "--limit", "2",
+ "--marker", self.snapshots[0].id,
+ ]
+ verifylist = [
+ ("long", True),
+ ("limit", 2),
+ ("marker", self.snapshots[0].id),
+ ('all_projects', False),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ self.snapshots_mock.list.assert_called_once_with(
+ limit=2,
+ marker=self.snapshots[0].id,
+ search_opts={'all_tenants': False}
+ )
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
@@ -285,9 +303,21 @@ class TestSnapshotList(TestSnapshot):
columns, data = self.cmd.take_action(parsed_args)
+ self.snapshots_mock.list.assert_called_once_with(
+ limit=None, marker=None, search_opts={'all_tenants': True})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_snapshot_list_negative_limit(self):
+ arglist = [
+ "--limit", "-2",
+ ]
+ verifylist = [
+ ("limit", -2),
+ ]
+ self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
+ self.cmd, arglist, verifylist)
+
class TestSnapshotSet(TestSnapshot):
diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py
index e148bba4..b0316aef 100644
--- a/openstackclient/tests/volume/v2/test_type.py
+++ b/openstackclient/tests/volume/v2/test_type.py
@@ -12,13 +12,11 @@
# under the License.
#
-import copy
import mock
from osc_lib import exceptions
from osc_lib import utils
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
from openstackclient.tests import utils as tests_utils
from openstackclient.tests.volume.v2 import fakes as volume_fakes
@@ -199,26 +197,54 @@ class TestTypeList(TestType):
def test_type_list_without_options(self):
arglist = []
verifylist = [
- ("long", False)
+ ("long", False),
+ ("private", False),
+ ("public", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ self.types_mock.list.assert_called_once_with(is_public=None)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_type_list_with_options(self):
- arglist = ["--long"]
- verifylist = [("long", True)]
+ arglist = [
+ "--long",
+ "--public",
+ ]
+ verifylist = [
+ ("long", True),
+ ("private", False),
+ ("public", True),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ self.types_mock.list.assert_called_once_with(is_public=True)
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
+ def test_type_list_with_private_option(self):
+ arglist = [
+ "--private",
+ ]
+ verifylist = [
+ ("long", False),
+ ("private", True),
+ ("public", False),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.types_mock.list.assert_called_once_with(is_public=False)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
class TestTypeSet(TestType):
+ project = identity_fakes.FakeProject.create_one_project()
volume_type = volume_fakes.FakeType.create_one_type(
methods={'set_keys': None})
@@ -228,11 +254,7 @@ class TestTypeSet(TestType):
self.types_mock.get.return_value = self.volume_type
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Get the command object to test
self.cmd = volume_type.SetVolumeType(self.app, None)
@@ -339,11 +361,11 @@ class TestTypeSet(TestType):
def test_type_set_project_access(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
self.volume_type.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('volume_type', self.volume_type.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -353,7 +375,7 @@ class TestTypeSet(TestType):
self.types_access_mock.add_project_access.assert_called_with(
self.volume_type.id,
- identity_fakes.project_id,
+ self.project.id,
)
@@ -469,6 +491,7 @@ class TestTypeShow(TestType):
class TestTypeUnset(TestType):
+ project = identity_fakes.FakeProject.create_one_project()
volume_type = volume_fakes.FakeType.create_one_type(
methods={'unset_keys': None})
@@ -478,11 +501,7 @@ class TestTypeUnset(TestType):
self.types_mock.get.return_value = self.volume_type
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Get the command object to test
self.cmd = volume_type.UnsetVolumeType(self.app, None)
@@ -507,11 +526,11 @@ class TestTypeUnset(TestType):
def test_type_unset_project_access(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.project.id,
self.volume_type.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.project.id),
('volume_type', self.volume_type.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -521,7 +540,7 @@ class TestTypeUnset(TestType):
self.types_access_mock.remove_project_access.assert_called_with(
self.volume_type.id,
- identity_fakes.project_id,
+ self.project.id,
)
def test_type_unset_not_called_without_project_argument(self):
diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py
index db65c3bd..6f552ad6 100644
--- a/openstackclient/tests/volume/v2/test_volume.py
+++ b/openstackclient/tests/volume/v2/test_volume.py
@@ -12,14 +12,12 @@
# under the License.
#
-import copy
import mock
from mock import call
from osc_lib import exceptions
from osc_lib import utils
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
from openstackclient.tests.volume.v2 import fakes as volume_fakes
@@ -57,6 +55,9 @@ class TestVolume(volume_fakes.TestVolume):
class TestVolumeCreate(TestVolume):
+ project = identity_fakes.FakeProject.create_one_project()
+ user = identity_fakes.FakeUser.create_one_user()
+
columns = (
'attachments',
'availability_zone',
@@ -168,28 +169,20 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_user_project_id(self):
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Return a user
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.user
arglist = [
'--size', str(self.new_volume.size),
- '--project', identity_fakes.project_id,
- '--user', identity_fakes.user_id,
+ '--project', self.project.id,
+ '--user', self.user.id,
self.new_volume.name,
]
verifylist = [
('size', self.new_volume.size),
- ('project', identity_fakes.project_id),
- ('user', identity_fakes.user_id),
+ ('project', self.project.id),
+ ('user', self.user.id),
('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -205,8 +198,8 @@ class TestVolumeCreate(TestVolume):
name=self.new_volume.name,
description=None,
volume_type=None,
- user_id=identity_fakes.user_id,
- project_id=identity_fakes.project_id,
+ user_id=self.user.id,
+ project_id=self.project.id,
availability_zone=None,
metadata=None,
imageRef=None,
@@ -218,28 +211,20 @@ class TestVolumeCreate(TestVolume):
def test_volume_create_user_project_name(self):
# Return a project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.project
# Return a user
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.user
arglist = [
'--size', str(self.new_volume.size),
- '--project', identity_fakes.project_name,
- '--user', identity_fakes.user_name,
+ '--project', self.project.name,
+ '--user', self.user.name,
self.new_volume.name,
]
verifylist = [
('size', self.new_volume.size),
- ('project', identity_fakes.project_name),
- ('user', identity_fakes.user_name),
+ ('project', self.project.name),
+ ('user', self.user.name),
('name', self.new_volume.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -255,8 +240,8 @@ class TestVolumeCreate(TestVolume):
name=self.new_volume.name,
description=None,
volume_type=None,
- user_id=identity_fakes.user_id,
- project_id=identity_fakes.project_id,
+ user_id=self.user.id,
+ project_id=self.project.id,
availability_zone=None,
metadata=None,
imageRef=None,
@@ -435,13 +420,16 @@ class TestVolumeDelete(TestVolume):
volumes[0].id
]
verifylist = [
- ("volumes", [volumes[0].id])
+ ("force", False),
+ ("purge", False),
+ ("volumes", [volumes[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.volumes_mock.delete.assert_called_with(volumes[0].id)
+ self.volumes_mock.delete.assert_called_once_with(
+ volumes[0].id, cascade=False)
self.assertIsNone(result)
def test_volume_delete_multi_volumes(self):
@@ -449,13 +437,15 @@ class TestVolumeDelete(TestVolume):
arglist = [v.id for v in volumes]
verifylist = [
+ ('force', False),
+ ('purge', False),
('volumes', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- calls = [call(v.id) for v in volumes]
+ calls = [call(v.id, cascade=False) for v in volumes]
self.volumes_mock.delete.assert_has_calls(calls)
self.assertIsNone(result)
@@ -467,6 +457,8 @@ class TestVolumeDelete(TestVolume):
'unexist_volume',
]
verifylist = [
+ ('force', False),
+ ('purge', False),
('volumes', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -486,12 +478,53 @@ class TestVolumeDelete(TestVolume):
self.assertEqual(2, find_mock.call_count)
self.volumes_mock.delete.assert_called_once_with(
- volumes[0].id
- )
+ volumes[0].id, cascade=False)
+
+ def test_volume_delete_with_purge(self):
+ volumes = self.setup_volumes_mock(count=1)
+
+ arglist = [
+ '--purge',
+ volumes[0].id,
+ ]
+ verifylist = [
+ ('force', False),
+ ('purge', True),
+ ('volumes', [volumes[0].id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.delete.assert_called_once_with(
+ volumes[0].id, cascade=True)
+ self.assertIsNone(result)
+
+ def test_volume_delete_with_force(self):
+ volumes = self.setup_volumes_mock(count=1)
+
+ arglist = [
+ '--force',
+ volumes[0].id,
+ ]
+ verifylist = [
+ ('force', True),
+ ('purge', False),
+ ('volumes', [volumes[0].id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.force_delete.assert_called_once_with(volumes[0].id)
+ self.assertIsNone(result)
class TestVolumeList(TestVolume):
+ project = identity_fakes.FakeProject.create_one_project()
+ user = identity_fakes.FakeUser.create_one_user()
+
columns = [
'ID',
'Display Name',
@@ -506,21 +539,9 @@ class TestVolumeList(TestVolume):
self.mock_volume = volume_fakes.FakeVolume.create_one_volume()
self.volumes_mock.list.return_value = [self.mock_volume]
- self.users_mock.get.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- ),
- ]
+ self.users_mock.get.return_value = self.user
- self.projects_mock.get.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- ),
- ]
+ self.projects_mock.get.return_value = self.project
# Get the command object to test
self.cmd = volume.ListVolume(self.app, None)
@@ -553,10 +574,10 @@ class TestVolumeList(TestVolume):
def test_volume_list_project(self):
arglist = [
- '--project', identity_fakes.project_name,
+ '--project', self.project.name,
]
verifylist = [
- ('project', identity_fakes.project_name),
+ ('project', self.project.name),
('long', False),
('all_projects', False),
('status', None),
@@ -581,12 +602,12 @@ class TestVolumeList(TestVolume):
def test_volume_list_project_domain(self):
arglist = [
- '--project', identity_fakes.project_name,
- '--project-domain', identity_fakes.domain_name,
+ '--project', self.project.name,
+ '--project-domain', self.project.domain_id,
]
verifylist = [
- ('project', identity_fakes.project_name),
- ('project_domain', identity_fakes.domain_name),
+ ('project', self.project.name),
+ ('project_domain', self.project.domain_id),
('long', False),
('all_projects', False),
('status', None),
@@ -611,10 +632,10 @@ class TestVolumeList(TestVolume):
def test_volume_list_user(self):
arglist = [
- '--user', identity_fakes.user_name,
+ '--user', self.user.name,
]
verifylist = [
- ('user', identity_fakes.user_name),
+ ('user', self.user.name),
('long', False),
('all_projects', False),
('status', None),
@@ -638,12 +659,12 @@ class TestVolumeList(TestVolume):
def test_volume_list_user_domain(self):
arglist = [
- '--user', identity_fakes.user_name,
- '--user-domain', identity_fakes.domain_name,
+ '--user', self.user.name,
+ '--user-domain', self.user.domain_id,
]
verifylist = [
- ('user', identity_fakes.user_name),
- ('user_domain', identity_fakes.domain_name),
+ ('user', self.user.name),
+ ('user_domain', self.user.domain_id),
('long', False),
('all_projects', False),
('status', None),
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index ea0c441c..11f20673 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -19,6 +19,7 @@ from osc_lib import utils
from openstackclient.i18n import _
+
LOG = logging.getLogger(__name__)
DEFAULT_API_VERSION = '2'
diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py
index ba692074..8304a5eb 100644
--- a/openstackclient/volume/v2/snapshot.py
+++ b/openstackclient/volume/v2/snapshot.py
@@ -134,6 +134,18 @@ class ListSnapshot(command.Lister):
default=False,
help=_('List additional fields in output'),
)
+ parser.add_argument(
+ '--marker',
+ metavar='<marker>',
+ help=_('The last snapshot ID of the previous page'),
+ )
+ parser.add_argument(
+ '--limit',
+ type=int,
+ action=parseractions.NonNegativeAction,
+ metavar='<limit>',
+ help=_('Maximum number of snapshots to display'),
+ )
return parser
def take_action(self, parsed_args):
@@ -174,7 +186,10 @@ class ListSnapshot(command.Lister):
}
data = self.app.client_manager.volume.volume_snapshots.list(
- search_opts=search_opts)
+ search_opts=search_opts,
+ marker=parsed_args.marker,
+ limit=parsed_args.limit,
+ )
return (column_headers,
(utils.get_item_properties(
s, columns,
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
index 85f267ef..6f055922 100644
--- a/openstackclient/volume/v2/volume.py
+++ b/openstackclient/volume/v2/volume.py
@@ -166,13 +166,19 @@ class DeleteVolume(command.Command):
nargs="+",
help=_("Volume(s) to delete (name or ID)")
)
- parser.add_argument(
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument(
"--force",
action="store_true",
- default=False,
help=_("Attempt forced removal of volume(s), regardless of state "
"(defaults to False)")
)
+ group.add_argument(
+ "--purge",
+ action="store_true",
+ help=_("Remove any snapshots along with volume(s) "
+ "(defaults to False)")
+ )
return parser
def take_action(self, parsed_args):
@@ -186,12 +192,13 @@ class DeleteVolume(command.Command):
if parsed_args.force:
volume_client.volumes.force_delete(volume_obj.id)
else:
- volume_client.volumes.delete(volume_obj.id)
+ volume_client.volumes.delete(volume_obj.id,
+ cascade=parsed_args.purge)
except Exception as e:
result += 1
LOG.error(_("Failed to delete volume with "
- "name or ID '%(volume)s': %(e)s")
- % {'volume': i, 'e': e})
+ "name or ID '%(volume)s': %(e)s"),
+ {'volume': i, 'e': e})
if result > 0:
total = len(parsed_args.volumes)
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
index 62d619d0..e42fffe0 100644
--- a/openstackclient/volume/v2/volume_type.py
+++ b/openstackclient/volume/v2/volume_type.py
@@ -160,6 +160,17 @@ class ListVolumeType(command.Lister):
action='store_true',
default=False,
help=_('List additional fields in output'))
+ public_group = parser.add_mutually_exclusive_group()
+ public_group.add_argument(
+ "--public",
+ action="store_true",
+ help=_("List only public types")
+ )
+ public_group.add_argument(
+ "--private",
+ action="store_true",
+ help=_("List only private types (admin only)")
+ )
return parser
def take_action(self, parsed_args):
@@ -169,7 +180,14 @@ class ListVolumeType(command.Lister):
else:
columns = ['ID', 'Name']
column_headers = columns
- data = self.app.client_manager.volume.volume_types.list()
+
+ is_public = None
+ if parsed_args.public:
+ is_public = True
+ if parsed_args.private:
+ is_public = False
+ data = self.app.client_manager.volume.volume_types.list(
+ is_public=is_public)
return (column_headers,
(utils.get_item_properties(
s, columns,