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 <rbrady@redhat.com>
Co-Authored-By: Dougal Matthews <dougal@redhat.com>

Change-Id: Ibd5b2f12b453b70c54272e43ae31195895bd4a20
Depends-On: I17116c0f995ab76ed79bd8b2df57629c1ed4e4d0
This commit is contained in:
Dan Prince 2016-05-20 17:48:03 -04:00
parent 1e2902ba3b
commit 3397094dde
4 changed files with 103 additions and 1 deletions

View File

@ -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

View File

@ -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
)

View File

@ -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')

View File

@ -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(