summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuriy Zveryanskyy <yzveryanskyy@mirantis.com>2013-09-25 18:52:40 +0300
committerYuriy Zveryanskyy <yzveryanskyy@mirantis.com>2013-09-26 14:47:08 +0300
commit0d740b26cd0acecef457e185704a316f773e0cee (patch)
tree6a2ca56aaec204584ac5dd0ec2ceb81f66c81433
parent98670162c74c245cb671ca53c934f0533b3d570a (diff)
downloadironic-0d740b26cd0acecef457e185704a316f773e0cee.tar.gz
Integer types support in api
This patch adds validation 'driver_info' (for nodes) and 'extra' (nodes, chassis, ports) for accept integers as values. Change-Id: I930bb408ab9f3fde49034978413651ea0e7e28e9
-rw-r--r--ironic/api/controllers/v1/chassis.py3
-rw-r--r--ironic/api/controllers/v1/node.py13
-rw-r--r--ironic/api/controllers/v1/port.py3
-rw-r--r--ironic/api/controllers/v1/utils.py17
-rw-r--r--ironic/tests/api/test_chassis.py13
-rw-r--r--ironic/tests/api/test_nodes.py11
-rw-r--r--ironic/tests/api/test_ports.py13
7 files changed, 64 insertions, 9 deletions
diff --git a/ironic/api/controllers/v1/chassis.py b/ironic/api/controllers/v1/chassis.py
index d189ab7fc..cce219838 100644
--- a/ironic/api/controllers/v1/chassis.py
+++ b/ironic/api/controllers/v1/chassis.py
@@ -17,6 +17,7 @@
# under the License.
import jsonpatch
+import six
import pecan
from pecan import rest
@@ -52,7 +53,7 @@ class Chassis(base.APIBase):
description = wtypes.text
"The description of the chassis"
- extra = {wtypes.text: wtypes.text}
+ extra = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)}
"The metadata of the chassis"
links = [link.Link]
diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py
index 073d37a87..306697ba3 100644
--- a/ironic/api/controllers/v1/node.py
+++ b/ironic/api/controllers/v1/node.py
@@ -16,6 +16,7 @@
# under the License.
import jsonpatch
+import six
import pecan
from pecan import rest
@@ -195,17 +196,15 @@ class Node(base.APIBase):
# NOTE: translate 'driver_info' internally to 'management_configuration'
driver = wtypes.text
- # FIXME(lucasagomes): it should accept at least wtypes.text or wtypes.int
- # as value
- driver_info = {wtypes.text: wtypes.text}
+ driver_info = {wtypes.text: utils.ValidTypes(wtypes.text,
+ six.integer_types)}
- # FIXME(lucasagomes): it should accept at least wtypes.text or wtypes.int
- # as value
- extra = {wtypes.text: wtypes.text}
+ extra = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)}
# NOTE: properties should use a class to enforce required properties
# current list: arch, cpus, disk, ram, image
- properties = {wtypes.text: wtypes.text}
+ properties = {wtypes.text: utils.ValidTypes(wtypes.text,
+ six.integer_types)}
# NOTE: translate 'chassis_id' to a link to the chassis resource
# and accept a chassis uuid when creating a node.
diff --git a/ironic/api/controllers/v1/port.py b/ironic/api/controllers/v1/port.py
index a3bb5c85c..2bfc80793 100644
--- a/ironic/api/controllers/v1/port.py
+++ b/ironic/api/controllers/v1/port.py
@@ -16,6 +16,7 @@
# under the License.
import jsonpatch
+import six
import pecan
from pecan import rest
@@ -47,7 +48,7 @@ class Port(base.APIBase):
address = wtypes.text
- extra = {wtypes.text: wtypes.text}
+ extra = {wtypes.text: utils.ValidTypes(wtypes.text, six.integer_types)}
node_id = int
diff --git a/ironic/api/controllers/v1/utils.py b/ironic/api/controllers/v1/utils.py
index 50851dd39..5a979bddd 100644
--- a/ironic/api/controllers/v1/utils.py
+++ b/ironic/api/controllers/v1/utils.py
@@ -69,3 +69,20 @@ def validate_patch(patch):
"attribute (%s) to the "
"resource is not allowed")
% path)
+
+
+class ValidTypes(wsme.types.UserType):
+ """User type for validate that value has one of a few types."""
+
+ def __init__(self, *types):
+ self.types = types
+
+ def validate(self, value):
+ for t in self.types:
+ if t is wsme.types.text and isinstance(value, wsme.types.bytes):
+ value = value.decode()
+ if isinstance(value, t):
+ return value
+ else:
+ raise ValueError("Wrong type. Expected '%s', got '%s'" % (
+ self.types, type(value)))
diff --git a/ironic/tests/api/test_chassis.py b/ironic/tests/api/test_chassis.py
index 603d5c632..0bae4d1e0 100644
--- a/ironic/tests/api/test_chassis.py
+++ b/ironic/tests/api/test_chassis.py
@@ -16,6 +16,8 @@
Tests for the API /chassis/ methods.
"""
+import webtest.app
+
from ironic.openstack.common import uuidutils
from ironic.tests.api import base
from ironic.tests.db import utils as dbutils
@@ -262,6 +264,17 @@ class TestPost(base.FunctionalTest):
expect_errors=True)
self.assertEqual(response.status_int, 403)
+ def test_create_chassis_valid_extra(self):
+ cdict = dbutils.get_test_chassis(extra={'foo': 123})
+ self.post_json('/chassis', cdict)
+ result = self.get_json('/chassis/%s' % cdict['uuid'])
+ self.assertEqual(cdict['extra'], result['extra'])
+
+ def test_create_chassis_invalid_extra(self):
+ cdict = dbutils.get_test_chassis(extra={'foo': 0.123})
+ self.assertRaises(webtest.app.AppError, self.post_json, '/chassis',
+ cdict)
+
class TestDelete(base.FunctionalTest):
diff --git a/ironic/tests/api/test_nodes.py b/ironic/tests/api/test_nodes.py
index d70c89a0a..a6be049e3 100644
--- a/ironic/tests/api/test_nodes.py
+++ b/ironic/tests/api/test_nodes.py
@@ -286,6 +286,17 @@ class TestPost(base.FunctionalTest):
result = self.get_json('/nodes/%s' % ndict['uuid'])
self.assertEqual(ndict['uuid'], result['uuid'])
+ def test_create_node_valid_extra(self):
+ ndict = dbutils.get_test_node(extra={'foo': 123})
+ self.post_json('/nodes', ndict)
+ result = self.get_json('/nodes/%s' % ndict['uuid'])
+ self.assertEqual(ndict['extra'], result['extra'])
+
+ def test_create_node_invalid_extra(self):
+ ndict = dbutils.get_test_node(extra={'foo': 0.123})
+ self.assertRaises(webtest.app.AppError, self.post_json, '/nodes',
+ ndict)
+
def test_vendor_passthru(self):
ndict = dbutils.get_test_node()
self.post_json('/nodes', ndict)
diff --git a/ironic/tests/api/test_ports.py b/ironic/tests/api/test_ports.py
index 9d9af6038..b843db189 100644
--- a/ironic/tests/api/test_ports.py
+++ b/ironic/tests/api/test_ports.py
@@ -16,6 +16,8 @@
Tests for the API /ports/ methods.
"""
+import webtest.app
+
from ironic.openstack.common import uuidutils
from ironic.tests.api import base
from ironic.tests.db import utils as dbutils
@@ -236,6 +238,17 @@ class TestPost(base.FunctionalTest):
self.assertEqual(pdict['address'], result['address'])
self.assertTrue(uuidutils.is_uuid_like(result['uuid']))
+ def test_create_port_valid_extra(self):
+ pdict = dbutils.get_test_port(extra={'foo': 123})
+ self.post_json('/ports', pdict)
+ result = self.get_json('/ports/%s' % pdict['uuid'])
+ self.assertEqual(pdict['extra'], result['extra'])
+
+ def test_create_port_invalid_extra(self):
+ pdict = dbutils.get_test_port(extra={'foo': 0.123})
+ self.assertRaises(webtest.app.AppError, self.post_json, '/ports',
+ pdict)
+
class TestDelete(base.FunctionalTest):