Instance groups: validate policy configuration

Ensure that API does not allow conflicting policies to be configured
on an instance group. More specifically the user should not be allowed
to configured 'anti-affinity' and 'affinity' on the same instance group.

In addition to this a validation will also be done on the policy, that is,
if the policy is not supported then an exception will be raised.

This is part of blueprint instance-group-api-extension.

Change-Id: Id19c55cb60109819429f73e2b28efe7f15cc5194
This commit is contained in:
Gary Kotton 2014-02-28 10:37:39 -08:00
parent aeda1f6e64
commit 26bf8c0dd0
18 changed files with 62 additions and 19 deletions

View File

@ -2,7 +2,7 @@
"server_group": {
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<server_group xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="5bbcc3c4-1da2-4437-a48a-66f15b1b13f9" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>

View File

@ -3,7 +3,7 @@
{
"id": "616fb98f-46ca-475e-917e-2563e5a8cd19",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -2,7 +2,7 @@
<server_groups xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server_group id="5bbcc3c4-1da2-4437-a48a-66f15b1b13f9" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>

View File

@ -1,6 +1,6 @@
{
"server_group": {
"name": "test",
"policies": ["test_policy"]
"policies": ["anti-affinity"]
}
}

View File

@ -1,5 +1,5 @@
<server_group name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
</server_group>

View File

@ -2,7 +2,7 @@
"server_group": {
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<server_group xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="5bbcc3c4-1da2-4437-a48a-66f15b1b13f9" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>

View File

@ -29,6 +29,7 @@ from nova.openstack.common import log as logging
from nova import utils
LOG = logging.getLogger(__name__)
SUPPORTED_POLICIES = ['anti-affinity', 'affinity']
authorize = extensions.extension_authorizer('compute', 'server_groups')
@ -153,6 +154,28 @@ class ServerGroupController(wsgi.Controller):
server_group['metadata'] = group.metadetails or {}
return server_group
def _validate_policies(self, policies):
"""Validate the policies.
Validates that there are no contradicting policies, for example
'anti-affinity' and 'affinity' in the same group.
:param policies: the given policies of the server_group
"""
if not policies:
return
if ('anti-affinity' in policies and
'affinity' in policies):
msg = _("Conflicting policies configured!")
raise nova.exception.InvalidInput(reason=msg)
not_supported = []
for policy in policies:
if policy not in SUPPORTED_POLICIES:
not_supported.append(policy)
if not_supported:
msg = _("Invalid policies: %s") % ', '.join(not_supported)
raise nova.exception.InvalidInput(reason=msg)
def _validate_input_body(self, body, entity_name):
if not self.is_valid_body(body, entity_name):
msg = _("the body is invalid.")
@ -160,6 +183,10 @@ class ServerGroupController(wsgi.Controller):
subbody = dict(body[entity_name])
policies = subbody.get('policies')
# Validate that the policies do not contradict one another
self._validate_policies(policies)
expected_fields = ['name', 'policies']
for field in expected_fields:
value = subbody.pop(field, None)

View File

@ -96,7 +96,7 @@ class ServerGroupTest(test.TestCase):
def test_create_server_group_normal(self):
req = fakes.HTTPRequest.blank('/v2/fake/os-server-groups')
sgroup = server_group_template()
policies = ['test_policy']
policies = ['anti-affinity']
sgroup['policies'] = policies
res_dict = self.controller.create(req, {'server_group': sgroup})
self.assertEqual(res_dict['server_group']['name'], 'test')
@ -122,6 +122,22 @@ class ServerGroupTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
req, {'server_group': sgroup})
def test_create_server_group_conflicting_policies(self):
sgroup = server_group_template()
policies = ['anti-affinity', 'affinity']
sgroup['policies'] = policies
req = fakes.HTTPRequest.blank('/v2/fake/os-server-groups')
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
req, {'server_group': sgroup})
def test_create_server_group_not_supported(self):
sgroup = server_group_template()
policies = ['storage-affinity', 'anti-affinity', 'rack-affinity']
sgroup['policies'] = policies
req = fakes.HTTPRequest.blank('/v2/fake/os-server-groups')
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
req, {'server_group': sgroup})
def test_create_server_group_with_no_body(self):
req = fakes.HTTPRequest.blank('/v2/fake/os-server-groups')
self.assertRaises(webob.exc.HTTPBadRequest,
@ -135,7 +151,7 @@ class ServerGroupTest(test.TestCase):
def test_list_server_group_by_tenant(self):
groups = []
policies = ['test_policy']
policies = ['anti-affinity']
members = ['1', '2']
metadata = {'key1': 'value1'}
names = ['default-x', 'test']
@ -165,7 +181,7 @@ class ServerGroupTest(test.TestCase):
def test_list_server_group_all(self):
all_groups = []
tenant_groups = []
policies = ['test_policy']
policies = ['anti-affinity']
members = ['1', '2']
metadata = {'key1': 'value1'}
names = ['default-x', 'test']

View File

@ -2,7 +2,7 @@
"server_group": {
"id": "%(id)s",
"name": "%(name)s",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<server_group xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="%(id)s" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>

View File

@ -3,7 +3,7 @@
{
"id": "%(id)s",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -2,7 +2,7 @@
<server_groups xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server_group id="%(id)s" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>

View File

@ -1,6 +1,6 @@
{
"server_group": {
"name": "%(name)s",
"policies": ["test_policy"]
"policies": ["anti-affinity"]
}
}

View File

@ -1,5 +1,5 @@
<server_group name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
</server_group>

View File

@ -2,7 +2,7 @@
"server_group": {
"id": "%(id)s",
"name": "%(name)s",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<server_group xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="%(id)s" name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
<members/>
<metadata/>