diff options
Diffstat (limited to 'openstackclient/network')
| -rw-r--r-- | openstackclient/network/sdk_utils.py | 23 | ||||
| -rw-r--r-- | openstackclient/network/v2/network.py | 44 | ||||
| -rw-r--r-- | openstackclient/network/v2/network_agent.py | 124 | ||||
| -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/port.py | 14 | ||||
| -rw-r--r-- | openstackclient/network/v2/security_group.py | 50 | ||||
| -rw-r--r-- | openstackclient/network/v2/subnet.py | 10 |
8 files changed, 236 insertions, 58 deletions
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/network.py b/openstackclient/network/v2/network.py index 3aa8ec84..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): @@ -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/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/port.py b/openstackclient/network/v2/port.py index 6117175e..eced93ce 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -130,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 @@ -138,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: @@ -235,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 " @@ -325,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)") 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/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: |
