diff options
author | Dmitry Tantsur <divius.inside@gmail.com> | 2019-02-25 11:24:53 +0100 |
---|---|---|
committer | Dmitry Tantsur <divius.inside@gmail.com> | 2019-03-05 19:14:56 +0100 |
commit | 3e1e0c9d5e6e5753d0fe2529901986ea36934971 (patch) | |
tree | 0dfd46645b8ca7e81bf6b37ed3262da43f2cc14d /ironic/api/controllers/v1/utils.py | |
parent | ec2f7f992e1cca141df26441bdbf9cd9c682541c (diff) | |
download | ironic-3e1e0c9d5e6e5753d0fe2529901986ea36934971.tar.gz |
Allow building configdrive from JSON in the API
Extend the API with the ability to build config drives from meta_data,
network_data and user_data, where meta_data and network_data are JSON
objects, and user_data is either a JSON object, a JSON array or
raw contents as a string.
This change uses openstacksdk (which is already an indirect dependency)
for building config drives.
Change-Id: Ie1f399a4cb6d4fe5afec79341d3bccc0f81204b2
Story: #2005083
Task: #29663
Diffstat (limited to 'ironic/api/controllers/v1/utils.py')
-rw-r--r-- | ironic/api/controllers/v1/utils.py | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/ironic/api/controllers/v1/utils.py b/ironic/api/controllers/v1/utils.py index f75cf5617..5123be509 100644 --- a/ironic/api/controllers/v1/utils.py +++ b/ironic/api/controllers/v1/utils.py @@ -17,6 +17,8 @@ import inspect import re import jsonpatch +import jsonschema +from jsonschema import exceptions as json_schema_exc import os_traits from oslo_config import cfg from oslo_utils import uuidutils @@ -586,7 +588,30 @@ def check_allow_driver_detail(detail): 'opr': versions.MINOR_30_DYNAMIC_DRIVERS}) -def check_allow_configdrive(target): +_CONFIG_DRIVE_SCHEMA = { + 'anyOf': [ + { + 'type': 'object', + 'properties': { + 'meta_data': {'type': 'object'}, + 'network_data': {'type': 'object'}, + 'user_data': { + 'type': ['object', 'array', 'string', 'null'] + } + }, + 'additionalProperties': False + }, + { + 'type': ['string', 'null'] + } + ] +} + + +def check_allow_configdrive(target, configdrive=None): + if not configdrive: + return + allowed_targets = [states.ACTIVE] if allow_node_rebuild_with_configdrive(): allowed_targets.append(states.REBUILD) @@ -597,6 +622,21 @@ def check_allow_configdrive(target): raise wsme.exc.ClientSideError( msg, status_code=http_client.BAD_REQUEST) + try: + jsonschema.validate(configdrive, _CONFIG_DRIVE_SCHEMA) + except json_schema_exc.ValidationError as e: + msg = _('Invalid configdrive format: %s') % e + raise wsme.exc.ClientSideError( + msg, status_code=http_client.BAD_REQUEST) + + if isinstance(configdrive, dict) and not allow_build_configdrive(): + msg = _('Providing a JSON object for configdrive is only supported' + ' starting with API version %(base)s.%(opr)s') % { + 'base': versions.BASE_VERSION, + 'opr': versions.MINOR_56_BUILD_CONFIGDRIVE} + raise wsme.exc.ClientSideError( + msg, status_code=http_client.BAD_REQUEST) + def check_allow_filter_by_fault(fault): """Check if filtering nodes by fault is allowed. @@ -1094,3 +1134,11 @@ def check_policy(policy_name): """ cdict = pecan.request.context.to_policy_values() policy.authorize(policy_name, cdict, cdict) + + +def allow_build_configdrive(): + """Check if building configdrive is allowed. + + Version 1.56 of the API added support for building configdrive. + """ + return pecan.request.version.minor >= versions.MINOR_56_BUILD_CONFIGDRIVE |