diff --git a/mistral/actions/generator_factory.py b/mistral/actions/generator_factory.py index 2c94b2938..765d298c7 100644 --- a/mistral/actions/generator_factory.py +++ b/mistral/actions/generator_factory.py @@ -19,16 +19,17 @@ from mistral.actions.openstack.action_generator import base SUPPORTED_MODULES = [ 'Nova', 'Glance', 'Keystone', 'Heat', 'Neutron', 'Cinder', 'Ceilometer', - 'Trove', 'Ironic' + 'Trove', 'Ironic', 'Baremetal Introspection' ] def all_generators(): for mod_name in SUPPORTED_MODULES: - mod_namespace = mod_name.lower() - mod_cls_name = 'mistral.actions.openstack.actions.%sAction' % mod_name + prefix = mod_name.replace(' ', '') + mod_namespace = mod_name.lower().replace(' ', '_') + mod_cls_name = 'mistral.actions.openstack.actions.%sAction' % prefix mod_action_cls = importutils.import_class(mod_cls_name) - generator_cls_name = '%sActionGenerator' % mod_name + generator_cls_name = '%sActionGenerator' % prefix yield type( generator_cls_name, diff --git a/mistral/actions/openstack/actions.py b/mistral/actions/openstack/actions.py index 9f7c65cab..5cec4a83a 100644 --- a/mistral/actions/openstack/actions.py +++ b/mistral/actions/openstack/actions.py @@ -16,6 +16,7 @@ from ceilometerclient.v2 import client as ceilometerclient from cinderclient.v2 import client as cinderclient from glanceclient.v2 import client as glanceclient from heatclient.v1 import client as heatclient +from ironic_inspector_client import v1 as ironic_inspector_client from ironicclient.v1 import client as ironicclient from keystoneclient import httpclient from keystoneclient.v3 import client as keystoneclient @@ -289,3 +290,21 @@ class IronicAction(base.OpenStackAction): @classmethod def _get_fake_client(cls): return cls._client_class("http://127.0.0.1:6385/") + + +class BaremetalIntrospectionAction(base.OpenStackAction): + _client_class = ironic_inspector_client.ClientV1 + + def _get_client(self): + ctx = context.ctx() + + LOG.debug("Baremetal introspection action security context: %s" % ctx) + + inspector_endpoint = keystone_utils.get_endpoint_for_project( + 'baremetal-introspection') + + return self._client_class( + api_version=1, + inspector_url=inspector_endpoint.url, + auth_token=ctx.auth_token, + ) diff --git a/mistral/actions/openstack/mapping.json b/mistral/actions/openstack/mapping.json index 80ebc8e40..57ac432ba 100644 --- a/mistral/actions/openstack/mapping.json +++ b/mistral/actions/openstack/mapping.json @@ -910,5 +910,17 @@ "port_get_by_address": "port.get_by_address", "port_list": "port.list", "port_update": "port.update" + }, + "baremetal_introspection": { + "_comment": "It uses ironic_inspector_client.v1.", + "introspect": "introspect", + "get_status": "get_status", + "get_data": "get_data", + "rules_create": "rules.create", + "rules_delete": "rules.delete", + "rules_delete_all": "rules.delete_all", + "rules_from_json": "rules.from_json", + "rules_get": "rules.get", + "rules_get_all": "rules.get_all" } } diff --git a/mistral/tests/unit/actions/openstack/test_generator.py b/mistral/tests/unit/actions/openstack/test_generator.py index 84a38f712..83ac4deff 100644 --- a/mistral/tests/unit/actions/openstack/test_generator.py +++ b/mistral/tests/unit/actions/openstack/test_generator.py @@ -26,6 +26,8 @@ MODULE_MAPPING = { 'ceilometer': ['ceilometer.alarms_list', actions.CeilometerAction], 'trove': ['trove.instances_list', actions.TroveAction], 'ironic': ['ironic.node_list', actions.IronicAction], + 'baremetal_introspection': ['baremetal_introspection.introspect', + actions.BaremetalIntrospectionAction], } EXTRA_MODULES = ['neutron'] diff --git a/mistral/tests/unit/actions/openstack/test_openstack_actions.py b/mistral/tests/unit/actions/openstack/test_openstack_actions.py index 3d2b16510..38a05e2c7 100644 --- a/mistral/tests/unit/actions/openstack/test_openstack_actions.py +++ b/mistral/tests/unit/actions/openstack/test_openstack_actions.py @@ -126,3 +126,15 @@ class OpenStackActionTest(base.BaseTestCase): self.assertTrue(mocked().node.get.called) mocked().node.get.assert_called_once_with(node="1234-abcd") + + @mock.patch.object(actions.BaremetalIntrospectionAction, '_get_client') + def test_baremetal_introspector_action(self, mocked): + method_name = "get_status" + action_class = actions.BaremetalIntrospectionAction + action_class.client_method_name = method_name + params = {'uuid': '1234'} + action = action_class(**params) + action.run() + + self.assertTrue(mocked().get_status.called) + mocked().get_status.assert_called_once_with(uuid="1234") diff --git a/requirements.txt b/requirements.txt index 4d2ada983..b4e8866bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,6 +30,7 @@ python-neutronclient>=2.6.0 python-novaclient!=2.33.0,>=2.29.0 python-troveclient>=1.2.0 python-ironicclient>=0.8.0 +python-ironic-inspector-client>=1.3.0 PyYAML>=3.1.0 requests>=2.8.1 retrying!=1.3.0,>=1.2.3 # Apache-2.0 diff --git a/tools/get_action_list.py b/tools/get_action_list.py index a0be1c263..0ebdd876d 100644 --- a/tools/get_action_list.py +++ b/tools/get_action_list.py @@ -36,6 +36,8 @@ from troveclient.v1 import client as troveclient # TODO(nmakhotkin): Find a rational way to do it for neutron. # TODO(nmakhotkin): Implement recursive way of searching for managers # TODO(nmakhotkin): (e.g. keystone). +# TODO(dprince): Need to update ironic_inspector_client before we can +# plug it in cleanly here. """It is simple CLI tool which allows to see and update mapping.json file if needed. mapping.json contains all allowing OpenStack actions sorted by @@ -158,6 +160,7 @@ CLIENTS = { 'trove': get_trove_client, 'ironic': get_ironic_client, # 'neutron': get_nova_client + # 'baremetal_introspection': ... } BASE_MANAGERS = { 'nova': BASE_NOVA_MANAGER, @@ -169,6 +172,7 @@ BASE_MANAGERS = { 'trove': BASE_TROVE_MANAGER, 'ironic': BASE_IRONIC_MANAGER, # 'neutron': BASE_NOVA_MANAGER + # 'baremetal_introspection': ... } NAMESPACES = { 'glance': GLANCE_NAMESPACE_LIST,