summaryrefslogtreecommitdiff
path: root/ironic/api
diff options
context:
space:
mode:
authorJulia Kreger <juliaashleykreger@gmail.com>2018-11-16 11:10:15 -0800
committerJulia Kreger <juliaashleykreger@gmail.com>2018-12-10 14:27:31 -0800
commit052d90506fdb75479250705be4ba033f9f025c76 (patch)
treedb179129de168f2d96eefcbed8a84430cff3d6c9 /ironic/api
parent88e13746267f64376b7ed1cd9fd95a770b1b1989 (diff)
downloadironic-052d90506fdb75479250705be4ba033f9f025c76.tar.gz
Add "owner" information field
Adds "owner" field on the node object and exposes it for updates via the API. Additionally, fixed a couple minor items related to the prior where we missed updating version numbers in rebases. Change-Id: Iaaf3db97d21de9b11236cf2d18ffcc3f73f6e50c Story: #2001814 Task: #12550
Diffstat (limited to 'ironic/api')
-rw-r--r--ironic/api/controllers/v1/node.py72
-rw-r--r--ironic/api/controllers/v1/utils.py19
-rw-r--r--ironic/api/controllers/v1/versions.py5
3 files changed, 58 insertions, 38 deletions
diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py
index 41c890e41..d18452cb8 100644
--- a/ironic/api/controllers/v1/node.py
+++ b/ironic/api/controllers/v1/node.py
@@ -1075,6 +1075,9 @@ class Node(base.APIBase):
conductor = wsme.wsattr(wtypes.text, readonly=True)
"""Represent the conductor currently serving the node"""
+ owner = wsme.wsattr(wtypes.text)
+ """Field for storage of physical node owner"""
+
# NOTE(deva): "conductor_affinity" shouldn't be presented on the
# API because it's an internal value. Don't add it here.
@@ -1277,7 +1280,7 @@ class Node(base.APIBase):
storage_interface=None, traits=[], rescue_interface=None,
bios_interface=None, conductor_group="",
automated_clean=None, protected=False,
- protected_reason=None)
+ protected_reason=None, owner=None)
# NOTE(matty_dubs): The chassis_uuid getter() is based on the
# _chassis_uuid variable:
sample._chassis_uuid = 'edcad704-b2da-41d5-96d9-afd580ecfa12'
@@ -1589,35 +1592,12 @@ class NodesController(rest.RestController):
filtered_nodes.append(n)
return filtered_nodes
- def _create_node_filters(self, chassis_uuid=None, associated=None,
- maintenance=None, provision_state=None,
- driver=None, resource_class=None, fault=None,
- conductor_group=None):
- filters = {}
- if chassis_uuid:
- filters['chassis_uuid'] = chassis_uuid
- if associated is not None:
- filters['associated'] = associated
- if maintenance is not None:
- filters['maintenance'] = maintenance
- if provision_state:
- filters['provision_state'] = provision_state
- if driver:
- filters['driver'] = driver
- if resource_class is not None:
- filters['resource_class'] = resource_class
- if fault is not None:
- filters['fault'] = fault
- if conductor_group is not None:
- filters['conductor_group'] = conductor_group
- return filters
-
def _get_nodes_collection(self, chassis_uuid, instance_uuid, associated,
maintenance, provision_state, marker, limit,
sort_key, sort_dir, driver=None,
resource_class=None, resource_url=None,
fields=None, fault=None, conductor_group=None,
- detail=None, conductor=None):
+ detail=None, conductor=None, owner=None):
if self.from_chassis and not chassis_uuid:
raise exception.MissingParameterValue(
_("Chassis id not specified."))
@@ -1650,10 +1630,22 @@ class NodesController(rest.RestController):
# be generated, which we don't want.
limit = 0
else:
- filters = self._create_node_filters(chassis_uuid, associated,
- maintenance, provision_state,
- driver, resource_class, fault,
- conductor_group)
+ possible_filters = {
+ 'maintenance': maintenance,
+ 'chassis_uuid': chassis_uuid,
+ 'associated': associated,
+ 'provision_state': provision_state,
+ 'driver': driver,
+ 'resource_class': resource_class,
+ 'fault': fault,
+ 'conductor_group': conductor_group,
+ 'owner': owner,
+ }
+ filters = {}
+ for key, value in possible_filters.items():
+ if value is not None:
+ filters[key] = value
+
nodes = objects.Node.list(pecan.request.context, limit, marker_obj,
sort_key=sort_key, sort_dir=sort_dir,
filters=filters)
@@ -1764,12 +1756,14 @@ class NodesController(rest.RestController):
@expose.expose(NodeCollection, types.uuid, types.uuid, types.boolean,
types.boolean, wtypes.text, types.uuid, int, wtypes.text,
wtypes.text, wtypes.text, types.listtype, wtypes.text,
- wtypes.text, wtypes.text, types.boolean, wtypes.text)
+ wtypes.text, wtypes.text, types.boolean, wtypes.text,
+ wtypes.text)
def get_all(self, chassis_uuid=None, instance_uuid=None, associated=None,
maintenance=None, provision_state=None, marker=None,
limit=None, sort_key='id', sort_dir='asc', driver=None,
fields=None, resource_class=None, fault=None,
- conductor_group=None, detail=None, conductor=None):
+ conductor_group=None, detail=None, conductor=None,
+ owner=None):
"""Retrieve a list of nodes.
:param chassis_uuid: Optional UUID of a chassis, to get only nodes for
@@ -1799,6 +1793,8 @@ class NodesController(rest.RestController):
that conductor_group.
:param conductor: Optional string value to get only nodes managed by
that conductor.
+ :param owner: Optional string value that set the owner whose nodes
+ are to be retrurned.
:param fields: Optional, a list with a specified set of fields
of the resource to be returned.
:param fault: Optional string value to get only nodes with that fault.
@@ -1815,6 +1811,7 @@ class NodesController(rest.RestController):
api_utils.check_allow_filter_by_fault(fault)
api_utils.check_allow_filter_by_conductor_group(conductor_group)
api_utils.check_allow_filter_by_conductor(conductor)
+ api_utils.check_allow_filter_by_owner(owner)
fields = api_utils.get_request_return_fields(fields, detail,
_DEFAULT_RETURN_FIELDS)
@@ -1828,18 +1825,19 @@ class NodesController(rest.RestController):
fields=fields, fault=fault,
conductor_group=conductor_group,
detail=detail,
- conductor=conductor)
+ conductor=conductor,
+ owner=owner)
@METRICS.timer('NodesController.detail')
@expose.expose(NodeCollection, types.uuid, types.uuid, types.boolean,
types.boolean, wtypes.text, types.uuid, int, wtypes.text,
wtypes.text, wtypes.text, wtypes.text, wtypes.text,
- wtypes.text, wtypes.text)
+ wtypes.text, wtypes.text, wtypes.text)
def detail(self, chassis_uuid=None, instance_uuid=None, associated=None,
maintenance=None, provision_state=None, marker=None,
limit=None, sort_key='id', sort_dir='asc', driver=None,
resource_class=None, fault=None, conductor_group=None,
- conductor=None):
+ conductor=None, owner=None):
"""Retrieve a list of nodes with detail.
:param chassis_uuid: Optional UUID of a chassis, to get only nodes for
@@ -1868,6 +1866,8 @@ class NodesController(rest.RestController):
:param fault: Optional string value to get only nodes with that fault.
:param conductor_group: Optional string value to get only nodes with
that conductor_group.
+ :param owner: Optional string value that set the owner whose nodes
+ are to be retrurned.
"""
cdict = pecan.request.context.to_policy_values()
policy.authorize('baremetal:node:get', cdict, cdict)
@@ -1877,6 +1877,7 @@ class NodesController(rest.RestController):
api_utils.check_allow_specify_resource_class(resource_class)
api_utils.check_allow_filter_by_fault(fault)
api_utils.check_allow_filter_by_conductor_group(conductor_group)
+ api_utils.check_allow_filter_by_owner(owner)
api_utils.check_allowed_fields([sort_key])
# /detail should only work against collections
parent = pecan.request.path.split('/')[:-1][-1]
@@ -1895,7 +1896,8 @@ class NodesController(rest.RestController):
resource_url=resource_url,
fault=fault,
conductor_group=conductor_group,
- conductor=conductor)
+ conductor=conductor,
+ owner=owner)
@METRICS.timer('NodesController.validate')
@expose.expose(wtypes.text, types.uuid_or_name, types.uuid)
diff --git a/ironic/api/controllers/v1/utils.py b/ironic/api/controllers/v1/utils.py
index bed014844..4fb56f7ea 100644
--- a/ironic/api/controllers/v1/utils.py
+++ b/ironic/api/controllers/v1/utils.py
@@ -379,6 +379,7 @@ VERSIONED_FIELDS = {
'protected': versions.MINOR_48_NODE_PROTECTED,
'protected_reason': versions.MINOR_48_NODE_PROTECTED,
'conductor': versions.MINOR_49_CONDUCTORS,
+ 'owner': versions.MINOR_50_NODE_OWNER,
}
for field in V31_FIELDS:
@@ -544,6 +545,20 @@ def check_allow_filter_by_conductor_group(conductor_group):
'opr': versions.MINOR_46_NODE_CONDUCTOR_GROUP})
+def check_allow_filter_by_owner(owner):
+ """Check if filtering nodes by owner is allowed.
+
+ Version 1.50 of the API allows filtering nodes by owner.
+ """
+ if (owner is not None and pecan.request.version.minor
+ < versions.MINOR_50_NODE_OWNER):
+ raise exception.NotAcceptable(_(
+ "Request not acceptable. The minimal required API version "
+ "should be %(base)s.%(opr)s") %
+ {'base': versions.BASE_VERSION,
+ 'opr': versions.MINOR_50_NODE_OWNER})
+
+
def initial_node_provision_state():
"""Return node state to use by default when creating new nodes.
@@ -930,7 +945,7 @@ def get_request_return_fields(fields, detail, default_fields):
def allow_expose_conductors():
"""Check if accessing conductor endpoints is allowed.
- Version 1.48 of the API exposed conductor endpoints and conductor field
+ Version 1.49 of the API exposed conductor endpoints and conductor field
for the node.
"""
return pecan.request.version.minor >= versions.MINOR_49_CONDUCTORS
@@ -939,7 +954,7 @@ def allow_expose_conductors():
def check_allow_filter_by_conductor(conductor):
"""Check if filtering nodes by conductor is allowed.
- Version 1.48 of the API allows filtering nodes by conductor.
+ Version 1.49 of the API allows filtering nodes by conductor.
"""
if conductor is not None and not allow_expose_conductors():
raise exception.NotAcceptable(_(
diff --git a/ironic/api/controllers/v1/versions.py b/ironic/api/controllers/v1/versions.py
index 826df55d1..fcc83195a 100644
--- a/ironic/api/controllers/v1/versions.py
+++ b/ironic/api/controllers/v1/versions.py
@@ -86,6 +86,8 @@ BASE_VERSION = 1
# v1.46: Add conductor_group to the node object.
# v1.47: Add automated_clean to the node object.
# v1.48: Add protected to the node object.
+# v1.49: Exposes current conductor on the node object.
+# v1.50: Add owner to the node object.
MINOR_0_JUNO = 0
MINOR_1_INITIAL_VERSION = 1
@@ -137,6 +139,7 @@ MINOR_46_NODE_CONDUCTOR_GROUP = 46
MINOR_47_NODE_AUTOMATED_CLEAN = 47
MINOR_48_NODE_PROTECTED = 48
MINOR_49_CONDUCTORS = 49
+MINOR_50_NODE_OWNER = 50
# When adding another version, update:
# - MINOR_MAX_VERSION
@@ -144,7 +147,7 @@ MINOR_49_CONDUCTORS = 49
# explanation of what changed in the new version
# - common/release_mappings.py, RELEASE_MAPPING['master']['api']
-MINOR_MAX_VERSION = MINOR_49_CONDUCTORS
+MINOR_MAX_VERSION = MINOR_50_NODE_OWNER
# String representations of the minor and maximum versions
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)