Add force option

Partially Implements: blueprint add-force-field-to-audit
Depends-on: Ib2d221ea9c994dea396c54cc8d2d32237025a1d4

Change-Id: I235bbd298b7fa8ad9d8b01a94d68376c8ac27e8d
This commit is contained in:
licanwei
2019-05-06 19:35:49 +08:00
committed by chenker
parent f062e60990
commit cde518be31
6 changed files with 226 additions and 18 deletions

View File

@@ -27,6 +27,7 @@ if not LOG.handlers:
MINOR_1_START_END_TIMING = '1.1'
MINOR_2_FORCE_AUDIT = '1.2'
HEADER_NAME = "OpenStack-API-Version"
# key is a deprecated version and value is an alternative version.
DEPRECATED_VERSIONS = {}
@@ -44,6 +45,15 @@ def allow_start_end_audit_time(requested_version):
APIVersion(MINOR_1_START_END_TIMING))
def launch_audit_forced(requested_version):
"""Check if we should support force option for Audit.
Version 1.2 of the API added support for force option.
"""
return (APIVersion(requested_version) >=
APIVersion(MINOR_2_FORCE_AUDIT))
class APIVersion(object):
"""This class represents an API Version Request.

View File

@@ -38,13 +38,10 @@ from watcherclient.common import api_versioning
from watcherclient import exceptions
# NOTE(deva): Record the latest version that this client was tested with.
# We still have a lot of work to do in the client to implement
# microversion support in the client properly! See
# http://specs.openstack.org/openstack/watcher-specs/specs/kilo/api-microversions.html # noqa
# for full details.
# Record the latest version that this client was tested with.
DEFAULT_VER = '1.latest'
LAST_KNOWN_API_VERSION = 1
# Minor version 2 for adding force option to audit
LAST_KNOWN_API_VERSION = 2
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
LOG = logging.getLogger(__name__)

View File

@@ -474,3 +474,191 @@ class AuditShellTestv11(AuditShellTest):
audit.update(v11)
self.FIELDS.extend(['start_time', 'end_time'])
self.FIELD_LABELS.extend(['Start Time', 'End Time'])
class AuditShellTestv12(AuditShellTest):
def setUp(self):
super(AuditShellTestv12, self).setUp(os_infra_optim_api_version='1.2')
v11 = dict(start_time=None, end_time=None)
v12 = dict(force=False)
for audit in (self.AUDIT_1, self.AUDIT_2, self.AUDIT_3):
audit.update(v11)
audit.update(v12)
self.FIELDS.extend(['start_time', 'end_time', 'force'])
self.FIELD_LABELS.extend(['Start Time', 'End Time', 'Force'])
def test_do_audit_create_with_force(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_3)
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
self.m_audit_template_mgr.get.return_value = audit_template
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -a f8e47706-efcf-49a4-a5c4-af604eb492f2 --force')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
audit_template_uuid='f8e47706-efcf-49a4-a5c4-af604eb492f2',
audit_type='ONESHOT',
auto_trigger=False,
force=True
)
def test_do_audit_create_with_audit_template_uuid(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_3)
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
self.m_audit_template_mgr.get.return_value = audit_template
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -a f8e47706-efcf-49a4-a5c4-af604eb492f2')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
audit_template_uuid='f8e47706-efcf-49a4-a5c4-af604eb492f2',
audit_type='ONESHOT',
auto_trigger=False,
force=False
)
def test_do_audit_create_with_audit_template_name(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_3)
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
self.m_audit_template_mgr.get.return_value = audit_template
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd('audit create -a at1')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
audit_template_uuid='f8e47706-efcf-49a4-a5c4-af604eb492f2',
auto_trigger=False,
audit_type='ONESHOT',
force=False
)
def test_do_audit_create_with_goal(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
auto_trigger=False,
audit_type='ONESHOT',
force=False
)
def test_do_audit_create_with_goal_and_strategy(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 -s '
'2cf86250-d309-4b81-818e-1537f3dba6e5')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
strategy='2cf86250-d309-4b81-818e-1537f3dba6e5',
auto_trigger=False,
audit_type='ONESHOT',
force=False
)
def test_do_audit_create_with_type(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 -t ONESHOT')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
auto_trigger=False,
audit_type='ONESHOT',
force=False
)
def test_do_audit_create_with_parameter(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 -p para1=10 '
'-p para2=20')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='ONESHOT',
auto_trigger=False,
parameters={'para1': 10, 'para2': 20},
force=False
)
def test_do_audit_create_with_type_continuous(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 '
'-t CONTINUOUS -i 3600')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='CONTINUOUS',
auto_trigger=False,
interval='3600',
force=False
)
def test_do_audit_create_with_name(self):
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 '
'-t CONTINUOUS -i 3600 --name my_audit')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='CONTINUOUS',
auto_trigger=False,
interval='3600',
name='my_audit',
force=False
)

View File

@@ -20,7 +20,7 @@ from watcherclient import exceptions as exc
CREATION_ATTRIBUTES = ['audit_template_uuid', 'audit_type', 'interval',
'parameters', 'goal', 'strategy', 'auto_trigger',
'name', 'start_time', 'end_time']
'name', 'start_time', 'end_time', 'force']
class Audit(base.Resource):

View File

@@ -26,7 +26,7 @@ from watcherclient import exceptions
from watcherclient.v1 import resource_fields as res_fields
def drop_start_end_field(app_args, fields, field_labels):
def drop_unsupported_field(app_args, fields, field_labels):
fields = copy.copy(fields)
field_labels = copy.copy(field_labels)
api_ver = app_args.os_infra_optim_api_version
@@ -35,6 +35,9 @@ def drop_start_end_field(app_args, fields, field_labels):
('Start Time', 'End Time')):
fields.remove(field)
field_labels.remove(label)
if not api_versioning.launch_audit_forced(api_ver):
fields.remove('force')
field_labels.remove('Force')
return fields, field_labels
@@ -62,8 +65,8 @@ class ShowAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns,
column_headers)
columns, column_headers = drop_unsupported_field(
self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns)
@@ -136,8 +139,8 @@ class ListAudit(command.Lister):
field_labels = res_fields.AUDIT_SHORT_LIST_FIELD_LABELS
if parsed_args.detail:
fields, field_labels = drop_start_end_field(self.app_args, fields,
field_labels)
fields, field_labels = drop_unsupported_field(
self.app_args, fields, field_labels)
params.update(common_utils.common_params_for_list(
parsed_args, fields, field_labels))
@@ -220,6 +223,12 @@ class CreateAudit(command.ShowOne):
metavar='<end_time>',
help=_('CONTINUOUS audit local end time. '
'Format: YYYY-MM-DD hh:mm:ss'))
parser.add_argument(
'--force',
dest='force',
action='store_true',
help=_('Launch audit even if action plan '
'is ongoing. default is False'))
return parser
@@ -236,6 +245,9 @@ class CreateAudit(command.ShowOne):
field_list.append('start_time')
if parsed_args.end_time is not None:
field_list.append('end_time')
if api_versioning.launch_audit_forced(api_ver):
if parsed_args.force is not None:
field_list.append('force')
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and v is not None)
@@ -252,8 +264,8 @@ class CreateAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns,
column_headers)
columns, column_headers = drop_unsupported_field(
self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns)
@@ -295,8 +307,8 @@ class UpdateAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns,
column_headers)
columns, column_headers = drop_unsupported_field(
self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns)

View File

@@ -33,12 +33,13 @@ AUDIT_TEMPLATE_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Goal', 'Strategy']
AUDIT_FIELDS = ['uuid', 'name', 'created_at', 'updated_at', 'deleted_at',
'state', 'audit_type', 'parameters', 'interval', 'goal_name',
'strategy_name', 'scope', 'auto_trigger', 'next_run_time',
'hostname', 'start_time', 'end_time']
'hostname', 'start_time', 'end_time', 'force']
AUDIT_FIELD_LABELS = ['UUID', 'Name', 'Created At', 'Updated At', 'Deleted At',
'State', 'Audit Type', 'Parameters', 'Interval', 'Goal',
'Strategy', 'Audit Scope', 'Auto Trigger',
'Next Run Time', 'Hostname', 'Start Time', 'End Time']
'Next Run Time', 'Hostname', 'Start Time', 'End Time',
'Force']
AUDIT_SHORT_LIST_FIELDS = ['uuid', 'name', 'audit_type',
'state', 'goal_name', 'strategy_name',