summaryrefslogtreecommitdiff
path: root/openstackclient/network
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2023-01-31 12:40:59 +0000
committerGerrit Code Review <review@openstack.org>2023-01-31 12:40:59 +0000
commitf9b025e4cb6a500381499de0842b4688c253f2fc (patch)
tree41b2c5217690a82717ddfb393a1168dcf2d77e22 /openstackclient/network
parentf1da522cc3c2f1055157d41c783e18597608fbb6 (diff)
parent7f1c21b27aafacbf041d48d8b042901032310d5e (diff)
downloadpython-openstackclient-f9b025e4cb6a500381499de0842b4688c253f2fc.tar.gz
Merge "Move network trunk commands from python-neutronclient"
Diffstat (limited to 'openstackclient/network')
-rw-r--r--openstackclient/network/v2/network_trunk.py402
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']