# Copyright 2016 Huawei, Inc. 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. # """Mogan v1 Baremetal flavor action implementations""" import copy import logging from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from moganclient.common import base from moganclient.common.i18n import _ LOG = logging.getLogger(__name__) class CreateFlavor(command.ShowOne): """Create a new baremetal flavor""" def get_parser(self, prog_name): parser = super(CreateFlavor, self).get_parser(prog_name) parser.add_argument( "name", metavar="", help=_("New baremetal flavor name") ) public_group = parser.add_mutually_exclusive_group() public_group.add_argument( "--public", action="store_true", help=_("Flavor is available to other projects (default)") ) public_group.add_argument( "--private", action="store_true", help=_("Flavor is not available to other projects") ) parser.add_argument( "--description", metavar="", help=_("Flavor description"), ) parser.add_argument( "--property", metavar="", action=parseractions.KeyValueAction, help=_("Property to add to this flavor " "(repeat option to set multiple properties)") ) return parser def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute info = {} is_public = True if parsed_args.public: is_public = True if parsed_args.private: is_public = False data = bc_client.flavor.create( name=parsed_args.name, is_public=is_public, description=parsed_args.description, ) info.update(data._info) if parsed_args.property: bc_client.flavor.update_extra_specs(data, parsed_args.property) extra_specs = bc_client.flavor.get_extra_specs(data) info.update(extra_specs) return zip(*sorted(info.items())) class DeleteFlavor(command.Command): """Delete existing baremetal flavor(s)""" def get_parser(self, prog_name): parser = super(DeleteFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='', nargs='+', help=_("Flavor(s) to delete (name or UUID)") ) return parser def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute result = 0 for one_flavor in parsed_args.flavor: try: data = utils.find_resource( bc_client.flavor, one_flavor) bc_client.flavor.delete(data.uuid) except Exception as e: result += 1 LOG.error(_("Failed to delete flavor with name or UUID " "'%(flavor)s': %(e)s") % {'flavor': one_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 ListFlavor(command.Lister): """List all baremetal flavors""" def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute data = bc_client.flavor.list() column_headers = ( "UUID", "Name", "Is Public", "Description", "Properties", ) columns = ( "UUID", "Name", "Is Public", "Description", "Extra Specs", ) return (column_headers, (utils.get_item_properties( s, columns, ) for s in data)) class SetFlavor(command.Command): """Set baremetal flavor properties""" def get_parser(self, prog_name): parser = super(SetFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='', help=_("Flavor to modify (name or UUID)") ) parser.add_argument( "--property", metavar="", action=parseractions.KeyValueAction, help=_("Property to set on " "(repeat option to set multiple properties)") ) parser.add_argument( "--no-property", dest="no_property", action="store_true", help=_("Remove all properties from " "(specify both --property and --no-property to " "overwrite the current properties)"), ) return parser def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute data = utils.find_resource( bc_client.flavor, parsed_args.flavor, ) set_property = None del_property_key = None # NOTE(RuiChen): extra specs update API is append mode, so if the # options is overwrite mode, the update and delete # properties need to be handled in client side. if parsed_args.no_property and parsed_args.property: # override del_property_key = data.extra_specs.keys() set_property = copy.deepcopy(parsed_args.property) elif parsed_args.property: # append set_property = copy.deepcopy(parsed_args.property) elif parsed_args.no_property: # clean del_property_key = data.extra_specs.keys() result = 0 if del_property_key is not None: for each_key in del_property_key: try: # If the key is in the set_property, it will be updated # in the follow logic. if (set_property is None or each_key not in set_property): bc_client.flavor.delete_extra_specs( data, each_key ) except Exception as e: result += 1 LOG.error(_("Failed to remove flavor property with key " "'%(key)s': %(e)s") % {'key': each_key, 'e': e}) if set_property is not None: try: bc_client.flavor.update_extra_specs( data, set_property ) except Exception as e: result += 1 LOG.error(_("Failed to update flavor property with key/value " "'%(key)s': %(e)s") % {'key': set_property, 'e': e}) if result > 0: msg = (_("Set flavor %(flavor)s property failed.") % { 'flavor': base.getid(data)}) raise exceptions.CommandError(msg) class ShowFlavor(command.ShowOne): """Display baremetal flavor details""" def get_parser(self, prog_name): parser = super(ShowFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='', help=_("Flavor to display (name or UUID)") ) return parser def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute data = utils.find_resource( bc_client.flavor, parsed_args.flavor, ) info = {} info.update(data._info) return zip(*sorted(info.items())) class UnsetFlavor(command.Command): """Unset baremetal flavor properties""" def get_parser(self, prog_name): parser = super(UnsetFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='', help=_("Flavor to modify (name or UUID)") ) parser.add_argument( "--property", metavar="", action='append', help=_("Property to remove from " "(repeat option to remove multiple properties)") ) return parser def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute data = utils.find_resource( bc_client.flavor, parsed_args.flavor, ) unset_property_key = [] if parsed_args.property: unset_property_key = list( set(data.extra_specs.keys()).intersection( set(parsed_args.property))) result = 0 for each_key in unset_property_key: try: bc_client.flavor.delete_extra_specs(data, each_key) except Exception as e: result += 1 LOG.error(_("Failed to remove flavor property with key " "'%(key)s': %(e)s") % {'key': each_key, 'e': e}) if result > 0: total = len(unset_property_key) msg = (_("%(result)s of %(total)s flavor property failed " "to remove.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg)