Introduce openstackclient plugin
Adds the code necessary for ironicclient to work as a plugin for openstackclient. * baremetal list * baremetal show * baremetal delete * baremetal create * baremetal set * baremetal unset Change-Id: I91ea4f4a63b0e7a8ea004c47422d19ca0f288dcd
This commit is contained in:
		
							
								
								
									
										0
									
								
								ironicclient/osc/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ironicclient/osc/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										51
									
								
								ironicclient/osc/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								ironicclient/osc/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
# Copyright 2010 Jacob Kaplan-Moss
 | 
			
		||||
# Copyright 2011 OpenStack Foundation
 | 
			
		||||
# Copyright 2011 Piston Cloud Computing, Inc.
 | 
			
		||||
#
 | 
			
		||||
# Modified by: Brad P. Crochet <brad@redhat.com>
 | 
			
		||||
#
 | 
			
		||||
# 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.
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
OpenStack Client factory.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from oslo_utils import importutils
 | 
			
		||||
 | 
			
		||||
from ironicclient.common.i18n import _
 | 
			
		||||
from ironicclient import exceptions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_client_class(version):
 | 
			
		||||
    version_map = {
 | 
			
		||||
        '1': 'ironicclient.v1.client.Client',
 | 
			
		||||
        '1.5': 'ironicclient.v1.client.Client',
 | 
			
		||||
        '1.6': 'ironicclient.v1.client.Client',
 | 
			
		||||
        '1.9': 'ironicclient.v1.client.Client',
 | 
			
		||||
    }
 | 
			
		||||
    try:
 | 
			
		||||
        client_path = version_map[str(version)]
 | 
			
		||||
    except (KeyError, ValueError):
 | 
			
		||||
        msg = _("Invalid client version '%(version)s'. must be one of: "
 | 
			
		||||
                "%(keys)s") % {'version': version,
 | 
			
		||||
                               'keys': ', '.join(version_map)}
 | 
			
		||||
        raise exceptions.UnsupportedVersion(msg)
 | 
			
		||||
 | 
			
		||||
    return importutils.import_class(client_path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def Client(version, *args, **kwargs):
 | 
			
		||||
    client_class = get_client_class(version)
 | 
			
		||||
    return client_class(*args, **kwargs)
 | 
			
		||||
							
								
								
									
										70
									
								
								ironicclient/osc/plugin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								ironicclient/osc/plugin.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 2015 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from openstackclient.common import exceptions
 | 
			
		||||
from openstackclient.common import utils
 | 
			
		||||
 | 
			
		||||
from ironicclient.osc import client as ironic_client
 | 
			
		||||
 | 
			
		||||
LOG = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
DEFAULT_BAREMETAL_API_VERSION = '1.6'
 | 
			
		||||
API_VERSION_OPTION = 'os_baremetal_api_version'
 | 
			
		||||
API_NAME = 'baremetal'
 | 
			
		||||
API_VERSIONS = {
 | 
			
		||||
    '1': 'ironicclient.osc.client',
 | 
			
		||||
    '1.5': 'ironicclient.osc.client',
 | 
			
		||||
    '1.6': 'ironicclient.osc.client',
 | 
			
		||||
    '1.9': 'ironicclient.osc.client',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_client(instance):
 | 
			
		||||
    """Returns a baremetal service client."""
 | 
			
		||||
    try:
 | 
			
		||||
        baremetal_client = ironic_client.get_client_class(
 | 
			
		||||
            instance._api_version[API_NAME])
 | 
			
		||||
    except Exception:
 | 
			
		||||
        msg = "Invalid %s client version '%s'. Must be one of %s" % (
 | 
			
		||||
            (API_NAME, instance._api_version[API_NAME],
 | 
			
		||||
                ", ".join(sorted(API_VERSIONS))))
 | 
			
		||||
        raise exceptions.UnsupportedVersion(msg)
 | 
			
		||||
    LOG.debug('Instantiating baremetal client: %s', baremetal_client)
 | 
			
		||||
 | 
			
		||||
    client = baremetal_client(
 | 
			
		||||
        os_ironic_api_version=instance._api_version[API_NAME],
 | 
			
		||||
        session=instance.session,
 | 
			
		||||
        region_name=instance._region_name,
 | 
			
		||||
        endpoint=instance.auth_ref.auth_url,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    return client
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_option_parser(parser):
 | 
			
		||||
    """Hook to add global options."""
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--os-baremetal-api-version',
 | 
			
		||||
        metavar='<baremetal-api-version>',
 | 
			
		||||
        default=utils.env(
 | 
			
		||||
            'OS_BAREMETAL_API_VERSION',
 | 
			
		||||
            default=DEFAULT_BAREMETAL_API_VERSION),
 | 
			
		||||
        help='Baremetal API version, default=' +
 | 
			
		||||
             DEFAULT_BAREMETAL_API_VERSION +
 | 
			
		||||
             ' (Env: OS_BAREMETAL_API_VERSION)')
 | 
			
		||||
    return parser
 | 
			
		||||
							
								
								
									
										0
									
								
								ironicclient/osc/v1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ironicclient/osc/v1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										320
									
								
								ironicclient/osc/v1/baremetal.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								ironicclient/osc/v1/baremetal.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,320 @@
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 2015 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
from cliff import command
 | 
			
		||||
from cliff import lister
 | 
			
		||||
from cliff import show
 | 
			
		||||
from openstackclient.common import utils as oscutils
 | 
			
		||||
 | 
			
		||||
from ironicclient.common.i18n import _
 | 
			
		||||
from ironicclient.common import utils
 | 
			
		||||
from ironicclient import exc
 | 
			
		||||
from ironicclient.v1 import resource_fields as res_fields
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateBaremetal(show.ShowOne):
 | 
			
		||||
    """Register a new node with the baremetal service"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".CreateBaremetal")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(CreateBaremetal, self).get_parser(prog_name)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--chassis-uuid',
 | 
			
		||||
            dest='chassis_uuid',
 | 
			
		||||
            metavar='<chassis>',
 | 
			
		||||
            help='UUID of the chassis that this node belongs to.')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--driver',
 | 
			
		||||
            metavar='<driver>',
 | 
			
		||||
            required=True,
 | 
			
		||||
            help='Driver used to control the node [REQUIRED].')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--driver-info',
 | 
			
		||||
            metavar='<key=value>',
 | 
			
		||||
            action='append',
 | 
			
		||||
            help='Key/value pair used by the driver, such as out-of-band '
 | 
			
		||||
                 'management credentials. Can be specified multiple times.')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--property',
 | 
			
		||||
            dest='properties',
 | 
			
		||||
            metavar='<key=value>',
 | 
			
		||||
            action='append',
 | 
			
		||||
            help='Key/value pair describing the physical characteristics of '
 | 
			
		||||
                 'the node. This is exported to Nova and used by the '
 | 
			
		||||
                 'scheduler. Can be specified multiple times.')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--extra',
 | 
			
		||||
            metavar='<key=value>',
 | 
			
		||||
            action='append',
 | 
			
		||||
            help="Record arbitrary key/value metadata. "
 | 
			
		||||
                 "Can be specified multiple times.")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--uuid',
 | 
			
		||||
            metavar='<uuid>',
 | 
			
		||||
            help="Unique UUID for the node.")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--name',
 | 
			
		||||
            metavar='<name>',
 | 
			
		||||
            help="Unique name for the node.")
 | 
			
		||||
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        baremetal_client = self.app.client_manager.baremetal
 | 
			
		||||
 | 
			
		||||
        field_list = ['chassis_uuid', 'driver', 'driver_info',
 | 
			
		||||
                      'properties', 'extra', 'uuid', 'name']
 | 
			
		||||
        fields = dict((k, v) for (k, v) in vars(parsed_args).items()
 | 
			
		||||
                      if k in field_list and not (v is None))
 | 
			
		||||
        fields = utils.args_array_to_dict(fields, 'driver_info')
 | 
			
		||||
        fields = utils.args_array_to_dict(fields, 'extra')
 | 
			
		||||
        fields = utils.args_array_to_dict(fields, 'properties')
 | 
			
		||||
        node = baremetal_client.node.create(**fields)._info
 | 
			
		||||
 | 
			
		||||
        node.pop('links', None)
 | 
			
		||||
 | 
			
		||||
        return self.dict2columns(node)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteBaremetal(command.Command):
 | 
			
		||||
    """Unregister a baremetal node"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".DeleteBaremetal")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(DeleteBaremetal, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "node",
 | 
			
		||||
            metavar="<node>",
 | 
			
		||||
            help="Node to delete (name or ID)")
 | 
			
		||||
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        baremetal_client = self.app.client_manager.baremetal
 | 
			
		||||
 | 
			
		||||
        node = oscutils.find_resource(baremetal_client.node,
 | 
			
		||||
                                      parsed_args.node)
 | 
			
		||||
        baremetal_client.node.delete(node.uuid)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListBaremetal(lister.Lister):
 | 
			
		||||
    """List baremetal nodes"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".ListBaremetal")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ListBaremetal, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--limit',
 | 
			
		||||
            metavar='<limit>',
 | 
			
		||||
            type=int,
 | 
			
		||||
            help='Maximum number of nodes to return per request, '
 | 
			
		||||
                 '0 for no limit. Default is the maximum number used '
 | 
			
		||||
                 'by the Baremetal API Service.'
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--marker',
 | 
			
		||||
            metavar='<node>',
 | 
			
		||||
            help='Node UUID (for example, of the last node in the list from '
 | 
			
		||||
                 'a previous request). Returns the list of nodes after this '
 | 
			
		||||
                 'UUID.'
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--sort',
 | 
			
		||||
            metavar="<key>[:<direction>]",
 | 
			
		||||
            help='Sort output by selected keys and directions(asc or desc) '
 | 
			
		||||
                 '(default: asc), multiple keys and directions can be '
 | 
			
		||||
                 'specified separated by comma',
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--maintenance',
 | 
			
		||||
            dest='maintenance',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help="List nodes in maintenance mode.",
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--associated',
 | 
			
		||||
            dest='associated',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help="List only nodes associated with an instance."
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--long',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help="Show detailed information about the nodes."
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)" % parsed_args)
 | 
			
		||||
        client = self.app.client_manager.baremetal
 | 
			
		||||
 | 
			
		||||
        columns = res_fields.NODE_RESOURCE
 | 
			
		||||
 | 
			
		||||
        params = {}
 | 
			
		||||
        if parsed_args.limit is not None and parsed_args.limit < 0:
 | 
			
		||||
            raise exc.CommandError(
 | 
			
		||||
                _('Expected non-negative --limit, got %s') %
 | 
			
		||||
                parsed_args.limit)
 | 
			
		||||
        params['limit'] = parsed_args.limit
 | 
			
		||||
        params['marker'] = parsed_args.marker
 | 
			
		||||
        if parsed_args.associated:
 | 
			
		||||
            params['associated'] = parsed_args.associated
 | 
			
		||||
        if parsed_args.maintenance:
 | 
			
		||||
            params['maintenance'] = parsed_args.maintenance
 | 
			
		||||
 | 
			
		||||
        if parsed_args.long:
 | 
			
		||||
            columns = res_fields.NODE_DETAILED_RESOURCE
 | 
			
		||||
        params['detail'] = parsed_args.long
 | 
			
		||||
 | 
			
		||||
        self.log.debug("params(%s)" % params)
 | 
			
		||||
        data = client.node.list(**params)
 | 
			
		||||
 | 
			
		||||
        data = oscutils.sort_items(data, parsed_args.sort)
 | 
			
		||||
 | 
			
		||||
        return (columns.labels,
 | 
			
		||||
                (oscutils.get_item_properties(s, columns.fields, formatters={
 | 
			
		||||
                    'Properties': oscutils.format_dict},) for s in data))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SetBaremetal(command.Command):
 | 
			
		||||
    """Set baremetal properties"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".SetBaremetal")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(SetBaremetal, self).get_parser(prog_name)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'node',
 | 
			
		||||
            metavar='<node>',
 | 
			
		||||
            help="Name or UUID of the node."
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--property",
 | 
			
		||||
            metavar="<path=value>",
 | 
			
		||||
            action='append',
 | 
			
		||||
            help='Property to add to this baremetal host '
 | 
			
		||||
                 '(repeat option to set multiple properties)',
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        baremetal_client = self.app.client_manager.baremetal
 | 
			
		||||
 | 
			
		||||
        properties = []
 | 
			
		||||
        if parsed_args.property:
 | 
			
		||||
            properties = utils.args_array_to_patch(
 | 
			
		||||
                'add', parsed_args.property)
 | 
			
		||||
        baremetal_client.node.update(parsed_args.node, properties)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowBaremetal(show.ShowOne):
 | 
			
		||||
    """Show baremetal node details"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".ShowBaremetal")
 | 
			
		||||
    LONG_FIELDS = [
 | 
			
		||||
        'extra',
 | 
			
		||||
        'properties',
 | 
			
		||||
        'ports',
 | 
			
		||||
        'driver_info',
 | 
			
		||||
        'driver_internal_info',
 | 
			
		||||
        'instance_info',
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ShowBaremetal, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "node",
 | 
			
		||||
            metavar="<node>",
 | 
			
		||||
            help="Name or UUID of the node (or instance UUID if --instance "
 | 
			
		||||
                 "is specified)")
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--instance',
 | 
			
		||||
            dest='instance_uuid',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='<node> is an instance UUID.')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--long',
 | 
			
		||||
            action='store_true')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        baremetal_client = self.app.client_manager.baremetal
 | 
			
		||||
        if parsed_args.instance_uuid:
 | 
			
		||||
            node = baremetal_client.node.get_by_instance_uuid(
 | 
			
		||||
                parsed_args.node)._info
 | 
			
		||||
        else:
 | 
			
		||||
            node = oscutils.find_resource(baremetal_client.node,
 | 
			
		||||
                                          parsed_args.node)._info
 | 
			
		||||
        node.pop("links", None)
 | 
			
		||||
        if not parsed_args.long:
 | 
			
		||||
            for field in self.LONG_FIELDS:
 | 
			
		||||
                node.pop(field, None)
 | 
			
		||||
 | 
			
		||||
        return zip(*sorted(six.iteritems(node)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UnsetBaremetal(command.Command):
 | 
			
		||||
    """Unset baremetal properties"""
 | 
			
		||||
    log = logging.getLogger(__name__ + ".UnsetBaremetal")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(UnsetBaremetal, self).get_parser(prog_name)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'node',
 | 
			
		||||
            metavar='<node>',
 | 
			
		||||
            help="Name or UUID of the node."
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--property',
 | 
			
		||||
            metavar='<path>',
 | 
			
		||||
            action='append',
 | 
			
		||||
            help='Property to unset on this baremetal host '
 | 
			
		||||
                 '(repeat option to unset multiple properties)',
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action(%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        baremetal_client = self.app.client_manager.baremetal
 | 
			
		||||
 | 
			
		||||
        if not parsed_args.node and not parsed_args.property:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        patch = utils.args_array_to_patch('remove', parsed_args.property)
 | 
			
		||||
        baremetal_client.node.update(parsed_args.node, patch)
 | 
			
		||||
							
								
								
									
										0
									
								
								ironicclient/tests/unit/osc/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ironicclient/tests/unit/osc/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										58
									
								
								ironicclient/tests/unit/osc/fakes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								ironicclient/tests/unit/osc/fakes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 2015 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
AUTH_TOKEN = "foobar"
 | 
			
		||||
AUTH_URL = "http://0.0.0.0"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeApp(object):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        _stdout = None
 | 
			
		||||
        self.client_manager = None
 | 
			
		||||
        self.stdin = sys.stdin
 | 
			
		||||
        self.stdout = _stdout or sys.stdout
 | 
			
		||||
        self.stderr = sys.stderr
 | 
			
		||||
        self.restapi = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeClientManager(object):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.identity = None
 | 
			
		||||
        self.auth_ref = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeResource(object):
 | 
			
		||||
    def __init__(self, manager, info, loaded=False):
 | 
			
		||||
        self.__name__ = type(self).__name__
 | 
			
		||||
        self.manager = manager
 | 
			
		||||
        self._info = info
 | 
			
		||||
        self._add_details(info)
 | 
			
		||||
        self._loaded = loaded
 | 
			
		||||
 | 
			
		||||
    def _add_details(self, info):
 | 
			
		||||
        for (k, v) in six.iteritems(info):
 | 
			
		||||
            setattr(self, k, v)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and
 | 
			
		||||
                          k != 'manager')
 | 
			
		||||
        info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
 | 
			
		||||
        return "<%s %s>" % (self.__class__.__name__, info)
 | 
			
		||||
							
								
								
									
										0
									
								
								ironicclient/tests/unit/osc/v1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ironicclient/tests/unit/osc/v1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										52
									
								
								ironicclient/tests/unit/osc/v1/fakes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								ironicclient/tests/unit/osc/v1/fakes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 2015 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import mock
 | 
			
		||||
from openstackclient.tests import utils
 | 
			
		||||
 | 
			
		||||
from ironicclient.tests.unit.osc import fakes
 | 
			
		||||
 | 
			
		||||
baremetal_uuid = 'xxx-xxxxxx-xxxx'
 | 
			
		||||
baremetal_name = 'fake name'
 | 
			
		||||
baremetal_instance_uuid = 'yyy-yyyyyy-yyyy'
 | 
			
		||||
baremetal_power_state = None
 | 
			
		||||
baremetal_provision_state = None
 | 
			
		||||
baremetal_maintenance = False
 | 
			
		||||
 | 
			
		||||
BAREMETAL = {
 | 
			
		||||
    'uuid': baremetal_uuid,
 | 
			
		||||
    'name': baremetal_name,
 | 
			
		||||
    'instance_uuid': baremetal_instance_uuid,
 | 
			
		||||
    'power_state': baremetal_power_state,
 | 
			
		||||
    'provision_state': baremetal_provision_state,
 | 
			
		||||
    'maintenance': baremetal_maintenance,
 | 
			
		||||
    'links': []
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetal(utils.TestCommand):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetal, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
 | 
			
		||||
        self.app.client_manager.baremetal = mock.Mock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeBaremetalResource(fakes.FakeResource):
 | 
			
		||||
 | 
			
		||||
    def get_keys(self):
 | 
			
		||||
        return {'property': 'value'}
 | 
			
		||||
							
								
								
									
										515
									
								
								ironicclient/tests/unit/osc/v1/test_baremetal.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										515
									
								
								ironicclient/tests/unit/osc/v1/test_baremetal.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,515 @@
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 2015 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import copy
 | 
			
		||||
 | 
			
		||||
from openstackclient.tests import utils as oscutils
 | 
			
		||||
 | 
			
		||||
from ironicclient.osc.v1 import baremetal
 | 
			
		||||
from ironicclient.tests.unit.osc.v1 import fakes as baremetal_fakes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetal(baremetal_fakes.TestBaremetal):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetal, self).setUp()
 | 
			
		||||
 | 
			
		||||
        # Get a shortcut to the FlavorManager Mock
 | 
			
		||||
        self.baremetal_mock = self.app.client_manager.baremetal
 | 
			
		||||
        self.baremetal_mock.reset_mock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalCreate(TestBaremetal):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalCreate, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.create.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.CreateBaremetal(self.app, None)
 | 
			
		||||
        self.arglist = ['--driver', 'fake_driver']
 | 
			
		||||
        self.verifylist = [('driver', 'fake_driver')]
 | 
			
		||||
        self.collist = (
 | 
			
		||||
            'instance_uuid',
 | 
			
		||||
            'maintenance',
 | 
			
		||||
            'name',
 | 
			
		||||
            'power_state',
 | 
			
		||||
            'provision_state',
 | 
			
		||||
            'uuid'
 | 
			
		||||
        )
 | 
			
		||||
        self.datalist = (
 | 
			
		||||
            'yyy-yyyyyy-yyyy',
 | 
			
		||||
            baremetal_fakes.baremetal_maintenance,
 | 
			
		||||
            baremetal_fakes.baremetal_name,
 | 
			
		||||
            baremetal_fakes.baremetal_power_state,
 | 
			
		||||
            baremetal_fakes.baremetal_provision_state,
 | 
			
		||||
            baremetal_fakes.baremetal_uuid,
 | 
			
		||||
        )
 | 
			
		||||
        self.actual_kwargs = {
 | 
			
		||||
            'driver': 'fake_driver',
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def check_with_options(self, addl_arglist, addl_verifylist, addl_kwargs):
 | 
			
		||||
        arglist = copy.copy(self.arglist) + addl_arglist
 | 
			
		||||
        verifylist = copy.copy(self.verifylist) + addl_verifylist
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        collist = copy.copy(self.collist)
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
 | 
			
		||||
        datalist = copy.copy(self.datalist)
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
        kwargs = copy.copy(self.actual_kwargs)
 | 
			
		||||
        kwargs.update(addl_kwargs)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.create.assert_called_once_with(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_no_options(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        self.assertRaises(oscutils.ParserException,
 | 
			
		||||
                          self.check_parser,
 | 
			
		||||
                          self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_driver(self):
 | 
			
		||||
        arglist = copy.copy(self.arglist)
 | 
			
		||||
 | 
			
		||||
        verifylist = copy.copy(self.verifylist)
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        collist = copy.copy(self.collist)
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
 | 
			
		||||
        datalist = copy.copy(self.datalist)
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
        kwargs = copy.copy(self.actual_kwargs)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.create.assert_called_once_with(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_chassis(self):
 | 
			
		||||
        self.check_with_options(['--chassis', 'chassis_uuid'],
 | 
			
		||||
                                [('chassis_uuid', 'chassis_uuid')],
 | 
			
		||||
                                {'chassis_uuid': 'chassis_uuid'})
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_driver_info(self):
 | 
			
		||||
        self.check_with_options(['--driver-info', 'arg1=val1',
 | 
			
		||||
                                 '--driver-info', 'arg2=val2'],
 | 
			
		||||
                                [('driver_info',
 | 
			
		||||
                                  ['arg1=val1',
 | 
			
		||||
                                   'arg2=val2'])],
 | 
			
		||||
                                {'driver_info': {
 | 
			
		||||
                                    'arg1': 'val1',
 | 
			
		||||
                                    'arg2': 'val2'}})
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_properties(self):
 | 
			
		||||
        self.check_with_options(['--property', 'arg1=val1',
 | 
			
		||||
                                 '--property', 'arg2=val2'],
 | 
			
		||||
                                [('properties',
 | 
			
		||||
                                  ['arg1=val1',
 | 
			
		||||
                                   'arg2=val2'])],
 | 
			
		||||
                                {'properties': {
 | 
			
		||||
                                    'arg1': 'val1',
 | 
			
		||||
                                    'arg2': 'val2'}})
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_extra(self):
 | 
			
		||||
        self.check_with_options(['--extra', 'arg1=val1',
 | 
			
		||||
                                 '--extra', 'arg2=val2'],
 | 
			
		||||
                                [('extra',
 | 
			
		||||
                                  ['arg1=val1',
 | 
			
		||||
                                   'arg2=val2'])],
 | 
			
		||||
                                {'extra': {
 | 
			
		||||
                                    'arg1': 'val1',
 | 
			
		||||
                                    'arg2': 'val2'}})
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_uuid(self):
 | 
			
		||||
        self.check_with_options(['--uuid', 'uuid'],
 | 
			
		||||
                                [('uuid', 'uuid')],
 | 
			
		||||
                                {'uuid': 'uuid'})
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_create_with_name(self):
 | 
			
		||||
        self.check_with_options(['--name', 'name'],
 | 
			
		||||
                                [('name', 'name')],
 | 
			
		||||
                                {'name': 'name'})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalDelete(TestBaremetal):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalDelete, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.get.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.DeleteBaremetal(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_delete(self):
 | 
			
		||||
        arglist = ['xxx-xxxxxx-xxxx']
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        args = ['xxx-xxxxxx-xxxx']
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.delete.assert_called_with(
 | 
			
		||||
            *args
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalList(TestBaremetal):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalList, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.list.return_value = [
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.ListBaremetal(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_list_no_options(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'detail': False,
 | 
			
		||||
            'marker': None,
 | 
			
		||||
            'limit': None,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.list.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        collist = (
 | 
			
		||||
            "UUID",
 | 
			
		||||
            "Name",
 | 
			
		||||
            "Instance UUID",
 | 
			
		||||
            "Power State",
 | 
			
		||||
            "Provisioning State",
 | 
			
		||||
            "Maintenance"
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
        datalist = ((
 | 
			
		||||
            baremetal_fakes.baremetal_uuid,
 | 
			
		||||
            baremetal_fakes.baremetal_name,
 | 
			
		||||
            baremetal_fakes.baremetal_instance_uuid,
 | 
			
		||||
            baremetal_fakes.baremetal_power_state,
 | 
			
		||||
            baremetal_fakes.baremetal_provision_state,
 | 
			
		||||
            baremetal_fakes.baremetal_maintenance,
 | 
			
		||||
        ), )
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_list_long(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--long',
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('long', True),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'detail': True,
 | 
			
		||||
            'marker': None,
 | 
			
		||||
            'limit': None,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.list.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        collist = ('Chassis UUID', 'Created At', 'Clean Step',
 | 
			
		||||
                   'Console Enabled', 'Driver', 'Driver Info',
 | 
			
		||||
                   'Driver Internal Info', 'Extra', 'Instance Info',
 | 
			
		||||
                   'Instance UUID', 'Last Error', 'Maintenance',
 | 
			
		||||
                   'Maintenance Reason', 'Power State', 'Properties',
 | 
			
		||||
                   'Provisioning State', 'Provision Updated At', 'Reservation',
 | 
			
		||||
                   'Target Power State', 'Target Provision State',
 | 
			
		||||
                   'Updated At', 'Inspection Finished At',
 | 
			
		||||
                   'Inspection Started At', 'UUID', 'Name')
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
        datalist = ((
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            baremetal_fakes.baremetal_instance_uuid,
 | 
			
		||||
            '',
 | 
			
		||||
            baremetal_fakes.baremetal_maintenance,
 | 
			
		||||
            '',
 | 
			
		||||
            baremetal_fakes.baremetal_power_state,
 | 
			
		||||
            '',
 | 
			
		||||
            baremetal_fakes.baremetal_provision_state,
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            baremetal_fakes.baremetal_uuid,
 | 
			
		||||
            baremetal_fakes.baremetal_name,
 | 
			
		||||
        ), )
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalSet(TestBaremetal):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalSet, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.SetBaremetal(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_set_no_options(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        self.assertRaises(oscutils.ParserException,
 | 
			
		||||
                          self.check_parser,
 | 
			
		||||
                          self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_set_one_property(self):
 | 
			
		||||
        arglist = ['node_uuid', '--property', 'path/to/property=value']
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('node', 'node_uuid'),
 | 
			
		||||
            ('property', ['path/to/property=value']),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.assert_called_once_with(
 | 
			
		||||
            'node_uuid',
 | 
			
		||||
            [{'path': '/path/to/property', 'value': 'value', 'op': 'add'}])
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_set_multiple_properties(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            'node_uuid',
 | 
			
		||||
            '--property', 'path/to/property=value',
 | 
			
		||||
            '--property', 'other/path=value2'
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('node', 'node_uuid'),
 | 
			
		||||
            ('property',
 | 
			
		||||
             [
 | 
			
		||||
                 'path/to/property=value',
 | 
			
		||||
                 'other/path=value2',
 | 
			
		||||
             ]),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.assert_called_once_with(
 | 
			
		||||
            'node_uuid',
 | 
			
		||||
            [{'path': '/path/to/property', 'value': 'value', 'op': 'add'},
 | 
			
		||||
             {'path': '/other/path', 'value': 'value2', 'op': 'add'}]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalShow(TestBaremetal):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalShow, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.get.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.get_by_instance_uuid.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.ShowBaremetal(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_show(self):
 | 
			
		||||
        arglist = ['xxx-xxxxxx-xxxx']
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        args = ['xxx-xxxxxx-xxxx']
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.get.assert_called_with(
 | 
			
		||||
            *args
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        collist = (
 | 
			
		||||
            'instance_uuid',
 | 
			
		||||
            'maintenance',
 | 
			
		||||
            'name',
 | 
			
		||||
            'power_state',
 | 
			
		||||
            'provision_state',
 | 
			
		||||
            'uuid'
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
        datalist = (
 | 
			
		||||
            'yyy-yyyyyy-yyyy',
 | 
			
		||||
            baremetal_fakes.baremetal_maintenance,
 | 
			
		||||
            baremetal_fakes.baremetal_name,
 | 
			
		||||
            baremetal_fakes.baremetal_power_state,
 | 
			
		||||
            baremetal_fakes.baremetal_provision_state,
 | 
			
		||||
            baremetal_fakes.baremetal_uuid
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_show_no_node(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        self.assertRaises(oscutils.ParserException,
 | 
			
		||||
                          self.check_parser,
 | 
			
		||||
                          self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_show_with_instance_uuid(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            'xxx-xxxxxx-xxxx',
 | 
			
		||||
            '--instance',
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('instance_uuid', True)
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # DisplayCommandBase.take_action() returns two tuples
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        args = ['xxx-xxxxxx-xxxx']
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.get_by_instance_uuid.assert_called_with(
 | 
			
		||||
            *args
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBaremetalUnset(TestBaremetal):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestBaremetalUnset, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.return_value = (
 | 
			
		||||
            baremetal_fakes.FakeBaremetalResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(baremetal_fakes.BAREMETAL),
 | 
			
		||||
                loaded=True,
 | 
			
		||||
            ))
 | 
			
		||||
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = baremetal.UnsetBaremetal(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_unset_no_options(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = []
 | 
			
		||||
 | 
			
		||||
        self.assertRaises(oscutils.ParserException,
 | 
			
		||||
                          self.check_parser,
 | 
			
		||||
                          self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_unset_one_property(self):
 | 
			
		||||
        arglist = ['node_uuid', '--property', 'path/to/property']
 | 
			
		||||
        verifylist = [('node', 'node_uuid'),
 | 
			
		||||
                      ('property', ['path/to/property'])]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.assert_called_once_with(
 | 
			
		||||
            'node_uuid',
 | 
			
		||||
            [{'path': '/path/to/property', 'op': 'remove'}])
 | 
			
		||||
 | 
			
		||||
    def test_baremetal_unset_multiple_properties(self):
 | 
			
		||||
        arglist = ['node_uuid',
 | 
			
		||||
                   '--property', 'path/to/property',
 | 
			
		||||
                   '--property', 'other/path']
 | 
			
		||||
        verifylist = [('node', 'node_uuid'),
 | 
			
		||||
                      ('property',
 | 
			
		||||
                       ['path/to/property',
 | 
			
		||||
                        'other/path'])]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.baremetal_mock.node.update.assert_called_once_with(
 | 
			
		||||
            'node_uuid',
 | 
			
		||||
            [{'path': '/path/to/property', 'op': 'remove'},
 | 
			
		||||
             {'path': '/other/path', 'op': 'remove'}]
 | 
			
		||||
        )
 | 
			
		||||
@@ -5,10 +5,12 @@ pbr<2.0,>=1.4
 | 
			
		||||
anyjson>=0.3.3
 | 
			
		||||
appdirs>=1.3.0 # MIT License
 | 
			
		||||
dogpile.cache>=0.5.4
 | 
			
		||||
cliff>=1.14.0          # Apache-2.0
 | 
			
		||||
httplib2>=0.7.5
 | 
			
		||||
lxml>=2.3
 | 
			
		||||
oslo.i18n>=1.5.0 # Apache-2.0
 | 
			
		||||
oslo.utils>=2.0.0 # Apache-2.0
 | 
			
		||||
PrettyTable<0.8,>=0.7
 | 
			
		||||
python-keystoneclient>=1.6.0
 | 
			
		||||
python-openstackclient>=1.5.0
 | 
			
		||||
six>=1.9.0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								setup.cfg
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								setup.cfg
									
									
									
									
									
								
							@@ -25,6 +25,17 @@ packages = ironicclient
 | 
			
		||||
console_scripts =
 | 
			
		||||
    ironic = ironicclient.shell:main
 | 
			
		||||
 | 
			
		||||
openstack.cli.extension =
 | 
			
		||||
    baremetal = ironicclient.osc.plugin
 | 
			
		||||
 | 
			
		||||
openstack.baremetal.v1 =
 | 
			
		||||
    baremetal_create = ironicclient.osc.v1.baremetal:CreateBaremetal
 | 
			
		||||
    baremetal_delete = ironicclient.osc.v1.baremetal:DeleteBaremetal
 | 
			
		||||
    baremetal_list = ironicclient.osc.v1.baremetal:ListBaremetal
 | 
			
		||||
    baremetal_set = ironicclient.osc.v1.baremetal:SetBaremetal
 | 
			
		||||
    baremetal_show = ironicclient.osc.v1.baremetal:ShowBaremetal
 | 
			
		||||
    baremetal_unset = ironicclient.osc.v1.baremetal:UnsetBaremetal
 | 
			
		||||
 | 
			
		||||
[pbr]
 | 
			
		||||
autodoc_index_modules = True
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user