Allow to send extra attributes in Neutron related commands
To deprecate and drop support for neutronclient CLI and use only OSC we need feature parity between OSC and neutronclient. Last missing piece here is possibility to send in POST/PUT requests unknown parameters to the Neutron server. This patch adds such possibility to the OSC. Change-Id: Iba09297c2be9fb9fa0be1b3dc65755277b79230e
This commit is contained in:
parent
6bdf030953
commit
b26b7f3440
@ -38,7 +38,7 @@ msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
openstacksdk==0.53.0
|
||||
openstacksdk==0.56.0
|
||||
os-client-config==2.1.0
|
||||
os-service-types==1.7.0
|
||||
osc-lib==2.3.0
|
||||
|
@ -16,10 +16,12 @@ import contextlib
|
||||
import logging
|
||||
|
||||
import openstack.exceptions
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.network import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -75,7 +77,6 @@ class NetDetectionMixin(metaclass=abc.ABCMeta):
|
||||
"""
|
||||
# Have we set it up yet for this command?
|
||||
if not hasattr(self, '_net_type'):
|
||||
# import pdb; pdb.set_trace()
|
||||
try:
|
||||
if self.app.client_manager.is_network_endpoint_enabled():
|
||||
net_type = _NET_TYPE_NEUTRON
|
||||
@ -255,3 +256,74 @@ class NetworkAndComputeShowOne(NetDetectionMixin, command.ShowOne,
|
||||
if exc.details:
|
||||
msg += ", " + str(exc.details)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
|
||||
class NeutronCommandWithExtraArgs(command.Command):
|
||||
"""Create and Update commands with additional extra properties.
|
||||
|
||||
Extra properties can be passed to the command and are then send to the
|
||||
Neutron as given to the command.
|
||||
"""
|
||||
|
||||
# dict of allowed types
|
||||
_allowed_types_dict = {
|
||||
'bool': utils.str2bool,
|
||||
'dict': utils.str2dict,
|
||||
'list': utils.str2list,
|
||||
'int': int,
|
||||
'str': str,
|
||||
}
|
||||
|
||||
def _get_property_converter(self, _property):
|
||||
if 'type' not in _property:
|
||||
converter = str
|
||||
else:
|
||||
converter = self._allowed_types_dict.get(_property['type'])
|
||||
|
||||
if not converter:
|
||||
raise exceptions.CommandError(
|
||||
_("Type {property_type} of property {name} "
|
||||
"is not supported").format(
|
||||
property_type=_property['type'],
|
||||
name=_property['name']))
|
||||
return converter
|
||||
|
||||
def _parse_extra_properties(self, extra_properties):
|
||||
result = {}
|
||||
if extra_properties:
|
||||
for _property in extra_properties:
|
||||
converter = self._get_property_converter(_property)
|
||||
result[_property['name']] = converter(_property['value'])
|
||||
return result
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(NeutronCommandWithExtraArgs, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--extra-property',
|
||||
metavar='type=<property_type>,name=<property_name>,'
|
||||
'value=<property_value>',
|
||||
dest='extra_properties',
|
||||
action=parseractions.MultiKeyValueAction,
|
||||
required_keys=['name', 'value'],
|
||||
optional_keys=['type'],
|
||||
help=_("Additional parameters can be passed using this property. "
|
||||
"Default type of the extra property is string ('str'), but "
|
||||
"other types can be used as well. Available types are: "
|
||||
"'dict', 'list', 'str', 'bool', 'int'. "
|
||||
"In case of 'list' type, 'value' can be "
|
||||
"semicolon-separated list of values. "
|
||||
"For 'dict' value is semicolon-separated list of the "
|
||||
"key:value pairs.")
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
class NeutronUnsetCommandWithExtraArgs(NeutronCommandWithExtraArgs):
|
||||
|
||||
def _parse_extra_properties(self, extra_properties):
|
||||
result = {}
|
||||
if extra_properties:
|
||||
for _property in extra_properties:
|
||||
result[_property['name']] = None
|
||||
|
||||
return result
|
||||
|
@ -11,6 +11,10 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from osc_lib import exceptions
|
||||
|
||||
from openstackclient.i18n import _
|
||||
|
||||
|
||||
# Transform compute security group rule for display.
|
||||
def transform_compute_security_group_rule(sg_rule):
|
||||
@ -39,3 +43,41 @@ def transform_compute_security_group_rule(sg_rule):
|
||||
else:
|
||||
info['remote_security_group'] = ''
|
||||
return info
|
||||
|
||||
|
||||
def str2bool(strbool):
|
||||
if strbool is None:
|
||||
return None
|
||||
return strbool.lower() == 'true'
|
||||
|
||||
|
||||
def str2list(strlist):
|
||||
result = []
|
||||
if strlist:
|
||||
result = strlist.split(';')
|
||||
return result
|
||||
|
||||
|
||||
def str2dict(strdict):
|
||||
"""Convert key1:value1;key2:value2;... string into dictionary.
|
||||
|
||||
:param strdict: string in the form of key1:value1;key2:value2
|
||||
"""
|
||||
result = {}
|
||||
if not strdict:
|
||||
return result
|
||||
i = 0
|
||||
kvlist = []
|
||||
for kv in strdict.split(';'):
|
||||
if ':' in kv:
|
||||
kvlist.append(kv)
|
||||
i += 1
|
||||
elif i == 0:
|
||||
msg = _("missing value for key '%s'")
|
||||
raise exceptions.CommandError(msg % kv)
|
||||
else:
|
||||
kvlist[i - 1] = "%s;%s" % (kvlist[i - 1], kv)
|
||||
for kv in kvlist:
|
||||
key, sep, value = kv.partition(':')
|
||||
result[key] = value
|
||||
return result
|
||||
|
@ -22,6 +22,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -57,7 +58,7 @@ def _get_attrs(client_manager, parsed_args):
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateAddressGroup(command.ShowOne):
|
||||
class CreateAddressGroup(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new Address Group")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -93,6 +94,9 @@ class CreateAddressGroup(command.ShowOne):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
obj = client.create_address_group(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
@ -191,7 +195,7 @@ class ListAddressGroup(command.Lister):
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetAddressGroup(command.Command):
|
||||
class SetAddressGroup(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set address group properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -231,6 +235,9 @@ class SetAddressGroup(command.Command):
|
||||
attrs['name'] = parsed_args.name
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = parsed_args.description
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_address_group(obj, **attrs)
|
||||
if parsed_args.address:
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -57,7 +58,7 @@ def _get_attrs(client_manager, parsed_args):
|
||||
|
||||
# TODO(rtheis): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateAddressScope(command.ShowOne):
|
||||
class CreateAddressScope(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new Address Scope")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -98,6 +99,8 @@ class CreateAddressScope(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_address_scope(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
@ -226,7 +229,7 @@ class ListAddressScope(command.Lister):
|
||||
|
||||
# TODO(rtheis): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetAddressScope(command.Command):
|
||||
class SetAddressScope(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set address scope properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -267,6 +270,8 @@ class SetAddressScope(command.Command):
|
||||
attrs['shared'] = True
|
||||
if parsed_args.no_share:
|
||||
attrs['shared'] = False
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.update_address_scope(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
"""IP Floating action implementations"""
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from osc_lib.utils import tags as _tag
|
||||
|
||||
@ -94,7 +93,8 @@ def _get_attrs(client_manager, parsed_args):
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateFloatingIP(common.NetworkAndComputeShowOne):
|
||||
class CreateFloatingIP(common.NetworkAndComputeShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create floating IP")
|
||||
|
||||
def update_parser_common(self, parser):
|
||||
@ -175,6 +175,8 @@ class CreateFloatingIP(common.NetworkAndComputeShowOne):
|
||||
|
||||
def take_action_network(self, client, parsed_args):
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
with common.check_missing_extension_if_error(
|
||||
self.app.client_manager.network, attrs):
|
||||
obj = client.create_ip(**attrs)
|
||||
@ -390,7 +392,7 @@ class ListFloatingIP(common.NetworkAndComputeLister):
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetFloatingIP(command.Command):
|
||||
class SetFloatingIP(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set floating IP Properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -456,6 +458,9 @@ class SetFloatingIP(command.Command):
|
||||
if 'no_qos_policy' in parsed_args and parsed_args.no_qos_policy:
|
||||
attrs['qos_policy_id'] = None
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_ip(obj, **attrs)
|
||||
|
||||
@ -490,7 +495,7 @@ class ShowFloatingIP(common.NetworkAndComputeShowOne):
|
||||
return (columns, data)
|
||||
|
||||
|
||||
class UnsetFloatingIP(command.Command):
|
||||
class UnsetFloatingIP(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Unset floating IP Properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -526,6 +531,8 @@ class UnsetFloatingIP(command.Command):
|
||||
attrs['port_id'] = None
|
||||
if parsed_args.qos_policy:
|
||||
attrs['qos_policy_id'] = None
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_ip(obj, **attrs)
|
||||
|
@ -19,6 +19,7 @@ from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -32,7 +33,8 @@ def _get_columns(item):
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||
|
||||
|
||||
class CreateFloatingIPPortForwarding(command.ShowOne):
|
||||
class CreateFloatingIPPortForwarding(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create floating IP port forwarding")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -122,6 +124,9 @@ class CreateFloatingIPPortForwarding(command.ShowOne):
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = parsed_args.description
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
obj = client.create_floating_ip_port_forwarding(
|
||||
floating_ip.id,
|
||||
**attrs
|
||||
@ -258,7 +263,7 @@ class ListFloatingIPPortForwarding(command.Lister):
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetFloatingIPPortForwarding(command.Command):
|
||||
class SetFloatingIPPortForwarding(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set floating IP Port Forwarding Properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -352,6 +357,9 @@ class SetFloatingIPPortForwarding(command.Command):
|
||||
if parsed_args.description is not None:
|
||||
attrs['description'] = parsed_args.description
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
client.update_floating_ip_port_forwarding(
|
||||
floating_ip.id, parsed_args.port_forwarding_id, **attrs)
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
from cliff import columns as cliff_columns
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from osc_lib.utils import tags as _tag
|
||||
|
||||
@ -189,7 +188,8 @@ def _add_additional_network_options(parser):
|
||||
|
||||
# TODO(sindhu): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateNetwork(common.NetworkAndComputeShowOne):
|
||||
class CreateNetwork(common.NetworkAndComputeShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new network")
|
||||
|
||||
def update_parser_common(self, parser):
|
||||
@ -334,6 +334,8 @@ class CreateNetwork(common.NetworkAndComputeShowOne):
|
||||
attrs['vlan_transparent'] = True
|
||||
if parsed_args.no_transparent_vlan:
|
||||
attrs['vlan_transparent'] = False
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
with common.check_missing_extension_if_error(
|
||||
self.app.client_manager.network, attrs):
|
||||
obj = client.create_network(**attrs)
|
||||
@ -623,7 +625,7 @@ class ListNetwork(common.NetworkAndComputeLister):
|
||||
|
||||
# TODO(sindhu): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetNetwork(command.Command):
|
||||
class SetNetwork(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -728,6 +730,8 @@ class SetNetwork(command.Command):
|
||||
obj = client.find_network(parsed_args.network, ignore_missing=False)
|
||||
|
||||
attrs = _get_attrs_network(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
if attrs:
|
||||
with common.check_missing_extension_if_error(
|
||||
self.app.client_manager.network, attrs):
|
||||
@ -761,7 +765,7 @@ class ShowNetwork(common.NetworkAndComputeShowOne):
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class UnsetNetwork(command.Command):
|
||||
class UnsetNetwork(common.NeutronUnsetCommandWithExtraArgs):
|
||||
_description = _("Unset network properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -778,8 +782,9 @@ class UnsetNetwork(command.Command):
|
||||
client = self.app.client_manager.network
|
||||
obj = client.find_network(parsed_args.network, ignore_missing=False)
|
||||
|
||||
# NOTE: As of now, UnsetNetwork has no attributes which need
|
||||
# to be updated by update_network().
|
||||
attrs = self._parse_extra_properties(parsed_args.extra_properties)
|
||||
if attrs:
|
||||
client.update_network(obj, **attrs)
|
||||
|
||||
# tags is a subresource and it needs to be updated separately.
|
||||
_tag.update_tags_for_unset(client, obj, parsed_args)
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -88,7 +89,7 @@ class AddNetworkFlavorToProfile(command.Command):
|
||||
|
||||
# TODO(dasanind): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateNetworkFlavor(command.ShowOne):
|
||||
class CreateNetworkFlavor(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new network flavor")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -134,6 +135,8 @@ class CreateNetworkFlavor(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_flavor(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
@ -234,7 +237,7 @@ class RemoveNetworkFlavorFromProfile(command.Command):
|
||||
|
||||
# TODO(dasanind): Use only the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetNetworkFlavor(command.Command):
|
||||
class SetNetworkFlavor(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network flavor properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -281,6 +284,8 @@ class SetNetworkFlavor(command.Command):
|
||||
attrs['enabled'] = True
|
||||
if parsed_args.disable:
|
||||
attrs['enabled'] = False
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.update_flavor(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -60,7 +61,8 @@ def _get_attrs(client_manager, parsed_args):
|
||||
|
||||
# TODO(ndahiwade): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateNetworkFlavorProfile(command.ShowOne):
|
||||
class CreateNetworkFlavorProfile(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new network flavor profile")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -103,6 +105,8 @@ class CreateNetworkFlavorProfile(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if parsed_args.driver is None and parsed_args.metainfo is None:
|
||||
msg = _("Either --driver or --metainfo or both are required")
|
||||
@ -180,7 +184,7 @@ class ListNetworkFlavorProfile(command.Lister):
|
||||
|
||||
# TODO(ndahiwade): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetNetworkFlavorProfile(command.Command):
|
||||
class SetNetworkFlavorProfile(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network flavor profile properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -225,6 +229,8 @@ class SetNetworkFlavorProfile(command.Command):
|
||||
obj = client.find_service_profile(parsed_args.flavor_profile,
|
||||
ignore_missing=False)
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
client.update_service_profile(obj, **attrs)
|
||||
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -59,7 +60,7 @@ def _get_attrs(client_manager, parsed_args):
|
||||
|
||||
# TODO(ankur-gupta-f): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateMeter(command.ShowOne):
|
||||
class CreateMeter(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create network meter")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -100,6 +101,8 @@ class CreateMeter(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_metering_label(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -64,7 +65,7 @@ def _get_attrs(client_manager, parsed_args):
|
||||
return attrs
|
||||
|
||||
|
||||
class CreateMeterRule(command.ShowOne):
|
||||
class CreateMeterRule(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new meter rule")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -130,6 +131,8 @@ class CreateMeterRule(command.ShowOne):
|
||||
ignore_missing=False)
|
||||
parsed_args.meter = _meter.id
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_metering_label_rule(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -67,7 +68,8 @@ def _get_attrs(client_manager, parsed_args):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateNetworkQosPolicy(command.ShowOne):
|
||||
class CreateNetworkQosPolicy(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a QoS policy")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -117,6 +119,8 @@ class CreateNetworkQosPolicy(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_qos_policy(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns, formatters={})
|
||||
@ -209,7 +213,7 @@ class ListNetworkQosPolicy(command.Lister):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetNetworkQosPolicy(command.Command):
|
||||
class SetNetworkQosPolicy(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set QoS policy properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -259,6 +263,8 @@ class SetNetworkQosPolicy(command.Command):
|
||||
parsed_args.policy,
|
||||
ignore_missing=False)
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.update_qos_policy(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -171,7 +172,8 @@ def _add_rule_arguments(parser):
|
||||
)
|
||||
|
||||
|
||||
class CreateNetworkQosRule(command.ShowOne):
|
||||
class CreateNetworkQosRule(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new Network QoS rule")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -198,6 +200,8 @@ class CreateNetworkQosRule(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
network_client = self.app.client_manager.network
|
||||
attrs = _get_attrs(network_client, parsed_args, is_create=True)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
try:
|
||||
obj = _rule_action_call(
|
||||
network_client, ACTION_CREATE, parsed_args.type)(
|
||||
@ -285,7 +289,7 @@ class ListNetworkQosRule(command.Lister):
|
||||
(_get_item_properties(s, columns) for s in data))
|
||||
|
||||
|
||||
class SetNetworkQosRule(command.Command):
|
||||
class SetNetworkQosRule(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set Network QoS rule properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -312,6 +316,8 @@ class SetNetworkQosRule(command.Command):
|
||||
if not rule_type:
|
||||
raise Exception('Rule not found')
|
||||
attrs = _get_attrs(network_client, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
qos_id = attrs.pop('qos_policy_id')
|
||||
qos_rule = _rule_action_call(network_client, ACTION_FIND,
|
||||
rule_type)(attrs.pop('id'), qos_id)
|
||||
|
@ -21,6 +21,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -90,7 +91,7 @@ def _get_attrs(client_manager, parsed_args):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateNetworkRBAC(command.ShowOne):
|
||||
class CreateNetworkRBAC(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create network RBAC policy")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -150,6 +151,8 @@ class CreateNetworkRBAC(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_rbac_policy(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns)
|
||||
@ -253,7 +256,7 @@ class ListNetworkRBAC(command.Lister):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetNetworkRBAC(command.Command):
|
||||
class SetNetworkRBAC(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network RBAC policy properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -291,6 +294,8 @@ class SetNetworkRBAC(command.Command):
|
||||
parsed_args.target_project_domain,
|
||||
).id
|
||||
attrs['target_tenant'] = project_id
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.update_rbac_policy(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -30,7 +31,8 @@ def _get_columns(item):
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, {})
|
||||
|
||||
|
||||
class CreateNetworkSegment(command.ShowOne):
|
||||
class CreateNetworkSegment(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new network segment")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -88,6 +90,8 @@ class CreateNetworkSegment(command.ShowOne):
|
||||
attrs['physical_network'] = parsed_args.physical_network
|
||||
if parsed_args.segment is not None:
|
||||
attrs['segmentation_id'] = parsed_args.segment
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_segment(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns)
|
||||
@ -189,7 +193,7 @@ class ListNetworkSegment(command.Lister):
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetNetworkSegment(command.Command):
|
||||
class SetNetworkSegment(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network segment properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -220,6 +224,8 @@ class SetNetworkSegment(command.Command):
|
||||
attrs['description'] = parsed_args.description
|
||||
if parsed_args.name is not None:
|
||||
attrs['name'] = parsed_args.name
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.update_segment(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -87,7 +88,8 @@ def _update_additional_fields_from_props(columns, props):
|
||||
return props
|
||||
|
||||
|
||||
class CreateNetworkSegmentRange(command.ShowOne):
|
||||
class CreateNetworkSegmentRange(command.ShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create new network segment range")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -209,6 +211,10 @@ class CreateNetworkSegmentRange(command.ShowOne):
|
||||
|
||||
if parsed_args.physical_network:
|
||||
attrs['physical_network'] = parsed_args.physical_network
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
obj = network_client.create_network_segment_range(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(obj, columns)
|
||||
@ -365,7 +371,7 @@ class ListNetworkSegmentRange(command.Lister):
|
||||
return headers, display_props
|
||||
|
||||
|
||||
class SetNetworkSegmentRange(command.Command):
|
||||
class SetNetworkSegmentRange(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set network segment range properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -419,6 +425,8 @@ class SetNetworkSegmentRange(command.Command):
|
||||
attrs['minimum'] = parsed_args.minimum
|
||||
if parsed_args.maximum:
|
||||
attrs['maximum'] = parsed_args.maximum
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
network_client.update_network_segment_range(obj, **attrs)
|
||||
|
||||
|
||||
|
@ -326,7 +326,7 @@ def _convert_extra_dhcp_options(parsed_args):
|
||||
return dhcp_options
|
||||
|
||||
|
||||
class CreatePort(command.ShowOne):
|
||||
class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new port")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -501,6 +501,9 @@ class CreatePort(command.ShowOne):
|
||||
if parsed_args.tags:
|
||||
attrs['tags'] = list(set(parsed_args.tags))
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
with common.check_missing_extension_if_error(
|
||||
self.app.client_manager.network, attrs):
|
||||
obj = client.create_port(**attrs)
|
||||
@ -697,7 +700,7 @@ class ListPort(command.Lister):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetPort(command.Command):
|
||||
class SetPort(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set port properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -871,6 +874,9 @@ class SetPort(command.Command):
|
||||
if parsed_args.data_plane_status:
|
||||
attrs['data_plane_status'] = parsed_args.data_plane_status
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
with common.check_missing_extension_if_error(
|
||||
self.app.client_manager.network, attrs):
|
||||
@ -902,7 +908,7 @@ class ShowPort(command.ShowOne):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class UnsetPort(command.Command):
|
||||
class UnsetPort(common.NeutronUnsetCommandWithExtraArgs):
|
||||
_description = _("Unset port properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -1023,6 +1029,9 @@ class UnsetPort(command.Command):
|
||||
if parsed_args.numa_policy:
|
||||
attrs['numa_affinity_policy'] = None
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_port(obj, **attrs)
|
||||
|
||||
|
@ -27,6 +27,7 @@ from osc_lib.utils import tags as _tag
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -256,7 +257,7 @@ class RemoveExtraRoutesFromRouter(command.ShowOne):
|
||||
|
||||
# TODO(yanxing'an): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateRouter(command.ShowOne):
|
||||
class CreateRouter(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new router")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -332,6 +333,9 @@ class CreateRouter(command.ShowOne):
|
||||
attrs['ha'] = True
|
||||
if parsed_args.no_ha:
|
||||
attrs['ha'] = False
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
obj = client.create_router(**attrs)
|
||||
# tags cannot be set when created, so tags need to be set later.
|
||||
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||
@ -576,7 +580,7 @@ class RemoveSubnetFromRouter(command.Command):
|
||||
|
||||
# TODO(yanxing'an): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetRouter(command.Command):
|
||||
class SetRouter(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set router properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -767,6 +771,10 @@ class SetRouter(command.Command):
|
||||
|
||||
if 'no_qos_policy' in parsed_args and parsed_args.no_qos_policy:
|
||||
attrs['external_gateway_info']['qos_policy_id'] = None
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_router(obj, **attrs)
|
||||
# tags is a subresource and it needs to be updated separately.
|
||||
@ -809,7 +817,7 @@ class ShowRouter(command.ShowOne):
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class UnsetRouter(command.Command):
|
||||
class UnsetRouter(common.NeutronUnsetCommandWithExtraArgs):
|
||||
_description = _("Unset router properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -875,6 +883,10 @@ class UnsetRouter(command.Command):
|
||||
|
||||
if parsed_args.external_gateway:
|
||||
attrs['external_gateway_info'] = {}
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_router(obj, **attrs)
|
||||
# tags is a subresource and it needs to be updated separately.
|
||||
|
@ -95,7 +95,8 @@ def _get_columns(item):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateSecurityGroup(common.NetworkAndComputeShowOne):
|
||||
class CreateSecurityGroup(common.NetworkAndComputeShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new security group")
|
||||
|
||||
def update_parser_common(self, parser):
|
||||
@ -160,6 +161,8 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
|
||||
parsed_args.project_domain,
|
||||
).id
|
||||
attrs['tenant_id'] = project_id
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
# Create the security group and display the results.
|
||||
obj = client.create_security_group(**attrs)
|
||||
@ -310,7 +313,8 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetSecurityGroup(common.NetworkAndComputeCommand):
|
||||
class SetSecurityGroup(common.NetworkAndComputeCommand,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set security group properties")
|
||||
|
||||
def update_parser_common(self, parser):
|
||||
@ -362,6 +366,8 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
|
||||
attrs['stateful'] = True
|
||||
if parsed_args.stateless:
|
||||
attrs['stateful'] = False
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
# NOTE(rtheis): Previous behavior did not raise a CommandError
|
||||
# if there were no updates. Maintain this behavior and issue
|
||||
# the update.
|
||||
|
@ -104,7 +104,8 @@ def _is_icmp_protocol(protocol):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
|
||||
class CreateSecurityGroupRule(common.NetworkAndComputeShowOne,
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a new security group rule")
|
||||
|
||||
def update_parser_common(self, parser):
|
||||
@ -355,6 +356,9 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
|
||||
).id
|
||||
attrs['tenant_id'] = project_id
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
# Create and show the security group rule.
|
||||
obj = client.create_security_group_rule(**attrs)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
|
@ -26,6 +26,7 @@ from osc_lib.utils import tags as _tag
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -250,7 +251,7 @@ def _get_attrs(client_manager, parsed_args, is_create=True):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateSubnet(command.ShowOne):
|
||||
class CreateSubnet(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create a subnet")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -373,6 +374,8 @@ class CreateSubnet(command.ShowOne):
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = _get_attrs(self.app.client_manager, parsed_args)
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_subnet(**attrs)
|
||||
# tags cannot be set when created, so tags need to be set later.
|
||||
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||
@ -545,7 +548,7 @@ class ListSubnet(command.Lister):
|
||||
|
||||
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetSubnet(command.Command):
|
||||
class SetSubnet(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set subnet properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -630,6 +633,8 @@ class SetSubnet(command.Command):
|
||||
attrs['allocation_pools'] = []
|
||||
if 'service_types' in attrs:
|
||||
attrs['service_types'] += obj.service_types
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
if attrs:
|
||||
client.update_subnet(obj, **attrs)
|
||||
# tags is a subresource and it needs to be updated separately.
|
||||
@ -657,7 +662,7 @@ class ShowSubnet(command.ShowOne):
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class UnsetSubnet(command.Command):
|
||||
class UnsetSubnet(common.NeutronUnsetCommandWithExtraArgs):
|
||||
_description = _("Unset subnet properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -744,6 +749,9 @@ class UnsetSubnet(command.Command):
|
||||
_update_arguments(attrs['service_types'],
|
||||
parsed_args.service_types,
|
||||
'service-type')
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_subnet(obj, **attrs)
|
||||
|
||||
|
@ -24,6 +24,7 @@ from osc_lib.utils import tags as _tag
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from openstackclient.identity import common as identity_common
|
||||
from openstackclient.network import common
|
||||
from openstackclient.network import sdk_utils
|
||||
|
||||
|
||||
@ -146,7 +147,7 @@ def _add_default_options(parser):
|
||||
|
||||
# TODO(rtheis): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class CreateSubnetPool(command.ShowOne):
|
||||
class CreateSubnetPool(command.ShowOne, common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Create subnet pool")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -203,6 +204,8 @@ class CreateSubnetPool(command.ShowOne):
|
||||
# NeutronServer expects prefixes to be a List
|
||||
if "prefixes" not in attrs:
|
||||
attrs['prefixes'] = []
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
obj = client.create_subnet_pool(**attrs)
|
||||
# tags cannot be set when created, so tags need to be set later.
|
||||
_tag.update_tags_for_set(client, obj, parsed_args)
|
||||
@ -351,7 +354,7 @@ class ListSubnetPool(command.Lister):
|
||||
|
||||
# TODO(rtheis): Use the SDK resource mapped attribute names once the
|
||||
# OSC minimum requirements include SDK 1.0.
|
||||
class SetSubnetPool(command.Command):
|
||||
class SetSubnetPool(common.NeutronCommandWithExtraArgs):
|
||||
_description = _("Set subnet pool properties")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
@ -408,6 +411,9 @@ class SetSubnetPool(command.Command):
|
||||
if 'prefixes' in attrs:
|
||||
attrs['prefixes'].extend(obj.prefixes)
|
||||
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
|
||||
if attrs:
|
||||
client.update_subnet_pool(obj, **attrs)
|
||||
# tags is a subresource and it needs to be updated separately.
|
||||
|
@ -102,6 +102,27 @@ class FakeNetworkAndComputeShowOne(common.NetworkAndComputeShowOne):
|
||||
return client.compute_action(parsed_args)
|
||||
|
||||
|
||||
class FakeCreateNeutronCommandWithExtraArgs(
|
||||
common.NeutronCommandWithExtraArgs):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(FakeCreateNeutronCommandWithExtraArgs,
|
||||
self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--known-attribute',
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.network
|
||||
attrs = {}
|
||||
if 'known_attribute' in parsed_args:
|
||||
attrs['known_attribute'] = parsed_args.known_attribute
|
||||
attrs.update(
|
||||
self._parse_extra_properties(parsed_args.extra_properties))
|
||||
client.test_create_action(**attrs)
|
||||
|
||||
|
||||
class TestNetworkAndCompute(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
@ -187,3 +208,121 @@ class TestNetworkAndComputeShowOne(TestNetworkAndCompute):
|
||||
m_action.side_effect = openstack.exceptions.HttpException("bar")
|
||||
self.assertRaisesRegex(exceptions.CommandError, "bar",
|
||||
self.cmd.take_action, mock.Mock())
|
||||
|
||||
|
||||
class TestNeutronCommandWithExtraArgs(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNeutronCommandWithExtraArgs, self).setUp()
|
||||
|
||||
self.namespace = argparse.Namespace()
|
||||
|
||||
self.app.client_manager.network = mock.Mock()
|
||||
self.network = self.app.client_manager.network
|
||||
self.network.test_create_action = mock.Mock()
|
||||
|
||||
# Subclasses can override the command object to test.
|
||||
self.cmd = FakeCreateNeutronCommandWithExtraArgs(
|
||||
self.app, self.namespace)
|
||||
|
||||
def test_create_extra_attributes_default_type(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'name=extra_name,value=extra_value'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'value': 'extra_value'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value', extra_name='extra_value')
|
||||
|
||||
def test_create_extra_attributes_string(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'type=str,name=extra_name,value=extra_value'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'type': 'str',
|
||||
'value': 'extra_value'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value', extra_name='extra_value')
|
||||
|
||||
def test_create_extra_attributes_bool(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'type=bool,name=extra_name,value=TrUe'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'type': 'bool',
|
||||
'value': 'TrUe'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value', extra_name=True)
|
||||
|
||||
def test_create_extra_attributes_int(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'type=int,name=extra_name,value=8'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'type': 'int',
|
||||
'value': '8'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value', extra_name=8)
|
||||
|
||||
def test_create_extra_attributes_list(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'type=list,name=extra_name,value=v_1;v_2'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'type': 'list',
|
||||
'value': 'v_1;v_2'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value', extra_name=['v_1', 'v_2'])
|
||||
|
||||
def test_create_extra_attributes_dict(self):
|
||||
arglist = [
|
||||
'--known-attribute', 'known-value',
|
||||
'--extra-property', 'type=dict,name=extra_name,value=n1:v1;n2:v2'
|
||||
]
|
||||
verifylist = [
|
||||
('known_attribute', 'known-value'),
|
||||
('extra_properties', [{'name': 'extra_name',
|
||||
'type': 'dict',
|
||||
'value': 'n1:v1;n2:v2'}])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.network.test_create_action.assert_called_with(
|
||||
known_attribute='known-value',
|
||||
extra_name={'n1': 'v1', 'n2': 'v2'})
|
||||
|
59
openstackclient/tests/unit/network/test_utils.py
Normal file
59
openstackclient/tests/unit/network/test_utils.py
Normal file
@ -0,0 +1,59 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from osc_lib import exceptions
|
||||
|
||||
from openstackclient.network import utils
|
||||
from openstackclient.tests.unit import utils as tests_utils
|
||||
|
||||
|
||||
class TestUtils(tests_utils.TestCase):
|
||||
|
||||
def test_str2bool(self):
|
||||
self.assertTrue(utils.str2bool("true"))
|
||||
self.assertTrue(utils.str2bool("True"))
|
||||
self.assertTrue(utils.str2bool("TRUE"))
|
||||
self.assertTrue(utils.str2bool("TrUe"))
|
||||
|
||||
self.assertFalse(utils.str2bool("false"))
|
||||
self.assertFalse(utils.str2bool("False"))
|
||||
self.assertFalse(utils.str2bool("FALSE"))
|
||||
self.assertFalse(utils.str2bool("FaLsE"))
|
||||
self.assertFalse(utils.str2bool("Something else"))
|
||||
self.assertFalse(utils.str2bool(""))
|
||||
|
||||
self.assertIsNone(utils.str2bool(None))
|
||||
|
||||
def test_str2list(self):
|
||||
self.assertEqual(
|
||||
['a', 'b', 'c'], utils.str2list("a;b;c"))
|
||||
self.assertEqual(
|
||||
['abc'], utils.str2list("abc"))
|
||||
|
||||
self.assertEqual([], utils.str2list(""))
|
||||
self.assertEqual([], utils.str2list(None))
|
||||
|
||||
def test_str2dict(self):
|
||||
self.assertEqual(
|
||||
{'a': 'aaa', 'b': '2'},
|
||||
utils.str2dict('a:aaa;b:2'))
|
||||
self.assertEqual(
|
||||
{'a': 'aaa;b;c', 'd': 'ddd'},
|
||||
utils.str2dict('a:aaa;b;c;d:ddd'))
|
||||
|
||||
self.assertEqual({}, utils.str2dict(""))
|
||||
self.assertEqual({}, utils.str2dict(None))
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
utils.str2dict, "aaa;b:2")
|
@ -5,7 +5,7 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
|
||||
cliff>=3.5.0 # Apache-2.0
|
||||
iso8601>=0.1.11 # MIT
|
||||
openstacksdk>=0.53.0 # Apache-2.0
|
||||
openstacksdk>=0.56.0 # Apache-2.0
|
||||
osc-lib>=2.3.0 # Apache-2.0
|
||||
oslo.i18n>=3.15.3 # Apache-2.0
|
||||
oslo.utils>=3.33.0 # Apache-2.0
|
||||
|
Loading…
Reference in New Issue
Block a user