diff options
Diffstat (limited to 'openstackclient/network')
| -rw-r--r-- | openstackclient/network/client.py | 5 | ||||
| -rw-r--r-- | openstackclient/network/sdk_utils.py | 23 | ||||
| -rw-r--r-- | openstackclient/network/v2/floating_ip.py | 4 | ||||
| -rw-r--r-- | openstackclient/network/v2/network.py | 52 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_agent.py | 124 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_auto_allocated_topology.py | 136 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_flavor.py | 247 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_meter.py (renamed from openstackclient/network/v2/meter.py) | 0 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_qos_policy.py | 29 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_qos_rule.py | 3 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_qos_rule_type.py | 5 | ||||
| -rw-r--r-- | openstackclient/network/v2/port.py | 62 | ||||
| -rw-r--r-- | openstackclient/network/v2/security_group.py | 50 | ||||
| -rw-r--r-- | openstackclient/network/v2/security_group_rule.py | 2 | ||||
| -rw-r--r-- | openstackclient/network/v2/subnet.py | 10 |
15 files changed, 654 insertions, 98 deletions
diff --git a/openstackclient/network/client.py b/openstackclient/network/client.py index c562058d..9525b947 100644 --- a/openstackclient/network/client.py +++ b/openstackclient/network/client.py @@ -44,6 +44,11 @@ def make_client(instance): LOG.debug('Connection: %s', conn) LOG.debug('Network client initialized using OpenStack SDK: %s', conn.network) + + # NOTE(dtroyer): Horrible ugly hack since we don't actually save + # the connection anywhere yet, so stash it in the + # instance directly from here for other uses + instance.sdk_connection = conn return conn.network diff --git a/openstackclient/network/sdk_utils.py b/openstackclient/network/sdk_utils.py index 7bd54e46..04f168be 100644 --- a/openstackclient/network/sdk_utils.py +++ b/openstackclient/network/sdk_utils.py @@ -13,8 +13,24 @@ import six -# Get the OSC show command display and attribute columns for an SDK resource. -def get_osc_show_columns_for_sdk_resource(sdk_resource, osc_column_map): +def get_osc_show_columns_for_sdk_resource( + sdk_resource, + osc_column_map, + invisible_columns=[] +): + """Get and filter the display and attribute columns for an SDK resource. + + Common utility function for preparing the output of an OSC show command. + Some of the columns may need to get renamed, others made invisible. + + :param sdk_resource: An SDK resource + :param osc_column_map: A hash of mappings for display column names + :param invisible_columns: A list of invisible column names + + :returns: Two tuples containing the names of the display and attribute + columns + """ + if getattr(sdk_resource, 'allow_get', None) is not None: resource_dict = sdk_resource.to_dict( body=True, headers=False, ignore_none=False) @@ -24,6 +40,9 @@ def get_osc_show_columns_for_sdk_resource(sdk_resource, osc_column_map): # Build the OSC column names to display for the SDK resource. attr_map = {} display_columns = list(resource_dict.keys()) + for col_name in invisible_columns: + if col_name in display_columns: + display_columns.remove(col_name) for sdk_attr, osc_attr in six.iteritems(osc_column_map): if sdk_attr in display_columns: attr_map[osc_attr] = sdk_attr diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py index 980c41c7..41b208aa 100644 --- a/openstackclient/network/v2/floating_ip.py +++ b/openstackclient/network/v2/floating_ip.py @@ -241,7 +241,7 @@ class DeleteFloatingIP(common.NetworkAndComputeDelete): def take_action_network(self, client, parsed_args): (obj, self.ip_cache) = _find_floating_ip( - client.session, + self.app.client_manager.sdk_connection.session, self.ip_cache, self.r, ignore_missing=False, @@ -472,7 +472,7 @@ class ShowFloatingIP(common.NetworkAndComputeShowOne): def take_action_network(self, client, parsed_args): (obj, self.ip_cache) = _find_floating_ip( - client.session, + self.app.client_manager.sdk_connection.session, [], parsed_args.floating_ip, ignore_missing=False, diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 655147d9..3e0bb776 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -60,12 +60,10 @@ def _get_network_columns(item): def _get_columns(item): - columns = list(item.keys()) - if 'tenant_id' in columns: - columns.remove('tenant_id') - if 'project_id' not in columns: - columns.append('project_id') - return tuple(sorted(columns)) + column_map = { + 'tenant_id': 'project_id', + } + return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) def _get_attrs(client_manager, parsed_args): @@ -111,10 +109,10 @@ def _get_attrs(client_manager, parsed_args): attrs['router:external'] = False if parsed_args.external: attrs['router:external'] = True - if parsed_args.no_default: - attrs['is_default'] = False - if parsed_args.default: - attrs['is_default'] = True + if parsed_args.no_default: + attrs['is_default'] = False + if parsed_args.default: + attrs['is_default'] = True # Update Provider network options if parsed_args.provider_network_type: attrs['provider:network_type'] = parsed_args.provider_network_type @@ -305,9 +303,9 @@ class CreateNetwork(common.NetworkAndComputeShowOne): def take_action_compute(self, client, parsed_args): attrs = _get_attrs_compute(self.app.client_manager, parsed_args) obj = client.networks.create(**attrs) - columns = _get_columns(obj._info) + display_columns, columns = _get_columns(obj._info) data = utils.get_dict_properties(obj._info, columns) - return (columns, data) + return (display_columns, data) class DeleteNetwork(common.NetworkAndComputeDelete): @@ -420,7 +418,11 @@ class ListNetwork(common.NetworkAndComputeLister): help=_("List networks according to VLAN ID for VLAN networks " "or Tunnel ID for GENEVE/GRE/VXLAN networks") ) - + parser.add_argument( + '--agent', + metavar='<agent-id>', + dest='agent_id', + help=_('List networks hosted by agent (ID only)')) return parser def take_action_network(self, client, parsed_args): @@ -450,6 +452,26 @@ class ListNetwork(common.NetworkAndComputeLister): 'Router Type', 'Availability Zones', ) + elif parsed_args.agent_id: + columns = ( + 'id', + 'name', + 'subnet_ids' + ) + column_headers = ( + 'ID', + 'Name', + 'Subnets', + ) + client = self.app.client_manager.network + dhcp_agent = client.get_agent(parsed_args.agent_id) + data = client.dhcp_agent_hosting_networks(dhcp_agent) + + return (column_headers, + (utils.get_item_properties( + s, columns, + formatters=_formatters, + ) for s in data)) else: columns = ( 'id', @@ -665,6 +687,6 @@ class ShowNetwork(common.NetworkAndComputeShowOne): client.networks, parsed_args.network, ) - columns = _get_columns(obj._info) + display_columns, columns = _get_columns(obj._info) data = utils.get_dict_properties(obj._info, columns) - return (columns, data) + return (display_columns, data) diff --git a/openstackclient/network/v2/network_agent.py b/openstackclient/network/v2/network_agent.py index d429fa08..7c2edb88 100644 --- a/openstackclient/network/v2/network_agent.py +++ b/openstackclient/network/v2/network_agent.py @@ -29,7 +29,6 @@ LOG = logging.getLogger(__name__) def _format_admin_state(state): return 'UP' if state else 'DOWN' - _formatters = { 'admin_state_up': _format_admin_state, 'is_admin_state_up': _format_admin_state, @@ -45,6 +44,40 @@ def _get_network_columns(item): return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) +class AddNetworkToAgent(command.Command): + _description = _("Add network to an agent") + + def get_parser(self, prog_name): + parser = super(AddNetworkToAgent, self).get_parser(prog_name) + parser.add_argument( + '--dhcp', + action='store_true', + help=_('Add network to a DHCP agent')) + parser.add_argument( + 'agent_id', + metavar='<agent-id>', + help=_('Agent to which a network is added. (ID only)')) + parser.add_argument( + 'network', + metavar='<network>', + help=_('Network to be added to an agent. (ID or name)')) + + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + agent = client.get_agent(parsed_args.agent_id) + if parsed_args.dhcp: + network = client.find_network( + parsed_args.network, ignore_missing=False) + try: + client.add_dhcp_agent_to_network(agent, network) + except Exception: + msg = 'Failed to add {} to {}'.format( + network.name, agent.agent_type) + exceptions.CommandError(msg) + + class DeleteNetworkAgent(command.Command): _description = _("Delete network agent(s)") @@ -89,10 +122,11 @@ class ListNetworkAgent(command.Lister): parser.add_argument( '--agent-type', metavar='<agent-type>', - choices=["dhcp", "open-vswitch", "linux-bridge", "ofa", "l3", - "loadbalancer", "metering", "metadata", "macvtap", "nic"], + choices=["bgp", "dhcp", "open-vswitch", "linux-bridge", "ofa", + "l3", "loadbalancer", "metering", "metadata", "macvtap", + "nic"], help=_("List only agents with the specified agent type. " - "The supported agent types are: dhcp, open-vswitch, " + "The supported agent types are: bgp, dhcp, open-vswitch, " "linux-bridge, ofa, l3, loadbalancer, metering, " "metadata, macvtap, nic.") ) @@ -101,6 +135,11 @@ class ListNetworkAgent(command.Lister): metavar='<host>', help=_("List only agents running on the specified host") ) + parser.add_argument( + '--network', + metavar='<network>', + help=_('List agents hosting a network (name or ID)') + ) return parser def take_action(self, parsed_args): @@ -125,6 +164,7 @@ class ListNetworkAgent(command.Lister): ) key_value = { + 'bgp': 'BGP dynamic routing agent', 'dhcp': 'DHCP agent', 'open-vswitch': 'Open vSwitch agent', 'linux-bridge': 'Linux bridge agent', @@ -138,16 +178,72 @@ class ListNetworkAgent(command.Lister): } filters = {} - if parsed_args.agent_type is not None: - filters['agent_type'] = key_value[parsed_args.agent_type] - if parsed_args.host is not None: - filters['host'] = parsed_args.host - - data = client.agents(**filters) - return (column_headers, - (utils.get_item_properties( - s, columns, formatters=_formatters, - ) for s in data)) + if parsed_args.network is not None: + columns = ( + 'id', + 'host', + 'is_admin_state_up', + 'is_alive', + ) + column_headers = ( + 'ID', + 'Host', + 'Admin State Up', + 'Alive', + ) + network = client.find_network( + parsed_args.network, ignore_missing=False) + data = client.network_hosting_dhcp_agents(network) + + return (column_headers, + (utils.get_item_properties( + s, columns, + formatters=_formatters, + ) for s in data)) + else: + if parsed_args.agent_type is not None: + filters['agent_type'] = key_value[parsed_args.agent_type] + if parsed_args.host is not None: + filters['host'] = parsed_args.host + + data = client.agents(**filters) + return (column_headers, + (utils.get_item_properties( + s, columns, formatters=_formatters, + ) for s in data)) + + +class RemoveNetworkFromAgent(command.Command): + _description = _("Remove network from an agent.") + + def get_parser(self, prog_name): + parser = super(RemoveNetworkFromAgent, self).get_parser(prog_name) + parser.add_argument( + '--dhcp', + action='store_true', + help=_('Remove network from DHCP agent')) + parser.add_argument( + 'agent_id', + metavar='<agent-id>', + help=_('Agent to which a network is removed. (ID only)')) + parser.add_argument( + 'network', + metavar='<network>', + help=_('Network to be removed from an agent. (ID or name)')) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + agent = client.get_agent(parsed_args.agent_id) + if parsed_args.dhcp: + network = client.find_network( + parsed_args.network, ignore_missing=False) + try: + client.remove_dhcp_agent_from_network(agent, network) + except Exception: + msg = 'Failed to remove {} to {}'.format( + network.name, agent.agent_type) + exceptions.CommandError(msg) # TODO(huanxuan): Use the SDK resource mapped attribute names once the diff --git a/openstackclient/network/v2/network_auto_allocated_topology.py b/openstackclient/network/v2/network_auto_allocated_topology.py new file mode 100644 index 00000000..36f39200 --- /dev/null +++ b/openstackclient/network/v2/network_auto_allocated_topology.py @@ -0,0 +1,136 @@ +# 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. +# + +"""Auto-allocated Topology Implementations""" + +import logging + +from osc_lib.command import command +from osc_lib import utils + +from openstackclient.i18n import _ +from openstackclient.identity import common as identity_common +from openstackclient.network import sdk_utils + +LOG = logging.getLogger(__name__) + + +def _get_columns(item): + column_map = { + 'tenant_id': 'project_id', + } + return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) + + +def _format_check_resource_columns(): + return ('dry_run',) + + +def _format_check_resource(item): + item_id = getattr(item, 'id', False) + if item_id == 'dry-run=pass': + item.check_resource = 'pass' + return item + + +def _get_attrs(client_manager, parsed_args): + attrs = {} + if parsed_args.project: + identity_client = client_manager.identity + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + if parsed_args.check_resources: + attrs['check_resources'] = True + + return attrs + + +# TODO(ankur-gupta-f): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. +class CreateAutoAllocatedTopology(command.ShowOne): + _description = _("Create the auto allocated topology for project") + + def get_parser(self, prog_name): + parser = super(CreateAutoAllocatedTopology, self).get_parser(prog_name) + parser.add_argument( + '--project', + metavar='<project>', + help=_("Return the auto allocated topology for a given project. " + "Default is current project") + ) + identity_common.add_project_domain_option_to_parser(parser) + parser.add_argument( + '--check-resources', + action='store_true', + help=_("Validate the requirements for auto allocated topology. " + "Does not return a topology.") + ) + parser.add_argument( + '--or-show', + action='store_true', + default=True, + help=_("If topology exists returns the topology's " + "information (Default)") + ) + + return parser + + def check_resource_topology(self, client, parsed_args): + obj = client.validate_auto_allocated_topology(parsed_args.project) + + columns = _format_check_resource_columns() + data = utils.get_item_properties(_format_check_resource(obj), + columns, + formatters={}) + + return (columns, data) + + def get_topology(self, client, parsed_args): + obj = client.get_auto_allocated_topology(parsed_args.project) + display_columns, columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns, formatters={}) + return (display_columns, data) + + def take_action(self, parsed_args): + client = self.app.client_manager.network + if parsed_args.check_resources: + columns, data = self.check_resource_topology(client, parsed_args) + else: + columns, data = self.get_topology(client, parsed_args) + return (columns, data) + + +# TODO(ankur-gupta-f): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. +class DeleteAutoAllocatedTopology(command.Command): + _description = _("Delete auto allocated topology for project") + + def get_parser(self, prog_name): + parser = super(DeleteAutoAllocatedTopology, self).get_parser(prog_name) + parser.add_argument( + '--project', + metavar='<project>', + help=_('Delete auto allocated topology for a given project. ' + 'Default is the current project') + ) + identity_common.add_project_domain_option_to_parser(parser) + + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + client.delete_auto_allocated_topology(parsed_args.project) diff --git a/openstackclient/network/v2/network_flavor.py b/openstackclient/network/v2/network_flavor.py new file mode 100644 index 00000000..3a3324c0 --- /dev/null +++ b/openstackclient/network/v2/network_flavor.py @@ -0,0 +1,247 @@ +# 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. +# + +"""Flavor action implementations""" + +import logging + +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils + +from openstackclient.i18n import _ +from openstackclient.identity import common as identity_common +from openstackclient.network import sdk_utils + + +LOG = logging.getLogger(__name__) + + +def _get_columns(item): + column_map = { + 'is_enabled': 'enabled', + 'tenant_id': 'project_id', + } + + return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) + + +def _get_attrs(client_manager, parsed_args): + attrs = {} + attrs['name'] = parsed_args.name + attrs['service_type'] = parsed_args.service_type + if parsed_args.description is not None: + attrs['description'] = parsed_args.description + if parsed_args.enable: + attrs['enabled'] = True + if parsed_args.disable: + attrs['enabled'] = False + if 'project' in parsed_args and parsed_args.project is not None: + identity_client = client_manager.identity + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + + return attrs + + +# TODO(dasanind): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. +class CreateNetworkFlavor(command.ShowOne): + _description = _("Create new network flavor") + + def get_parser(self, prog_name): + parser = super(CreateNetworkFlavor, self).get_parser(prog_name) + parser.add_argument( + 'name', + metavar="<name>", + help=_("Name for the flavor") + ) + parser.add_argument( + '--service-type', + metavar="<service-type>", + required=True, + help=_('Service type to which the flavor applies to: e.g. VPN ' + '(See openstack network service provider list for loaded ' + 'examples.)') + ) + parser.add_argument( + '--description', + help=_('Description for the flavor') + ) + parser.add_argument( + '--project', + metavar="<project>", + help=_("Owner's project (name or ID)") + ) + identity_common.add_project_domain_option_to_parser(parser) + + enable_group = parser.add_mutually_exclusive_group() + enable_group.add_argument( + '--enable', + action='store_true', + help=_("Enable the flavor (default)") + ) + enable_group.add_argument( + '--disable', + action='store_true', + help=_("Disable the flavor") + ) + + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + attrs = _get_attrs(self.app.client_manager, parsed_args) + obj = client.create_flavor(**attrs) + display_columns, columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns, formatters={}) + + return (display_columns, data) + + +class DeleteNetworkFlavor(command.Command): + _description = _("Delete network flavors") + + def get_parser(self, prog_name): + parser = super(DeleteNetworkFlavor, self).get_parser(prog_name) + + parser.add_argument( + 'flavor', + metavar='<flavor>', + nargs='+', + help=_('Flavor(s) to delete (name or ID)') + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + result = 0 + + for flavor in parsed_args.flavor: + try: + obj = client.find_flavor(flavor, ignore_missing=False) + client.delete_flavor(obj) + except Exception as e: + result += 1 + LOG.error(_("Failed to delete flavor with " + "name or ID '%(flavor)s': %(e)s"), + {"flavor": flavor, "e": e}) + if result > 0: + total = len(parsed_args.flavor) + msg = (_("%(result)s of %(total)s flavors failed " + "to delete.") % {"result": result, "total": total}) + raise exceptions.CommandError(msg) + + +class ListNetworkFlavor(command.Lister): + _description = _("List network flavors") + + def take_action(self, parsed_args): + client = self.app.client_manager.network + + columns = ( + 'id', + 'name', + 'is_enabled', + 'service_type', + 'description' + ) + column_headers = ( + 'ID', + 'Name', + 'Enabled', + 'Service Type', + 'Description' + ) + + data = client.flavors() + return (column_headers, + (utils.get_item_properties( + s, columns, + ) for s in data)) + + +# TODO(dasanind): Use only the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. +class SetNetworkFlavor(command.Command): + _description = _("Set network flavor properties") + + def get_parser(self, prog_name): + parser = super(SetNetworkFlavor, self).get_parser(prog_name) + parser.add_argument( + 'flavor', + metavar="<flavor>", + help=_("Flavor to update (name or ID)") + ) + parser.add_argument( + '--description', + help=_('Set network flavor description') + ) + enable_group = parser.add_mutually_exclusive_group() + enable_group.add_argument( + '--disable', + action='store_true', + help=_("Disable network flavor") + ) + enable_group.add_argument( + '--enable', + action='store_true', + help=_("Enable network flavor") + ) + parser.add_argument( + '--name', + metavar="<name>", + help=_('Set flavor name') + ) + + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj = client.find_flavor( + parsed_args.flavor, + ignore_missing=False) + attrs = {} + if parsed_args.name is not None: + attrs['name'] = parsed_args.name + if parsed_args.description is not None: + attrs['description'] = parsed_args.description + if parsed_args.enable: + attrs['enabled'] = True + if parsed_args.disable: + attrs['enabled'] = False + client.update_flavor(obj, **attrs) + + +class ShowNetworkFlavor(command.ShowOne): + _description = _("Display network flavor details") + + def get_parser(self, prog_name): + parser = super(ShowNetworkFlavor, self).get_parser(prog_name) + parser.add_argument( + 'flavor', + metavar='<flavor>', + help=_('Flavor to display (name or ID)') + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj = client.find_flavor(parsed_args.flavor, ignore_missing=False) + display_columns, columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns) + return display_columns, data diff --git a/openstackclient/network/v2/meter.py b/openstackclient/network/v2/network_meter.py index df0e1da1..df0e1da1 100644 --- a/openstackclient/network/v2/meter.py +++ b/openstackclient/network/v2/network_meter.py diff --git a/openstackclient/network/v2/network_qos_policy.py b/openstackclient/network/v2/network_qos_policy.py index 5ccbe36b..fef3ec88 100644 --- a/openstackclient/network/v2/network_qos_policy.py +++ b/openstackclient/network/v2/network_qos_policy.py @@ -37,9 +37,9 @@ def _get_columns(item): def _get_attrs(client_manager, parsed_args): attrs = {} - if parsed_args.name is not None: + if 'name' in parsed_args and parsed_args.name is not None: attrs['name'] = str(parsed_args.name) - if parsed_args.description is not None: + if 'description' in parsed_args and parsed_args.description is not None: attrs['description'] = parsed_args.description if parsed_args.share: attrs['shared'] = True @@ -143,6 +143,27 @@ class DeleteNetworkQosPolicy(command.Command): class ListNetworkQosPolicy(command.Lister): _description = _("List QoS policies") + def get_parser(self, prog_name): + parser = super(ListNetworkQosPolicy, self).get_parser(prog_name) + parser.add_argument( + '--project', + metavar='<project>', + help=_("List qos policies according to their project (name or ID)") + ) + identity_common.add_project_domain_option_to_parser(parser) + shared_group = parser.add_mutually_exclusive_group() + shared_group.add_argument( + '--share', + action='store_true', + help=_("List qos policies shared between projects") + ) + shared_group.add_argument( + '--no-share', + action='store_true', + help=_("List qos policies not shared between projects") + ) + return parser + def take_action(self, parsed_args): client = self.app.client_manager.network columns = ( @@ -157,8 +178,8 @@ class ListNetworkQosPolicy(command.Lister): 'Shared', 'Project', ) - data = client.qos_policies() - + attrs = _get_attrs(self.app.client_manager, parsed_args) + data = client.qos_policies(**attrs) return (column_headers, (utils.get_item_properties( s, columns, formatters={}, diff --git a/openstackclient/network/v2/network_qos_rule.py b/openstackclient/network/v2/network_qos_rule.py index a662ca18..baed0424 100644 --- a/openstackclient/network/v2/network_qos_rule.py +++ b/openstackclient/network/v2/network_qos_rule.py @@ -14,7 +14,6 @@ # under the License. import itertools -import logging import six from osc_lib.command import command @@ -25,8 +24,6 @@ from openstackclient.i18n import _ from openstackclient.network import sdk_utils -LOG = logging.getLogger(__name__) - RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth-limit' RULE_TYPE_DSCP_MARKING = 'dscp-marking' RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum-bandwidth' diff --git a/openstackclient/network/v2/network_qos_rule_type.py b/openstackclient/network/v2/network_qos_rule_type.py index 657eb54b..52f8e235 100644 --- a/openstackclient/network/v2/network_qos_rule_type.py +++ b/openstackclient/network/v2/network_qos_rule_type.py @@ -13,17 +13,12 @@ # License for the specific language governing permissions and limitations # under the License. -import logging - from osc_lib.command import command from osc_lib import utils from openstackclient.i18n import _ -LOG = logging.getLogger(__name__) - - class ListNetworkQosRuleType(command.Lister): _description = _("List QoS rule types") diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py index 7283dc07..eced93ce 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -51,7 +51,6 @@ _formatters = { 'extra_dhcp_opts': utils.format_list_of_dicts, 'fixed_ips': utils.format_list_of_dicts, 'security_group_ids': utils.format_list, - 'security_groups': utils.format_list, } @@ -64,7 +63,6 @@ def _get_columns(item): 'binding:vnic_type': 'binding_vnic_type', 'is_admin_state_up': 'admin_state_up', 'is_port_security_enabled': 'port_security_enabled', - 'security_group_ids': 'security_groups', 'tenant_id': 'project_id', } return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) @@ -132,6 +130,8 @@ def _get_attrs(client_manager, parsed_args): attrs['binding:vnic_type'] = parsed_args.vnic_type if parsed_args.host: attrs['binding:host_id'] = parsed_args.host + if parsed_args.mac_address is not None: + attrs['mac_address'] = parsed_args.mac_address if parsed_args.dns_name is not None: attrs['dns_name'] = parsed_args.dns_name @@ -140,8 +140,6 @@ def _get_attrs(client_manager, parsed_args): attrs['name'] = str(parsed_args.name) # The remaining options do not support 'port set' command, so they require # additional check - if 'mac_address' in parsed_args and parsed_args.mac_address is not None: - attrs['mac_address'] = parsed_args.mac_address if 'network' in parsed_args and parsed_args.network is not None: attrs['network_id'] = parsed_args.network if 'project' in parsed_args and parsed_args.project is not None: @@ -237,6 +235,11 @@ def _add_updatable_args(parser): help=argparse.SUPPRESS, ) parser.add_argument( + '--mac-address', + metavar='<mac-address>', + help=_("MAC address of this port (admin only)") + ) + parser.add_argument( '--device-owner', metavar='<device-owner>', help=_("Device owner of this port. This is the entity that uses " @@ -327,11 +330,6 @@ class CreatePort(command.ShowOne): help=_("Disable port") ) parser.add_argument( - '--mac-address', - metavar='<mac-address>', - help=_("MAC address of this port") - ) - parser.add_argument( '--project', metavar='<project>', help=_("Owner's project (name or ID)") @@ -349,7 +347,7 @@ class CreatePort(command.ShowOne): '--security-group', metavar='<security-group>', action='append', - dest='security_groups', + dest='security_group', help=_("Security group to associate with this port (name or ID) " "(repeat option to set multiple security groups)") ) @@ -391,12 +389,13 @@ class CreatePort(command.ShowOne): _prepare_fixed_ips(self.app.client_manager, parsed_args) attrs = _get_attrs(self.app.client_manager, parsed_args) - if parsed_args.security_groups: - attrs['security_groups'] = [client.find_security_group( - sg, ignore_missing=False).id - for sg in parsed_args.security_groups] - if parsed_args.no_security_group: - attrs['security_groups'] = [] + if parsed_args.security_group: + attrs['security_group_ids'] = [client.find_security_group( + sg, ignore_missing=False).id + for sg in + parsed_args.security_group] + elif parsed_args.no_security_group: + attrs['security_group_ids'] = [] if parsed_args.allowed_address_pairs: attrs['allowed_address_pairs'] = ( _convert_address_pairs(parsed_args)) @@ -626,7 +625,7 @@ class SetPort(command.Command): '--security-group', metavar='<security-group>', action='append', - dest='security_groups', + dest='security_group', help=_("Security group to associate with this port (name or ID) " "(repeat option to set multiple security groups)") ) @@ -694,17 +693,16 @@ class SetPort(command.Command): attrs['fixed_ips'] += [ip for ip in obj.fixed_ips if ip] elif parsed_args.no_fixed_ip: attrs['fixed_ips'] = [] - if parsed_args.security_groups and parsed_args.no_security_group: - attrs['security_groups'] = [client.find_security_group(sg, - ignore_missing=False).id - for sg in parsed_args.security_groups] - elif parsed_args.security_groups: - attrs['security_groups'] = obj.security_groups - for sg in parsed_args.security_groups: - sg_id = client.find_security_group(sg, ignore_missing=False).id - attrs['security_groups'].append(sg_id) + + if parsed_args.security_group: + attrs['security_group_ids'] = [ + client.find_security_group(sg, ignore_missing=False).id for + sg in parsed_args.security_group] + if not parsed_args.no_security_group: + attrs['security_group_ids'] += obj.security_group_ids + elif parsed_args.no_security_group: - attrs['security_groups'] = [] + attrs['security_group_ids'] = [] if (parsed_args.allowed_address_pairs and parsed_args.no_allowed_address_pair): @@ -769,7 +767,7 @@ class UnsetPort(command.Command): '--security-group', metavar='<security-group>', action='append', - dest='security_groups', + dest='security_group_ids', help=_("Security group which should be removed this port (name " "or ID) (repeat option to unset multiple security groups)") ) @@ -802,7 +800,7 @@ class UnsetPort(command.Command): # Unset* classes tmp_fixed_ips = copy.deepcopy(obj.fixed_ips) tmp_binding_profile = copy.deepcopy(obj.binding_profile) - tmp_secgroups = copy.deepcopy(obj.security_groups) + tmp_secgroups = copy.deepcopy(obj.security_group_ids) tmp_addr_pairs = copy.deepcopy(obj.allowed_address_pairs) _prepare_fixed_ips(self.app.client_manager, parsed_args) attrs = {} @@ -822,16 +820,16 @@ class UnsetPort(command.Command): msg = _("Port does not contain binding-profile %s") % key raise exceptions.CommandError(msg) attrs['binding:profile'] = tmp_binding_profile - if parsed_args.security_groups: + if parsed_args.security_group_ids: try: - for sg in parsed_args.security_groups: + for sg in parsed_args.security_group_ids: sg_id = client.find_security_group( sg, ignore_missing=False).id tmp_secgroups.remove(sg_id) except ValueError: msg = _("Port does not contain security group %s") % sg raise exceptions.CommandError(msg) - attrs['security_groups'] = tmp_secgroups + attrs['security_group_ids'] = tmp_secgroups if parsed_args.allowed_address_pairs: try: for addr in _convert_address_pairs(parsed_args): diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py index c6d9ede7..182d4817 100644 --- a/openstackclient/network/v2/security_group.py +++ b/openstackclient/network/v2/security_group.py @@ -210,21 +210,6 @@ class ListSecurityGroup(common.NetworkAndComputeLister): ) return parser - def _get_return_data(self, data, include_project=True): - columns = ( - "ID", - "Name", - "Description", - ) - column_headers = columns - if include_project: - columns = columns + ('Tenant ID',) - column_headers = column_headers + ('Project',) - return (column_headers, - (utils.get_item_properties( - s, columns, - ) for s in data)) - def take_action_network(self, client, parsed_args): filters = {} if parsed_args.project: @@ -236,13 +221,42 @@ class ListSecurityGroup(common.NetworkAndComputeLister): ).id filters['tenant_id'] = project_id filters['project_id'] = project_id - return self._get_return_data(client.security_groups(**filters)) + data = client.security_groups(**filters) + + columns = ( + "ID", + "Name", + "Description", + "Project ID" + ) + column_headers = ( + "ID", + "Name", + "Description", + "Project" + ) + return (column_headers, + (utils.get_item_properties( + s, columns, + ) for s in data)) def take_action_compute(self, client, parsed_args): search = {'all_tenants': parsed_args.all_projects} data = client.security_groups.list(search_opts=search) - return self._get_return_data(data, - include_project=parsed_args.all_projects) + + columns = ( + "ID", + "Name", + "Description", + ) + column_headers = columns + if parsed_args.all_projects: + columns = columns + ('Tenant ID',) + column_headers = column_headers + ('Project',) + return (column_headers, + (utils.get_item_properties( + s, columns, + ) for s in data)) class SetSecurityGroup(common.NetworkAndComputeCommand): diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py index 63b80d25..8f07c5a4 100644 --- a/openstackclient/network/v2/security_group_rule.py +++ b/openstackclient/network/v2/security_group_rule.py @@ -521,7 +521,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): 'port_range', ) if parsed_args.long: - columns = columns + ('direction', 'ethertype',) + columns = columns + ('direction', 'ether_type',) columns = columns + ('remote_group_id',) # Get the security group rules using the requested query. diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py index 2771858b..403b4cd2 100644 --- a/openstackclient/network/v2/subnet.py +++ b/openstackclient/network/v2/subnet.py @@ -132,7 +132,13 @@ def _get_columns(item): 'subnet_pool_id': 'subnetpool_id', 'tenant_id': 'project_id', } - return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) + # Do not show this column when displaying a subnet + invisible_columns = ['use_default_subnetpool'] + return sdk_utils.get_osc_show_columns_for_sdk_resource( + item, + column_map, + invisible_columns=invisible_columns + ) def convert_entries_to_nexthop(entries): @@ -179,7 +185,7 @@ def _get_attrs(client_manager, parsed_args, is_create=True): ignore_missing=False) attrs['subnetpool_id'] = subnet_pool.id if parsed_args.use_default_subnet_pool: - attrs['use_default_subnetpool'] = True + attrs['use_default_subnet_pool'] = True if parsed_args.prefix_length is not None: attrs['prefixlen'] = parsed_args.prefix_length if parsed_args.subnet_range is not None: |
