mogan/mogan/engine/baremetal/ironic.py

157 lines
5.2 KiB
Python

# Copyright 2016 Huawei Technologies Co.,LTD.
# 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.
from ironicclient import exceptions as client_e
from oslo_log import log as logging
from mogan.common.i18n import _LE
from mogan.common.i18n import _LW
from mogan.common import states
from mogan.engine.baremetal import ironic_states
LOG = logging.getLogger(__name__)
_NODE_FIELDS = ('uuid', 'power_state', 'target_power_state', 'provision_state',
'target_provision_state', 'last_error', 'maintenance',
'properties', 'instance_uuid')
_POWER_STATE_MAP = {
ironic_states.POWER_ON: states.POWER_ON,
ironic_states.NOSTATE: states.NOSTATE,
ironic_states.POWER_OFF: states.POWER_OFF,
}
def map_power_state(state):
try:
return _POWER_STATE_MAP[state]
except KeyError:
LOG.warning(_LW("Power state %s not found."), state)
return states.NOSTATE
def get_power_state(ironicclient, instance_uuid):
try:
node = ironicclient.call('node.get_by_instance_uuid',
instance_uuid, fields=('power_state',))
return map_power_state(node.power_state)
except client_e.NotFound:
return map_power_state(ironic_states.NOSTATE)
def get_ports_from_node(ironicclient, node_uuid, detail=False):
"""List the MAC addresses and the port types from a node."""
ports = ironicclient.call("node.list_ports", node_uuid, detail=detail)
return ports
def plug_vif(ironicclient, ironic_port_id, port_id):
patch = [{'op': 'add',
'path': '/extra/vif_port_id',
'value': port_id}]
ironicclient.call("port.update", ironic_port_id, patch)
def unplug_vif(ironicclient, ironic_port_id):
patch = [{'op': 'remove',
'path': '/extra/vif_port_id'}]
try:
ironicclient.call("port.update", ironic_port_id, patch)
except client_e.BadRequest:
pass
def set_instance_info(ironicclient, instance):
patch = []
# Associate the node with an instance
patch.append({'path': '/instance_uuid', 'op': 'add',
'value': instance.uuid})
# Add the required fields to deploy a node.
patch.append({'path': '/instance_info/image_source', 'op': 'add',
'value': instance.image_uuid})
patch.append({'path': '/instance_info/root_gb', 'op': 'add',
'value': '10'})
patch.append({'path': '/instance_info/swap_mb', 'op': 'add',
'value': '0'})
patch.append({'path': '/instance_info/display_name',
'op': 'add', 'value': instance.name})
patch.append({'path': '/instance_info/vcpus', 'op': 'add',
'value': '1'})
patch.append({'path': '/instance_info/memory_mb', 'op': 'add',
'value': '10240'})
patch.append({'path': '/instance_info/local_gb', 'op': 'add',
'value': '10'})
ironicclient.call("node.update", instance.node_uuid, patch)
def unset_instance_info(ironicclient, instance):
patch = [{'path': '/instance_info', 'op': 'remove'},
{'path': '/instance_uuid', 'op': 'remove'}]
ironicclient.call("node.update", instance.node_uuid, patch)
def do_node_deploy(ironicclient, node_uuid):
# trigger the node deploy
ironicclient.call("node.set_provision_state", node_uuid,
ironic_states.ACTIVE)
def get_node_by_instance(ironicclient, instance_uuid, fields=None):
if fields is None:
fields = _NODE_FIELDS
return ironicclient.call('node.get_by_instance_uuid',
instance_uuid, fields=fields)
def destroy_node(ironicclient, node_uuid):
# trigger the node destroy
ironicclient.call("node.set_provision_state", node_uuid,
ironic_states.DELETED)
def validate_node(ironicclient, node_uuid):
return ironicclient.call("node.validate", node_uuid)
def get_node_list(ironicclient, **kwargs):
"""Helper function to return the list of nodes.
If unable to connect ironic server, an empty list is returned.
:returns: a list of raw node from ironic
"""
try:
node_list = ironicclient.call("node.list", **kwargs)
except client_e.ClientException as e:
LOG.exception(_LE("Could not get nodes from ironic. Reason: "
"%(detail)s"), {'detail': e.message})
node_list = []
return node_list
def get_node_states(ironicclient, node_uuid):
return ironicclient.call("node.states", node_uuid)
# Do we need to catch NotFound exception.
def set_power_state(ironicclient, node_uuid, state):
ironicclient.call("node.set_power_state", node_uuid, state)
# Do we need to catch NotFound exception.