From 3397094ddee794cb8e73e93873b60e8f6c408bd0 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 20 May 2016 17:48:03 -0400 Subject: [PATCH] Add RegisterNodesAction action This patch adds a custom wrapper around the tripleo-common utils/nodes.py register_all_nodes function so that we can call it in a workflow to help register nodes. Co-Authored-By: Ryan Brady Co-Authored-By: Dougal Matthews Change-Id: Ibd5b2f12b453b70c54272e43ae31195895bd4a20 Depends-On: I17116c0f995ab76ed79bd8b2df57629c1ed4e4d0 --- setup.cfg | 1 + tripleo_common/actions/baremetal.py | 60 +++++++++++++++++++++++++++++ tripleo_common/actions/base.py | 24 ++++++++++++ tripleo_common/utils/glance.py | 19 ++++++++- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tripleo_common/actions/baremetal.py diff --git a/setup.cfg b/setup.cfg index d522d31d3..733c05e56 100644 --- a/setup.cfg +++ b/setup.cfg @@ -58,3 +58,4 @@ mistral.actions = tripleo.create_plan = tripleo_common.actions.plan:CreatePlanAction tripleo.get_capabilities = tripleo_common.actions.heat_capabilities:GetCapabilitiesAction tripleo.update_capabilities = tripleo_common.actions.heat_capabilities:UpdateCapabilitiesAction + tripleo.register_or_update_nodes = tripleo_common.actions.baremetal:RegisterOrUpdateNodes diff --git a/tripleo_common/actions/baremetal.py b/tripleo_common/actions/baremetal.py new file mode 100644 index 000000000..342b9da8c --- /dev/null +++ b/tripleo_common/actions/baremetal.py @@ -0,0 +1,60 @@ +# Copyright 2016 Red Hat, 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. +import logging + +from mistral.workflow import utils as mistral_workflow_utils +from tripleo_common.actions import base +from tripleo_common.utils import nodes + +LOG = logging.getLogger(__name__) + + +class RegisterOrUpdateNodes(base.TripleOAction): + """Register Nodes Action + + :param nodes_json: list of nodes & attributes in json format + :param remove: Should nodes not in the list be removed? + :param kernel_name: Glance ID of the kernel to use for the nodes. + :param ramdisk_name: Glance ID of the ramdisk to use for the nodes. + :return: list of node objects representing the new nodes. + """ + + def __init__(self, nodes_json, remove=False, kernel_name=None, + ramdisk_name=None): + super(RegisterOrUpdateNodes, self).__init__() + self.nodes_json = nodes_json + self.remove = remove + self.kernel_name = kernel_name + self.ramdisk_name = ramdisk_name + + def run(self): + baremetal_client = self._get_baremetal_client() + image_client = self._get_image_client() + + try: + return nodes.register_all_nodes( + 'service_host', # unused + self.nodes_json, + client=baremetal_client, + remove=self.remove, + glance_client=image_client, + kernel_name=self.kernel_name, + ramdisk_name=self.ramdisk_name) + except Exception as err: + LOG.exception("Error registering nodes with ironic.") + return mistral_workflow_utils.Result( + "", + err.message + ) diff --git a/tripleo_common/actions/base.py b/tripleo_common/actions/base.py index 7db53f40e..447dbd414 100644 --- a/tripleo_common/actions/base.py +++ b/tripleo_common/actions/base.py @@ -14,7 +14,9 @@ # under the License. import logging +from glanceclient.v2 import client as glanceclient from heatclient.v1 import client as heatclient +from ironicclient.v1 import client as ironicclient from mistral.actions import base from mistral import context from mistral.utils.openstack import keystone as keystone_utils @@ -41,6 +43,28 @@ class TripleOAction(base.Action): return swift_client.Connection(**kwargs) + def _get_baremetal_client(self): + ctx = context.ctx() + + ironic_endpoint = keystone_utils.get_endpoint_for_project('ironic') + + return ironicclient.Client( + ironic_endpoint.url, + token=ctx.auth_token, + region_name=ironic_endpoint.region, + os_ironic_api_version='1.11' + ) + + def _get_image_client(self): + ctx = context.ctx() + + glance_endpoint = keystone_utils.get_endpoint_for_project('glance') + return glanceclient.Client( + glance_endpoint.url, + token=ctx.auth_token, + region_name=glance_endpoint.region + ) + def _get_orchestration_client(self): ctx = context.ctx() heat_endpoint = keystone_utils.get_endpoint_for_project('heat') diff --git a/tripleo_common/utils/glance.py b/tripleo_common/utils/glance.py index 00bacde6d..0ca41dd77 100644 --- a/tripleo_common/utils/glance.py +++ b/tripleo_common/utils/glance.py @@ -17,6 +17,7 @@ import collections import logging from glanceclient import exc as exceptions +from glanceclient.v2.client import Client as real_glance_client LOG = logging.getLogger(__name__) @@ -50,7 +51,23 @@ def _upload_file(glanceclient, name, path, disk_format, type_name, skip_missing=False): image_tuple = collections.namedtuple('image', ['id']) try: - image = glanceclient.images.find(name=name, disk_format=disk_format) + if isinstance(glanceclient, real_glance_client): + images = glanceclient.images.list(name=name, + disk_format=disk_format) + image = None + for img in images: + if img['name'] == name and img['disk_format'] == disk_format: + image = img + if not image: + raise exceptions.NotFound("No image found") + else: + # TODO(dprince) remove this + # This code expects the python-openstackclient version of + # "glanceclient" (which isn't pure python-glanceclient) and is + # here for backwards compat until python-tripleoclient starts + # using the Mistral API for this functionality. + image = glanceclient.images.find(name=name, + disk_format=disk_format) except exceptions.NotFound: if path: image = glanceclient.images.create(