diff options
Diffstat (limited to 'openstackclient/network/v2/network_trunk.py')
-rw-r--r-- | openstackclient/network/v2/network_trunk.py | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/openstackclient/network/v2/network_trunk.py b/openstackclient/network/v2/network_trunk.py new file mode 100644 index 00000000..c5f62901 --- /dev/null +++ b/openstackclient/network/v2/network_trunk.py @@ -0,0 +1,402 @@ +# Copyright 2016 ZTE Corporation. +# All Rights Reserved +# +# 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. +# + +"""Network trunk and subports action implementations""" +import logging + +from cliff import columns as cliff_columns +from osc_lib.cli import format_columns +from osc_lib.cli import identity as identity_utils +from osc_lib.cli import parseractions +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils as osc_utils + +from openstackclient.i18n import _ + +LOG = logging.getLogger(__name__) + +TRUNK = 'trunk' +TRUNKS = 'trunks' +SUB_PORTS = 'sub_ports' + + +class AdminStateColumn(cliff_columns.FormattableColumn): + def human_readable(self): + return 'UP' if self._value else 'DOWN' + + +class CreateNetworkTrunk(command.ShowOne): + """Create a network trunk for a given project""" + + def get_parser(self, prog_name): + parser = super(CreateNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + 'name', + metavar='<name>', + help=_("Name of the trunk to create") + ) + parser.add_argument( + '--description', + metavar='<description>', + help=_("A description of the trunk") + ) + parser.add_argument( + '--parent-port', + metavar='<parent-port>', + required=True, + help=_("Parent port belonging to this trunk (name or ID)") + ) + parser.add_argument( + '--subport', + metavar='<port=,segmentation-type=,segmentation-id=>', + action=parseractions.MultiKeyValueAction, dest='add_subports', + optional_keys=['segmentation-id', 'segmentation-type'], + required_keys=['port'], + help=_("Subport to add. Subport is of form " + "\'port=<name or ID>,segmentation-type=<segmentation-type>," + "segmentation-id=<segmentation-ID>\' (--subport) option " + "can be repeated") + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + action='store_true', + default=True, + help=_("Enable trunk (default)") + ) + admin_group.add_argument( + '--disable', + action='store_true', + help=_("Disable trunk") + ) + identity_utils.add_project_owner_option_to_parser(parser) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + attrs = _get_attrs_for_trunk(self.app.client_manager, + parsed_args) + obj = client.create_trunk(**attrs) + display_columns, columns = _get_columns(obj) + data = osc_utils.get_dict_properties(obj, columns, + formatters=_formatters) + return display_columns, data + + +class DeleteNetworkTrunk(command.Command): + """Delete a given network trunk""" + + def get_parser(self, prog_name): + parser = super(DeleteNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + 'trunk', + metavar="<trunk>", + nargs="+", + help=_("Trunk(s) to delete (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + result = 0 + for trunk in parsed_args.trunk: + try: + trunk_id = client.find_trunk(trunk).id + client.delete_trunk(trunk_id) + except Exception as e: + result += 1 + LOG.error(_("Failed to delete trunk with name " + "or ID '%(trunk)s': %(e)s"), + {'trunk': trunk, 'e': e}) + if result > 0: + total = len(parsed_args.trunk) + msg = (_("%(result)s of %(total)s trunks failed " + "to delete.") % {'result': result, 'total': total}) + raise exceptions.CommandError(msg) + + +class ListNetworkTrunk(command.Lister): + """List all network trunks""" + + def get_parser(self, prog_name): + parser = super(ListNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help=_("List additional fields in output") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + data = client.trunks() + headers = ( + 'ID', + 'Name', + 'Parent Port', + 'Description' + ) + columns = ( + 'id', + 'name', + 'port_id', + 'description' + ) + if parsed_args.long: + headers += ( + 'Status', + 'State', + 'Created At', + 'Updated At', + ) + columns += ( + 'status', + 'admin_state_up', + 'created_at', + 'updated_at' + ) + return (headers, + (osc_utils.get_item_properties( + s, columns, + formatters=_formatters, + ) for s in data)) + + +class SetNetworkTrunk(command.Command): + """Set network trunk properties""" + + def get_parser(self, prog_name): + parser = super(SetNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + 'trunk', + metavar="<trunk>", + help=_("Trunk to modify (name or ID)") + ) + parser.add_argument( + '--name', + metavar="<name>", + help=_("Set trunk name") + ) + parser.add_argument( + '--description', + metavar='<description>', + help=_("A description of the trunk") + ) + parser.add_argument( + '--subport', + metavar='<port=,segmentation-type=,segmentation-id=>', + action=parseractions.MultiKeyValueAction, dest='set_subports', + optional_keys=['segmentation-id', 'segmentation-type'], + required_keys=['port'], + help=_("Subport to add. Subport is of form " + "\'port=<name or ID>,segmentation-type=<segmentation-type>" + ",segmentation-id=<segmentation-ID>\' (--subport) option " + "can be repeated") + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + action='store_true', + help=_("Enable trunk") + ) + admin_group.add_argument( + '--disable', + action='store_true', + help=_("Disable trunk") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + trunk_id = client.find_trunk(parsed_args.trunk) + attrs = _get_attrs_for_trunk(self.app.client_manager, parsed_args) + try: + client.update_trunk(trunk_id, **attrs) + except Exception as e: + msg = (_("Failed to set trunk '%(t)s': %(e)s") + % {'t': parsed_args.trunk, 'e': e}) + raise exceptions.CommandError(msg) + if parsed_args.set_subports: + subport_attrs = _get_attrs_for_subports(self.app.client_manager, + parsed_args) + try: + client.add_trunk_subports(trunk_id, subport_attrs) + except Exception as e: + msg = (_("Failed to add subports to trunk '%(t)s': %(e)s") + % {'t': parsed_args.trunk, 'e': e}) + raise exceptions.CommandError(msg) + + +class ShowNetworkTrunk(command.ShowOne): + """Show information of a given network trunk""" + def get_parser(self, prog_name): + parser = super(ShowNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + 'trunk', + metavar="<trunk>", + help=_("Trunk to display (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + trunk_id = client.find_trunk(parsed_args.trunk).id + obj = client.get_trunk(trunk_id) + display_columns, columns = _get_columns(obj) + data = osc_utils.get_dict_properties(obj, columns, + formatters=_formatters) + return display_columns, data + + +class ListNetworkSubport(command.Lister): + """List all subports for a given network trunk""" + + def get_parser(self, prog_name): + parser = super(ListNetworkSubport, self).get_parser(prog_name) + parser.add_argument( + '--trunk', + required=True, + metavar="<trunk>", + help=_("List subports belonging to this trunk (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + trunk_id = client.find_trunk(parsed_args.trunk) + data = client.get_trunk_subports(trunk_id) + headers = ('Port', 'Segmentation Type', 'Segmentation ID') + columns = ('port_id', 'segmentation_type', 'segmentation_id') + return (headers, + (osc_utils.get_dict_properties( + s, columns, + ) for s in data[SUB_PORTS])) + + +class UnsetNetworkTrunk(command.Command): + """Unset subports from a given network trunk""" + + def get_parser(self, prog_name): + parser = super(UnsetNetworkTrunk, self).get_parser(prog_name) + parser.add_argument( + 'trunk', + metavar="<trunk>", + help=_("Unset subports from this trunk (name or ID)") + ) + parser.add_argument( + '--subport', + metavar="<subport>", + required=True, + action='append', dest='unset_subports', + help=_("Subport to delete (name or ID of the port) " + "(--subport) option can be repeated") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + attrs = _get_attrs_for_subports(self.app.client_manager, parsed_args) + trunk_id = client.find_trunk(parsed_args.trunk) + client.delete_trunk_subports(trunk_id, attrs) + + +_formatters = { + 'admin_state_up': AdminStateColumn, + 'sub_ports': format_columns.ListDictColumn, +} + + +def _get_columns(item): + column_map = {} + hidden_columns = ['location', 'tenant_id'] + return osc_utils.get_osc_show_columns_for_sdk_resource( + item, + column_map, + hidden_columns + ) + + +def _get_attrs_for_trunk(client_manager, parsed_args): + attrs = {} + if parsed_args.name is not None: + attrs['name'] = str(parsed_args.name) + if parsed_args.description is not None: + attrs['description'] = str(parsed_args.description) + if parsed_args.enable: + attrs['admin_state_up'] = True + if parsed_args.disable: + attrs['admin_state_up'] = False + if 'parent_port' in parsed_args and parsed_args.parent_port is not None: + port_id = client_manager.network.find_port( + parsed_args.parent_port)['id'] + attrs['port_id'] = port_id + if 'add_subports' in parsed_args and parsed_args.add_subports is not None: + attrs[SUB_PORTS] = _format_subports(client_manager, + parsed_args.add_subports) + + # "trunk set" command doesn't support setting project. + if 'project' in parsed_args and parsed_args.project is not None: + identity_client = client_manager.identity + project_id = identity_utils.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + + return attrs + + +def _format_subports(client_manager, subports): + attrs = [] + for subport in subports: + subport_attrs = {} + if subport.get('port'): + port_id = client_manager.network.find_port(subport['port'])['id'] + subport_attrs['port_id'] = port_id + if subport.get('segmentation-id'): + try: + subport_attrs['segmentation_id'] = int( + subport['segmentation-id']) + except ValueError: + msg = (_("Segmentation-id '%s' is not an integer") % + subport['segmentation-id']) + raise exceptions.CommandError(msg) + if subport.get('segmentation-type'): + subport_attrs['segmentation_type'] = subport['segmentation-type'] + attrs.append(subport_attrs) + return attrs + + +def _get_attrs_for_subports(client_manager, parsed_args): + attrs = {} + if 'set_subports' in parsed_args and parsed_args.set_subports is not None: + attrs = _format_subports(client_manager, + parsed_args.set_subports) + if ('unset_subports' in parsed_args and + parsed_args.unset_subports is not None): + subports_list = [] + for subport in parsed_args.unset_subports: + port_id = client_manager.network.find_port(subport)['id'] + subports_list.append({'port_id': port_id}) + attrs = subports_list + return attrs + + +def _get_id(client, id_or_name, resource): + return client.find_resource(resource, str(id_or_name))['id'] |