Skip to content

Commit

Permalink
Instance groups: validate policy configuration
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gkotton committed Mar 7, 2014
1 parent aeda1f6 commit 26bf8c0
Show file tree
Hide file tree
Showing 18 changed files with 62 additions and 19 deletions.
Expand Up @@ -2,7 +2,7 @@
"server_group": {
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
@@ -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/>
Expand Down
Expand Up @@ -3,7 +3,7 @@
{
"id": "616fb98f-46ca-475e-917e-2563e5a8cd19",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
Expand Up @@ -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/>
Expand Down
@@ -1,6 +1,6 @@
{
"server_group": {
"name": "test",
"policies": ["test_policy"]
"policies": ["anti-affinity"]
}
}
@@ -1,5 +1,5 @@
<server_group name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
</server_group>
Expand Up @@ -2,7 +2,7 @@
"server_group": {
"id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
@@ -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/>
Expand Down
27 changes: 27 additions & 0 deletions nova/api/openstack/compute/contrib/server_groups.py
Expand Up @@ -29,6 +29,7 @@
from nova import utils

LOG = logging.getLogger(__name__)
SUPPORTED_POLICIES = ['anti-affinity', 'affinity']

authorize = extensions.extension_authorizer('compute', 'server_groups')

Expand Down Expand Up @@ -153,13 +154,39 @@ def _format_server_group(self, context, group):
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.")
raise nova.exception.InvalidInput(reason=msg)

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)
Expand Down
22 changes: 19 additions & 3 deletions nova/tests/api/openstack/compute/contrib/test_server_groups.py
Expand Up @@ -96,7 +96,7 @@ def test_create_server_group_with_no_policies(self):
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')
Expand All @@ -122,6 +122,22 @@ def test_create_server_group_with_illegal_name(self):
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,
Expand All @@ -135,7 +151,7 @@ def test_create_server_group_with_no_server_group(self):

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']
Expand Down Expand Up @@ -165,7 +181,7 @@ def return_server_groups(context, project_id):
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']
Expand Down
Expand Up @@ -2,7 +2,7 @@
"server_group": {
"id": "%(id)s",
"name": "%(name)s",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
@@ -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/>
Expand Down
Expand Up @@ -3,7 +3,7 @@
{
"id": "%(id)s",
"name": "test",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
Expand Up @@ -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/>
Expand Down
@@ -1,6 +1,6 @@
{
"server_group": {
"name": "%(name)s",
"policies": ["test_policy"]
"policies": ["anti-affinity"]
}
}
@@ -1,5 +1,5 @@
<server_group name="test">
<policies>
<policy>test_policy</policy>
<policy>anti-affinity</policy>
</policies>
</server_group>
Expand Up @@ -2,7 +2,7 @@
"server_group": {
"id": "%(id)s",
"name": "%(name)s",
"policies": ["test_policy"],
"policies": ["anti-affinity"],
"members": [],
"metadata": {}
}
Expand Down
@@ -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/>
Expand Down

0 comments on commit 26bf8c0

Please sign in to comment.