diff options
author | Julia Kreger <juliaashleykreger@gmail.com> | 2018-11-16 11:10:15 -0800 |
---|---|---|
committer | Julia Kreger <juliaashleykreger@gmail.com> | 2018-12-10 14:27:31 -0800 |
commit | 052d90506fdb75479250705be4ba033f9f025c76 (patch) | |
tree | db179129de168f2d96eefcbed8a84430cff3d6c9 /ironic/api | |
parent | 88e13746267f64376b7ed1cd9fd95a770b1b1989 (diff) | |
download | ironic-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.py | 72 | ||||
-rw-r--r-- | ironic/api/controllers/v1/utils.py | 19 | ||||
-rw-r--r-- | ironic/api/controllers/v1/versions.py | 5 |
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) |