summaryrefslogtreecommitdiff
path: root/ironic/api/controllers/v1/utils.py
diff options
context:
space:
mode:
authorDmitry Tantsur <divius.inside@gmail.com>2019-02-25 11:24:53 +0100
committerDmitry Tantsur <divius.inside@gmail.com>2019-03-05 19:14:56 +0100
commit3e1e0c9d5e6e5753d0fe2529901986ea36934971 (patch)
tree0dfd46645b8ca7e81bf6b37ed3262da43f2cc14d /ironic/api/controllers/v1/utils.py
parentec2f7f992e1cca141df26441bdbf9cd9c682541c (diff)
downloadironic-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.py50
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