summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-02-12 13:20:10 +0000
committerGerrit Code Review <review@openstack.org>2021-02-12 13:20:10 +0000
commitb22429fa8bd823f10b555dc9b07c712101c80c60 (patch)
tree927a26eb55ce1b862e3fc4238bd8b32b7ecb6113
parent71a875faccdd9a546c28eac8b89bb8d958b65a55 (diff)
parent606549c1c95b3f2c611b8bd5771e19dadeed3995 (diff)
downloadironic-b22429fa8bd823f10b555dc9b07c712101c80c60.tar.gz
Merge "Populate existing policy tests"
-rw-r--r--doc/source/contributor/index.rst1
-rw-r--r--doc/source/contributor/rbac-testing.rst119
-rw-r--r--ironic/tests/unit/api/base.py15
-rw-r--r--ironic/tests/unit/api/test_acl.py150
-rw-r--r--ironic/tests/unit/api/test_acl_basic.yaml1
-rw-r--r--ironic/tests/unit/api/test_rbac_legacy.yaml2020
6 files changed, 1965 insertions, 341 deletions
diff --git a/doc/source/contributor/index.rst b/doc/source/contributor/index.rst
index 0377bdb34..072490554 100644
--- a/doc/source/contributor/index.rst
+++ b/doc/source/contributor/index.rst
@@ -32,6 +32,7 @@ primarily for developers.
Developing New Notifications <notifications>
OSProfiler Tracing <osprofiler-support>
Rolling Upgrades <rolling-upgrades>
+ Role Based Access Control Testing <rbac-testing>
These pages contain information for PTLs, cross-project liaisons, and core
reviewers.
diff --git a/doc/source/contributor/rbac-testing.rst b/doc/source/contributor/rbac-testing.rst
new file mode 100644
index 000000000..dca06b36d
--- /dev/null
+++ b/doc/source/contributor/rbac-testing.rst
@@ -0,0 +1,119 @@
+==================================
+Role Based Acces Control - Testing
+==================================
+
+.. todo: This entire file is being added in to provide context for
+ reviewers so we can keep in-line comments to the necessary points
+ in the yaml files. It *IS* written with a forward awareness of the
+ later patches, but it is also broad in nature attempting to provide
+ context to aid in review.
+
+The Role Based Access control testing is a minor departure from the ironic
+standard pattern of entirely python based unit testing. In part this was done
+for purposes of speed and to keep the declaration of the test context.
+
+This also lended itself to be very useful due to the nature of A/B testing
+which is requried to properly migrate the Ironic project from a project
+scoped universe where an ``admin project`` is utilized as the authenticating
+factor coupled with two custom roles, ``baremetal_admin``, and
+``baremetal_observer``.
+
+As a contributor looking back after getting a over a thousand additional tests
+in place using this method, it definitely helped the speed at which these
+were created, and then ported to support additional.
+
+How these tests work
+====================
+
+These tests execute API calls through the API layer, using the appropriate
+verb and header, which settings to prevent the ``keystonemiddleware`` from
+intercepting and replacing the headers we're passing. Ultimately this is a
+feature, and it helps quite a bit.
+
+The second aspect of how this works is we're mocking the conductor RPC
+``get_topic_for`` and ``get_random_topic_for`` methods. These calls raise
+Temporary Unavailable, since trying to execute the entire interaction into
+the conductor is moderately pointless because all policy enforement is
+located with-in the API layer.
+
+At the same time wiring everything up to go from API to conductor code and
+back would have been a heavier lift. As such, the tests largely look for
+one of the following error codes.
+
+* 200 - Got the item from the API - This is an database driven interaction.
+* 201 - Created - This is databaes driven interaction. These are rare.
+* 204 - Accepted - This is a database driven interaction. These are rare.
+* 403 - Forbidden - This tells us the policy worked as expected where
+ access was denied.
+* 404 - NotFound - This is typically when objects were not found. Before
+ ironic becomes scope aware, these are generally only in the drivers
+ API endpoint's behavior. In System scope aware Project scoped
+ configuration, i.e. later RBAC tests, this will become the dominant
+ response for project scoped users as responding with a 403 if they
+ could be an owner or lessee would provide insight into the existence
+ of a node.
+* 503 - Service Unavailable - In the context of our tests, we expect this
+ when a request *has* been successfully authenticated and would have
+ been sent along to the conductor.
+
+How to make changes or review these tests?
+==========================================
+
+The tests cycle through the various endpoints, and repeating patterns
+are clearly visible. Typically this means a given endpoint is cycled
+through with the same basic test using slightly different parameters
+such as different authentication parameters. When it comes to system
+scope aware tests supporting node ``owners`` and ``lessee``, these
+tests will cycle a little more with slightly different attributes
+as the operation is not general against a shared common node, but
+different nodes.
+
+Some tests will test body contents, or attributes. some will validate
+the number of records returned. This is important later with ``owner``
+and ``lessee`` having slightly different views of the universe.
+
+Some general rules apply
+
+* Admins can do things
+* Members can do some things, but not everything
+* Readers can always read, but as we get into sensitive data later on
+ such as fields containing infrastucture internal addresses, these values
+ will become hidden and additional tests will examine this.
+* Third party, or external/other Admins will find nothing but sadness
+ in empty lists, 403, 404, or even 500 errors.
+
+What is/will be tested?
+=======================
+
+The idea is to in essence test as much as possible, however as these
+tests Role Based Access Control related capabilities will come in a
+series of phases, styles vary a little.
+
+The first phase is ``"legacy"``. In essence these are partially
+programatically generated and then human reviewed and values populated
+with expected values.
+
+The second phase is remarkably similar to ``legacy``. It is the safety net
+where we execute the ``legacy`` tests with the updated ``oslo.policy``
+configuration to help enforce scopes. These tests will intentionally begin to
+fail in phase three.
+
+The third phase is the implementation of System scope awareness for the
+API. In this process, as various portions of the API are made system scope
+aware. The ``legacy`` tests are marked as ``deprecated`` which signals to
+the second phase test sequences that they are **expected** to fail. New
+``system scoped`` tests are also implemented which are matched up by name
+to the ``legacy`` tests. The major difference being some header values,
+and a user with a ``member`` role in the ``system`` scope now has some
+rights.
+
+The forth phase, is implementaiton of ``owner`` and ``lessee`` aware
+project scoping. The testing approach is similar, however it is much more of
+a "shotgun" approach. We test what we know should work, and what know should
+not work, but we do not have redundant testing for each role as ``admin``
+users are also ``members``, and since the policy rules are designed around
+thresholds of access, it just made no sense to run the same test for admin
+and members, where member was the threshold. These thresholds will vary with
+the proposed default policy. The forth scope also tests a third party external
+admin as a negative test to ensure that we are also denying access to
+resources appropriately.
diff --git a/ironic/tests/unit/api/base.py b/ironic/tests/unit/api/base.py
index 3d80ee42f..ebf89df32 100644
--- a/ironic/tests/unit/api/base.py
+++ b/ironic/tests/unit/api/base.py
@@ -112,7 +112,7 @@ class BaseApiTest(db_base.DbTestCase):
return response
def put_json(self, path, params, expect_errors=False, headers=None,
- extra_environ=None, status=None):
+ extra_environ=None, status=None, path_prefix=PATH_PREFIX):
"""Sends simulated HTTP PUT request to Pecan test app.
:param path: url path of target service
@@ -127,10 +127,11 @@ class BaseApiTest(db_base.DbTestCase):
return self._request_json(path=path, params=params,
expect_errors=expect_errors,
headers=headers, extra_environ=extra_environ,
- status=status, method="put")
+ status=status, method="put",
+ path_prefix=path_prefix)
def post_json(self, path, params, expect_errors=False, headers=None,
- extra_environ=None, status=None):
+ extra_environ=None, status=None, path_prefix=PATH_PREFIX):
"""Sends simulated HTTP POST request to Pecan test app.
:param path: url path of target service
@@ -145,10 +146,11 @@ class BaseApiTest(db_base.DbTestCase):
return self._request_json(path=path, params=params,
expect_errors=expect_errors,
headers=headers, extra_environ=extra_environ,
- status=status, method="post")
+ status=status, method="post",
+ path_prefix=path_prefix)
def patch_json(self, path, params, expect_errors=False, headers=None,
- extra_environ=None, status=None):
+ extra_environ=None, status=None, path_prefix=PATH_PREFIX):
"""Sends simulated HTTP PATCH request to Pecan test app.
:param path: url path of target service
@@ -163,7 +165,8 @@ class BaseApiTest(db_base.DbTestCase):
return self._request_json(path=path, params=params,
expect_errors=expect_errors,
headers=headers, extra_environ=extra_environ,
- status=status, method="patch")
+ status=status, method="patch",
+ path_prefix=path_prefix)
def delete(self, path, expect_errors=False, headers=None,
extra_environ=None, status=None, path_prefix=PATH_PREFIX):
diff --git a/ironic/tests/unit/api/test_acl.py b/ironic/tests/unit/api/test_acl.py
index aa9a74019..adea1fe4e 100644
--- a/ironic/tests/unit/api/test_acl.py
+++ b/ironic/tests/unit/api/test_acl.py
@@ -23,6 +23,9 @@ import ddt
from keystonemiddleware import auth_token
from oslo_config import cfg
+from ironic.api.controllers.v1 import versions as api_versions
+from ironic.common import exception
+from ironic.conductor import rpcapi
from ironic.tests.unit.api import base
from ironic.tests.unit.db import utils as db_utils
@@ -42,6 +45,17 @@ class TestACLBase(base.BaseApiTest):
self.mock_auth = mock_auth.start()
self.addCleanup(mock_auth.stop)
+ topic = mock.patch.object(
+ rpcapi.ConductorAPI, 'get_topic_for', autospec=True)
+ self.mock_topic = topic.start()
+ self.mock_topic.side_effect = exception.TemporaryFailure
+ self.addCleanup(topic.stop)
+ rtopic = mock.patch.object(rpcapi.ConductorAPI, 'get_random_topic',
+ autospec=True)
+ self.mock_random_topic = rtopic.start()
+ self.mock_random_topic.side_effect = exception.TemporaryFailure
+ self.addCleanup(rtopic.stop)
+
def _make_app(self):
cfg.CONF.set_override('auth_strategy', 'keystone')
return super(TestACLBase, self)._make_app()
@@ -53,23 +67,70 @@ class TestACLBase(base.BaseApiTest):
def _check_skip(self, **kwargs):
if kwargs.get('skip_reason'):
self.skipTest(kwargs.get('skip_reason'))
- # Remove ASAP, but as a few hundred tests use this, we can
- # rip it out later.
- if kwargs.get('skip'):
- self.skipTest(kwargs.get('skip_reason', 'Not implemented'))
def _fake_process_request(self, request, auth_token_request):
pass
def _test_request(self, path, params=None, headers=None, method='get',
- assert_status=None, assert_dict_contains=None):
+ body=None, assert_status=None,
+ assert_dict_contains=None,
+ assert_list_length=None):
path = path.format(**self.format_data)
self.mock_auth.side_effect = self._fake_process_request
+ # always request the latest api version
+ version = api_versions.max_version_string()
+ rheaders = {
+ 'X-OpenStack-Ironic-API-Version': version
+ }
+ # NOTE(TheJulia): Logging the test request to aid
+ # in troubleshooting ACL testing. This is a pattern
+ # followed in API unit testing in ironic, and
+ # really does help.
+ print('API ACL Testing Path %s %s' % (method, path))
+ if headers:
+ for k, v in headers.items():
+ rheaders[k] = v.format(**self.format_data)
+
if method == 'get':
response = self.get_json(
path,
- headers=headers,
+ headers=rheaders,
+ expect_errors=True,
+ extra_environ=self.environ,
+ path_prefix=''
+ )
+ elif method == 'put':
+ response = self.put_json(
+ path,
+ headers=rheaders,
+ expect_errors=True,
+ extra_environ=self.environ,
+ path_prefix='',
+ params=body
+ )
+ elif method == 'post':
+ response = self.post_json(
+ path,
+ headers=rheaders,
+ expect_errors=True,
+ extra_environ=self.environ,
+ path_prefix='',
+ params=body
+ )
+ elif method == 'patch':
+ response = self.patch_json(
+ path,
+ params=body,
+ headers=rheaders,
+ expect_errors=True,
+ extra_environ=self.environ,
+ path_prefix=''
+ )
+ elif method == 'delete':
+ response = self.delete(
+ path,
+ headers=rheaders,
expect_errors=True,
extra_environ=self.environ,
path_prefix=''
@@ -77,12 +138,10 @@ class TestACLBase(base.BaseApiTest):
else:
assert False, 'Unimplemented test method: %s' % method
- other_asserts = bool(assert_dict_contains)
-
if assert_status:
self.assertEqual(assert_status, response.status_int)
else:
- self.assertIsNotNone(other_asserts,
+ self.assertIsNotNone(assert_status,
'Tests must include an assert_status')
if assert_dict_contains:
@@ -91,6 +150,22 @@ class TestACLBase(base.BaseApiTest):
self.assertEqual(v.format(**self.format_data),
response.json[k])
+ if assert_list_length:
+ for root, length in assert_list_length.items():
+ # root - object to look inside
+ # length - number of expected elements which will be
+ # important for owner/lessee testing.
+ items = response.json[root]
+ self.assertIsInstance(items, list)
+ self.assertEqual(length, len(items))
+
+ # NOTE(TheJulia): API tests in Ironic tend to have a pattern
+ # to print request and response data to aid in development
+ # and troubleshooting. As such the prints should remain,
+ # at least until we are through primary development of the
+ # this test suite.
+ print('ACL Test GOT %s' % response)
+
@ddt.ddt
class TestRBACBasic(TestACLBase):
@@ -110,8 +185,61 @@ class TestRBACBasic(TestACLBase):
class TestRBACModelBeforeScopes(TestACLBase):
def _create_test_data(self):
- fake_db_node = db_utils.create_test_node(chassis_id=None)
- self.format_data['node_ident'] = fake_db_node['uuid']
+ allocated_node_id = 31
+ fake_db_allocation = db_utils.create_test_allocation(
+ node_id=allocated_node_id,
+ resource_class="CUSTOM_TEST")
+ fake_db_node = db_utils.create_test_node(
+ chassis_id=None,
+ driver='fake-driverz')
+ fake_db_node_alloced = db_utils.create_test_node(
+ id=allocated_node_id,
+ chassis_id=None,
+ allocation_id=fake_db_allocation['id'],
+ uuid='22e26c0b-03f2-4d2e-ae87-c02d7f33c000',
+ driver='fake-driverz')
+ fake_vif_port_id = "ee21d58f-5de2-4956-85ff-33935ea1ca00"
+ fake_db_port = db_utils.create_test_port(
+ node_id=fake_db_node['id'],
+ internal_info={'tenant_vif_port_id': fake_vif_port_id})
+ fake_db_portgroup = db_utils.create_test_portgroup(
+ node_id=fake_db_node['id'])
+ fake_db_chassis = db_utils.create_test_chassis()
+ fake_db_deploy_template = db_utils.create_test_deploy_template()
+ fake_db_conductor = db_utils.create_test_conductor()
+ fake_db_volume_target = db_utils.create_test_volume_target(
+ node_id=fake_db_allocation['id'])
+ fake_db_volume_connector = db_utils.create_test_volume_connector(
+ node_id=fake_db_allocation['id'])
+ # Trait name aligns with create_test_node_trait.
+ fake_trait = 'trait'
+ fake_setting = 'FAKE_SETTING'
+ db_utils.create_test_bios_setting(
+ node_id=fake_db_node['id'],
+ name=fake_setting,
+ value=fake_setting)
+ db_utils.create_test_node_trait(
+ node_id=fake_db_node['id'])
+
+ self.format_data.update({
+ 'node_ident': fake_db_node['uuid'],
+ 'allocated_node_ident': fake_db_node_alloced['uuid'],
+ 'port_ident': fake_db_port['uuid'],
+ 'portgroup_ident': fake_db_portgroup['uuid'],
+ 'chassis_ident': fake_db_chassis['uuid'],
+ 'deploy_template_ident': fake_db_deploy_template['uuid'],
+ 'allocation_ident': fake_db_allocation['uuid'],
+ 'conductor_ident': fake_db_conductor['hostname'],
+ 'vif_ident': fake_vif_port_id,
+ # Can't use the same fake-driver as other tests can
+ # pollute a global method cache in the API that is in the
+ # test runner, resulting in false positives.
+ 'driver_name': 'fake-driverz',
+ 'bios_setting': fake_setting,
+ 'trait': fake_trait,
+ 'volume_target_ident': fake_db_volume_target['uuid'],
+ 'volume_connector_ident': fake_db_volume_connector['uuid'],
+ })
@ddt.file_data('test_rbac_legacy.yaml')
@ddt.unpack
diff --git a/ironic/tests/unit/api/test_acl_basic.yaml b/ironic/tests/unit/api/test_acl_basic.yaml
index 52be09d8e..78e860180 100644
--- a/ironic/tests/unit/api/test_acl_basic.yaml
+++ b/ironic/tests/unit/api/test_acl_basic.yaml
@@ -19,6 +19,7 @@ project_admin_can_get_node:
assert_dict_contains:
uuid: '{node_uuid}'
driver: 'fake-hardware'
+ assert_status: 200
project_member_cannot_get_node:
path: *node_path
diff --git a/ironic/tests/unit/api/test_rbac_legacy.yaml b/ironic/tests/unit/api/test_rbac_legacy.yaml
index 2e9b6b48a..cccb0b0db 100644
--- a/ironic/tests/unit/api/test_rbac_legacy.yaml
+++ b/ironic/tests/unit/api/test_rbac_legacy.yaml
@@ -1,643 +1,2015 @@
+# NOTE(TheJulia): This file is intended for legacy project RBAC testing
+# and is entirely project scoped in nature. This file will not be used
+# for system scoped testing, which will be kept to separate files to
+# enable the legacy tests to eventually be removed once support
+# for the legacy rules has been removed from Ironic.
+#
+# For more information on the how these tests work, see:
+# doc/source/contributor/rbac-testing.rst
+
+values:
+ skip_reason: "These are fake reference values for YAML templating"
+ # Project scoped admin token
+ admin_headers: &admin_headers
+ X-Auth-Token: 'baremetal-admin-token'
+ X-Project-ID: 66140b35c7524c6da836ca834e3fd3f9
+ X-Roles: baremetal_admin
+ X-Project-Name: baremetal
+ # Project scoped other member token.
+ member_headers: &member_headers
+ X-Auth-Token: 'baremetal-member-token'
+ X-Project-ID: 66140b35c7524c6da836ca834e3fd3f9
+ X-Roles: member
+ X-Project-Name: baremetal
+ # Project scoped Observer Token
+ observer_headers: &observer_headers
+ X-Auth-Token: 'baremetal-observer-token'
+ X-Project-ID: 66140b35c7524c6da836ca834e3fd3f9
+ X-Project-Name: baremetal
+ X-Roles: baremetal_observer
+ other_admin_headers: &other_admin_headers
+ X-Auth-Token: 'other-admin-token'
+ X-Project-ID: a1111111111111111111111111111111
+ X-Roles: admin,member,reader
+ X-Project-Name: 'other-project'
+ owner_project_id: &owner_project_id '{owner_project_id}'
+ other_project_id: &other_project_id '{other_project_id}'
+ node_ident: &node_ident '{node_ident}'
+
# Nodes - https://docs.openstack.org/api-ref/baremetal/?expanded=#nodes-nodes
-nodes_post_allow:
+nodes_post_admin:
+ path: '/v1/nodes'
+ method: post
+ headers: *admin_headers
+ body: &node_post_body
+ name: node
+ driver: fake-driverz
+ assert_status: 503
+
+nodes_post_member:
path: '/v1/nodes'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ body: *node_post_body
+ assert_status: 403
+
+nodes_post_observer:
+ path: '/v1/nodes'
+ method: post
+ headers: *observer_headers
+ body: *node_post_body
+ assert_status: 403
+
+nodes_get_node_admin:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *admin_headers
+ assert_dict_contains:
+ uuid: '{node_ident}'
+ driver: 'fake-driverz'
+ assert_status: 200
+
+nodes_get_node_member:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_get_node_observer:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *observer_headers
+ assert_dict_contains:
+ uuid: '{node_ident}'
+ driver: 'fake-driverz'
+ assert_status: 200
-nodes_get_allow:
+nodes_get_node_other_admin:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *other_admin_headers
+ # FIXME(TheJulia): So this is not great, but it is default for now
+ # And MUST be changed moving forward, just not in this patch.
+ # This just represents the *current* state, not what the world should be
+ # in the end.
+ assert_status: 200
+
+nodes_get_admin:
+ path: '/v1/nodes'
+ method: get
+ headers: *admin_headers
+ assert_list_length:
+ nodes: 2
+ assert_status: 200
+
+nodes_get_other_admin:
path: '/v1/nodes'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *other_admin_headers
+ assert_list_length:
+ nodes: 2
+ assert_status: 200
+
+nodes_detail_get_admin:
+ path: '/v1/nodes/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
-nodes_detail_get_allow:
+nodes_detail_get_member:
path: '/v1/nodes/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+nodes_detail_get_observer:
+ path: '/v1/nodes/detail'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_node_ident_get_admin:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_node_ident_get_member:
+ path: '/v1/nodes/{node_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_node_ident_get_allow:
+nodes_node_ident_get_observer:
path: '/v1/nodes/{node_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_node_ident_patch_admin:
+ path: '/v1/nodes/{node_ident}'
+ method: patch
+ headers: *admin_headers
+ body: &extra_patch
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+ assert_status: 503
+
+nodes_node_ident_patch_member:
+ path: '/v1/nodes/{node_ident}'
+ method: patch
+ headers: *member_headers
+ body: *extra_patch
+ assert_status: 403
-nodes_node_ident_patch_allow:
+nodes_node_ident_patch_observer:
path: '/v1/nodes/{node_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *extra_patch
+ assert_status: 403
+
+nodes_node_ident_delete_admin:
+ path: '/v1/nodes/{node_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_node_ident_delete_member:
+ path: '/v1/nodes/{node_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
-nodes_node_ident_delete_allow:
+nodes_node_ident_delete_observer:
path: '/v1/nodes/{node_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
# Node Management - https://docs.openstack.org/api-ref/baremetal/?expanded=#node-management-nodes
-nodes_validate_get_allow:
+nodes_validate_get_admin:
+ path: '/v1/nodes/{node_ident}/validate'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_validate_get_member:
+ path: '/v1/nodes/{node_ident}/validate'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_validate_get_observer:
path: '/v1/nodes/{node_ident}/validate'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_maintenance_put_admin:
+ path: '/v1/nodes/{node_ident}/maintenance'
+ method: put
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_maintenance_put_member:
+ path: '/v1/nodes/{node_ident}/maintenance'
+ method: put
+ headers: *member_headers
+ assert_status: 403
-nodes_maintenance_put_allow:
+nodes_maintenance_put_observer:
path: '/v1/nodes/{node_ident}/maintenance'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
-nodes_maintenance_delete_allow:
+nodes_maintenance_delete_admin:
path: '/v1/nodes/{node_ident}/maintenance'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_maintenance_delete_member:
+ path: '/v1/nodes/{node_ident}/maintenance'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
+
+nodes_maintenance_delete_observer:
+ path: '/v1/nodes/{node_ident}/maintenance'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_management_boot_device_put_admin:
+ path: '/v1/nodes/{node_ident}/management/boot_device'
+ method: put
+ headers: *admin_headers
+ body: &boot_device_body
+ boot_device: pxe
+ assert_status: 503
+
+nodes_management_boot_device_put_member:
+ path: '/v1/nodes/{node_ident}/management/boot_device'
+ method: put
+ headers: *member_headers
+ body: *boot_device_body
+ assert_status: 403
-nodes_management_boot_device_put_allow:
+nodes_management_boot_device_put_observer:
path: '/v1/nodes/{node_ident}/management/boot_device'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *boot_device_body
+ assert_status: 403
+
+nodes_management_boot_device_get_admin:
+ path: '/v1/nodes/{node_ident}/management/boot_device'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_management_boot_device_get_member:
+ path: '/v1/nodes/{node_ident}/management/boot_device'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_management_boot_device_get_allow:
+nodes_management_boot_device_get_observer:
path: '/v1/nodes/{node_ident}/management/boot_device'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 503
+
+nodes_management_boot_device_supported_get_admin:
+ path: '/v1/nodes/{node_ident}/management/boot_device/supported'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_management_boot_device_supported_get_member:
+ path: '/v1/nodes/{node_ident}/management/boot_device/supported'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_management_boot_device_supported_get_allow:
+nodes_management_boot_device_supported_get_observer:
path: '/v1/nodes/{node_ident}/management/boot_device/supported'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 503
-nodes_management_inject_nmi_put_allow:
+nodes_management_inject_nmi_put_admin:
path: '/v1/nodes/{node_ident}/management/inject_nmi'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ body: {}
+ assert_status: 503
-nodes_states_get_allow:
+nodes_management_inject_nmi_put_member:
+ path: '/v1/nodes/{node_ident}/management/inject_nmi'
+ method: put
+ headers: *member_headers
+ body: {}
+ assert_status: 403
+
+nodes_management_inject_nmi_put_observer:
+ path: '/v1/nodes/{node_ident}/management/inject_nmi'
+ method: put
+ headers: *observer_headers
+ body: {}
+ assert_status: 403
+
+
+nodes_states_get_admin:
+ path: '/v1/nodes/{node_ident}/states'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_states_get_member:
+ path: '/v1/nodes/{node_ident}/states'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_states_get_observer:
path: '/v1/nodes/{node_ident}/states'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_states_power_put_admin:
+ path: '/v1/nodes/{node_ident}/states/power'
+ method: put
+ headers: *admin_headers
+ body: &power_body
+ target: "power on"
+ assert_status: 503
-nodes_states_power_put_allow:
+nodes_states_power_put_member:
path: '/v1/nodes/{node_ident}/states/power'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ body: *power_body
+ assert_status: 403
-nodes_states_provision_put_allow:
+nodes_states_power_put_observer:
+ path: '/v1/nodes/{node_ident}/states/power'
+ method: put
+ headers: *observer_headers
+ body: *power_body
+ assert_status: 403
+
+nodes_states_provision_put_admin:
+ path: '/v1/nodes/{node_ident}/states/provision'
+ method: put
+ headers: *admin_headers
+ body: &provision_body
+ target: deploy
+ assert_status: 503
+
+nodes_states_provision_put_member:
+ path: '/v1/nodes/{node_ident}/states/provision'
+ method: put
+ headers: *member_headers
+ body: *provision_body
+ assert_status: 403
+
+nodes_states_provision_put_observer:
path: '/v1/nodes/{node_ident}/states/provision'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *provision_body
+ assert_status: 403
+
+nodes_states_raid_put_admin:
+ path: '/v1/nodes/{node_ident}/states/raid'
+ method: put
+ headers: *admin_headers
+ body: &raid_body
+ target_raid_config:
+ logical_disks:
+ - size_gb: 500
+ is_root_volume: true
+ raid_level: 1
+ assert_status: 503
+
+nodes_states_raid_put_member:
+ path: '/v1/nodes/{node_ident}/states/raid'
+ method: put
+ headers: *member_headers
+ body: *raid_body
+ assert_status: 403
-nodes_states_raid_put_allow:
+nodes_states_raid_put_observer:
path: '/v1/nodes/{node_ident}/states/raid'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *raid_body
+ assert_status: 403
+
+nodes_states_console_get_admin:
+ path: '/v1/nodes/{node_ident}/states/console'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_states_console_get_member:
+ path: '/v1/nodes/{node_ident}/states/console'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_states_console_get_allow:
+nodes_states_console_get_admin:
path: '/v1/nodes/{node_ident}/states/console'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_states_console_put_admin:
+ path: '/v1/nodes/{node_ident}/states/console'
+ method: put
+ headers: *admin_headers
+ body: &console_body_put
+ enabled: true
+ assert_status: 503
+
+nodes_states_console_put_member:
+ path: '/v1/nodes/{node_ident}/states/console'
+ method: put
+ headers: *member_headers
+ body: *console_body_put
+ assert_status: 403
-nodes_states_console_put_allow:
+nodes_states_console_put_observer:
path: '/v1/nodes/{node_ident}/states/console'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *console_body_put
+ assert_status: 403
# Node Traits - https://docs.openstack.org/api-ref/baremetal/?expanded=#node-vendor-passthru-nodes
-nodes_vendor_passthru_methods_get_allow:
+# Calls conductor upon the get as a task is required.
+nodes_vendor_passthru_methods_get_admin:
+ path: '/v1/nodes/{node_ident}/vendor_passthru/methods'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vendor_passthru_methods_get_member:
+ path: '/v1/nodes/{node_ident}/vendor_passthru/methods'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vendor_passthru_methods_get_observer:
path: '/v1/nodes/{node_ident}/vendor_passthru/methods'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
-nodes_vendor_passthru_get_allow:
- path: '/v1/nodes/{node_ident}/vendor_passthru'
+nodes_vendor_passthru_get_admin:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
-nodes_vendor_passthru_post_allow:
- path: '/v1/nodes/{node_ident}/vendor_passthru'
+nodes_vendor_passthru_get_member:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vendor_passthru_get_observer:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: get
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_vendor_passthru_post_admin:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: post
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vendor_passthru_post_member:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: post
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vendor_passthru_post_observer:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
-nodes_vendor_passthru_put_allow:
- path: '/v1/nodes/{node_ident}/vendor_passthru'
+nodes_vendor_passthru_put_admin:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vendor_passthru_put_member:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: put
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vendor_passthru_put_observer:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: put
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_vendor_passthru_delete_admin:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vendor_passthru_delete_member:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
-nodes_vendor_passthru_delete_allow:
- path: '/v1/nodes/{node_ident}/vendor_passthru'
+nodes_vendor_passthru_delete_observer:
+ path: '/v1/nodes/{node_ident}/vendor_passthru?method=test'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
# Node Traits - https://docs.openstack.org/api-ref/baremetal/#node-traits-nodes
-nodes_traits_get_allow:
+nodes_traits_get_admin:
path: '/v1/nodes/{node_ident}/traits'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 200
-nodes_traits_put_allow:
+nodes_traits_get_member:
+ path: '/v1/nodes/{node_ident}/traits'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_traits_get_observer:
+ path: '/v1/nodes/{node_ident}/traits'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_traits_put_admin:
+ path: '/v1/nodes/{node_ident}/traits'
+ method: put
+ headers: *admin_headers
+ assert_status: 503
+ body: &traits_body
+ traits:
+ - CUSTOM_TRAIT1
+ - HW_CPU_X86_VMX
+
+nodes_traits_put_member:
path: '/v1/nodes/{node_ident}/traits'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+ body: *traits_body
-nodes_traits_delete_allow:
+nodes_traits_put_observer:
path: '/v1/nodes/{node_ident}/traits'
+ method: put
+ headers: *observer_headers
+ assert_status: 403
+ body: *traits_body
+
+nodes_traits_delete_admin:
+ path: '/v1/nodes/{node_ident}/traits/{trait}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_traits_delete_member:
+ path: '/v1/nodes/{node_ident}/traits/{trait}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-nodes_traits_trait_put_allow:
+nodes_traits_delete_observer:
path: '/v1/nodes/{node_ident}/traits/{trait}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_traits_trait_put_admin:
+ path: '/v1/nodes/{node_ident}/traits/CUSTOM_TRAIT2'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
-nodes_traits_trait_delete_allow:
+nodes_traits_trait_put_member:
+ path: '/v1/nodes/{node_ident}/traits/CUSTOM_TRAIT2'
+ method: put
+ headers: *member_headers
+ assert_status: 403
+
+nodes_traits_trait_put_observer:
+ path: '/v1/nodes/{node_ident}/traits/CUSTOM_TRAIT2'
+ method: put
+ headers: *observer_headers
+ assert_status: 403
+
+nodes_traits_trait_delete_admin:
+ path: '/v1/nodes/{node_ident}/traits/{trait}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_traits_trait_delete_member:
+ path: '/v1/nodes/{node_ident}/traits/{trait}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
+
+nodes_traits_trait_delete_observer:
path: '/v1/nodes/{node_ident}/traits/{trait}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
# VIFS - https://docs.openstack.org/api-ref/baremetal/#vifs-virtual-interfaces-of-nodes
# TODO(TheJulia): VIFS will need fairly exhaustive testing given the use path.
# i.e. ensure user has rights to a vif and all.
-nodes_vifs_get_allow:
+# Apparently the get operation hits the conductor?!?
+# With mocked conductor 503 is returned.
+nodes_vifs_get_admin:
+ path: '/v1/nodes/{node_ident}/vifs'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vifs_get_member:
+ path: '/v1/nodes/{node_ident}/vifs'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vifs_get_observer:
path: '/v1/nodes/{node_ident}/vifs'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
-nodes_vifs_post_allow:
+nodes_vifs_post_admin:
path: '/v1/nodes/{node_ident}/vifs'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+ body: &vif_body
+ id: ee21d58f-5de2-4956-85ff-33935ea1ca00
-nodes_vifs_node_vif_ident_delete_allow:
- path: '/v1/nodes/{node_ident}/vifs/{node_vif_ident}'
+nodes_vifs_post_member:
+ path: '/v1/nodes/{node_ident}/vifs'
+ method: post
+ headers: *member_headers
+ assert_status: 403
+ body: *vif_body
+
+nodes_vifs_post_observer:
+ path: '/v1/nodes/{node_ident}/vifs'
+ method: post
+ headers: *observer_headers
+ assert_status: 403
+ body: *vif_body
+
+# This calls the conductor, hence not status 403.
+nodes_vifs_node_vif_ident_delete_admin:
+ path: '/v1/nodes/{node_ident}/vifs/{vif_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_vifs_node_vif_ident_delete_member:
+ path: '/v1/nodes/{node_ident}/vifs/{vif_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+nodes_vifs_node_vif_ident_delete_observer:
+ path: '/v1/nodes/{node_ident}/vifs/{vif_ident}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Indicators - https://docs.openstack.org/api-ref/baremetal/#indicators-management
-nodes_management_indicators_get_allow:
+nodes_management_indicators_get_admin:
+ path: '/v1/nodes/{node_ident}/management/indicators'
+ method: get
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_management_indicators_get_member:
+ path: '/v1/nodes/{node_ident}/management/indicators'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_management_indicators_get_observer:
path: '/v1/nodes/{node_ident}/management/indicators'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 503
nodes_management_indicators_component_get_allow:
path: '/v1/nodes/{node_ident}/management/indicators/{component}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ skip_reason: API appears to be broken and should be patched outside of this work.
nodes_management_indicators_component_ind_ident_get_allow:
path: '/v1/nodes/{node_ident}/management/indicators/{component}/{ind_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ skip_reason: API appears to be broken and should be patched outside of this work.
nodes_management_indicators_component_ind_ident_put_allow:
path: '/v1/nodes/{node_ident}/management/indicators/{component}/{ind_ident}'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ skip_reason: API appears to be broken and should be patched outside of this work.
# Portgroups - https://docs.openstack.org/api-ref/baremetal/#portgroups-portgroups
-portgroups_get_allow:
+portgroups_get_admin:
path: '/v1/portgroups'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 200
-portgroups_post_allow:
+portgroups_get_member:
+ path: '/v1/portgroups'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+portgroups_get_observer:
+ path: '/v1/portgroups'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+# Returns 400 as the node uuid cannot be found, but
+# it is past the access controls.
+portgroups_post_admin:
+ path: '/v1/portgroups'
+ method: post
+ headers: *admin_headers
+ body: &portgroup_body
+ node_uuid: 68a552fb-dcd2-43bf-9302-e4c93287be16
+ assert_status: 400
+
+portgroups_post_member:
+ path: '/v1/portgroups'
+ method: post
+ headers: *member_headers
+ body: *portgroup_body
+ assert_status: 403
+
+portgroups_post_observer:
path: '/v1/portgroups'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *portgroup_body
+ assert_status: 403
+
+portgroups_detail_get_admin:
+ path: '/v1/portgroups/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+portgroups_detail_get_member:
+ path: '/v1/portgroups/detail'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-portgroups_detail_get_allow:
+portgroups_detail_get_observer:
path: '/v1/portgroups/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+portgroups_portgroup_ident_get_admin:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+portgroups_portgroup_ident_get_member:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-portgroups_portgroup_ident_get_allow:
+portgroups_portgroup_ident_get_observer:
path: '/v1/portgroups/{portgroup_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
-portgroups_portgroup_ident_patch_allow:
+portgroups_portgroup_ident_patch_admin:
path: '/v1/portgroups/{portgroup_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ body: &portgroup_patch_body
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+ assert_status: 503
+
+portgroups_portgroup_ident_patch_member:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: patch
+ headers: *member_headers
+ body: *portgroup_patch_body
+ assert_status: 403
+
+portgroups_portgroup_ident_patch_observer:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: patch
+ headers: *observer_headers
+ body: *portgroup_patch_body
+ assert_status: 403
+
+portgroups_portgroup_ident_delete_admin:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
-portgroups_portgroup_ident_delete_allow:
+portgroups_portgroup_ident_delete_member:
path: '/v1/portgroups/{portgroup_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+portgroups_portgroup_ident_delete_observer:
+ path: '/v1/portgroups/{portgroup_ident}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Portgroups by node - https://docs.openstack.org/api-ref/baremetal/#listing-portgroups-by-node-nodes-portgroups
-nodes_portgroups_get_allow:
+nodes_portgroups_get_admin:
+ path: '/v1/nodes/{node_ident}/portgroups'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_portgroups_get_member:
+ path: '/v1/nodes/{node_ident}/portgroups'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_portgroups_get_observer:
path: '/v1/nodes/{node_ident}/portgroups'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_portgroups_detail_get_admin:
+ path: '/v1/nodes/{node_ident}/portgroups/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
-nodes_portgroups_detail_get_allow:
+nodes_portgroups_detail_get_member:
path: '/v1/nodes/{node_ident}/portgroups/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+nodes_portgroups_detail_get_observer:
+ path: '/v1/nodes/{node_ident}/portgroups/detail'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
# Ports - https://docs.openstack.org/api-ref/baremetal/#ports-ports
-ports_get_allow:
+ports_get_admin:
+ path: '/v1/ports'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+ports_get_member:
+ path: '/v1/ports'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+ports_get_observer:
path: '/v1/ports'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+# NOTE(TheJulia): Returns 400 when the conductor calls are
+# mocked indicating node lookup failed, which means the access
+# check was successful.
+ports_post_admin:
+ path: '/v1/ports'
+ method: post
+ headers: *admin_headers
+ assert_status: 400
+ body: &port_body
+ node_uuid: 68a552fb-dcd2-43bf-9302-e4c93287be16
+ address: 00:01:02:03:04:05
-ports_post_allow:
+ports_post_member:
path: '/v1/ports'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+ body: *port_body
-ports_detail_get_allow:
+ports_post_observer:
+ path: '/v1/ports'
+ method: post
+ headers: *observer_headers
+ assert_status: 403
+ body: *port_body
+
+ports_detail_get_admin:
+ path: '/v1/ports/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+ports_detail_get_member:
path: '/v1/ports/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-ports_port_id_get_allow:
- path: '/v1/ports/{port_id}'
+ports_detail_get_observer:
+ path: '/v1/ports/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
-ports_port_id_patch_allow:
- path: '/v1/ports/{port_id}'
+ports_port_id_get_admin:
+ path: '/v1/ports/{port_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+ports_port_id_get_member:
+ path: '/v1/ports/{port_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+ports_port_id_get_observer:
+ path: '/v1/ports/{port_ident}'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+ports_port_id_patch_admin:
+ path: '/v1/ports/{port_ident}'
+ method: patch
+ headers: *admin_headers
+ assert_status: 503
+ body: &port_patch_body
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+
+ports_port_id_patch_member:
+ path: '/v1/ports/{port_ident}'
+ method: patch
+ headers: *member_headers
+ assert_status: 403
+ body: *port_patch_body
+
+ports_port_id_patch_observer:
+ path: '/v1/ports/{port_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+ body: *port_patch_body
-ports_port_id_delete_allow:
- path: '/v1/ports/{port_id}'
+ports_port_id_delete_admin:
+ path: '/v1/ports/{port_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+
+ports_port_id_delete_member:
+ path: '/v1/ports/{port_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
+
+ports_port_id_delete_observer:
+ path: '/v1/ports/{port_ident}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Ports by node - https://docs.openstack.org/api-ref/baremetal/#listing-ports-by-node-nodes-ports
-nodes_ports_get_allow:
+nodes_ports_get_admin:
+ path: '/v1/nodes/{node_ident}/ports'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_ports_get_member:
+ path: '/v1/nodes/{node_ident}/ports'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_ports_get_observer:
path: '/v1/nodes/{node_ident}/ports'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_ports_detail_get_admin:
+ path: '/v1/nodes/{node_ident}/ports/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_ports_detail_get_member:
+ path: '/v1/nodes/{node_ident}/ports/detail'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_ports_detail_get_allow:
+nodes_ports_detail_get_observer:
path: '/v1/nodes/{node_ident}/ports/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
# Ports by portgroup - https://docs.openstack.org/api-ref/baremetal/#listing-ports-by-portgroup-portgroup-ports
-portgroups_ports_get_allow:
+portgroups_ports_get_admin:
path: '/v1/portgroups/{portgroup_ident}/ports'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 200
+
+portgroups_ports_get_member:
+ path: '/v1/portgroups/{portgroup_ident}/ports'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+portgroups_ports_get_observer:
+ path: '/v1/portgroups/{portgroup_ident}/ports'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+portgroups_ports_detail_get_admin:
+ path: '/v1/portgroups/{portgroup_ident}/ports/detail'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+portgroups_ports_detail_get_member:
+ path: '/v1/portgroups/{portgroup_ident}/ports/detail'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-portgroups_ports_detail_get_allow:
+portgroups_ports_detail_get_observer:
path: '/v1/portgroups/{portgroup_ident}/ports/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
# Volume(s) - https://docs.openstack.org/api-ref/baremetal/#volume-volume
# TODO(TheJulia): volumes will likely need some level of exhaustive testing.
# i.e. ensure that the volume is permissible. However this may not be possible
# here.
-volume_get_allow:
+volume_get_admin:
+ path: '/v1/volume'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+volume_get_member:
path: '/v1/volume'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+volume_get_observer:
+ path: '/v1/volume'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
# Volume connectors
-volume_connectors_get_allow:
+volume_connectors_get_admin:
+ path: '/v1/volume/connectors'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+volume_connectors_get_member:
+ path: '/v1/volume/connectors'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+volume_connectors_get_observer:
path: '/v1/volume/connectors'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+# NOTE(TheJulia): This ends up returning a 400 due to the
+# UUID not already being in ironic.
+volume_connectors_post_admin:
+ path: '/v1/volume/connectors'
+ method: post
+ headers: *admin_headers
+ assert_status: 400
+ body: &volume_connector_body
+ node_uuid: 68a552fb-dcd2-43bf-9302-e4c93287be16
+ type: ip
+ connector_id: 192.168.1.100
+
+volume_connectors_post_member:
+ path: '/v1/volume/connectors'
+ method: post
+ headers: *member_headers
+ assert_status: 403
+ body: *volume_connector_body
-volume_connectors_post_allow:
+volume_connectors_post_observer:
path: '/v1/volume/connectors'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+ body: *volume_connector_body
+
+volume_volume_connector_id_get_admin:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
-volume_volume_connector_id_get_allow:
- path: '/v1/volume/connectors/{volume_connector_id}'
+volume_volume_connector_id_get_member:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-volume_volume_connector_id_patch_allow:
- path: '/v1/volume/connectors/{volume_connector_id}'
+volume_volume_connector_id_get_observer:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+volume_volume_connector_id_patch_admin:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: patch
+ headers: *admin_headers
+ body: &connector_patch_body
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+ assert_status: 503
+
+volume_volume_connector_id_patch_member:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: patch
+ headers: *member_headers
+ body: *connector_patch_body
+ assert_status: 403
+
+volume_volume_connector_id_patch_observer:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *connector_patch_body
+ assert_status: 403
+
+volume_volume_connector_id_delete_admin:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+volume_volume_connector_id_delete_member:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
-volume_volume_connector_id_delete_allow:
- path: '/v1/volume/connectors/{volume_connector_id}'
+volume_volume_connector_id_delete_observer:
+ path: '/v1/volume/connectors/{volume_connector_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
# Volume targets
-volume_targets_get_allow:
+volume_targets_get_admin:
+ path: '/v1/volume/targets'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+volume_targets_get_member:
path: '/v1/volume/targets'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+volume_targets_get_observer:
+ path: '/v1/volume/targets'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+# NOTE(TheJulia): Because we can't seem to get the uuid
+# to load from an existing uuid, since we're not subsituting
+# it, this will return with 400 due to the ID not matching.
+volume_targets_post_admin:
+ path: '/v1/volume/targets'
+ method: post
+ headers: *admin_headers
+ assert_status: 400
+ body: &volume_target_body
+ node_uuid: 68a552fb-dcd2-43bf-9302-e4c93287be16
+ volume_type: iscsi
+ boot_index: 0
+ volume_id: 'test-id'
+
+volume_targets_post_member:
+ path: '/v1/volume/targets'
+ method: post
+ headers: *member_headers
+ assert_status: 403
+ body: *volume_target_body
-volume_targets_post_allow:
+volume_targets_post_observer:
path: '/v1/volume/targets'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+ body: *volume_target_body
+
+volume_volume_target_id_get_admin:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+volume_volume_target_id_get_member:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-volume_volume_target_id_get_allow:
- path: '/v1/volume/targets/{volume_target_id}'
+volume_volume_target_id_get_observer:
+ path: '/v1/volume/targets/{volume_target_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
-volume_volume_target_id_patch_allow:
- path: '/v1/volume/targets/{volume_target_id}'
+volume_volume_target_id_patch_admin:
+ path: '/v1/volume/targets/{volume_target_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ body: &volume_target_patch
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+ headers: *admin_headers
+ assert_status: 503
+
+volume_volume_target_id_patch_admin:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: patch
+ body: *volume_target_patch
+ headers: *member_headers
+ assert_status: 403
+
+volume_volume_target_id_patch_observer:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: patch
+ body: *volume_target_patch
+ headers: *observer_headers
+ assert_status: 403
+
+volume_volume_target_id_delete_admin:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 503
+
+volume_volume_target_id_delete_member:
+ path: '/v1/volume/targets/{volume_target_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
-volume_volume_target_id_delete_allow:
- path: '/v1/volume/targets/{volume_target_id}'
+volume_volume_target_id_delete_observer:
+ path: '/v1/volume/targets/{volume_target_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
# Get Volumes by Node - https://docs.openstack.org/api-ref/baremetal/#listing-volume-resources-by-node-nodes-volume
-nodes_volume_get_allow:
+nodes_volume_get_admin:
+ path: '/v1/nodes/{node_ident}/volume'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_volume_get_member:
+ path: '/v1/nodes/{node_ident}/volume'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_volume_get_observer:
path: '/v1/nodes/{node_ident}/volume'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_volume_connectors_get_admin:
+ path: '/v1/nodes/{node_ident}/volume/connectors'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
-nodes_volume_connectors_get_allow:
+nodes_volume_connectors_get_member:
path: '/v1/nodes/{node_ident}/volume/connectors'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-nodes_volume_targets_get_allow:
+nodes_volume_connectors_get_observer:
+ path: '/v1/nodes/{node_ident}/volume/connectors'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_volume_targets_get_admin:
+ path: '/v1/nodes/{node_ident}/volume/targets'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_volume_targets_get_member:
+ path: '/v1/nodes/{node_ident}/volume/targets'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_volume_targets_get_observer:
path: '/v1/nodes/{node_ident}/volume/targets'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
# Drivers - https://docs.openstack.org/api-ref/baremetal/#drivers-drivers
-drivers_get_allow:
+drivers_get_admin:
+ path: '/v1/drivers'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+drivers_get_member:
path: '/v1/drivers'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+drivers_get_observer:
+ path: '/v1/drivers'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+# TODO(TheJulia): This is presently returning a 404,
+# except it should not be. :\
+drivers_driver_name_get_admin:
+ path: '/v1/drivers/{driver_name}'
+ method: get
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_driver_name_get_member:
+ path: '/v1/drivers/{driver_name}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-drivers_driver_name_get_allow:
+# TODO(TheJulia): This is presently returning a 404,
+# except it should not be. :\
+drivers_driver_name_get_observer:
path: '/v1/drivers/{driver_name}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 404
+
+drivers_properties_get_admin:
+ path: '/v1/drivers/{driver_name}/properties'
+ method: get
+ headers: *admin_headers
+ assert_status: 404
-drivers_properties_get_allow:
+drivers_properties_get_member:
path: '/v1/drivers/{driver_name}/properties'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-drivers_raid_logical_disk_properties_get_allow:
+drivers_properties_get_observer:
+ path: '/v1/drivers/{driver_name}/properties'
+ method: get
+ headers: *observer_headers
+ assert_status: 404
+
+drivers_raid_logical_disk_properties_get_admin:
+ path: '/v1/drivers/{driver_name}/raid/logical_disk_properties'
+ method: get
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_raid_logical_disk_properties_get_member:
path: '/v1/drivers/{driver_name}/raid/logical_disk_properties'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+drivers_raid_logical_disk_properties_get_observer:
+ path: '/v1/drivers/{driver_name}/raid/logical_disk_properties'
+ method: get
+ headers: *observer_headers
+ assert_status: 404
# Driver vendor passthru - https://docs.openstack.org/api-ref/baremetal/#driver-vendor-passthru-drivers
-drivers_vendor_passthru_methods_get_allow:
+drivers_vendor_passthru_methods_get_admin:
+ path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
+ method: get
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_vendor_passthru_methods_get_member:
path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+drivers_vendor_passthru_methods_get_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru/methods'
+ method: get
+ headers: *observer_headers
+ assert_status: 403
+
+drivers_vendor_passthru_get_admin:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: get
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_vendor_passthru_get_member:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-drivers_vendor_passthru_get_allow:
- path: '/v1/drivers/{driver_name}/vendor_passthru'
+drivers_vendor_passthru_get_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+
+drivers_vendor_passthru_post_admin:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: post
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_vendor_passthru_post_member:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: post
+ headers: *member_headers
+ assert_status: 403
-drivers_vendor_passthru_post_allow:
- path: '/v1/drivers/{driver_name}/vendor_passthru'
+drivers_vendor_passthru_post_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+
+drivers_vendor_passthru_put_admin:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: put
+ headers: *admin_headers
+ assert_status: 404
+
+drivers_vendor_passthru_put_member:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: put
+ headers: *member_headers
+ assert_status: 403
-drivers_vendor_passthru_put_allow:
- path: '/v1/drivers/{driver_name}/vendor_passthru'
+drivers_vendor_passthru_put_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
method: put
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403
+
+# NOTE(TheJulia): Returns an error due to the driver name
+# not matching, but this should be pass policy checking.
+# "No conductors registered."
+drivers_vendor_passthru_delete_admin:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: delete
+ headers: *admin_headers
+ assert_status: 404
-drivers_vendor_passthru_delete_allow:
- path: '/v1/drivers/{driver_name}/vendor_passthru'
+drivers_vendor_passthru_delete_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+drivers_vendor_passthru_delete_observer:
+ path: '/v1/drivers/{driver_name}/vendor_passthru?method=test'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Node Bios - https://docs.openstack.org/api-ref/baremetal/#node-bios-nodes
-nodes_bios_get_allow:
+nodes_bios_get_admin:
+ path: '/v1/nodes/{node_ident}/bios'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_bios_get_member:
+ path: '/v1/nodes/{node_ident}/bios'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_bios_get_observer:
path: '/v1/nodes/{node_ident}/bios'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+nodes_bios_bios_setting_get_admin:
+ path: '/v1/nodes/{node_ident}/bios/{bios_setting}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_bios_bios_setting_get_member:
+ path: '/v1/nodes/{node_ident}/bios/{bios_setting}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-nodes_bios_bios_setting_get_allow:
+nodes_bios_bios_setting_get_observer:
path: '/v1/nodes/{node_ident}/bios/{bios_setting}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
# Conductors - https://docs.openstack.org/api-ref/baremetal/#allocations-allocations
-conductors_get_allow:
+conductors_get_admin:
+ path: '/v1/conductors'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+conductors_get_member:
+ path: '/v1/conductors'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+conductors_get_observer:
path: '/v1/conductors'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
-conductors_hostname_get_allow:
- path: '/v1/conductors/{hostname}'
+
+conductors_hostname_get_admin:
+ path: '/v1/conductors/{conductor_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+conductors_hostname_get_member:
+ path: '/v1/conductors/{conductor_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+conductors_hostname_get_observer:
+ path: '/v1/conductors/{conductor_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
# Allocations - https://docs.openstack.org/api-ref/baremetal/#allocations-allocations
-allocations_post_allow:
+allocations_post_admin:
+ path: '/v1/allocations'
+ method: post
+ headers: *admin_headers
+ body: &allocation_body
+ resource_class: CUSTOM_TEST
+ assert_status: 503
+
+allocations_post_member:
path: '/v1/allocations'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ body: *allocation_body
+ assert_status: 403
-allocations_get_allow:
+allocations_post_observer:
path: '/v1/allocations'
+ method: post
+ headers: *observer_headers
+ body: *allocation_body
+ assert_status: 403
+
+allocations_get_admin:
+ path: '/v1/allocations'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+allocations_get_member:
+ path: '/v1/allocations'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+allocations_get_observer:
+ path: '/v1/allocations'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+allocations_allocation_id_get_admin:
+ path: '/v1/allocations/{allocation_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+allocations_allocation_id_get_member:
+ path: '/v1/allocations/{allocation_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-allocations_allocation_id_get_allow:
- path: '/v1/allocations/{allocation_id}'
+allocations_allocation_id_get_observer:
+ path: '/v1/allocations/{allocation_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+allocations_allocation_id_patch_admin:
+ path: '/v1/allocations/{allocation_ident}'
+ method: patch
+ headers: *admin_headers
+ body: &allocation_patch
+ - op: replace
+ path: /extra
+ value: {'test': 'testing'}
+ assert_status: 200
+
+allocations_allocation_id_patch_member:
+ path: '/v1/allocations/{allocation_ident}'
+ method: patch
+ headers: *member_headers
+ body: *allocation_patch
+ assert_status: 403
-allocations_allocation_id_patch_allow:
- path: '/v1/allocations/{allocation_id}'
+allocations_allocation_id_patch_observer:
+ path: '/v1/allocations/{allocation_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *allocation_patch
+ assert_status: 403
-allocations_allocation_id_delete_allow:
- path: '/v1/allocations/{allocation_id}'
+allocations_allocation_id_delete_admin:
+ path: '/v1/allocations/{allocation_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+
+allocations_allocation_id_delete_member:
+ path: '/v1/allocations/{allocation_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
+
+allocations_allocation_id_delete_observer:
+ path: '/v1/allocations/{allocation_ident}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Allocations ( Node level) - https://docs.openstack.org/api-ref/baremetal/#node-allocation-allocations-nodes
-nodes_allocation_get_allow:
- path: '/v1/nodes/{node_ident}/allocation'
+nodes_allocation_get_admin:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+nodes_allocation_get_member:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+nodes_allocation_get_observer:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
-nodes_allocation_delete_allow:
- path: '/v1/nodes/{node_ident}/allocation'
+nodes_allocation_delete_admin:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 503
+
+nodes_allocation_delete_member:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
+
+nodes_allocation_delete_observer:
+ path: '/v1/nodes/{allocated_node_ident}/allocation'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Deploy Templates - https://docs.openstack.org/api-ref/baremetal/#deploy-templates-deploy-templates
-deploy_templates_post_allow:
+deploy_templates_post_admin:
+ path: '/v1/deploy_templates'
+ method: post
+ body: &deploy_template_body
+ name: 'CUSTOM_TEST_TEMPLATE'
+ steps:
+ - interface: 'deploy'
+ step: 'noop'
+ args: {}
+ priority: 0
+ headers: *admin_headers
+ assert_status: 201
+
+deploy_templates_post_member:
+ path: '/v1/deploy_templates'
+ method: post
+ body: *deploy_template_body
+ headers: *member_headers
+ assert_status: 403
+
+deploy_templates_post_observer:
path: '/v1/deploy_templates'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ body: *deploy_template_body
+ headers: *observer_headers
+ assert_status: 403
+
+deploy_templates_get_admin:
+ path: '/v1/deploy_templates'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
-deploy_templates_get_allow:
+deploy_templates_get_member:
path: '/v1/deploy_templates'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+deploy_templates_get_observer:
+ path: '/v1/deploy_templates'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+deploy_templates_deploy_template_id_get_admin:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+deploy_templates_deploy_template_id_get_member:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
-deploy_templates_deploy_template_id_get_allow:
- path: '/v1/deploy_templates/{deploy_template_id}'
+deploy_templates_deploy_template_id_get_observer:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 200
+
+deploy_templates_deploy_template_id_patch_admin:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: patch
+ body: &template_patch
+ - op: replace
+ path: /name
+ value: 'CUSTOM_MAGIC'
+ headers: *admin_headers
+ assert_status: 200
+
+deploy_templates_deploy_template_id_patch_member:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: patch
+ body: *template_patch
+ headers: *member_headers
+ assert_status: 403
-deploy_templates_deploy_template_id_patch_allow:
- path: '/v1/deploy_templates/{deploy_template_id}'
+deploy_templates_deploy_template_id_patch_observer:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ body: *template_patch
+ headers: *observer_headers
+ assert_status: 403
+
+deploy_templates_deploy_template_id_delete_admin:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 204
-deploy_templates_deploy_template_id_delete_allow:
- path: '/v1/deploy_templates/{deploy_template_id}'
+deploy_templates_deploy_template_id_delete_member:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
+
+deploy_templates_deploy_template_id_delete_observer:
+ path: '/v1/deploy_templates/{deploy_template_ident}'
+ method: delete
+ headers: *observer_headers
+ assert_status: 403
# Chassis endpoints - https://docs.openstack.org/api-ref/baremetal/#chassis-chassis
-chassis_post_allow:
+chassis_post_admin:
+ path: '/v1/chassis'
+ method: post
+ headers: *admin_headers
+ body: &chassis_body
+ description: 'test-chassis'
+ assert_status: 201
+
+chassis_post_member:
+ path: '/v1/chassis'
+ method: post
+ headers: *member_headers
+ body: *chassis_body
+ assert_status: 403
+
+chassis_post_observer:
path: '/v1/chassis'
method: post
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ body: *chassis_body
+ assert_status: 403
-chassis_get_allow:
+chassis_get_admin:
path: '/v1/chassis'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 200
-chassis_detail_get_allow:
+chassis_get_member:
+ path: '/v1/chassis'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+chassis_get_observer:
+ path: '/v1/chassis'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+chassis_detail_get_admin:
path: '/v1/chassis/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *admin_headers
+ assert_status: 200
-chassis_chassis_id_get_allow:
- path: '/v1/chassis/{chassis_id}'
+chassis_detail_get_member:
+ path: '/v1/chassis/detail'
method: get
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *member_headers
+ assert_status: 403
-chassis_chassis_id_patch_allow:
- path: '/v1/chassis/{chassis_id}'
+chassis_detail_get_observer:
+ path: '/v1/chassis/detail'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+chassis_chassis_id_get_admin:
+ path: '/v1/chassis/{chassis_ident}'
+ method: get
+ headers: *admin_headers
+ assert_status: 200
+
+chassis_chassis_id_get_member:
+ path: '/v1/chassis/{chassis_ident}'
+ method: get
+ headers: *member_headers
+ assert_status: 403
+
+chassis_chassis_id_get_observer:
+ path: '/v1/chassis/{chassis_ident}'
+ method: get
+ headers: *observer_headers
+ assert_status: 200
+
+chassis_chassis_id_patch_admin:
+ path: '/v1/chassis/{chassis_ident}'
method: patch
- skip: true
- skip_reason: 'Not implemented yet'
+ body: &chassis_patch
+ - op: replace
+ path: /description
+ value: meow
+ headers: *admin_headers
+ assert_status: 200
+
+chassis_chassis_id_patch_member:
+ path: '/v1/chassis/{chassis_ident}'
+ method: patch
+ body: *chassis_patch
+ headers: *member_headers
+ assert_status: 403
+
+chassis_chassis_id_patch_observer:
+ path: '/v1/chassis/{chassis_ident}'
+ method: patch
+ body: *chassis_patch
+ headers: *observer_headers
+ assert_status: 403
+
+chassis_chassis_id_delete_admin:
+ path: '/v1/chassis/{chassis_ident}'
+ method: delete
+ headers: *admin_headers
+ assert_status: 204
+
+chassis_chassis_id_delete_member:
+ path: '/v1/chassis/{chassis_ident}'
+ method: delete
+ headers: *member_headers
+ assert_status: 403
-chassis_chassis_id_delete_allow:
- path: '/v1/chassis/{chassis_id}'
+chassis_chassis_id_delete_observer:
+ path: '/v1/chassis/{chassis_ident}'
method: delete
- skip: true
- skip_reason: 'Not implemented yet'
+ headers: *observer_headers
+ assert_status: 403