Add support for release network_metadata serialziation
Patch adds support for release network metadata serialization, by adding additional handler on release/<release_id>/networks for PUT/GET requestss Proper validation for release networking data Why not to add another field in release handler: 1. networks_metadata it is ours internal naming 2. url release/<release_id>/networks makes more sense for client applications Change-Id: I205ec786f1a9d772905ff22e426c1ce8a6d4d6e7 Closes-Bug: 1381557
This commit is contained in:
parent
35946b1f22
commit
4815936beb
@ -21,9 +21,8 @@ Handlers dealing with releases
|
||||
from nailgun.api.v1.handlers.base import CollectionHandler
|
||||
from nailgun.api.v1.handlers.base import content_json
|
||||
from nailgun.api.v1.handlers.base import SingleHandler
|
||||
|
||||
from nailgun.api.v1.validators.release import ReleaseNetworksValidator
|
||||
from nailgun.api.v1.validators.release import ReleaseValidator
|
||||
|
||||
from nailgun.objects import Release
|
||||
from nailgun.objects import ReleaseCollection
|
||||
|
||||
@ -50,3 +49,51 @@ class ReleaseCollectionHandler(CollectionHandler):
|
||||
"""
|
||||
q = sorted(self.collection.all(), reverse=True)
|
||||
return self.collection.to_json(q)
|
||||
|
||||
|
||||
class ReleaseNetworksHandler(SingleHandler):
|
||||
"""Release Handler for network metadata
|
||||
"""
|
||||
|
||||
single = Release
|
||||
validator = ReleaseNetworksValidator
|
||||
|
||||
@content_json
|
||||
def GET(self, obj_id):
|
||||
"""Read release networks metadata
|
||||
|
||||
:returns: Release networks metadata
|
||||
:http: * 201 (object successfully created)
|
||||
* 400 (invalid object data specified)
|
||||
* 404 (release object not found)
|
||||
"""
|
||||
obj = self.get_object_or_404(self.single, obj_id)
|
||||
return obj['networks_metadata']
|
||||
|
||||
@content_json
|
||||
def PUT(self, obj_id):
|
||||
"""Updates release networks metadata
|
||||
|
||||
:returns: Release networks metadata
|
||||
:http: * 201 (object successfully created)
|
||||
* 400 (invalid object data specified)
|
||||
* 404 (release object not found)
|
||||
"""
|
||||
obj = self.get_object_or_404(self.single, obj_id)
|
||||
data = self.checked_data()
|
||||
self.single.update(obj, {'networks_metadata': data})
|
||||
return obj['networks_metadata']
|
||||
|
||||
def POST(self, obj_id):
|
||||
"""Creation of metadata disallowed
|
||||
|
||||
:http: * 405 (method not supported)
|
||||
"""
|
||||
raise self.http(405, 'Create not supported for this entity')
|
||||
|
||||
def DELETE(self, obj_id):
|
||||
"""Deletion of metadata disallowed
|
||||
|
||||
:http: * 405 (method not supported)
|
||||
"""
|
||||
raise self.http(405, 'Delete not supported for this entity')
|
||||
|
@ -77,10 +77,10 @@ from nailgun.api.v1.handlers.orchestrator import DeploySelectedNodes
|
||||
from nailgun.api.v1.handlers.orchestrator import ProvisioningInfo
|
||||
from nailgun.api.v1.handlers.orchestrator import ProvisionSelectedNodes
|
||||
|
||||
|
||||
from nailgun.api.v1.handlers.registration import FuelKeyHandler
|
||||
from nailgun.api.v1.handlers.release import ReleaseCollectionHandler
|
||||
from nailgun.api.v1.handlers.release import ReleaseHandler
|
||||
from nailgun.api.v1.handlers.release import ReleaseNetworksHandler
|
||||
|
||||
from nailgun.api.v1.handlers.tasks import TaskCollectionHandler
|
||||
from nailgun.api.v1.handlers.tasks import TaskHandler
|
||||
@ -98,6 +98,8 @@ urls = (
|
||||
ReleaseCollectionHandler,
|
||||
r'/releases/(?P<obj_id>\d+)/?$',
|
||||
ReleaseHandler,
|
||||
r'/releases/(?P<obj_id>\d+)/networks/?$',
|
||||
ReleaseNetworksHandler,
|
||||
|
||||
r'/clusters/?$',
|
||||
ClusterCollectionHandler,
|
||||
|
63
nailgun/nailgun/api/v1/validators/json_schema/networks.py
Normal file
63
nailgun/nailgun/api/v1/validators/json_schema/networks.py
Normal file
@ -0,0 +1,63 @@
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
# Non-complete JSON Schema for validating IP addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_IP_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
'format': 'ipv4',
|
||||
}
|
||||
|
||||
|
||||
# Non-complete JSON schema for validating NET addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_NET_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
|
||||
# check for valid ip address and route prefix
|
||||
# e.g: 192.168.0.0/24
|
||||
'pattern': '^(({octet}\.){{3}}{octet})({prefix})?$'.format(
|
||||
octet='(2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?)',
|
||||
prefix='/(3[012]|[12]?[0-9])'
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# Non-complete JSON Schema for validating MAC addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_MAC_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
'pattern': '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$',
|
||||
}
|
||||
|
||||
|
||||
NETWORK = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {'type': 'string'},
|
||||
'cidr': _NET_ADDRESS_SCHEMA,
|
||||
'gateway': _IP_ADDRESS_SCHEMA,
|
||||
'ip_range': {'type': 'array'},
|
||||
'vlan_start': {'type': ['null', 'number']},
|
||||
'use_gateway': {'type': 'boolean'},
|
||||
'notation': {'type': ['string', 'null']},
|
||||
'render_type': {'type': ['null', 'string']},
|
||||
'map_priority': {'type': 'number'},
|
||||
'configurable': {'type': 'boolean'},
|
||||
'floating_range_var': {'type': 'string'},
|
||||
'ext_net_data': {'type': 'array'},
|
||||
'assign_vip': {'type': 'boolean'}},
|
||||
'required': ['name']
|
||||
}
|
@ -14,34 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# Non-complete JSON Schema for validating IP addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_IP_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
'format': 'ipv4',
|
||||
}
|
||||
|
||||
|
||||
# Non-complete JSON schema for validating NET addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_NET_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
|
||||
# check for valid ip address and route prefix
|
||||
# e.g: 192.168.0.0/24
|
||||
'pattern': '^(({octet}\.){{3}}{octet})({prefix})?$'.format(
|
||||
octet='(2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?)',
|
||||
prefix='/(3[012]|[12]?[0-9])'
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# Non-complete JSON Schema for validating MAC addresses.
|
||||
# Use it for better readability in the main schema.
|
||||
_MAC_ADDRESS_SCHEMA = {
|
||||
'type': 'string',
|
||||
'pattern': '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$',
|
||||
}
|
||||
from nailgun.api.v1.validators.json_schema import networks
|
||||
|
||||
|
||||
# TODO(@ikalnitsky): add `required` properties to all needed objects
|
||||
@ -51,8 +24,8 @@ node_format_schema = {
|
||||
'description': 'Object with node description',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'mac': _MAC_ADDRESS_SCHEMA,
|
||||
'ip': _IP_ADDRESS_SCHEMA,
|
||||
'mac': networks._MAC_ADDRESS_SCHEMA,
|
||||
'ip': networks._IP_ADDRESS_SCHEMA,
|
||||
'meta': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@ -63,9 +36,9 @@ node_format_schema = {
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ip': _IP_ADDRESS_SCHEMA,
|
||||
'netmask': _NET_ADDRESS_SCHEMA,
|
||||
'mac': _MAC_ADDRESS_SCHEMA,
|
||||
'ip': networks._IP_ADDRESS_SCHEMA,
|
||||
'netmask': networks._NET_ADDRESS_SCHEMA,
|
||||
'mac': networks._MAC_ADDRESS_SCHEMA,
|
||||
'state': {'type': 'string'},
|
||||
'name': {'type': 'string'},
|
||||
}
|
||||
|
46
nailgun/nailgun/api/v1/validators/json_schema/release.py
Normal file
46
nailgun/nailgun/api/v1/validators/json_schema/release.py
Normal file
@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nailgun.api.v1.validators.json_schema import networks
|
||||
|
||||
|
||||
NOVA_NETWORK_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'networks': {
|
||||
'type': 'array',
|
||||
'items': networks.NETWORK},
|
||||
'config': {'type': 'object'}},
|
||||
'required': ['networks', 'config']
|
||||
}
|
||||
|
||||
NEUTRON_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'networks': {
|
||||
'type': 'array',
|
||||
'items': networks.NETWORK},
|
||||
'config': {'type': 'object'}},
|
||||
'required': ['networks', 'config']
|
||||
}
|
||||
|
||||
NETWORKS_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'nova_network': NOVA_NETWORK_SCHEMA,
|
||||
'neutron': NEUTRON_SCHEMA,
|
||||
},
|
||||
'required': ['nova_network', 'neutron']
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
from sqlalchemy import not_
|
||||
|
||||
from nailgun.api.v1.validators.base import BasicValidator
|
||||
from nailgun.api.v1.validators.json_schema import release
|
||||
from nailgun.db import db
|
||||
from nailgun.db.sqlalchemy.models import Release
|
||||
from nailgun.errors import errors
|
||||
@ -126,3 +127,17 @@ class ReleaseValidator(BasicValidator):
|
||||
"Can't delete release with "
|
||||
"clusters assigned"
|
||||
)
|
||||
|
||||
|
||||
class ReleaseNetworksValidator(BasicValidator):
|
||||
|
||||
@classmethod
|
||||
def validate(cls, data):
|
||||
parsed = super(ReleaseNetworksValidator, cls).validate(data)
|
||||
cls.validate_schema(parsed)
|
||||
return parsed
|
||||
|
||||
@classmethod
|
||||
def validate_schema(cls, data):
|
||||
return super(ReleaseNetworksValidator, cls).validate_schema(
|
||||
data, release.NETWORKS_SCHEMA)
|
||||
|
@ -0,0 +1,62 @@
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from nailgun.openstack.common import jsonutils
|
||||
from nailgun.test.base import BaseIntegrationTest
|
||||
from nailgun.test.base import reverse
|
||||
|
||||
|
||||
class TestReleaseNetworksHandlers(BaseIntegrationTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestReleaseNetworksHandlers, self).setUp()
|
||||
self.release = self.env.create_release()
|
||||
|
||||
def test_get(self):
|
||||
resp = self.app.get(
|
||||
reverse('ReleaseNetworksHandler',
|
||||
kwargs={'obj_id': self.release.id}),
|
||||
headers=self.default_headers
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(self.release['networks_metadata'], resp.json)
|
||||
|
||||
def test_post(self):
|
||||
resp = self.app.post(
|
||||
reverse('ReleaseNetworksHandler',
|
||||
kwargs={'obj_id': self.release.id}),
|
||||
headers=self.default_headers,
|
||||
expect_errors=True
|
||||
)
|
||||
self.assertEqual(resp.status_code, 405)
|
||||
|
||||
def test_delete(self):
|
||||
resp = self.app.delete(
|
||||
reverse('ReleaseNetworksHandler',
|
||||
kwargs={'obj_id': self.release.id}),
|
||||
headers=self.default_headers,
|
||||
expect_errors=True
|
||||
)
|
||||
self.assertEqual(resp.status_code, 405)
|
||||
|
||||
def test_put(self):
|
||||
data = jsonutils.dumps(self.release['networks_metadata'])
|
||||
resp = self.app.put(
|
||||
reverse('ReleaseNetworksHandler',
|
||||
kwargs={'obj_id': self.release.id}),
|
||||
data,
|
||||
headers=self.default_headers
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
30
nailgun/nailgun/test/unit/test_release_networks_schema.py
Normal file
30
nailgun/nailgun/test/unit/test_release_networks_schema.py
Normal file
@ -0,0 +1,30 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import jsonschema
|
||||
|
||||
from nailgun.api.v1.validators.json_schema import release
|
||||
from nailgun.test import base
|
||||
|
||||
|
||||
class TestRelaseNetworksSchema(base.BaseTestCase):
|
||||
|
||||
def test_networks_schema(self):
|
||||
checker = jsonschema.FormatChecker()
|
||||
release_data = self.env.create_release()
|
||||
jsonschema.validate(
|
||||
release_data['networks_metadata'],
|
||||
release.NETWORKS_SCHEMA,
|
||||
format_checker=checker)
|
Loading…
Reference in New Issue
Block a user