Merge "ironic: Add support for Introspection Rules"

This commit is contained in:
Zuul 2023-05-19 10:13:50 +00:00 committed by Gerrit Code Review
commit b7ff0313aa
7 changed files with 255 additions and 1 deletions

View File

@ -5,3 +5,4 @@ Baremetal Introspection Resources
:maxdepth: 1
v1/introspection
v1/introspection_rule

View File

@ -0,0 +1,13 @@
openstack.baremetal_introspection.v1.introspection_rule
========================================================
.. automodule:: openstack.baremetal_introspection.v1.introspection_rule
The IntrospectionRule Class
----------------------------
The ``IntrospectionRule`` class inherits from
:class:`~openstack.resource.Resource`.
.. autoclass:: openstack.baremetal_introspection.v1.introspection_rule.IntrospectionRule
:members:

View File

@ -13,6 +13,9 @@
from openstack import _log
from openstack.baremetal.v1 import node as _node
from openstack.baremetal_introspection.v1 import introspection as _introspect
from openstack.baremetal_introspection.v1 import (
introspection_rule as _introspection_rule,
)
from openstack import exceptions
from openstack import proxy
@ -23,6 +26,7 @@ _logger = _log.setup_logging('openstack')
class Proxy(proxy.Proxy):
_resource_registry = {
"introspection": _introspect.Introspection,
"introspection_rule": _introspection_rule.IntrospectionRule,
}
def introspections(self, **query):
@ -128,7 +132,10 @@ class Proxy(proxy.Proxy):
raise
def wait_for_introspection(
self, introspection, timeout=None, ignore_error=False
self,
introspection,
timeout=None,
ignore_error=False,
):
"""Wait for the introspection to finish.
@ -147,3 +154,76 @@ class Proxy(proxy.Proxy):
"""
res = self._get_resource(_introspect.Introspection, introspection)
return res.wait(self, timeout=timeout, ignore_error=ignore_error)
def create_introspection_rule(self, **attrs):
"""Create a new introspection rules from attributes.
:param dict attrs: Keyword arguments which will be used to create
a :class:`~.introspection_rule.IntrospectionRule`,
comprised of the properties on the IntrospectionRule class.
:returns: :class:`~.introspection_rule.IntrospectionRule` instance.
"""
return self._create(_introspection_rule.IntrospectionRule, **attrs)
def delete_introspection_rule(
self,
introspection_rule,
ignore_missing=True,
):
"""Delete an introspection rule.
:param introspection_rule: The value can be either the ID of an
introspection rule or a
:class:`~.introspection_rule.IntrospectionRule` instance.
:param bool ignore_missing: When set to ``False``, an
exception:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the introspection rule could not be found. When set to
``True``, no exception will be raised when attempting to delete a
non-existent introspection rule.
:returns: ``None``
"""
self._delete(
_introspection_rule.IntrospectionRule,
introspection_rule,
ignore_missing=ignore_missing,
)
def get_introspection_rule(self, introspection_rule):
"""Get a specific introspection rule.
:param introspection_rule: The value can be the name or ID of an
introspection rule or a
:class:`~.introspection_rule.IntrospectionRule` instance.
:returns: :class:`~.introspection_rule.IntrospectionRule` instance.
:raises: :class:`~openstack.exceptions.ResourceNotFound` when no
introspection rule matching the name or ID could be found.
"""
return self._get(
_introspection_rule.IntrospectionRule,
introspection_rule,
)
def introspection_rules(self, **query):
"""Retrieve a generator of introspection rules.
:param dict query: Optional query parameters to be sent to restrict
the records to be returned. Available parameters include:
* ``uuid``: The UUID of the Ironic Inspector rule.
* ``limit``: List of a logic statementd or operations in rules,
that can be evaluated as True or False.
* ``actions``: List of operations that will be performed
if conditions of this rule are fulfilled.
* ``description``: Rule human-readable description.
* ``scope``: Scope of an introspection rule. If set, the rule
is only applied to nodes that have
matching inspection_scope property.
:returns: A generator of
:class:`~.introspection_rule.IntrospectionRule`
objects
"""
return self._list(_introspection_rule.IntrospectionRule, **query)

View File

@ -0,0 +1,44 @@
# 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 openstack.baremetal.v1 import _common
from openstack import resource
class IntrospectionRule(_common.ListMixin, resource.Resource):
resources_key = 'rules'
base_path = '/rules'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = False
allow_delete = True
allow_list = True
# created via POST with ID
create_method = 'POST'
create_requires_id = True
#: The UUID of the resource.
id = resource.Body('uuid', alternate_id=True)
#: List of a logic statementd or operations in rules
conditions = resource.Body('conditions', type=list)
#: List of operations that will be performed if conditions of this rule
#: are fulfilled.
actions = resource.Body('actions', type=list)
#: Rule human-readable description
description = resource.Body('description')
#: Scope of an introspection rule
scope = resource.Body('scope')
#: A list of relative links, including the self and bookmark links.
links = resource.Body('links', type=list)

View File

@ -0,0 +1,74 @@
# 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 openstack.baremetal_introspection.v1 import introspection_rule
from openstack.tests.unit import base
FAKE = {
"actions": [
{
"action": "set-attribute",
"path": "driver_info/deploy_kernel",
"value": "8fd65-c97b-4d00-aa8b-7ed166a60971",
},
{
"action": "set-attribute",
"path": "driver_info/deploy_ramdisk",
"value": "09e5420c-6932-4199-996e-9485c56b3394",
},
],
"conditions": [
{
"field": "node://driver_info.deploy_ramdisk",
"invert": False,
"multiple": "any",
"op": "is-empty",
},
{
"field": "node://driver_info.deploy_kernel",
"invert": False,
"multiple": "any",
"op": "is-empty",
},
],
"description": "Set deploy info if not already set on node",
"links": [
{
"href": "/v1/rules/7459bf7c-9ff9-43a8-ba9f-48542ecda66c",
"rel": "self",
}
],
"uuid": "7459bf7c-9ff9-43a8-ba9f-48542ecda66c",
"scope": "",
}
class TestIntrospectionRule(base.TestCase):
def test_basic(self):
sot = introspection_rule.IntrospectionRule()
self.assertIsNone(sot.resource_key)
self.assertEqual('rules', sot.resources_key)
self.assertEqual('/rules', sot.base_path)
self.assertTrue(sot.allow_create)
self.assertTrue(sot.allow_fetch)
self.assertFalse(sot.allow_commit)
self.assertTrue(sot.allow_delete)
self.assertTrue(sot.allow_list)
self.assertEqual('POST', sot.create_method)
def test_instantiate(self):
sot = introspection_rule.IntrospectionRule(**FAKE)
self.assertEqual(FAKE['conditions'], sot.conditions)
self.assertEqual(FAKE['actions'], sot.actions)
self.assertEqual(FAKE['description'], sot.description)
self.assertEqual(FAKE['uuid'], sot.id)
self.assertEqual(FAKE['scope'], sot.scope)

View File

@ -17,6 +17,7 @@ from keystoneauth1 import adapter
from openstack.baremetal.v1 import node as _node
from openstack.baremetal_introspection.v1 import _proxy
from openstack.baremetal_introspection.v1 import introspection
from openstack.baremetal_introspection.v1 import introspection_rule
from openstack import exceptions
from openstack.tests.unit import base
from openstack.tests.unit import test_proxy_base
@ -188,3 +189,41 @@ class TestGetData(base.TestCase):
microversion='1.17',
)
self.assertIs(data, mock_request.return_value.json.return_value)
class TestIntrospectionRule(test_proxy_base.TestProxyBase):
def setUp(self):
super().setUp()
self.proxy = _proxy.Proxy(self.session)
def test_introspection_rule_create(self):
self.verify_create(
self.proxy.create_introspection_rule,
introspection_rule.IntrospectionRule,
)
def test_introspection_rule_delete(self):
self.verify_delete(
self.proxy.delete_introspection_rule,
introspection_rule.IntrospectionRule,
False,
)
def test_introspection_rule_delete_ignore(self):
self.verify_delete(
self.proxy.delete_introspection_rule,
introspection_rule.IntrospectionRule,
True,
)
def test_introspection_rule_get(self):
self.verify_get(
self.proxy.get_introspection_rule,
introspection_rule.IntrospectionRule,
)
def test_introspection_rules(self):
self.verify_list(
self.proxy.introspection_rules,
introspection_rule.IntrospectionRule,
)

View File

@ -0,0 +1,3 @@
features:
- |
Add support for Ironic Inspector Introspection Rules API.