Refactored check for invalid goal

When creating a new audit template, the verification of its goal
existence was previously done in watcher/objects/audit_template.py.
This check was moved to api/controllers/v1/audit_template.py, rather
than in the DAO class.

Change-Id: I6efb0657f64c46a56914a946ec78013b9e47331b
Closes-Bug: #1536191
This commit is contained in:
Larry Rensing
2016-02-15 09:52:59 -06:00
parent 083b170083
commit 920bd502ec
4 changed files with 45 additions and 10 deletions

View File

@@ -50,6 +50,7 @@ provided as a list of key-value pairs.
import datetime
from oslo_config import cfg
import pecan
from pecan import rest
import wsme
@@ -67,11 +68,25 @@ from watcher import objects
class AuditTemplatePatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return []
@staticmethod
def validate(patch):
if patch.path == "/goal":
AuditTemplatePatchType._validate_goal(patch)
return types.JsonPatchType.validate(patch)
@staticmethod
def _validate_goal(patch):
serialized_patch = {'path': patch.path, 'op': patch.op}
if patch.value is not wsme.Unset:
serialized_patch['value'] = patch.value
new_goal = patch.value
if new_goal and new_goal not in cfg.CONF.watcher_goals.goals.keys():
raise exception.InvalidGoal(goal=new_goal)
class AuditTemplate(base.APIBase):
"""API representation of a audit template.
@@ -156,6 +171,12 @@ class AuditTemplate(base.APIBase):
updated_at=datetime.datetime.utcnow())
return cls._convert_with_links(sample, 'http://localhost:9322', expand)
@staticmethod
def validate(audit_template):
if audit_template.goal not in cfg.CONF.watcher_goals.goals.keys():
raise exception.InvalidGoal(audit_template.goal)
return audit_template
class AuditTemplateCollection(collection.Collection):
"""API representation of a collection of audit templates."""
@@ -287,12 +308,14 @@ class AuditTemplatesController(rest.RestController):
return AuditTemplate.convert_with_links(rpc_audit_template)
@wsme.validate(types.uuid, AuditTemplate)
@wsme_pecan.wsexpose(AuditTemplate, body=AuditTemplate, status_code=201)
def post(self, audit_template):
"""Create a new audit template.
:param audit template: a audit template within the request body.
"""
if self.from_audit_templates:
raise exception.OperationNotPermitted

View File

@@ -47,7 +47,6 @@ contain a list of extra parameters related to the
provided as a list of key-value pairs.
"""
from oslo_config import cfg
from watcher.common import exception
from watcher.common import utils
from watcher.db import api as dbapi
@@ -204,9 +203,6 @@ class AuditTemplate(base.WatcherObject):
"""
values = self.obj_get_changes()
goal = values['goal']
if goal not in cfg.CONF.watcher_goals.goals.keys():
raise exception.InvalidGoal(goal=goal)
db_audit_template = self.dbapi.create_audit_template(values)
self._from_db_object(self, db_audit_template)

View File

@@ -237,6 +237,8 @@ class TestPatch(api_base.FunctionalTest):
self.mock_audit_template_update = p.start()
self.mock_audit_template_update.side_effect = \
self._simulate_rpc_audit_template_update
cfg.CONF.set_override('goals', {"DUMMY": "DUMMY", "BASIC": "BASIC"},
group='watcher_goals', enforce_type=True)
self.addCleanup(p.stop)
def _simulate_rpc_audit_template_update(self, audit_template):
@@ -248,7 +250,7 @@ class TestPatch(api_base.FunctionalTest):
test_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = test_time
new_goal = 'BALANCE_LOAD'
new_goal = "BASIC"
response = self.get_json(
'/audit_templates/%s' % self.audit_template.uuid)
self.assertNotEqual(new_goal, response['goal'])
@@ -272,7 +274,7 @@ class TestPatch(api_base.FunctionalTest):
test_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = test_time
new_goal = 'BALANCE_LOAD'
new_goal = 'BASIC'
response = self.get_json(urlparse.quote(
'/audit_templates/%s' % self.audit_template.name))
self.assertNotEqual(new_goal, response['goal'])
@@ -294,15 +296,29 @@ class TestPatch(api_base.FunctionalTest):
def test_replace_non_existent_audit_template(self):
response = self.patch_json(
'/audit_templates/%s' % utils.generate_uuid(),
[{'path': '/goal', 'value': 'BALANCE_LOAD',
[{'path': '/goal', 'value': 'DUMMY',
'op': 'replace'}],
expect_errors=True)
self.assertEqual(404, response.status_int)
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
def test_replace_invalid_goal(self):
with mock.patch.object(
self.dbapi,
'update_audit_template',
wraps=self.dbapi.update_audit_template
) as cn_mock:
response = self.patch_json(
'/audit_templates/%s' % self.audit_template.uuid,
[{'path': '/goal', 'value': 'INVALID_GOAL',
'op': 'replace'}],
expect_errors=True)
self.assertEqual(400, response.status_int)
assert not cn_mock.called
def test_add_ok(self):
new_goal = 'BALANCE_LOAD'
new_goal = 'DUMMY'
response = self.patch_json(
'/audit_templates/%s' % self.audit_template.uuid,
[{'path': '/goal', 'value': new_goal, 'op': 'add'}])

View File

@@ -137,7 +137,7 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
new_name = 'my at new name %s' % uuid.uuid4()
new_description = 'my new at description'
new_host_aggregate = 10
new_goal = 'A NEW GOAL'
new_goal = 'BASIC_CONSOLIDATION'
new_extra = {'key1': 'new-value1', 'key2': 'new-value2'}
patch = [{'path': '/name',