Add strategy_id & goal_id fields in audit template

In this changeset, I updated the 'goal_id' field into the AuditTemplate
to now become a mandatory foreign key towards the Goal model. I also
added the 'strategy_id' field into the AuditTemplate model to be an
optional foreign key onto the Strategy model.

This changeset also includes an update of the /audit_template
Watcher API endpoint to reflect the previous changes.

As this changeset changes the API, this should be merged alongside the
related changeset from python-watcherclient.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Ic0573d036d1bbd7820f8eb963e47912d6b3ed1a9
This commit is contained in:
Vincent Françoise
2016-04-13 10:32:47 +02:00
parent e67b532110
commit 2966b93777
20 changed files with 614 additions and 341 deletions

View File

@@ -61,8 +61,10 @@ class InfraOptimClientJSON(base.BaseInfraOptimClient):
:param name: The name of the audit template. Default: My Audit Template
:param description: The description of the audit template.
Default: AT Description
:param goal: The goal associated within the audit template.
Default: DUMMY
:param goal_uuid: The related Goal UUID associated.
Default: None
:param strategy_uuid: The related Strategy UUID associated.
Default: None
:param host_aggregate: ID of the host aggregate targeted by
this audit template. Default: 1
:param extra: IMetadata associated to this audit template.
@@ -77,8 +79,9 @@ class InfraOptimClientJSON(base.BaseInfraOptimClient):
audit_template = {
'name': parameters.get('name', unique_name),
'description': parameters.get('description', ''),
'goal': parameters.get('goal', 'DUMMY'),
'description': parameters.get('description'),
'goal_uuid': parameters.get('goal_uuid'),
'strategy_uuid': parameters.get('strategy_uuid'),
'host_aggregate': parameters.get('host_aggregate', 1),
'extra': parameters.get('extra', {}),
}

View File

@@ -114,15 +114,18 @@ class BaseInfraOptimTest(test.BaseTestCase):
# ### AUDIT TEMPLATES ### #
@classmethod
def create_audit_template(cls, name=None, description=None, goal=None,
host_aggregate=None, extra=None):
def create_audit_template(cls, goal_uuid, name=None, description=None,
strategy_uuid=None, host_aggregate=None,
extra=None):
"""Wrapper utility for creating a test audit template
:param goal_uuid: The goal UUID related to the audit template.
Default: DUMMY
:param name: The name of the audit template. Default: My Audit Template
:param description: The description of the audit template.
Default: AT Description
:param goal: The goal associated within the audit template.
Default: DUMMY
:param strategy_uuid: The strategy UUID related to the audit template.
Default: dummy
:param host_aggregate: ID of the host aggregate targeted by
this audit template. Default: 1
:param extra: IMetadata associated to this audit template.
@@ -132,8 +135,9 @@ class BaseInfraOptimTest(test.BaseTestCase):
description = description or data_utils.rand_name(
'test-audit_template')
resp, body = cls.client.create_audit_template(
name=name, description=description, goal=goal,
host_aggregate=host_aggregate, extra=extra)
name=name, description=description, goal_uuid=goal_uuid,
strategy_uuid=strategy_uuid, host_aggregate=host_aggregate,
extra=extra)
cls.created_audit_templates.add(body['uuid'])

View File

@@ -30,7 +30,8 @@ class TestShowListAction(base.BaseInfraOptimTest):
@classmethod
def resource_setup(cls):
super(TestShowListAction, cls).resource_setup()
_, cls.audit_template = cls.create_audit_template()
_, cls.goal = cls.client.show_goal("DUMMY")
_, cls.audit_template = cls.create_audit_template(cls.goal['uuid'])
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
assert test.call_until_true(

View File

@@ -29,7 +29,8 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_action_plan(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
@@ -48,7 +49,8 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_delete_action_plan(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
@@ -69,7 +71,8 @@ class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_execute_dummy_action_plan(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
@@ -107,7 +110,8 @@ class TestShowListActionPlan(base.BaseInfraOptimTest):
@classmethod
def resource_setup(cls):
super(TestShowListActionPlan, cls).resource_setup()
_, cls.audit_template = cls.create_audit_template()
_, cls.goal = cls.client.show_goal("DUMMY")
_, cls.audit_template = cls.create_audit_template(cls.goal['uuid'])
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
assert test.call_until_true(

View File

@@ -33,7 +33,8 @@ class TestCreateUpdateDeleteAudit(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_oneshot(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
audit_params = dict(
audit_template_uuid=audit_template['uuid'],
@@ -48,7 +49,8 @@ class TestCreateUpdateDeleteAudit(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_continuous(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
audit_params = dict(
audit_template_uuid=audit_template['uuid'],
@@ -73,7 +75,8 @@ class TestCreateUpdateDeleteAudit(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_with_invalid_state(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
audit_params = dict(
audit_template_uuid=audit_template['uuid'],
@@ -85,7 +88,8 @@ class TestCreateUpdateDeleteAudit(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_with_no_state(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
audit_params = dict(
audit_template_uuid=audit_template['uuid'],
@@ -104,7 +108,8 @@ class TestCreateUpdateDeleteAudit(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_delete_audit(self):
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
_, body = self.create_audit(audit_template['uuid'])
audit_uuid = body['uuid']
@@ -123,7 +128,8 @@ class TestShowListAudit(base.BaseInfraOptimTest):
@classmethod
def resource_setup(cls):
super(TestShowListAudit, cls).resource_setup()
_, cls.audit_template = cls.create_audit_template()
_, cls.goal = cls.client.show_goal("DUMMY")
_, cls.audit_template = cls.create_audit_template(cls.goal['uuid'])
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
def assert_expected(self, expected, actual,

View File

@@ -29,10 +29,12 @@ class TestCreateDeleteAuditTemplate(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_template(self):
_, goal = self.client.show_goal("DUMMY")
params = {'name': 'my at name %s' % uuid.uuid4(),
'description': 'my at description',
'host_aggregate': 12,
'goal': 'DUMMY',
'goal_uuid': goal['uuid'],
'extra': {'str': 'value', 'int': 123, 'float': 0.123,
'bool': True, 'list': [1, 2, 3],
'dict': {'foo': 'bar'}}}
@@ -45,11 +47,13 @@ class TestCreateDeleteAuditTemplate(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_create_audit_template_unicode_description(self):
_, goal = self.client.show_goal("DUMMY")
# Use a unicode string for testing:
params = {'name': 'my at name %s' % uuid.uuid4(),
'description': 'my àt déscrïptïôn',
'host_aggregate': 12,
'goal': 'DUMMY',
'goal_uuid': goal['uuid'],
'extra': {'foo': 'bar'}}
_, body = self.create_audit_template(**params)
@@ -60,7 +64,8 @@ class TestCreateDeleteAuditTemplate(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_delete_audit_template(self):
_, body = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, body = self.create_audit_template(goal_uuid=goal['uuid'])
audit_uuid = body['uuid']
self.delete_audit_template(audit_uuid)
@@ -75,7 +80,10 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
@classmethod
def resource_setup(cls):
super(TestAuditTemplate, cls).resource_setup()
_, cls.audit_template = cls.create_audit_template()
_, cls.goal = cls.client.show_goal("DUMMY")
_, cls.strategy = cls.client.show_strategy("dummy")
_, cls.audit_template = cls.create_audit_template(
goal_uuid=cls.goal['uuid'], strategy_uuid=cls.strategy['uuid'])
@test.attr(type='smoke')
def test_show_audit_template(self):
@@ -85,9 +93,18 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
self.assert_expected(self.audit_template, audit_template)
@test.attr(type='smoke')
def test_filter_audit_template_by_goal(self):
def test_filter_audit_template_by_goal_uuid(self):
_, audit_templates = self.client.list_audit_templates(
goal=self.audit_template['goal'])
goal_uuid=self.audit_template['goal_uuid'])
audit_template_uuids = [
at["uuid"] for at in audit_templates['audit_templates']]
self.assertIn(self.audit_template['uuid'], audit_template_uuids)
@test.attr(type='smoke')
def test_filter_audit_template_by_strategy_uuid(self):
_, audit_templates = self.client.list_audit_templates(
strategy_uuid=self.audit_template['strategy_uuid'])
audit_template_uuids = [
at["uuid"] for at in audit_templates['audit_templates']]
@@ -116,7 +133,7 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
def test_list_with_limit(self):
# We create 3 extra audit templates to exceed the limit we fix
for _ in range(3):
self.create_audit_template()
self.create_audit_template(self.goal['uuid'])
_, body = self.client.list_audit_templates(limit=3)
@@ -126,10 +143,13 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
@test.attr(type='smoke')
def test_update_audit_template_replace(self):
_, new_goal = self.client.show_goal("SERVER_CONSOLIDATION")
_, new_strategy = self.client.show_strategy("basic")
params = {'name': 'my at name %s' % uuid.uuid4(),
'description': 'my at description',
'host_aggregate': 12,
'goal': 'DUMMY',
'goal_uuid': self.goal['uuid'],
'extra': {'key1': 'value1', 'key2': 'value2'}}
_, body = self.create_audit_template(**params)
@@ -137,7 +157,6 @@ 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 = 'SERVER_CONSOLIDATION'
new_extra = {'key1': 'new-value1', 'key2': 'new-value2'}
patch = [{'path': '/name',
@@ -149,9 +168,12 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
{'path': '/host_aggregate',
'op': 'replace',
'value': new_host_aggregate},
{'path': '/goal',
{'path': '/goal_uuid',
'op': 'replace',
'value': new_goal},
'value': new_goal['uuid']},
{'path': '/strategy_uuid',
'op': 'replace',
'value': new_strategy['uuid']},
{'path': '/extra/key1',
'op': 'replace',
'value': new_extra['key1']},
@@ -165,19 +187,19 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
self.assertEqual(new_name, body['name'])
self.assertEqual(new_description, body['description'])
self.assertEqual(new_host_aggregate, body['host_aggregate'])
self.assertEqual(new_goal, body['goal'])
self.assertEqual(new_goal['uuid'], body['goal_uuid'])
self.assertEqual(new_strategy['uuid'], body['strategy_uuid'])
self.assertEqual(new_extra, body['extra'])
@test.attr(type='smoke')
def test_update_audit_template_remove(self):
extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
description = 'my at description'
goal = 'DUMMY'
name = 'my at name %s' % uuid.uuid4()
params = {'name': name,
'description': description,
'host_aggregate': 12,
'goal': goal,
'goal_uuid': self.goal['uuid'],
'extra': extra}
_, audit_template = self.create_audit_template(**params)
@@ -208,14 +230,14 @@ class TestAuditTemplate(base.BaseInfraOptimTest):
# Assert nothing else was changed
self.assertEqual(name, body['name'])
self.assertEqual(description, body['description'])
self.assertEqual(goal, body['goal'])
self.assertEqual(self.goal['uuid'], body['goal_uuid'])
@test.attr(type='smoke')
def test_update_audit_template_add(self):
params = {'name': 'my at name %s' % uuid.uuid4(),
'description': 'my at description',
'host_aggregate': 12,
'goal': 'DUMMY'}
'goal_uuid': self.goal['uuid']}
_, body = self.create_audit_template(**params)

View File

@@ -73,27 +73,30 @@ class BaseInfraOptimScenarioTest(manager.ScenarioTest):
# ### AUDIT TEMPLATES ### #
def create_audit_template(self, name=None, description=None, goal=None,
host_aggregate=None, extra=None):
def create_audit_template(self, goal_uuid, name=None, description=None,
strategy_uuid=None, host_aggregate=None,
extra=None):
"""Wrapper utility for creating a test audit template
:param goal_uuid: The goal UUID related to the audit template.
Default: DUMMY
:param name: The name of the audit template. Default: My Audit Template
:param description: The description of the audit template.
Default: AT Description
:param goal: The goal associated within the audit template.
Default: DUMMY
:param strategy_uuid: The strategy UUID related to the audit template.
Default: dummy
:param host_aggregate: ID of the host aggregate targeted by
this audit template. Default: 1
:param extra: IMetadata associated to this audit template.
Default: {}
:return: A tuple with The HTTP response and its body
"""
description = description or data_utils.rand_name(
'test-audit_template')
resp, body = self.client.create_audit_template(
name=name, description=description, goal=goal,
host_aggregate=host_aggregate, extra=extra)
name=name, description=description, goal_uuid=goal_uuid,
strategy_uuid=strategy_uuid, host_aggregate=host_aggregate,
extra=extra)
self.addCleanup(
self.delete_audit_template,

View File

@@ -108,8 +108,8 @@ class TestExecuteBasicStrategy(base.BaseInfraOptimScenarioTest):
"""
self.addCleanup(self.rollback_compute_nodes_status)
self._create_one_instance_per_host()
_, audit_template = self.create_audit_template(goal=self.BASIC_GOAL)
_, goal = self.client.show_goal(self.BASIC_GOAL)
_, audit_template = self.create_audit_template(goal['uuid'])
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(

View File

@@ -37,7 +37,8 @@ class TestExecuteDummyStrategy(base.BaseInfraOptimScenarioTest):
- run the action plan
- get results and make sure it succeeded
"""
_, audit_template = self.create_audit_template()
_, goal = self.client.show_goal("DUMMY")
_, audit_template = self.create_audit_template(goal['uuid'])
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(