Audit API supports new force option
Depends-on:Ia08694d2fb76907ea14e64116af2e722fe930063 Change-Id: Ib2d221ea9c994dea396c54cc8d2d32237025a1d4 Implements: blueprint add-force-field-to-audit
This commit is contained in:
parent
3b9364d4c7
commit
2afd0dfcf5
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Add force field to Audit. User can set --force to enable the new option when
|
||||
launching audit. If force is True, audit will be executed despite of ongoing
|
||||
actionplan. The new audit may create a wrong actionplan if they use the same
|
||||
data model.
|
|
@ -73,6 +73,8 @@ def hide_fields_in_newer_versions(obj):
|
|||
if not api_utils.allow_start_end_audit_time():
|
||||
obj.start_time = wtypes.Unset
|
||||
obj.end_time = wtypes.Unset
|
||||
if not api_utils.allow_force():
|
||||
obj.force = wtypes.Unset
|
||||
|
||||
|
||||
class AuditPostType(wtypes.Base):
|
||||
|
@ -194,7 +196,8 @@ class AuditPostType(wtypes.Base):
|
|||
scope=self.scope,
|
||||
auto_trigger=self.auto_trigger,
|
||||
start_time=self.start_time,
|
||||
end_time=self.end_time)
|
||||
end_time=self.end_time,
|
||||
force=self.force)
|
||||
|
||||
|
||||
class AuditPatchType(types.JsonPatchType):
|
||||
|
|
|
@ -165,3 +165,12 @@ def allow_start_end_audit_time():
|
|||
audits.
|
||||
"""
|
||||
return pecan.request.version.minor >= versions.MINOR_1_START_END_TIMING
|
||||
|
||||
|
||||
def allow_force():
|
||||
"""Check if we should support optional force attribute for Audit.
|
||||
|
||||
Version 1.2 of the API added support for forced audits that allows to
|
||||
launch audit when other action plan is ongoing.
|
||||
"""
|
||||
return pecan.request.version.minor >= versions.MINOR_2_FORCE
|
||||
|
|
|
@ -22,11 +22,13 @@ BASE_VERSION = 1
|
|||
#
|
||||
# v1.0: corresponds to Rocky API
|
||||
# v1.1: Add start/end time for continuous audit
|
||||
# v1.2: Add force field to audit
|
||||
|
||||
MINOR_0_ROCKY = 0
|
||||
MINOR_1_START_END_TIMING = 1
|
||||
MINOR_2_FORCE = 2
|
||||
|
||||
MINOR_MAX_VERSION = MINOR_1_START_END_TIMING
|
||||
MINOR_MAX_VERSION = MINOR_2_FORCE
|
||||
|
||||
# String representations of the minor and maximum versions
|
||||
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_0_ROCKY)
|
||||
|
|
|
@ -121,7 +121,10 @@ class AuditHandler(BaseAuditHandler):
|
|||
|
||||
def pre_execute(self, audit, request_context):
|
||||
LOG.debug("Trigger audit %s", audit.uuid)
|
||||
self.check_ongoing_action_plans(request_context)
|
||||
# If audit.force is true, audit will be executed
|
||||
# despite of ongoing actionplan
|
||||
if not audit.force:
|
||||
self.check_ongoing_action_plans(request_context)
|
||||
# Write hostname that will execute this audit.
|
||||
audit.hostname = CONF.host
|
||||
# change state of the audit to ONGOING
|
||||
|
|
|
@ -950,6 +950,39 @@ class TestPost(api_base.FunctionalTest):
|
|||
self.assertIn(expected_error_msg, response.json['error_message'])
|
||||
assert not mock_trigger_audit.called
|
||||
|
||||
@mock.patch.object(deapi.DecisionEngineAPI, 'trigger_audit')
|
||||
def test_create_audit_with_force_false(self, mock_trigger_audit):
|
||||
mock_trigger_audit.return_value = mock.ANY
|
||||
|
||||
audit_dict = post_get_test_audit(
|
||||
params_to_exclude=['uuid', 'state', 'interval', 'scope',
|
||||
'next_run_time', 'hostname', 'goal'])
|
||||
|
||||
response = self.post_json(
|
||||
'/audits',
|
||||
audit_dict,
|
||||
headers={'OpenStack-API-Version': 'infra-optim 1.2'})
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertFalse(response.json['force'])
|
||||
|
||||
@mock.patch.object(deapi.DecisionEngineAPI, 'trigger_audit')
|
||||
def test_create_audit_with_force_true(self, mock_trigger_audit):
|
||||
mock_trigger_audit.return_value = mock.ANY
|
||||
|
||||
audit_dict = post_get_test_audit(
|
||||
params_to_exclude=['uuid', 'state', 'interval', 'scope',
|
||||
'next_run_time', 'hostname', 'goal'])
|
||||
|
||||
audit_dict['force'] = True
|
||||
response = self.post_json(
|
||||
'/audits',
|
||||
audit_dict,
|
||||
headers={'OpenStack-API-Version': 'infra-optim 1.2'})
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertTrue(response.json['force'])
|
||||
|
||||
|
||||
class TestDelete(api_base.FunctionalTest):
|
||||
|
||||
|
|
|
@ -227,6 +227,13 @@ class TestAutoTriggerActionPlan(base.DbTestCase):
|
|||
mock_applier.assert_called_once_with(self.context,
|
||||
self.recommended_action_plan.uuid)
|
||||
|
||||
@mock.patch.object(oneshot.OneShotAuditHandler, 'do_execute')
|
||||
def test_trigger_audit_with_force(self, mock_do_execute):
|
||||
audit_handler = oneshot.OneShotAuditHandler()
|
||||
self.audit.force = True
|
||||
audit_handler.execute(self.audit, self.context)
|
||||
self.assertTrue(mock_do_execute.called)
|
||||
|
||||
|
||||
class TestContinuousAuditHandler(base.DbTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue