baremetal: support for allocation API
Change-Id: Ie47a903430d6b54740152676d897b5f8759e36c2 Story: #2004341 Task: #28029
This commit is contained in:
parent
b7b7353e55
commit
e8ccfee5fa
@ -76,6 +76,16 @@ VIF Operations
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.detach_vif_from_node
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.list_node_vifs
|
||||
|
||||
Allocation Operations
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
.. autoclass:: openstack.baremetal.v1._proxy.Proxy
|
||||
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.create_allocation
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.delete_allocation
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.get_allocation
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.allocations
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.wait_for_allocation
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
|
@ -9,3 +9,4 @@ Baremetal Resources
|
||||
v1/node
|
||||
v1/port
|
||||
v1/port_group
|
||||
v1/allocation
|
||||
|
12
doc/source/user/resources/baremetal/v1/allocation.rst
Normal file
12
doc/source/user/resources/baremetal/v1/allocation.rst
Normal file
@ -0,0 +1,12 @@
|
||||
openstack.baremetal.v1.Allocation
|
||||
=================================
|
||||
|
||||
.. automodule:: openstack.baremetal.v1.allocation
|
||||
|
||||
The Allocation Class
|
||||
--------------------
|
||||
|
||||
The ``Allocation`` class inherits from :class:`~openstack.resource.Resource`.
|
||||
|
||||
.. autoclass:: openstack.baremetal.v1.allocation.Allocation
|
||||
:members:
|
@ -12,6 +12,7 @@
|
||||
|
||||
from openstack import _log
|
||||
from openstack.baremetal.v1 import _common
|
||||
from openstack.baremetal.v1 import allocation as _allocation
|
||||
from openstack.baremetal.v1 import chassis as _chassis
|
||||
from openstack.baremetal.v1 import driver as _driver
|
||||
from openstack.baremetal.v1 import node as _node
|
||||
@ -703,3 +704,94 @@ class Proxy(proxy.Proxy):
|
||||
"""
|
||||
res = self._get_resource(_node.Node, node)
|
||||
return res.list_vifs(self)
|
||||
|
||||
def allocations(self, **query):
|
||||
"""Retrieve a generator of allocations.
|
||||
|
||||
:param dict query: Optional query parameters to be sent to restrict
|
||||
the allocation to be returned. Available parameters include:
|
||||
|
||||
* ``fields``: A list containing one or more fields to be returned
|
||||
in the response. This may lead to some performance gain
|
||||
because other fields of the resource are not refreshed.
|
||||
* ``limit``: Requests at most the specified number of items be
|
||||
returned from the query.
|
||||
* ``marker``: Specifies the ID of the last-seen allocation. Use the
|
||||
``limit`` parameter to make an initial limited request and
|
||||
use the ID of the last-seen allocation from the response as
|
||||
the ``marker`` value in a subsequent limited request.
|
||||
* ``sort_dir``: Sorts the response by the requested sort direction.
|
||||
A valid value is ``asc`` (ascending) or ``desc``
|
||||
(descending). Default is ``asc``. You can specify multiple
|
||||
pairs of sort key and sort direction query parameters. If
|
||||
you omit the sort direction in a pair, the API uses the
|
||||
natural sorting direction of the server attribute that is
|
||||
provided as the ``sort_key``.
|
||||
* ``sort_key``: Sorts the response by the this attribute value.
|
||||
Default is ``id``. You can specify multiple pairs of sort
|
||||
key and sort direction query parameters. If you omit the
|
||||
sort direction in a pair, the API uses the natural sorting
|
||||
direction of the server attribute that is provided as the
|
||||
``sort_key``.
|
||||
|
||||
:returns: A generator of allocation instances.
|
||||
"""
|
||||
return _allocation.Allocation.list(self, **query)
|
||||
|
||||
def create_allocation(self, **attrs):
|
||||
"""Create a new allocation from attributes.
|
||||
|
||||
:param dict attrs: Keyword arguments that will be used to create a
|
||||
:class:`~openstack.baremetal.v1.allocation.Allocation`.
|
||||
|
||||
:returns: The results of allocation creation.
|
||||
:rtype: :class:`~openstack.baremetal.v1.allocation.Allocation`.
|
||||
"""
|
||||
return self._create(_allocation.Allocation, **attrs)
|
||||
|
||||
def get_allocation(self, allocation):
|
||||
"""Get a specific allocation.
|
||||
|
||||
:param allocation: The value can be the name or ID of an allocation or
|
||||
a :class:`~openstack.baremetal.v1.allocation.Allocation` instance.
|
||||
|
||||
:returns: One :class:`~openstack.baremetal.v1.allocation.Allocation`
|
||||
:raises: :class:`~openstack.exceptions.ResourceNotFound` when no
|
||||
allocation matching the name or ID could be found.
|
||||
"""
|
||||
return self._get(_allocation.Allocation, allocation)
|
||||
|
||||
def delete_allocation(self, allocation, ignore_missing=True):
|
||||
"""Delete an allocation.
|
||||
|
||||
:param allocation: The value can be the name or ID of an allocation or
|
||||
a :class:`~openstack.baremetal.v1.allocation.Allocation` instance.
|
||||
:param bool ignore_missing: When set to ``False``, an exception
|
||||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the allocation could not be found. When set to ``True``, no
|
||||
exception will be raised when attempting to delete a non-existent
|
||||
allocation.
|
||||
|
||||
:returns: The instance of the allocation which was deleted.
|
||||
:rtype: :class:`~openstack.baremetal.v1.allocation.Allocation`.
|
||||
"""
|
||||
return self._delete(_allocation.Allocation, allocation,
|
||||
ignore_missing=ignore_missing)
|
||||
|
||||
def wait_for_allocation(self, allocation, timeout=None,
|
||||
ignore_error=False):
|
||||
"""Wait for the allocation to become active.
|
||||
|
||||
:param allocation: The value can be the name or ID of an allocation or
|
||||
a :class:`~openstack.baremetal.v1.allocation.Allocation` instance.
|
||||
:param timeout: How much (in seconds) to wait for the allocation.
|
||||
The value of ``None`` (the default) means no client-side timeout.
|
||||
:param ignore_error: If ``True``, this call will raise an exception
|
||||
if the allocation reaches the ``error`` state. Otherwise the error
|
||||
state is considered successful and the call returns.
|
||||
|
||||
:returns: The instance of the allocation.
|
||||
:rtype: :class:`~openstack.baremetal.v1.allocation.Allocation`.
|
||||
"""
|
||||
res = self._get_resource(_allocation.Allocation, allocation)
|
||||
return res.wait(self, timeout=timeout, ignore_error=ignore_error)
|
||||
|
98
openstack/baremetal/v1/allocation.py
Normal file
98
openstack/baremetal/v1/allocation.py
Normal file
@ -0,0 +1,98 @@
|
||||
# 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 import _log
|
||||
from openstack.baremetal.v1 import _common
|
||||
from openstack import exceptions
|
||||
from openstack import resource
|
||||
from openstack import utils
|
||||
|
||||
|
||||
_logger = _log.setup_logging('openstack')
|
||||
|
||||
|
||||
class Allocation(_common.ListMixin, resource.Resource):
|
||||
|
||||
resources_key = 'allocations'
|
||||
base_path = '/allocations'
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_fetch = True
|
||||
allow_commit = False
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
_query_mapping = resource.QueryParameters(
|
||||
'node', 'resource_class', 'state',
|
||||
fields={'name': 'fields', 'type': _common.comma_separated_list},
|
||||
)
|
||||
|
||||
# The allocation API introduced in 1.52.
|
||||
_max_microversion = '1.52'
|
||||
|
||||
#: The candidate nodes for this allocation.
|
||||
candidate_nodes = resource.Body('candidate_nodes', type=list)
|
||||
#: Timestamp at which the allocation was created.
|
||||
created_at = resource.Body('created_at')
|
||||
#: A set of one or more arbitrary metadata key and value pairs.
|
||||
extra = resource.Body('extra', type=dict)
|
||||
#: The UUID for the allocation.
|
||||
id = resource.Body('uuid', alternate_id=True)
|
||||
#: The last error for the allocation.
|
||||
last_error = resource.Body("last_error")
|
||||
#: A list of relative links, including the self and bookmark links.
|
||||
links = resource.Body('links', type=list)
|
||||
#: The name of the allocation.
|
||||
name = resource.Body('name')
|
||||
#: UUID of the node this allocation belongs to.
|
||||
node_id = resource.Body('node_uuid')
|
||||
#: The requested resource class.
|
||||
resource_class = resource.Body('resource_class')
|
||||
#: The state of the allocation.
|
||||
state = resource.Body('state')
|
||||
#: The requested traits.
|
||||
traits = resource.Body('traits', type=list)
|
||||
#: Timestamp at which the allocation was last updated.
|
||||
updated_at = resource.Body('updated_at')
|
||||
|
||||
def wait(self, session, timeout=None, ignore_error=False):
|
||||
"""Wait for the allocation to become active.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~keystoneauth1.adapter.Adapter`
|
||||
:param timeout: How much (in seconds) to wait for the allocation.
|
||||
The value of ``None`` (the default) means no client-side timeout.
|
||||
:param ignore_error: If ``True``, this call will raise an exception
|
||||
if the allocation reaches the ``error`` state. Otherwise the error
|
||||
state is considered successful and the call returns.
|
||||
|
||||
:return: This :class:`Allocation` instance.
|
||||
"""
|
||||
if self.state == 'active':
|
||||
return self
|
||||
|
||||
for count in utils.iterate_timeout(
|
||||
timeout,
|
||||
"Timeout waiting for the allocation %s" % self.id):
|
||||
self.fetch(session)
|
||||
|
||||
if self.state == 'error' and not ignore_error:
|
||||
raise exceptions.SDKException(
|
||||
"Allocation %(allocation)s failed: %(error)s" %
|
||||
{'allocation': self.id, 'error': self.last_error})
|
||||
elif self.state != 'allocating':
|
||||
return self
|
||||
|
||||
_logger.debug('Still waiting for the allocation %(allocation)s '
|
||||
'to become active, the current state is %(state)s',
|
||||
{'allocation': self.id, 'state': self.state})
|
@ -56,10 +56,13 @@ class Node(_common.ListMixin, resource.Resource):
|
||||
is_maintenance='maintenance',
|
||||
)
|
||||
|
||||
# The conductor field introduced in 1.49 (Stein).
|
||||
_max_microversion = '1.49'
|
||||
# The allocation_uuid field introduced in 1.52 (Stein).
|
||||
_max_microversion = '1.52'
|
||||
|
||||
# Properties
|
||||
#: The UUID of the allocation associated with this node. Added in API
|
||||
#: microversion 1.52.
|
||||
allocation_id = resource.Body("allocation_uuid")
|
||||
#: The UUID of the chassis associated wit this node. Can be empty or None.
|
||||
chassis_id = resource.Body("chassis_uuid")
|
||||
#: The current clean step.
|
||||
|
@ -23,6 +23,13 @@ class BaseBaremetalTest(base.BaseFunctionalTest):
|
||||
self.require_service('baremetal',
|
||||
min_microversion=self.min_microversion)
|
||||
|
||||
def create_allocation(self, **kwargs):
|
||||
allocation = self.conn.baremetal.create_allocation(**kwargs)
|
||||
self.addCleanup(
|
||||
lambda: self.conn.baremetal.delete_allocation(allocation.id,
|
||||
ignore_missing=True))
|
||||
return allocation
|
||||
|
||||
def create_chassis(self, **kwargs):
|
||||
chassis = self.conn.baremetal.create_chassis(**kwargs)
|
||||
self.addCleanup(
|
||||
|
@ -0,0 +1,110 @@
|
||||
# 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 random
|
||||
|
||||
from openstack import exceptions
|
||||
from openstack.tests.functional.baremetal import base
|
||||
|
||||
|
||||
class TestBareMetalAllocation(base.BaseBaremetalTest):
|
||||
|
||||
min_microversion = '1.52'
|
||||
|
||||
def setUp(self):
|
||||
super(TestBareMetalAllocation, self).setUp()
|
||||
# NOTE(dtantsur): generate a unique resource class to prevent parallel
|
||||
# tests from clashing.
|
||||
self.resource_class = 'baremetal-%d' % random.randrange(1024)
|
||||
self.node = self._create_available_node()
|
||||
|
||||
def _create_available_node(self):
|
||||
node = self.create_node(resource_class=self.resource_class)
|
||||
self.conn.baremetal.set_node_provision_state(node, 'manage',
|
||||
wait=True)
|
||||
self.conn.baremetal.set_node_provision_state(node, 'provide',
|
||||
wait=True)
|
||||
# Make sure the node has non-empty power state by forcing power off.
|
||||
self.conn.baremetal.set_node_power_state(node, 'power off')
|
||||
self.addCleanup(
|
||||
lambda: self.conn.baremetal.update_node(node.id,
|
||||
instance_id=None))
|
||||
return node
|
||||
|
||||
def test_allocation_create_get_delete(self):
|
||||
allocation = self.create_allocation(resource_class=self.resource_class)
|
||||
self.assertEqual('allocating', allocation.state)
|
||||
self.assertIsNone(allocation.node_id)
|
||||
self.assertIsNone(allocation.last_error)
|
||||
|
||||
loaded = self.conn.baremetal.wait_for_allocation(allocation)
|
||||
self.assertEqual(loaded.id, allocation.id)
|
||||
self.assertEqual('active', allocation.state)
|
||||
self.assertEqual(self.node.id, allocation.node_id)
|
||||
self.assertIsNone(allocation.last_error)
|
||||
|
||||
node = self.conn.baremetal.get_node(self.node.id)
|
||||
self.assertEqual(allocation.id, node.allocation_id)
|
||||
|
||||
self.conn.baremetal.delete_allocation(allocation, ignore_missing=False)
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.baremetal.get_allocation, allocation.id)
|
||||
|
||||
def test_allocation_list(self):
|
||||
allocation1 = self.create_allocation(
|
||||
resource_class=self.resource_class)
|
||||
allocation2 = self.create_allocation(
|
||||
resource_class=self.resource_class + '-fail')
|
||||
|
||||
self.conn.baremetal.wait_for_allocation(allocation1)
|
||||
self.conn.baremetal.wait_for_allocation(allocation2, ignore_error=True)
|
||||
|
||||
allocations = self.conn.baremetal.allocations()
|
||||
self.assertEqual({p.id for p in allocations},
|
||||
{allocation1.id, allocation2.id})
|
||||
|
||||
allocations = self.conn.baremetal.allocations(state='active')
|
||||
self.assertEqual([p.id for p in allocations], [allocation1.id])
|
||||
|
||||
allocations = self.conn.baremetal.allocations(node=self.node.id)
|
||||
self.assertEqual([p.id for p in allocations], [allocation1.id])
|
||||
|
||||
allocations = self.conn.baremetal.allocations(
|
||||
resource_class=self.resource_class + '-fail')
|
||||
self.assertEqual([p.id for p in allocations], [allocation2.id])
|
||||
|
||||
def test_allocation_negative_failure(self):
|
||||
allocation = self.create_allocation(
|
||||
resource_class=self.resource_class + '-fail')
|
||||
self.assertRaises(exceptions.SDKException,
|
||||
self.conn.baremetal.wait_for_allocation,
|
||||
allocation)
|
||||
|
||||
allocation = self.conn.baremetal.get_allocation(allocation.id)
|
||||
self.assertEqual('error', allocation.state)
|
||||
self.assertIn(self.resource_class + '-fail', allocation.last_error)
|
||||
|
||||
def test_allocation_negative_non_existing(self):
|
||||
uuid = "5c9dcd04-2073-49bc-9618-99ae634d8971"
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.baremetal.get_allocation, uuid)
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.baremetal.delete_allocation, uuid,
|
||||
ignore_missing=False)
|
||||
self.assertIsNone(self.conn.baremetal.delete_allocation(uuid))
|
||||
|
||||
def test_allocation_fields(self):
|
||||
self.create_allocation(resource_class=self.resource_class)
|
||||
result = self.conn.baremetal.allocations(fields=['uuid'])
|
||||
for item in result:
|
||||
self.assertIsNotNone(item.id)
|
||||
self.assertIsNone(item.resource_class)
|
109
openstack/tests/unit/baremetal/v1/test_allocation.py
Normal file
109
openstack/tests/unit/baremetal/v1/test_allocation.py
Normal file
@ -0,0 +1,109 @@
|
||||
# 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 keystoneauth1 import adapter
|
||||
import mock
|
||||
|
||||
from openstack.baremetal.v1 import allocation
|
||||
from openstack import exceptions
|
||||
from openstack.tests.unit import base
|
||||
|
||||
FAKE = {
|
||||
"candidate_nodes": [],
|
||||
"created_at": "2016-08-18T22:28:48.165105+00:00",
|
||||
"extra": {},
|
||||
"last_error": None,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://127.0.0.1:6385/v1/allocations/<PG_ID>",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://127.0.0.1:6385/allocations/<PG_ID>",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"name": "test_allocation",
|
||||
"node_uuid": "6d85703a-565d-469a-96ce-30b6de53079d",
|
||||
"resource_class": "baremetal",
|
||||
"state": "active",
|
||||
"traits": [],
|
||||
"updated_at": None,
|
||||
"uuid": "e43c722c-248e-4c6e-8ce8-0d8ff129387a",
|
||||
}
|
||||
|
||||
|
||||
class TestAllocation(base.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = allocation.Allocation()
|
||||
self.assertIsNone(sot.resource_key)
|
||||
self.assertEqual('allocations', sot.resources_key)
|
||||
self.assertEqual('/allocations', 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)
|
||||
|
||||
def test_instantiate(self):
|
||||
sot = allocation.Allocation(**FAKE)
|
||||
self.assertEqual(FAKE['candidate_nodes'], sot.candidate_nodes)
|
||||
self.assertEqual(FAKE['created_at'], sot.created_at)
|
||||
self.assertEqual(FAKE['extra'], sot.extra)
|
||||
self.assertEqual(FAKE['last_error'], sot.last_error)
|
||||
self.assertEqual(FAKE['links'], sot.links)
|
||||
self.assertEqual(FAKE['name'], sot.name)
|
||||
self.assertEqual(FAKE['node_uuid'], sot.node_id)
|
||||
self.assertEqual(FAKE['resource_class'], sot.resource_class)
|
||||
self.assertEqual(FAKE['state'], sot.state)
|
||||
self.assertEqual(FAKE['traits'], sot.traits)
|
||||
self.assertEqual(FAKE['updated_at'], sot.updated_at)
|
||||
self.assertEqual(FAKE['uuid'], sot.id)
|
||||
|
||||
|
||||
@mock.patch('time.sleep', lambda _t: None)
|
||||
@mock.patch.object(allocation.Allocation, 'fetch', autospec=True)
|
||||
class TestWaitForAllocation(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestWaitForAllocation, self).setUp()
|
||||
self.session = mock.Mock(spec=adapter.Adapter)
|
||||
self.session.default_microversion = '1.52'
|
||||
self.fake = dict(FAKE, state='allocating', node_uuid=None)
|
||||
self.allocation = allocation.Allocation(**self.fake)
|
||||
|
||||
def test_already_active(self, mock_fetch):
|
||||
self.allocation.state = 'active'
|
||||
allocation = self.allocation.wait(None)
|
||||
self.assertIs(allocation, self.allocation)
|
||||
self.assertFalse(mock_fetch.called)
|
||||
|
||||
def test_wait(self, mock_fetch):
|
||||
marker = [False] # mutable object to modify in the closure
|
||||
|
||||
def _side_effect(allocation, session):
|
||||
if marker[0]:
|
||||
self.allocation.state = 'active'
|
||||
self.allocation.node_id = FAKE['node_uuid']
|
||||
else:
|
||||
marker[0] = True
|
||||
|
||||
mock_fetch.side_effect = _side_effect
|
||||
allocation = self.allocation.wait(self.session)
|
||||
self.assertIs(allocation, self.allocation)
|
||||
self.assertEqual(2, mock_fetch.call_count)
|
||||
|
||||
def test_timeout(self, mock_fetch):
|
||||
self.assertRaises(exceptions.ResourceTimeout,
|
||||
self.allocation.wait, self.session, timeout=0.001)
|
||||
mock_fetch.assert_called_with(self.allocation, self.session)
|
@ -13,6 +13,7 @@
|
||||
import mock
|
||||
|
||||
from openstack.baremetal.v1 import _proxy
|
||||
from openstack.baremetal.v1 import allocation
|
||||
from openstack.baremetal.v1 import chassis
|
||||
from openstack.baremetal.v1 import driver
|
||||
from openstack.baremetal.v1 import node
|
||||
@ -149,6 +150,20 @@ class TestBaremetalProxy(test_proxy_base.TestProxyBase):
|
||||
self.assertIs(result, mock_list.return_value)
|
||||
mock_list.assert_called_once_with(self.proxy, details=False, query=1)
|
||||
|
||||
def test_create_allocation(self):
|
||||
self.verify_create(self.proxy.create_allocation, allocation.Allocation)
|
||||
|
||||
def test_get_allocation(self):
|
||||
self.verify_get(self.proxy.get_allocation, allocation.Allocation)
|
||||
|
||||
def test_delete_allocation(self):
|
||||
self.verify_delete(self.proxy.delete_allocation, allocation.Allocation,
|
||||
False)
|
||||
|
||||
def test_delete_allocation_ignore(self):
|
||||
self.verify_delete(self.proxy.delete_allocation, allocation.Allocation,
|
||||
True)
|
||||
|
||||
|
||||
@mock.patch('time.sleep', lambda _sec: None)
|
||||
@mock.patch.object(_proxy.Proxy, 'get_node', autospec=True)
|
||||
|
4
releasenotes/notes/allocation-api-04f6b3b7a0ccc850.yaml
Normal file
4
releasenotes/notes/allocation-api-04f6b3b7a0ccc850.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds support for the baremetal allocation API.
|
Loading…
Reference in New Issue
Block a user