Merge "Add force option"

This commit is contained in:
Zuul
2019-05-30 02:06:14 +00:00
committed by Gerrit Code Review
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_1_START_END_TIMING = '1.1'
MINOR_2_FORCE_AUDIT = '1.2'
HEADER_NAME = "OpenStack-API-Version" HEADER_NAME = "OpenStack-API-Version"
# key is a deprecated version and value is an alternative version. # key is a deprecated version and value is an alternative version.
DEPRECATED_VERSIONS = {} DEPRECATED_VERSIONS = {}
@@ -44,6 +45,15 @@ def allow_start_end_audit_time(requested_version):
APIVersion(MINOR_1_START_END_TIMING)) 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): class APIVersion(object):
"""This class represents an API Version Request. """This class represents an API Version Request.

View File

@@ -38,13 +38,10 @@ from watcherclient.common import api_versioning
from watcherclient import exceptions from watcherclient import exceptions
# NOTE(deva): Record the latest version that this client was tested with. # 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.
DEFAULT_VER = '1.latest' 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) LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

@@ -474,3 +474,191 @@ class AuditShellTestv11(AuditShellTest):
audit.update(v11) audit.update(v11)
self.FIELDS.extend(['start_time', 'end_time']) self.FIELDS.extend(['start_time', 'end_time'])
self.FIELD_LABELS.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', CREATION_ATTRIBUTES = ['audit_template_uuid', 'audit_type', 'interval',
'parameters', 'goal', 'strategy', 'auto_trigger', 'parameters', 'goal', 'strategy', 'auto_trigger',
'name', 'start_time', 'end_time'] 'name', 'start_time', 'end_time', 'force']
class Audit(base.Resource): class Audit(base.Resource):

View File

@@ -26,7 +26,7 @@ from watcherclient import exceptions
from watcherclient.v1 import resource_fields as res_fields 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) fields = copy.copy(fields)
field_labels = copy.copy(field_labels) field_labels = copy.copy(field_labels)
api_ver = app_args.os_infra_optim_api_version 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')): ('Start Time', 'End Time')):
fields.remove(field) fields.remove(field)
field_labels.remove(label) field_labels.remove(label)
if not api_versioning.launch_audit_forced(api_ver):
fields.remove('force')
field_labels.remove('Force')
return fields, field_labels return fields, field_labels
@@ -62,8 +65,8 @@ class ShowAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns, columns, column_headers = drop_unsupported_field(
column_headers) self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns) 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 field_labels = res_fields.AUDIT_SHORT_LIST_FIELD_LABELS
if parsed_args.detail: if parsed_args.detail:
fields, field_labels = drop_start_end_field(self.app_args, fields, fields, field_labels = drop_unsupported_field(
field_labels) self.app_args, fields, field_labels)
params.update(common_utils.common_params_for_list( params.update(common_utils.common_params_for_list(
parsed_args, fields, field_labels)) parsed_args, fields, field_labels))
@@ -220,6 +223,12 @@ class CreateAudit(command.ShowOne):
metavar='<end_time>', metavar='<end_time>',
help=_('CONTINUOUS audit local end time. ' help=_('CONTINUOUS audit local end time. '
'Format: YYYY-MM-DD hh:mm:ss')) '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 return parser
@@ -236,6 +245,9 @@ class CreateAudit(command.ShowOne):
field_list.append('start_time') field_list.append('start_time')
if parsed_args.end_time is not None: if parsed_args.end_time is not None:
field_list.append('end_time') 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() fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and v is not None) if k in field_list and v is not None)
@@ -252,8 +264,8 @@ class CreateAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns, columns, column_headers = drop_unsupported_field(
column_headers) self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns) return column_headers, utils.get_item_properties(audit, columns)
@@ -295,8 +307,8 @@ class UpdateAudit(command.ShowOne):
columns = res_fields.AUDIT_FIELDS columns = res_fields.AUDIT_FIELDS
column_headers = res_fields.AUDIT_FIELD_LABELS column_headers = res_fields.AUDIT_FIELD_LABELS
columns, column_headers = drop_start_end_field(self.app_args, columns, columns, column_headers = drop_unsupported_field(
column_headers) self.app_args, columns, column_headers)
return column_headers, utils.get_item_properties(audit, columns) 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', AUDIT_FIELDS = ['uuid', 'name', 'created_at', 'updated_at', 'deleted_at',
'state', 'audit_type', 'parameters', 'interval', 'goal_name', 'state', 'audit_type', 'parameters', 'interval', 'goal_name',
'strategy_name', 'scope', 'auto_trigger', 'next_run_time', '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', AUDIT_FIELD_LABELS = ['UUID', 'Name', 'Created At', 'Updated At', 'Deleted At',
'State', 'Audit Type', 'Parameters', 'Interval', 'Goal', 'State', 'Audit Type', 'Parameters', 'Interval', 'Goal',
'Strategy', 'Audit Scope', 'Auto Trigger', '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', AUDIT_SHORT_LIST_FIELDS = ['uuid', 'name', 'audit_type',
'state', 'goal_name', 'strategy_name', 'state', 'goal_name', 'strategy_name',