baremetal: Add 'details' parameter to various 'find' proxy methods
In change I13f32e6ca9be9ed4eb42398aace47e3c5205a81f, we introduced support for a 'details' parameter to various proxy methods that supported it. Unfortunately there was a bug in the baremetal proxy layer changes, which were using a mixin to modify the 'Resource.list' class method to allow listing detailed responses easily via the resource layer. This necessitated a revert, change Icc70bbdc06b5f32722a93775aee2da4d7b7ca4ae. Take another go at this by reverting the revert and making the necessary changes to the mixin and proxy layer to make things compatible. We also fix a few bugs, where certain resources has the mixin applied, resulting in them attempting to use legacy path-based mechanism to retrieve detailed resources (GET /resource/detail) even though they didn't support this. Change-Id: I6acbcb4d9af35e68c04bb86e50c8844487bd7d6c Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
30d5753bcf
commit
147b66169d
|
@ -90,10 +90,39 @@ CHANGE_BOOT_MODE_VERSION = '1.76'
|
|||
|
||||
|
||||
class Resource(resource.Resource):
|
||||
"""A subclass for resources that use the path to request a detailed view.
|
||||
|
||||
Two patterns exist for fetching the detailed view when listing resources.
|
||||
|
||||
- As part of the path. For example:
|
||||
|
||||
GET /v1/ports/detail
|
||||
|
||||
- As a query parameter. For example:
|
||||
|
||||
GET /v1/conductors?detail=True
|
||||
|
||||
This handles resources that use the former pattern, namely:
|
||||
|
||||
- chassis
|
||||
- nodes
|
||||
- ports
|
||||
- portgroups
|
||||
"""
|
||||
base_path: str
|
||||
|
||||
@classmethod
|
||||
def list(cls, session, details=False, **params):
|
||||
def list(
|
||||
cls,
|
||||
session,
|
||||
paginated=True,
|
||||
base_path=None,
|
||||
allow_unknown_params=False,
|
||||
*,
|
||||
microversion=None,
|
||||
details=False,
|
||||
**params,
|
||||
):
|
||||
"""This method is a generator which yields resource objects.
|
||||
|
||||
This resource object list generator handles pagination and takes query
|
||||
|
@ -101,22 +130,102 @@ class Resource(resource.Resource):
|
|||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~keystoneauth1.adapter.Adapter`
|
||||
:param bool details: Whether to return detailed node records
|
||||
:param bool paginated: ``True`` if a GET to this resource returns
|
||||
a paginated series of responses, or ``False`` if a GET returns only
|
||||
one page of data. **When paginated is False only one page of data
|
||||
will be returned regardless of the API's support of pagination.**
|
||||
:param str base_path: Base part of the URI for listing resources, if
|
||||
different from :data:`~openstack.resource.Resource.base_path`.
|
||||
:param bool allow_unknown_params: ``True`` to accept, but discard
|
||||
unknown query parameters. This allows getting list of 'filters' and
|
||||
passing everything known to the server. ``False`` will result in
|
||||
validation exception when unknown query parameters are passed.
|
||||
:param str microversion: API version to override the negotiated one.
|
||||
:param bool details: Whether to return detailed resource records.
|
||||
:param dict params: These keyword arguments are passed through the
|
||||
:meth:`~openstack.resource.QueryParameter._transpose` method
|
||||
to find if any of them match expected query parameters to be
|
||||
sent in the *params* argument to
|
||||
:meth:`~keystoneauth1.adapter.Adapter.get`.
|
||||
:meth:`~openstack.resource.QueryParamter._transpose` method
|
||||
to find if any of them match expected query parameters to be sent
|
||||
in the *params* argument to
|
||||
:meth:`~keystoneauth1.adapter.Adapter.get`. They are additionally
|
||||
checked against the :data:`~openstack.resource.Resource.base_path`
|
||||
format string to see if any path fragments need to be filled in by
|
||||
the contents of this argument.
|
||||
Parameters supported as filters by the server side are passed in
|
||||
the API call, remaining parameters are applied as filters to the
|
||||
retrieved results.
|
||||
|
||||
:return: A generator of :class:`openstack.resource.Resource` objects.
|
||||
:return: A generator of :class:`Resource` objects.
|
||||
:raises: :exc:`~openstack.exceptions.MethodNotSupported` if
|
||||
:data:`Resource.allow_list` is not set to ``True``.
|
||||
:raises: :exc:`~openstack.exceptions.InvalidResourceQuery` if query
|
||||
contains invalid params.
|
||||
contains invalid params.
|
||||
"""
|
||||
base_path = cls.base_path
|
||||
if details:
|
||||
base_path += '/detail'
|
||||
if not base_path:
|
||||
base_path = cls.base_path
|
||||
if details:
|
||||
base_path += '/detail'
|
||||
|
||||
return super().list(
|
||||
session, paginated=True, base_path=base_path, **params
|
||||
session,
|
||||
paginated=paginated,
|
||||
base_path=base_path,
|
||||
allow_unknown_params=allow_unknown_params,
|
||||
microversion=microversion,
|
||||
**params,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def find(
|
||||
cls,
|
||||
session,
|
||||
name_or_id,
|
||||
ignore_missing=True,
|
||||
list_base_path=None,
|
||||
*,
|
||||
microversion=None,
|
||||
all_projects=None,
|
||||
details=False,
|
||||
**params,
|
||||
):
|
||||
"""Find a resource by its name or id.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~keystoneauth1.adapter.Adapter`
|
||||
:param name_or_id: This resource's identifier, if needed by
|
||||
the request. The default is ``None``.
|
||||
:param bool ignore_missing: When set to ``False``
|
||||
:class:`~openstack.exceptions.ResourceNotFound` will be raised when
|
||||
the resource does not exist. When set to ``True``, None will be
|
||||
returned when attempting to find a nonexistent resource.
|
||||
:param str list_base_path: base_path to be used when need listing
|
||||
resources.
|
||||
:param str microversion: API version to override the negotiated one.
|
||||
:param bool details: Whether to return detailed resource records.
|
||||
:param dict params: Any additional parameters to be passed into
|
||||
underlying methods, such as to
|
||||
:meth:`~openstack.resource.Resource.existing` in order to pass on
|
||||
URI parameters.
|
||||
|
||||
:return: The :class:`Resource` object matching the given name or id
|
||||
or None if nothing matches.
|
||||
:raises: :class:`openstack.exceptions.DuplicateResource` if more
|
||||
than one resource is found for this request.
|
||||
:raises: :class:`openstack.exceptions.ResourceNotFound` if nothing
|
||||
is found and ignore_missing is ``False``.
|
||||
"""
|
||||
if not list_base_path:
|
||||
list_base_path = cls.base_path
|
||||
if details:
|
||||
list_base_path += '/detail'
|
||||
|
||||
return super().find(
|
||||
session,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
list_base_path=list_base_path,
|
||||
microversion=microversion,
|
||||
all_projects=all_projects,
|
||||
**params,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ class Proxy(proxy.Proxy):
|
|||
error_message="No {resource_type} found for {value}".format(
|
||||
resource_type=resource_type.__name__, value=value
|
||||
),
|
||||
**kwargs
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def chassis(self, details=False, **query):
|
||||
|
@ -113,7 +113,9 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_chassis.Chassis, **attrs)
|
||||
|
||||
def find_chassis(self, name_or_id, ignore_missing=True):
|
||||
# TODO(stephenfin): Delete this. You can't lookup a chassis by name so this
|
||||
# is identical to get_chassis
|
||||
def find_chassis(self, name_or_id, ignore_missing=True, *, details=True):
|
||||
"""Find a single chassis.
|
||||
|
||||
:param str name_or_id: The ID of a chassis.
|
||||
|
@ -121,11 +123,17 @@ class Proxy(proxy.Proxy):
|
|||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the chassis does not exist. When set to `True``, None will
|
||||
be returned when attempting to find a nonexistent chassis.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the chassis should be returned.
|
||||
|
||||
:returns: One :class:`~openstack.baremetal.v1.chassis.Chassis` object
|
||||
or None.
|
||||
"""
|
||||
return self._find(
|
||||
_chassis.Chassis, name_or_id, ignore_missing=ignore_missing
|
||||
_chassis.Chassis,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_chassis(self, chassis, fields=None):
|
||||
|
@ -305,7 +313,7 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_node.Node, **attrs)
|
||||
|
||||
def find_node(self, name_or_id, ignore_missing=True):
|
||||
def find_node(self, name_or_id, ignore_missing=True, *, details=True):
|
||||
"""Find a single node.
|
||||
|
||||
:param str name_or_id: The name or ID of a node.
|
||||
|
@ -313,11 +321,16 @@ class Proxy(proxy.Proxy):
|
|||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the node does not exist. When set to `True``, None will
|
||||
be returned when attempting to find a nonexistent node.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the node should be returned.
|
||||
:returns: One :class:`~openstack.baremetal.v1.node.Node` object
|
||||
or None.
|
||||
"""
|
||||
return self._find(
|
||||
_node.Node, name_or_id, ignore_missing=ignore_missing
|
||||
_node.Node,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_node(self, node, fields=None):
|
||||
|
@ -768,7 +781,9 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_port.Port, **attrs)
|
||||
|
||||
def find_port(self, name_or_id, ignore_missing=True):
|
||||
# TODO(stephenfin): Delete this. You can't lookup a port by name so this is
|
||||
# identical to get_port
|
||||
def find_port(self, name_or_id, ignore_missing=True, *, details=True):
|
||||
"""Find a single port.
|
||||
|
||||
:param str name_or_id: The ID of a port.
|
||||
|
@ -776,11 +791,16 @@ class Proxy(proxy.Proxy):
|
|||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the port does not exist. When set to `True``, None will
|
||||
be returned when attempting to find a nonexistent port.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for every port should be returned.
|
||||
:returns: One :class:`~openstack.baremetal.v1.port.Port` object
|
||||
or None.
|
||||
"""
|
||||
return self._find(
|
||||
_port.Port, name_or_id, ignore_missing=ignore_missing
|
||||
_port.Port,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_port(self, port, fields=None):
|
||||
|
@ -887,7 +907,13 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_portgroup.PortGroup, **attrs)
|
||||
|
||||
def find_port_group(self, name_or_id, ignore_missing=True):
|
||||
def find_port_group(
|
||||
self,
|
||||
name_or_id,
|
||||
ignore_missing=True,
|
||||
*,
|
||||
details=True,
|
||||
):
|
||||
"""Find a single port group.
|
||||
|
||||
:param str name_or_id: The name or ID of a portgroup.
|
||||
|
@ -895,11 +921,16 @@ class Proxy(proxy.Proxy):
|
|||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the port group does not exist. When set to `True``, None will
|
||||
be returned when attempting to find a nonexistent port group.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the port group should be returned.
|
||||
:returns: One :class:`~openstack.baremetal.v1.port_group.PortGroup`
|
||||
object or None.
|
||||
"""
|
||||
return self._find(
|
||||
_portgroup.PortGroup, name_or_id, ignore_missing=ignore_missing
|
||||
_portgroup.PortGroup,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_port_group(self, port_group, fields=None):
|
||||
|
@ -1294,16 +1325,26 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_volumeconnector.VolumeConnector, **attrs)
|
||||
|
||||
def find_volume_connector(self, vc_id, ignore_missing=True):
|
||||
# TODO(stephenfin): Delete this. You can't lookup a volume connector by
|
||||
# name so this is identical to get_volume_connector
|
||||
def find_volume_connector(
|
||||
self,
|
||||
vc_id,
|
||||
ignore_missing=True,
|
||||
*,
|
||||
details=True,
|
||||
):
|
||||
"""Find a single volume connector.
|
||||
|
||||
:param str vc_id: The ID of a volume connector.
|
||||
|
||||
:param bool ignore_missing: When set to ``False``, an exception of
|
||||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the volume connector does not exist. When set to `True``,
|
||||
None will be returned when attempting to find a nonexistent
|
||||
volume connector.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the volume connector should be returned.
|
||||
|
||||
:returns: One
|
||||
:class:`~openstack.baremetal.v1.volumeconnector.VolumeConnector`
|
||||
object or None.
|
||||
|
@ -1312,6 +1353,7 @@ class Proxy(proxy.Proxy):
|
|||
_volumeconnector.VolumeConnector,
|
||||
vc_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_volume_connector(self, volume_connector, fields=None):
|
||||
|
@ -1441,22 +1483,29 @@ class Proxy(proxy.Proxy):
|
|||
"""
|
||||
return self._create(_volumetarget.VolumeTarget, **attrs)
|
||||
|
||||
def find_volume_target(self, vt_id, ignore_missing=True):
|
||||
# TODO(stephenfin): Delete this. You can't lookup a volume target by
|
||||
# name so this is identical to get_volume_connector
|
||||
def find_volume_target(self, vt_id, ignore_missing=True, *, details=True):
|
||||
"""Find a single volume target.
|
||||
|
||||
:param str vt_id: The ID of a volume target.
|
||||
|
||||
:param bool ignore_missing: When set to ``False``, an exception of
|
||||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the volume connector does not exist. When set to `True``,
|
||||
None will be returned when attempting to find a nonexistent
|
||||
volume target.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the volume target should be returned.
|
||||
|
||||
:returns: One
|
||||
:class:`~openstack.baremetal.v1.volumetarget.VolumeTarget`
|
||||
object or None.
|
||||
"""
|
||||
return self._find(
|
||||
_volumetarget.VolumeTarget, vt_id, ignore_missing=ignore_missing
|
||||
_volumetarget.VolumeTarget,
|
||||
vt_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def get_volume_target(self, volume_target, fields=None):
|
||||
|
@ -1624,6 +1673,35 @@ class Proxy(proxy.Proxy):
|
|||
_deploytemplates.DeployTemplate, deploy_template, fields=fields
|
||||
)
|
||||
|
||||
def find_deploy_template(
|
||||
self,
|
||||
name_or_id,
|
||||
ignore_missing=True,
|
||||
*,
|
||||
details=True,
|
||||
):
|
||||
"""Find a single deployment template.
|
||||
|
||||
:param str name_or_id: The name or ID of a deployment template.
|
||||
:param bool ignore_missing: When set to ``False``, an exception of
|
||||
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||
when the deployment template does not exist. When set to `True``,
|
||||
None will be returned when attempting to find a nonexistent
|
||||
deployment template.
|
||||
:param details: A boolean indicating whether the detailed information
|
||||
for the deployment template should be returned.
|
||||
|
||||
:returns: One
|
||||
:class:`~openstack.baremetal.v1.deploy_templates.DeployTemplate` or
|
||||
None.
|
||||
"""
|
||||
return self._find(
|
||||
_deploytemplates.DeployTemplate,
|
||||
name_or_id,
|
||||
ignore_missing=ignore_missing,
|
||||
details=details,
|
||||
)
|
||||
|
||||
def patch_deploy_template(self, deploy_template, patch):
|
||||
"""Apply a JSON patch to the deploy_templates.
|
||||
|
||||
|
@ -1655,6 +1733,10 @@ class Proxy(proxy.Proxy):
|
|||
query['details'] = True
|
||||
return _conductor.Conductor.list(self, **query)
|
||||
|
||||
# NOTE(stephenfin): There is no 'find_conductor' since conductors are
|
||||
# identified by the host name, not an arbitrary UUID, meaning
|
||||
# 'find_conductor' would be identical to 'get_conductor'
|
||||
|
||||
def get_conductor(self, conductor, fields=None):
|
||||
"""Get a specific conductor.
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ from openstack import resource
|
|||
from openstack import utils
|
||||
|
||||
|
||||
class Allocation(_common.Resource):
|
||||
class Allocation(resource.Resource):
|
||||
resources_key = 'allocations'
|
||||
base_path = '/allocations'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from openstack.baremetal.v1 import _common
|
|||
from openstack import resource
|
||||
|
||||
|
||||
class Conductor(_common.Resource):
|
||||
class Conductor(resource.Resource):
|
||||
resources_key = 'conductors'
|
||||
base_path = '/conductors'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from openstack.baremetal.v1 import _common
|
|||
from openstack import resource
|
||||
|
||||
|
||||
class DeployTemplate(_common.Resource):
|
||||
class DeployTemplate(resource.Resource):
|
||||
resources_key = 'deploy_templates'
|
||||
base_path = '/deploy_templates'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from openstack.baremetal.v1 import _common
|
|||
from openstack import resource
|
||||
|
||||
|
||||
class VolumeConnector(_common.Resource):
|
||||
class VolumeConnector(resource.Resource):
|
||||
resources_key = 'connectors'
|
||||
base_path = '/volume/connectors'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from openstack.baremetal.v1 import _common
|
|||
from openstack import resource
|
||||
|
||||
|
||||
class VolumeTarget(_common.Resource):
|
||||
class VolumeTarget(resource.Resource):
|
||||
resources_key = 'targets'
|
||||
base_path = '/volume/targets'
|
||||
|
||||
|
|
|
@ -10,11 +10,10 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.baremetal.v1 import _common
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class IntrospectionRule(_common.Resource):
|
||||
class IntrospectionRule(resource.Resource):
|
||||
resources_key = 'rules'
|
||||
base_path = '/rules'
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ from unittest 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 deploy_templates
|
||||
from openstack.baremetal.v1 import driver
|
||||
from openstack.baremetal.v1 import node
|
||||
from openstack.baremetal.v1 import port
|
||||
|
@ -60,7 +61,11 @@ class TestChassis(TestBaremetalProxy):
|
|||
self.verify_create(self.proxy.create_chassis, chassis.Chassis)
|
||||
|
||||
def test_find_chassis(self):
|
||||
self.verify_find(self.proxy.find_chassis, chassis.Chassis)
|
||||
self.verify_find(
|
||||
self.proxy.find_chassis,
|
||||
chassis.Chassis,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_chassis(self):
|
||||
self.verify_get(
|
||||
|
@ -110,7 +115,11 @@ class TestNode(TestBaremetalProxy):
|
|||
self.verify_create(self.proxy.create_node, node.Node)
|
||||
|
||||
def test_find_node(self):
|
||||
self.verify_find(self.proxy.find_node, node.Node)
|
||||
self.verify_find(
|
||||
self.proxy.find_node,
|
||||
node.Node,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_node(self):
|
||||
self.verify_get(
|
||||
|
@ -162,7 +171,11 @@ class TestPort(TestBaremetalProxy):
|
|||
self.verify_create(self.proxy.create_port, port.Port)
|
||||
|
||||
def test_find_port(self):
|
||||
self.verify_find(self.proxy.find_port, port.Port)
|
||||
self.verify_find(
|
||||
self.proxy.find_port,
|
||||
port.Port,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_port(self):
|
||||
self.verify_get(
|
||||
|
@ -236,7 +249,9 @@ class TestVolumeConnector(TestBaremetalProxy):
|
|||
|
||||
def test_find_volume_connector(self):
|
||||
self.verify_find(
|
||||
self.proxy.find_volume_connector, volume_connector.VolumeConnector
|
||||
self.proxy.find_volume_connector,
|
||||
volume_connector.VolumeConnector,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_volume_connector(self):
|
||||
|
@ -282,7 +297,9 @@ class TestVolumeTarget(TestBaremetalProxy):
|
|||
|
||||
def test_find_volume_target(self):
|
||||
self.verify_find(
|
||||
self.proxy.find_volume_target, volume_target.VolumeTarget
|
||||
self.proxy.find_volume_target,
|
||||
volume_target.VolumeTarget,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_volume_target(self):
|
||||
|
@ -304,6 +321,55 @@ class TestVolumeTarget(TestBaremetalProxy):
|
|||
)
|
||||
|
||||
|
||||
class TestDeployTemplate(TestBaremetalProxy):
|
||||
@mock.patch.object(deploy_templates.DeployTemplate, 'list')
|
||||
def test_deploy_templates_detailed(self, mock_list):
|
||||
result = self.proxy.deploy_templates(details=True, query=1)
|
||||
self.assertIs(result, mock_list.return_value)
|
||||
mock_list.assert_called_once_with(self.proxy, detail=True, query=1)
|
||||
|
||||
@mock.patch.object(deploy_templates.DeployTemplate, 'list')
|
||||
def test_deploy_templates_not_detailed(self, mock_list):
|
||||
result = self.proxy.deploy_templates(query=1)
|
||||
self.assertIs(result, mock_list.return_value)
|
||||
mock_list.assert_called_once_with(self.proxy, query=1)
|
||||
|
||||
def test_create_deploy_template(self):
|
||||
self.verify_create(
|
||||
self.proxy.create_deploy_template,
|
||||
deploy_templates.DeployTemplate,
|
||||
)
|
||||
|
||||
def test_find_deploy_template(self):
|
||||
self.verify_find(
|
||||
self.proxy.find_deploy_template,
|
||||
deploy_templates.DeployTemplate,
|
||||
expected_kwargs={'details': True},
|
||||
)
|
||||
|
||||
def test_get_deploy_template(self):
|
||||
self.verify_get(
|
||||
self.proxy.get_deploy_template,
|
||||
deploy_templates.DeployTemplate,
|
||||
mock_method=_MOCK_METHOD,
|
||||
expected_kwargs={'fields': None},
|
||||
)
|
||||
|
||||
def test_delete_deploy_template(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_deploy_template,
|
||||
deploy_templates.DeployTemplate,
|
||||
False,
|
||||
)
|
||||
|
||||
def test_delete_deploy_template_ignore(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_deploy_template,
|
||||
deploy_templates.DeployTemplate,
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
class TestMisc(TestBaremetalProxy):
|
||||
@mock.patch.object(node.Node, 'fetch', autospec=True)
|
||||
def test__get_with_fields_none(self, mock_fetch):
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
The following proxy ``find_*`` operations will now retrieve a detailed
|
||||
resource by default when retrieving by name:
|
||||
|
||||
* Bare metal (v1)
|
||||
|
||||
* ``find_chassis``
|
||||
* ``find_node``
|
||||
* ``find_port``
|
||||
* ``find_port_group``
|
||||
* ``find_volume_connector``
|
||||
* ``find_volume_target``
|
Loading…
Reference in New Issue