summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-12-06 23:58:43 +0000
committerGerrit Code Review <review@openstack.org>2020-12-06 23:58:43 +0000
commit2c3b2ffd489d466b665379c480336440cf3d8df5 (patch)
tree1f5c902749d86a7a2aeb202ffd358391634dfad7
parente49a61baeb5fd94d707058886ddb7333e8605f44 (diff)
parenta3644ebd6395fb767c5e8bec2aced93ca7f5f8df (diff)
downloadironic-2c3b2ffd489d466b665379c480336440cf3d8df5.tar.gz
Merge "Improve object_to_dict arguments"
-rw-r--r--ironic/api/controllers/v1/allocation.py13
-rw-r--r--ironic/api/controllers/v1/bios.py2
-rw-r--r--ironic/api/controllers/v1/conductor.py2
-rw-r--r--ironic/api/controllers/v1/node.py11
-rw-r--r--ironic/api/controllers/v1/utils.py71
-rw-r--r--ironic/tests/unit/api/controllers/v1/test_utils.py23
6 files changed, 63 insertions, 59 deletions
diff --git a/ironic/api/controllers/v1/allocation.py b/ironic/api/controllers/v1/allocation.py
index fb876c381..037e2c643 100644
--- a/ironic/api/controllers/v1/allocation.py
+++ b/ironic/api/controllers/v1/allocation.py
@@ -73,9 +73,16 @@ def convert_with_links(rpc_allocation, fields=None, sanitize=True):
allocation = api_utils.object_to_dict(
rpc_allocation,
link_resource='allocations',
- fields=('extra', 'name', 'state', 'last_error', 'resource_class',
- 'owner'),
- list_fields=('candidate_nodes', 'traits')
+ fields=(
+ 'candidate_nodes',
+ 'extra',
+ 'last_error',
+ 'name',
+ 'owner',
+ 'resource_class',
+ 'state',
+ 'traits'
+ )
)
try:
api_utils.populate_node_uuid(rpc_allocation, allocation)
diff --git a/ironic/api/controllers/v1/bios.py b/ironic/api/controllers/v1/bios.py
index 9475f766e..be6743d70 100644
--- a/ironic/api/controllers/v1/bios.py
+++ b/ironic/api/controllers/v1/bios.py
@@ -31,7 +31,7 @@ def convert_with_links(rpc_bios, node_uuid):
"""Build a dict containing a bios setting value."""
bios = api_utils.object_to_dict(
rpc_bios,
- uuid=False,
+ include_uuid=False,
fields=('name', 'value'),
link_resource='nodes',
link_resource_args="%s/bios/%s" % (node_uuid, rpc_bios.name),
diff --git a/ironic/api/controllers/v1/conductor.py b/ironic/api/controllers/v1/conductor.py
index 839eef576..c6e55a38f 100644
--- a/ironic/api/controllers/v1/conductor.py
+++ b/ironic/api/controllers/v1/conductor.py
@@ -36,7 +36,7 @@ DEFAULT_RETURN_FIELDS = ['hostname', 'conductor_group', 'alive']
def convert_with_links(rpc_conductor, fields=None, sanitize=True):
conductor = api_utils.object_to_dict(
rpc_conductor,
- uuid=False,
+ include_uuid=False,
fields=('hostname', 'conductor_group', 'drivers'),
link_resource='conductors',
link_resource_args=rpc_conductor.hostname
diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py
index 8340152a4..d07561f9c 100644
--- a/ironic/api/controllers/v1/node.py
+++ b/ironic/api/controllers/v1/node.py
@@ -1137,6 +1137,7 @@ def node_convert_with_links(rpc_node, fields=None, sanitize=True):
'boot_interface',
'clean_step',
'conductor_group',
+ 'console_enabled',
'console_interface',
'deploy_interface',
'deploy_step',
@@ -1146,11 +1147,14 @@ def node_convert_with_links(rpc_node, fields=None, sanitize=True):
'driver_internal_info',
'extra',
'fault',
+ 'inspection_finished_at',
+ 'inspection_started_at',
'inspect_interface',
'instance_info',
'instance_uuid',
'last_error',
'lessee',
+ 'maintenance',
'maintenance_reason',
'management_interface',
'name',
@@ -1160,13 +1164,16 @@ def node_convert_with_links(rpc_node, fields=None, sanitize=True):
'power_interface',
'power_state',
'properties',
+ 'protected',
'protected_reason',
'provision_state',
+ 'provision_updated_at',
'raid_config',
'raid_interface',
'rescue_interface',
'reservation',
'resource_class',
+ 'retired',
'retired_reason',
'storage_interface',
'target_power_state',
@@ -1174,10 +1181,6 @@ def node_convert_with_links(rpc_node, fields=None, sanitize=True):
'target_raid_config',
'vendor_interface'
),
- boolean_fields=('console_enabled', 'maintenance', 'protected',
- 'retired'),
- date_fields=('inspection_finished_at', 'inspection_started_at',
- 'provision_updated_at'),
)
node['traits'] = rpc_node.traits.get_trait_names()
diff --git a/ironic/api/controllers/v1/utils.py b/ironic/api/controllers/v1/utils.py
index 474987f9a..1d1e0aa24 100644
--- a/ironic/api/controllers/v1/utils.py
+++ b/ironic/api/controllers/v1/utils.py
@@ -38,6 +38,7 @@ from ironic.common import policy
from ironic.common import states
from ironic.common import utils
from ironic import objects
+from ironic.objects import fields as ofields
CONF = cfg.CONF
@@ -152,18 +153,18 @@ LOCAL_LINK_VALIDATOR = args.and_valid(
LOCAL_LINK_SMART_NIC_VALIDATOR = args.schema(LOCAL_LINK_SMART_NIC_SCHEMA)
-def object_to_dict(obj, created_at=True, updated_at=True, uuid=True,
- link_resource=None, link_resource_args=None, fields=None,
- list_fields=None, date_fields=None, boolean_fields=None):
+def object_to_dict(obj, include_created_at=True, include_updated_at=True,
+ include_uuid=True, link_resource=None,
+ link_resource_args=None, fields=None):
"""Helper function to convert RPC objects to REST API dicts.
:param obj:
RPC object to convert to a dict
- :param created_at:
+ :param include_created_at:
Whether to include standard base class attribute created_at
- :param updated_at:
+ :param include_updated_at:
Whether to include standard base class attribute updated_at
- :param uuid:
+ :param include_uuid:
Whether to include standard base class attribute uuid
:param link_resource:
When specified, generate a ``links`` value with a ``self`` and
@@ -172,47 +173,39 @@ def object_to_dict(obj, created_at=True, updated_at=True, uuid=True,
Resource arguments to be added to generated links. When not specified,
the object ``uuid`` will be used.
:param fields:
- Dict values to populate directly from object attributes
- :param list_fields:
- Dict values to populate from object attributes where an empty list is
- the default for empty attributes
- :param date_fields:
- Dict values to populate from object attributes as ISO 8601 dates,
- or None if the value is None
- :param boolean_fields:
- Dict values to populate from object attributes as boolean values
- or False if the value is empty
+ Key names for dict values to populate directly from object attributes
:returns: A dict containing values from the object
"""
url = api.request.public_url
to_dict = {}
- if uuid:
- to_dict['uuid'] = obj.uuid
+ all_fields = []
- if created_at:
- to_dict['created_at'] = (obj.created_at
- and obj.created_at.isoformat() or None)
- if updated_at:
- to_dict['updated_at'] = (obj.updated_at
- and obj.updated_at.isoformat() or None)
+ if include_uuid:
+ all_fields.append('uuid')
+ if include_created_at:
+ all_fields.append('created_at')
+ if include_updated_at:
+ all_fields.append('updated_at')
if fields:
- for field in fields:
- to_dict[field] = getattr(obj, field)
-
- if list_fields:
- for field in list_fields:
- to_dict[field] = getattr(obj, field) or []
-
- if date_fields:
- for field in date_fields:
- date = getattr(obj, field)
- to_dict[field] = date and date.isoformat() or None
-
- if boolean_fields:
- for field in boolean_fields:
- to_dict[field] = getattr(obj, field) or False
+ all_fields.extend(fields)
+
+ for field in all_fields:
+ value = to_dict[field] = getattr(obj, field)
+ empty_value = None
+ if isinstance(obj.fields[field], ofields.ListOfStringsField):
+ empty_value = []
+ elif isinstance(obj.fields[field], ofields.FlexibleDictField):
+ empty_value = {}
+ elif isinstance(obj.fields[field], ofields.DateTimeField):
+ if value:
+ value = value.isoformat()
+
+ if value is not None:
+ to_dict[field] = value
+ else:
+ to_dict[field] = empty_value
if link_resource:
if not link_resource_args:
diff --git a/ironic/tests/unit/api/controllers/v1/test_utils.py b/ironic/tests/unit/api/controllers/v1/test_utils.py
index 0d9b489fe..031042f7f 100644
--- a/ironic/tests/unit/api/controllers/v1/test_utils.py
+++ b/ironic/tests/unit/api/controllers/v1/test_utils.py
@@ -1596,8 +1596,7 @@ class TestObjectToDict(base.TestCase):
created_at=datetime.datetime(2000, 1, 1, 0, 0),
updated_at=datetime.datetime(2001, 1, 1, 0, 0),
inspection_started_at=datetime.datetime(2002, 1, 1, 0, 0),
- console_enabled=True,
- tags=['one', 'two', 'three'])
+ console_enabled=True)
p = mock.patch.object(api, 'request', autospec=False)
mock_req = p.start()
@@ -1614,9 +1613,9 @@ class TestObjectToDict(base.TestCase):
def test_no_base_attributes(self):
self.assertEqual({}, utils.object_to_dict(
self.node,
- created_at=False,
- updated_at=False,
- uuid=False)
+ include_created_at=False,
+ include_updated_at=False,
+ include_uuid=False)
)
def test_fields(self):
@@ -1628,16 +1627,18 @@ class TestObjectToDict(base.TestCase):
'inspection_finished_at': None,
'inspection_started_at': '2002-01-01T00:00:00+00:00',
'maintenance': False,
- 'tags': ['one', 'two', 'three'],
- 'traits': [],
'updated_at': '2001-01-01T00:00:00+00:00',
'uuid': '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'
}, utils.object_to_dict(
self.node,
- fields=['conductor_group', 'driver'],
- boolean_fields=['maintenance', 'console_enabled'],
- date_fields=['inspection_started_at', 'inspection_finished_at'],
- list_fields=['tags', 'traits'])
+ fields=[
+ 'conductor_group',
+ 'console_enabled',
+ 'driver',
+ 'inspection_finished_at',
+ 'inspection_started_at',
+ 'maintenance',
+ ])
)
def test_links(self):