summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/project_purge.py9
-rw-r--r--openstackclient/network/sdk_utils.py3
-rw-r--r--openstackclient/network/v2/port.py10
-rw-r--r--openstackclient/network/v2/security_group_rule.py4
-rwxr-xr-xopenstackclient/tests/functional/post_test_hook.sh2
-rwxr-xr-xopenstackclient/tests/functional/post_test_hook_tips.sh2
-rw-r--r--openstackclient/tests/functional/volume/v2/test_service.py14
-rw-r--r--openstackclient/tests/unit/common/test_project_purge.py24
-rw-r--r--openstackclient/tests/unit/image/v1/fakes.py1
-rw-r--r--openstackclient/tests/unit/image/v2/fakes.py1
-rw-r--r--openstackclient/tests/unit/network/v2/test_port.py26
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_rule_network.py170
12 files changed, 245 insertions, 21 deletions
diff --git a/openstackclient/common/project_purge.py b/openstackclient/common/project_purge.py
index dff954e7..5b1d0072 100644
--- a/openstackclient/common/project_purge.py
+++ b/openstackclient/common/project_purge.py
@@ -95,7 +95,14 @@ class ProjectPurge(command.Command):
# images
try:
image_client = self.app.client_manager.image
- data = image_client.images.list(owner=project_id)
+ api_version = int(image_client.version)
+ if api_version == 1:
+ data = image_client.images.list(owner=project_id)
+ elif api_version == 2:
+ kwargs = {'filters': {'owner': project_id}}
+ data = image_client.images.list(**kwargs)
+ else:
+ raise NotImplementedError
self.delete_objects(
image_client.images.delete, data, 'image', dry_run)
except Exception:
diff --git a/openstackclient/network/sdk_utils.py b/openstackclient/network/sdk_utils.py
index 04f168be..9f085617 100644
--- a/openstackclient/network/sdk_utils.py
+++ b/openstackclient/network/sdk_utils.py
@@ -16,7 +16,7 @@ import six
def get_osc_show_columns_for_sdk_resource(
sdk_resource,
osc_column_map,
- invisible_columns=[]
+ invisible_columns=None
):
"""Get and filter the display and attribute columns for an SDK resource.
@@ -40,6 +40,7 @@ def get_osc_show_columns_for_sdk_resource(
# Build the OSC column names to display for the SDK resource.
attr_map = {}
display_columns = list(resource_dict.keys())
+ invisible_columns = [] if invisible_columns is None else invisible_columns
for col_name in invisible_columns:
if col_name in display_columns:
display_columns.remove(col_name)
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index 9536fe86..4b23b339 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -302,7 +302,8 @@ class CreatePort(command.ShowOne):
help=_("Network this port belongs to (name or ID)")
)
_add_updatable_args(parser)
- parser.add_argument(
+ fixed_ip = parser.add_mutually_exclusive_group()
+ fixed_ip.add_argument(
'--fixed-ip',
metavar='subnet=<subnet>,ip-address=<ip-address>',
action=parseractions.MultiKeyValueAction,
@@ -311,6 +312,11 @@ class CreatePort(command.ShowOne):
"subnet=<subnet>,ip-address=<ip-address> "
"(repeat option to set multiple fixed IP addresses)")
)
+ fixed_ip.add_argument(
+ '--no-fixed-ip',
+ action='store_true',
+ help=_("No IP or subnet for this port.")
+ )
parser.add_argument(
'--binding-profile',
metavar='<binding-profile>',
@@ -402,6 +408,8 @@ class CreatePort(command.ShowOne):
if parsed_args.fixed_ip:
attrs['fixed_ips'] = parsed_args.fixed_ip
+ elif parsed_args.no_fixed_ip:
+ attrs['fixed_ips'] = []
if parsed_args.security_group:
attrs['security_group_ids'] = [client.find_security_group(
diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py
index ad685cf8..06d46725 100644
--- a/openstackclient/network/v2/security_group_rule.py
+++ b/openstackclient/network/v2/security_group_rule.py
@@ -294,9 +294,9 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
if parsed_args.dst_port and not is_icmp_protocol:
attrs['port_range_min'] = parsed_args.dst_port[0]
attrs['port_range_max'] = parsed_args.dst_port[1]
- if parsed_args.icmp_type:
+ if parsed_args.icmp_type is not None and parsed_args.icmp_type >= 0:
attrs['port_range_min'] = parsed_args.icmp_type
- if parsed_args.icmp_code:
+ if parsed_args.icmp_code is not None and parsed_args.icmp_code >= 0:
attrs['port_range_max'] = parsed_args.icmp_code
# NOTE(dtroyer): --src-ip and --src-group were deprecated in Nov 2016.
diff --git a/openstackclient/tests/functional/post_test_hook.sh b/openstackclient/tests/functional/post_test_hook.sh
index 2ae9178d..e3b48ef4 100755
--- a/openstackclient/tests/functional/post_test_hook.sh
+++ b/openstackclient/tests/functional/post_test_hook.sh
@@ -4,7 +4,7 @@
# OpenStack cloud. It will attempt to create an instance if one is not
# available. Do not run this script unless you know what you're doing.
# For more information refer to:
-# http://docs.openstack.org/developer/python-openstackclient/
+# https://docs.openstack.org/python-openstackclient/latest/
function generate_testr_results {
if [ -f .testrepository/0 ]; then
diff --git a/openstackclient/tests/functional/post_test_hook_tips.sh b/openstackclient/tests/functional/post_test_hook_tips.sh
index a4ad19ac..232527a3 100755
--- a/openstackclient/tests/functional/post_test_hook_tips.sh
+++ b/openstackclient/tests/functional/post_test_hook_tips.sh
@@ -4,7 +4,7 @@
# OpenStack cloud. It will attempt to create an instance if one is not
# available. Do not run this script unless you know what you're doing.
# For more information refer to:
-# http://docs.openstack.org/developer/python-openstackclient/
+# https://docs.openstack.org/python-openstackclient/latest/
# This particular script differs from the normal post_test_hook because
# it installs the master (tip) version of osc-lib, os-client-config
diff --git a/openstackclient/tests/functional/volume/v2/test_service.py b/openstackclient/tests/functional/volume/v2/test_service.py
index 6986fde6..7ec43fe8 100644
--- a/openstackclient/tests/functional/volume/v2/test_service.py
+++ b/openstackclient/tests/functional/volume/v2/test_service.py
@@ -24,6 +24,7 @@ class VolumeServiceTests(common.BaseVolumeTests):
# Get the nonredundant services and hosts
services = list(set([x['Binary'] for x in cmd_output]))
+ hosts = list(set([x['Host'] for x in cmd_output]))
# Test volume service list --service
cmd_output = json.loads(self.openstack(
@@ -37,8 +38,17 @@ class VolumeServiceTests(common.BaseVolumeTests):
x['Binary']
)
- # TODO(zhiyong.dai): test volume service list --host after solving
- # https://bugs.launchpad.net/python-openstackclient/+bug/1664451
+ # Test volume service list --host
+ cmd_output = json.loads(self.openstack(
+ 'volume service list -f json ' +
+ '--host ' +
+ hosts[0]
+ ))
+ for x in cmd_output:
+ self.assertIn(
+ hosts[0],
+ x['Host']
+ )
def test_volume_service_set(self):
diff --git a/openstackclient/tests/unit/common/test_project_purge.py b/openstackclient/tests/unit/common/test_project_purge.py
index 05a8aa3e..2385eae8 100644
--- a/openstackclient/tests/unit/common/test_project_purge.py
+++ b/openstackclient/tests/unit/common/test_project_purge.py
@@ -118,8 +118,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_called_once_with(self.project.id)
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
@@ -153,8 +153,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_not_called()
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
@@ -188,8 +188,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_not_called()
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
@@ -224,8 +224,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_called_once_with(self.project.id)
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
@@ -260,8 +260,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_called_once_with(self.project.id)
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
@@ -296,8 +296,8 @@ class TestProjectPurge(TestProjectPurgeInit):
self.projects_mock.delete.assert_called_once_with(self.project.id)
self.servers_mock.list.assert_called_once_with(
search_opts={'tenant_id': self.project.id})
- self.images_mock.list.assert_called_once_with(
- owner=self.project.id)
+ kwargs = {'filters': {'owner': self.project.id}}
+ self.images_mock.list.assert_called_once_with(**kwargs)
volume_search_opts = {'project_id': self.project.id}
self.volumes_mock.list.assert_called_once_with(
search_opts=volume_search_opts)
diff --git a/openstackclient/tests/unit/image/v1/fakes.py b/openstackclient/tests/unit/image/v1/fakes.py
index 80306257..bbec00fc 100644
--- a/openstackclient/tests/unit/image/v1/fakes.py
+++ b/openstackclient/tests/unit/image/v1/fakes.py
@@ -64,6 +64,7 @@ class FakeImagev1Client(object):
self.images.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
+ self.version = 1.0
class TestImagev1(utils.TestCommand):
diff --git a/openstackclient/tests/unit/image/v2/fakes.py b/openstackclient/tests/unit/image/v2/fakes.py
index eabc9325..d82d8114 100644
--- a/openstackclient/tests/unit/image/v2/fakes.py
+++ b/openstackclient/tests/unit/image/v2/fakes.py
@@ -156,6 +156,7 @@ class FakeImagev2Client(object):
self.image_tags.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
+ self.version = 2.0
class TestImagev2(utils.TestCommand):
diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index 45e1045d..3f751818 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -356,6 +356,32 @@ class TestCreatePort(TestPort):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
+ def test_create_with_no_fixed_ips(self):
+ arglist = [
+ '--network', self._port.network_id,
+ '--no-fixed-ip',
+ 'test-port',
+ ]
+ verifylist = [
+ ('network', self._port.network_id),
+ ('enable', True),
+ ('no_fixed_ip', True),
+ ('name', 'test-port'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_port.assert_called_once_with(**{
+ 'admin_state_up': True,
+ 'network_id': self._port.network_id,
+ 'fixed_ips': [],
+ 'name': 'test-port',
+ })
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
def test_create_port_with_allowed_address_pair_ipaddr(self):
pairs = [{'ip_address': '192.168.1.123'},
{'ip_address': '192.168.1.45'}]
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py b/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
index 5d9d03e9..36add8ca 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
@@ -407,6 +407,78 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
+ def test_create_icmp_code_zero(self):
+ self._setup_security_group_rule({
+ 'port_range_min': 15,
+ 'port_range_max': 0,
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--protocol', self._security_group_rule.protocol,
+ '--icmp-type', str(self._security_group_rule.port_range_min),
+ '--icmp-code', str(self._security_group_rule.port_range_max),
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('protocol', self._security_group_rule.protocol),
+ ('icmp_code', self._security_group_rule.port_range_max),
+ ('icmp_type', self._security_group_rule.port_range_min),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
+ def test_create_icmp_code_greater_than_zero(self):
+ self._setup_security_group_rule({
+ 'port_range_min': 15,
+ 'port_range_max': 18,
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--protocol', self._security_group_rule.protocol,
+ '--icmp-type', str(self._security_group_rule.port_range_min),
+ '--icmp-code', str(self._security_group_rule.port_range_max),
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('protocol', self._security_group_rule.protocol),
+ ('icmp_type', self._security_group_rule.port_range_min),
+ ('icmp_code', self._security_group_rule.port_range_max),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
+ def test_create_icmp_code_negative_value(self):
+ self._setup_security_group_rule({
+ 'port_range_min': 15,
+ 'port_range_max': None,
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--protocol', self._security_group_rule.protocol,
+ '--icmp-type', str(self._security_group_rule.port_range_min),
+ '--icmp-code', '-2',
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('protocol', self._security_group_rule.protocol),
+ ('icmp_type', self._security_group_rule.port_range_min),
+ ('icmp_code', -2),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
def test_create_icmp_type(self):
self._setup_security_group_rule({
'port_range_min': 15,
@@ -440,6 +512,104 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns, columns)
self.assertEqual(self.expected_data, data)
+ def test_create_icmp_type_zero(self):
+ self._setup_security_group_rule({
+ 'port_range_min': 0,
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--icmp-type', str(self._security_group_rule.port_range_min),
+ '--protocol', self._security_group_rule.protocol,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('dst_port', None),
+ ('icmp_type', self._security_group_rule.port_range_min),
+ ('icmp_code', None),
+ ('protocol', self._security_group_rule.protocol),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_security_group_rule.assert_called_once_with(**{
+ 'direction': self._security_group_rule.direction,
+ 'ethertype': self._security_group_rule.ether_type,
+ 'port_range_min': self._security_group_rule.port_range_min,
+ 'protocol': self._security_group_rule.protocol,
+ 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix,
+ 'security_group_id': self._security_group.id,
+ })
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
+ def test_create_icmp_type_greater_than_zero(self):
+ self._setup_security_group_rule({
+ 'port_range_min': 13, # timestamp
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--icmp-type', str(self._security_group_rule.port_range_min),
+ '--protocol', self._security_group_rule.protocol,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('dst_port', None),
+ ('icmp_type', self._security_group_rule.port_range_min),
+ ('icmp_code', None),
+ ('protocol', self._security_group_rule.protocol),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_security_group_rule.assert_called_once_with(**{
+ 'direction': self._security_group_rule.direction,
+ 'ethertype': self._security_group_rule.ether_type,
+ 'port_range_min': self._security_group_rule.port_range_min,
+ 'protocol': self._security_group_rule.protocol,
+ 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix,
+ 'security_group_id': self._security_group.id,
+ })
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
+ def test_create_icmp_type_negative_value(self):
+ self._setup_security_group_rule({
+ 'port_range_min': None, # timestamp
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '0.0.0.0/0',
+ })
+ arglist = [
+ '--icmp-type', '-13',
+ '--protocol', self._security_group_rule.protocol,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('dst_port', None),
+ ('icmp_type', -13),
+ ('icmp_code', None),
+ ('protocol', self._security_group_rule.protocol),
+ ('group', self._security_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_security_group_rule.assert_called_once_with(**{
+ 'direction': self._security_group_rule.direction,
+ 'ethertype': self._security_group_rule.ether_type,
+ 'protocol': self._security_group_rule.protocol,
+ 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix,
+ 'security_group_id': self._security_group.id,
+ })
+ self.assertEqual(self.expected_columns, columns)
+ self.assertEqual(self.expected_data, data)
+
def test_create_ipv6_icmp_type_code(self):
self._setup_security_group_rule({
'ether_type': 'IPv6',