add start and end time for continuous audit
Add new start_time and end_time fields when audit create Partially Implements: blueprint add-start-end-time-for-continuous-audit Change-Id: I37d1bd13649dfb92ce7526f04b25054ed088c4f2
This commit is contained in:
parent
8c89b3327b
commit
69f0493968
watcherclient
@ -17,6 +17,7 @@
|
|||||||
import pbr.version
|
import pbr.version
|
||||||
|
|
||||||
from watcherclient import client
|
from watcherclient import client
|
||||||
|
from watcherclient.common import api_versioning
|
||||||
from watcherclient import exceptions
|
from watcherclient import exceptions
|
||||||
|
|
||||||
|
|
||||||
@ -24,3 +25,11 @@ __version__ = pbr.version.VersionInfo(
|
|||||||
'python-watcherclient').version_string()
|
'python-watcherclient').version_string()
|
||||||
|
|
||||||
__all__ = ['client', 'exceptions', ]
|
__all__ = ['client', 'exceptions', ]
|
||||||
|
|
||||||
|
API_MIN_VERSION = api_versioning.APIVersion("1.0")
|
||||||
|
# The max version should be the latest version that is supported in the client,
|
||||||
|
# not necessarily the latest that the server can provide. This is only bumped
|
||||||
|
# when client supported the max version, and bumped sequentially, otherwise
|
||||||
|
# the client may break due to server side new version may include some
|
||||||
|
# backward incompatible change.
|
||||||
|
API_MAX_VERSION = api_versioning.APIVersion("1.1")
|
||||||
|
@ -19,6 +19,7 @@ import re
|
|||||||
from oslo_utils import strutils
|
from oslo_utils import strutils
|
||||||
|
|
||||||
from watcherclient._i18n import _
|
from watcherclient._i18n import _
|
||||||
|
from watcherclient.common import httpclient
|
||||||
from watcherclient import exceptions
|
from watcherclient import exceptions
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -27,13 +28,22 @@ if not LOG.handlers:
|
|||||||
|
|
||||||
|
|
||||||
HEADER_NAME = "OpenStack-API-Version"
|
HEADER_NAME = "OpenStack-API-Version"
|
||||||
SERVICE_TYPE = "infra-optim"
|
|
||||||
# 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 = {}
|
||||||
|
|
||||||
_type_error_msg = _("'%(other)s' should be an instance of '%(cls)s'")
|
_type_error_msg = _("'%(other)s' should be an instance of '%(cls)s'")
|
||||||
|
|
||||||
|
|
||||||
|
def allow_start_end_audit_time(requested_version):
|
||||||
|
"""Check if we should support optional start/end attributes for Audit.
|
||||||
|
|
||||||
|
Version 1.1 of the API added support for start and end time of continuous
|
||||||
|
audits.
|
||||||
|
"""
|
||||||
|
return (APIVersion(requested_version) >=
|
||||||
|
APIVersion(httpclient.MINOR_1_START_END_TIMING))
|
||||||
|
|
||||||
|
|
||||||
class APIVersion(object):
|
class APIVersion(object):
|
||||||
"""This class represents an API Version Request.
|
"""This class represents an API Version Request.
|
||||||
|
|
||||||
|
@ -43,7 +43,9 @@ from watcherclient import exceptions
|
|||||||
# http://specs.openstack.org/openstack/watcher-specs/specs/kilo/api-microversions.html # noqa
|
# http://specs.openstack.org/openstack/watcher-specs/specs/kilo/api-microversions.html # noqa
|
||||||
# for full details.
|
# for full details.
|
||||||
DEFAULT_VER = 'latest'
|
DEFAULT_VER = 'latest'
|
||||||
|
MINOR_1_START_END_TIMING = '1.1'
|
||||||
|
LAST_KNOWN_API_VERSION = 1
|
||||||
|
LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION)
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
USER_AGENT = 'python-watcherclient'
|
USER_AGENT = 'python-watcherclient'
|
||||||
@ -138,9 +140,9 @@ class VersionNegotiationMixin(object):
|
|||||||
return negotiated_ver
|
return negotiated_ver
|
||||||
|
|
||||||
def _generic_parse_version_headers(self, accessor_func):
|
def _generic_parse_version_headers(self, accessor_func):
|
||||||
min_ver = accessor_func('X-OpenStack-Watcher-API-Minimum-Version',
|
min_ver = accessor_func('OpenStack-API-Minimum-Version',
|
||||||
None)
|
None)
|
||||||
max_ver = accessor_func('X-OpenStack-Watcher-API-Maximum-Version',
|
max_ver = accessor_func('OpenStack-API-Maximum-Version',
|
||||||
None)
|
None)
|
||||||
return min_ver, max_ver
|
return min_ver, max_ver
|
||||||
|
|
||||||
@ -296,8 +298,9 @@ class HTTPClient(VersionNegotiationMixin):
|
|||||||
kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
|
kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
|
||||||
kwargs['headers'].setdefault('User-Agent', USER_AGENT)
|
kwargs['headers'].setdefault('User-Agent', USER_AGENT)
|
||||||
if self.os_watcher_api_version:
|
if self.os_watcher_api_version:
|
||||||
kwargs['headers'].setdefault('X-OpenStack-Watcher-API-Version',
|
kwargs['headers'].setdefault(
|
||||||
self.os_watcher_api_version)
|
'OpenStack-API-Version',
|
||||||
|
' '.join(['infra-optim', self.os_watcher_api_version]))
|
||||||
if self.auth_token:
|
if self.auth_token:
|
||||||
kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
|
kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
|
||||||
|
|
||||||
@ -322,8 +325,8 @@ class HTTPClient(VersionNegotiationMixin):
|
|||||||
|
|
||||||
if resp.status_code == http_client.NOT_ACCEPTABLE:
|
if resp.status_code == http_client.NOT_ACCEPTABLE:
|
||||||
negotiated_ver = self.negotiate_version(self.session, resp)
|
negotiated_ver = self.negotiate_version(self.session, resp)
|
||||||
kwargs['headers']['X-OpenStack-Watcher-API-Version'] = (
|
kwargs['headers']['OpenStack-API-Version'] = (
|
||||||
negotiated_ver)
|
' '.join(['infra-optim', negotiated_ver]))
|
||||||
return self._http_request(url, method, **kwargs)
|
return self._http_request(url, method, **kwargs)
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
@ -505,8 +508,10 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if getattr(self, 'os_watcher_api_version', None):
|
if getattr(self, 'os_watcher_api_version', None):
|
||||||
kwargs['headers'].setdefault('X-OpenStack-Watcher-API-Version',
|
kwargs['headers'].setdefault(
|
||||||
self.os_watcher_api_version)
|
'OpenStack-API-Version',
|
||||||
|
' '.join(['infra-optim',
|
||||||
|
self.os_watcher_api_version]))
|
||||||
|
|
||||||
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
|
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
|
||||||
endpoint_filter.setdefault('interface', self.interface)
|
endpoint_filter.setdefault('interface', self.interface)
|
||||||
@ -517,8 +522,8 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter):
|
|||||||
raise_exc=False, **kwargs)
|
raise_exc=False, **kwargs)
|
||||||
if resp.status_code == http_client.NOT_ACCEPTABLE:
|
if resp.status_code == http_client.NOT_ACCEPTABLE:
|
||||||
negotiated_ver = self.negotiate_version(self.session, resp)
|
negotiated_ver = self.negotiate_version(self.session, resp)
|
||||||
kwargs['headers']['X-OpenStack-Watcher-API-Version'] = (
|
kwargs['headers']['OpenStack-API-Version'] = (
|
||||||
negotiated_ver)
|
' '.join(['infra-optim', negotiated_ver]))
|
||||||
return self._http_request(url, method, **kwargs)
|
return self._http_request(url, method, **kwargs)
|
||||||
if resp.status_code >= http_client.BAD_REQUEST:
|
if resp.status_code >= http_client.BAD_REQUEST:
|
||||||
error_json = _extract_error_json(resp.content)
|
error_json = _extract_error_json(resp.content)
|
||||||
|
@ -15,6 +15,10 @@ import logging
|
|||||||
|
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
|
import watcherclient
|
||||||
|
from watcherclient.common import api_versioning
|
||||||
|
from watcherclient import exceptions
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
DEFAULT_API_VERSION = '1'
|
DEFAULT_API_VERSION = '1'
|
||||||
@ -27,9 +31,12 @@ API_VERSIONS = {
|
|||||||
|
|
||||||
def make_client(instance):
|
def make_client(instance):
|
||||||
"""Returns an infra-optim service client."""
|
"""Returns an infra-optim service client."""
|
||||||
|
|
||||||
|
version = api_versioning.APIVersion(instance._api_version[API_NAME])
|
||||||
|
|
||||||
infraoptim_client_class = utils.get_client_class(
|
infraoptim_client_class = utils.get_client_class(
|
||||||
API_NAME,
|
API_NAME,
|
||||||
instance._api_version[API_NAME],
|
version.ver_major,
|
||||||
API_VERSIONS)
|
API_VERSIONS)
|
||||||
LOG.debug('Instantiating infraoptim client: %s', infraoptim_client_class)
|
LOG.debug('Instantiating infraoptim client: %s', infraoptim_client_class)
|
||||||
|
|
||||||
@ -53,3 +60,30 @@ def build_option_parser(parser):
|
|||||||
DEFAULT_API_VERSION +
|
DEFAULT_API_VERSION +
|
||||||
' (Env: OS_INFRA_OPTIM_API_VERSION)'))
|
' (Env: OS_INFRA_OPTIM_API_VERSION)'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def check_api_version(check_version):
|
||||||
|
"""Validate version supplied by user
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
* True if version is OK
|
||||||
|
* False if the version has not been checked and the previous plugin
|
||||||
|
check should be performed
|
||||||
|
* throws an exception if the version is no good
|
||||||
|
"""
|
||||||
|
|
||||||
|
infra_api_version = api_versioning.get_api_version(check_version)
|
||||||
|
|
||||||
|
# Bypass X.latest format microversion
|
||||||
|
if not infra_api_version.is_latest():
|
||||||
|
if infra_api_version > api_versioning.APIVersion("2.0"):
|
||||||
|
if not infra_api_version.matches(
|
||||||
|
watcherclient.API_MIN_VERSION,
|
||||||
|
watcherclient.API_MAX_VERSION,
|
||||||
|
):
|
||||||
|
msg = "versions supported by client: %(min)s - %(max)s" % {
|
||||||
|
"min": watcherclient.API_MIN_VERSION.get_string(),
|
||||||
|
"max": watcherclient.API_MAX_VERSION.get_string(),
|
||||||
|
}
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
return True
|
||||||
|
@ -25,7 +25,7 @@ from watcherclient.tests.unit import utils
|
|||||||
|
|
||||||
class CommandTestCase(utils.BaseTestCase):
|
class CommandTestCase(utils.BaseTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self, os_watcher_api_version='1.0'):
|
||||||
super(CommandTestCase, self).setUp()
|
super(CommandTestCase, self).setUp()
|
||||||
|
|
||||||
self.fake_env = {
|
self.fake_env = {
|
||||||
@ -38,7 +38,7 @@ class CommandTestCase(utils.BaseTestCase):
|
|||||||
'os_username': 'test',
|
'os_username': 'test',
|
||||||
'os_password': 'test',
|
'os_password': 'test',
|
||||||
'timeout': 600,
|
'timeout': 600,
|
||||||
'os_watcher_api_version': '1'}
|
'os_watcher_api_version': os_watcher_api_version}
|
||||||
self.m_env = mock.Mock(
|
self.m_env = mock.Mock(
|
||||||
name='m_env',
|
name='m_env',
|
||||||
side_effect=lambda x, *args, **kwargs: self.fake_env.get(
|
side_effect=lambda x, *args, **kwargs: self.fake_env.get(
|
||||||
|
@ -20,7 +20,6 @@ import six
|
|||||||
from watcherclient import shell
|
from watcherclient import shell
|
||||||
from watcherclient.tests.unit.v1 import base
|
from watcherclient.tests.unit.v1 import base
|
||||||
from watcherclient import v1 as resource
|
from watcherclient import v1 as resource
|
||||||
from watcherclient.v1 import resource_fields
|
|
||||||
|
|
||||||
AUDIT_TEMPLATE_1 = {
|
AUDIT_TEMPLATE_1 = {
|
||||||
'uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
'uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
||||||
@ -52,76 +51,86 @@ STRATEGY_1 = {
|
|||||||
'deleted_at': None,
|
'deleted_at': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
AUDIT_1 = {
|
|
||||||
'uuid': '5869da81-4876-4687-a1ed-12cd64cf53d9',
|
|
||||||
'audit_type': 'ONESHOT',
|
|
||||||
'state': 'PENDING',
|
|
||||||
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
|
||||||
'audit_template_name': 'at1',
|
|
||||||
'goal_name': 'SERVER_CONSOLIDATION',
|
|
||||||
'strategy_name': 'basic',
|
|
||||||
'created_at': datetime.datetime.now().isoformat(),
|
|
||||||
'updated_at': None,
|
|
||||||
'deleted_at': None,
|
|
||||||
'parameters': None,
|
|
||||||
'interval': None,
|
|
||||||
'scope': '',
|
|
||||||
'auto_trigger': False,
|
|
||||||
'next_run_time': None,
|
|
||||||
'name': 'my_audit1',
|
|
||||||
'hostname': '',
|
|
||||||
}
|
|
||||||
|
|
||||||
AUDIT_2 = {
|
|
||||||
'uuid': 'a5199d0e-0702-4613-9234-5ae2af8dafea',
|
|
||||||
'audit_type': 'ONESHOT',
|
|
||||||
'state': 'PENDING',
|
|
||||||
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
|
||||||
'audit_template_name': 'at1',
|
|
||||||
'goal_name': 'fc087747-61be-4aad-8126-b701731ae836',
|
|
||||||
'strategy_name': 'auto',
|
|
||||||
'created_at': datetime.datetime.now().isoformat(),
|
|
||||||
'updated_at': None,
|
|
||||||
'deleted_at': None,
|
|
||||||
'parameters': None,
|
|
||||||
'interval': None,
|
|
||||||
'scope': '',
|
|
||||||
'auto_trigger': False,
|
|
||||||
'next_run_time': None,
|
|
||||||
'name': 'my_audit2',
|
|
||||||
'hostname': '',
|
|
||||||
}
|
|
||||||
|
|
||||||
AUDIT_3 = {
|
|
||||||
'uuid': '43199d0e-0712-1213-9674-5ae2af8dhgte',
|
|
||||||
'audit_type': 'ONESHOT',
|
|
||||||
'state': 'PENDING',
|
|
||||||
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
|
||||||
'audit_template_name': 'at1',
|
|
||||||
'goal_name': None,
|
|
||||||
'strategy_name': 'auto',
|
|
||||||
'created_at': datetime.datetime.now().isoformat(),
|
|
||||||
'updated_at': None,
|
|
||||||
'deleted_at': None,
|
|
||||||
'parameters': None,
|
|
||||||
'interval': 3600,
|
|
||||||
'scope': '',
|
|
||||||
'auto_trigger': True,
|
|
||||||
'next_run_time': None,
|
|
||||||
'name': 'my_audit3',
|
|
||||||
'hostname': '',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AuditShellTest(base.CommandTestCase):
|
class AuditShellTest(base.CommandTestCase):
|
||||||
|
|
||||||
SHORT_LIST_FIELDS = resource_fields.AUDIT_SHORT_LIST_FIELDS
|
AUDIT_1 = {
|
||||||
SHORT_LIST_FIELD_LABELS = resource_fields.AUDIT_SHORT_LIST_FIELD_LABELS
|
'uuid': '5869da81-4876-4687-a1ed-12cd64cf53d9',
|
||||||
FIELDS = resource_fields.AUDIT_FIELDS
|
'audit_type': 'ONESHOT',
|
||||||
FIELD_LABELS = resource_fields.AUDIT_FIELD_LABELS
|
'state': 'PENDING',
|
||||||
|
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
||||||
|
'audit_template_name': 'at1',
|
||||||
|
'goal_name': 'SERVER_CONSOLIDATION',
|
||||||
|
'strategy_name': 'basic',
|
||||||
|
'created_at': datetime.datetime.now().isoformat(),
|
||||||
|
'updated_at': None,
|
||||||
|
'deleted_at': None,
|
||||||
|
'parameters': None,
|
||||||
|
'interval': None,
|
||||||
|
'scope': '',
|
||||||
|
'auto_trigger': False,
|
||||||
|
'next_run_time': None,
|
||||||
|
'name': 'my_audit1',
|
||||||
|
'hostname': '',
|
||||||
|
}
|
||||||
|
|
||||||
def setUp(self):
|
AUDIT_2 = {
|
||||||
super(self.__class__, self).setUp()
|
'uuid': 'a5199d0e-0702-4613-9234-5ae2af8dafea',
|
||||||
|
'audit_type': 'ONESHOT',
|
||||||
|
'state': 'PENDING',
|
||||||
|
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
||||||
|
'audit_template_name': 'at1',
|
||||||
|
'goal_name': 'fc087747-61be-4aad-8126-b701731ae836',
|
||||||
|
'strategy_name': 'auto',
|
||||||
|
'created_at': datetime.datetime.now().isoformat(),
|
||||||
|
'updated_at': None,
|
||||||
|
'deleted_at': None,
|
||||||
|
'parameters': None,
|
||||||
|
'interval': None,
|
||||||
|
'scope': '',
|
||||||
|
'auto_trigger': False,
|
||||||
|
'next_run_time': None,
|
||||||
|
'name': 'my_audit2',
|
||||||
|
'hostname': '',
|
||||||
|
}
|
||||||
|
|
||||||
|
AUDIT_3 = {
|
||||||
|
'uuid': '43199d0e-0712-1213-9674-5ae2af8dhgte',
|
||||||
|
'audit_type': 'ONESHOT',
|
||||||
|
'state': 'PENDING',
|
||||||
|
'audit_template_uuid': 'f8e47706-efcf-49a4-a5c4-af604eb492f2',
|
||||||
|
'audit_template_name': 'at1',
|
||||||
|
'goal_name': None,
|
||||||
|
'strategy_name': 'auto',
|
||||||
|
'created_at': datetime.datetime.now().isoformat(),
|
||||||
|
'updated_at': None,
|
||||||
|
'deleted_at': None,
|
||||||
|
'parameters': None,
|
||||||
|
'interval': 3600,
|
||||||
|
'scope': '',
|
||||||
|
'auto_trigger': True,
|
||||||
|
'next_run_time': None,
|
||||||
|
'name': 'my_audit3',
|
||||||
|
'hostname': '',
|
||||||
|
}
|
||||||
|
|
||||||
|
SHORT_LIST_FIELDS = ['uuid', 'name', 'audit_type',
|
||||||
|
'state', 'goal_name', 'strategy_name',
|
||||||
|
'auto_trigger']
|
||||||
|
SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Audit Type', 'State', 'Goal',
|
||||||
|
'Strategy', 'Auto Trigger']
|
||||||
|
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']
|
||||||
|
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']
|
||||||
|
|
||||||
|
def setUp(self, os_watcher_api_version='1.0'):
|
||||||
|
super(AuditShellTest, self).setUp(
|
||||||
|
os_watcher_api_version=os_watcher_api_version)
|
||||||
|
|
||||||
# goal mock
|
# goal mock
|
||||||
p_goal_manager = mock.patch.object(resource, 'GoalManager')
|
p_goal_manager = mock.patch.object(resource, 'GoalManager')
|
||||||
@ -158,8 +167,8 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
self.cmd = shell.WatcherShell(stdout=self.stdout)
|
self.cmd = shell.WatcherShell(stdout=self.stdout)
|
||||||
|
|
||||||
def test_do_audit_list(self):
|
def test_do_audit_list(self):
|
||||||
audit1 = resource.Audit(mock.Mock(), AUDIT_1)
|
audit1 = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
audit2 = resource.Audit(mock.Mock(), AUDIT_2)
|
audit2 = resource.Audit(mock.Mock(), self.AUDIT_2)
|
||||||
self.m_audit_mgr.list.return_value = [
|
self.m_audit_mgr.list.return_value = [
|
||||||
audit1, audit2]
|
audit1, audit2]
|
||||||
|
|
||||||
@ -176,7 +185,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
self.m_audit_mgr.list.assert_called_once_with(detail=False)
|
self.m_audit_mgr.list.assert_called_once_with(detail=False)
|
||||||
|
|
||||||
def test_do_audit_list_marker(self):
|
def test_do_audit_list_marker(self):
|
||||||
audit2 = resource.Audit(mock.Mock(), AUDIT_2)
|
audit2 = resource.Audit(mock.Mock(), self.AUDIT_2)
|
||||||
self.m_audit_mgr.list.return_value = [audit2]
|
self.m_audit_mgr.list.return_value = [audit2]
|
||||||
|
|
||||||
exit_code, results = self.run_cmd(
|
exit_code, results = self.run_cmd(
|
||||||
@ -193,8 +202,8 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
marker='5869da81-4876-4687-a1ed-12cd64cf53d9')
|
marker='5869da81-4876-4687-a1ed-12cd64cf53d9')
|
||||||
|
|
||||||
def test_do_audit_list_detail(self):
|
def test_do_audit_list_detail(self):
|
||||||
audit1 = resource.Audit(mock.Mock(), AUDIT_1)
|
audit1 = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
audit2 = resource.Audit(mock.Mock(), AUDIT_2)
|
audit2 = resource.Audit(mock.Mock(), self.AUDIT_2)
|
||||||
self.m_audit_mgr.list.return_value = [
|
self.m_audit_mgr.list.return_value = [
|
||||||
audit1, audit2]
|
audit1, audit2]
|
||||||
|
|
||||||
@ -211,7 +220,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
self.m_audit_mgr.list.assert_called_once_with(detail=True)
|
self.m_audit_mgr.list.assert_called_once_with(detail=True)
|
||||||
|
|
||||||
def test_do_audit_show_by_uuid(self):
|
def test_do_audit_show_by_uuid(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.get.return_value = audit
|
self.m_audit_mgr.get.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -225,7 +234,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
'5869da81-4876-4687-a1ed-12cd64cf53d9')
|
'5869da81-4876-4687-a1ed-12cd64cf53d9')
|
||||||
|
|
||||||
def test_do_audit_show_by_name(self):
|
def test_do_audit_show_by_name(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.get.return_value = audit
|
self.m_audit_mgr.get.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -278,7 +287,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
'5b157edd-5a7e-4aaa-b511-f7b33ec86e9f')
|
'5b157edd-5a7e-4aaa-b511-f7b33ec86e9f')
|
||||||
|
|
||||||
def test_do_audit_update(self):
|
def test_do_audit_update(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.update.return_value = audit
|
self.m_audit_mgr.update.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -294,7 +303,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
|
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
|
||||||
|
|
||||||
def test_do_audit_update_by_name(self):
|
def test_do_audit_update_by_name(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.update.return_value = audit
|
self.m_audit_mgr.update.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -309,7 +318,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
|
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
|
||||||
|
|
||||||
def test_do_audit_create_with_audit_template_uuid(self):
|
def test_do_audit_create_with_audit_template_uuid(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_3)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_3)
|
||||||
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
|
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
|
||||||
self.m_audit_template_mgr.get.return_value = audit_template
|
self.m_audit_template_mgr.get.return_value = audit_template
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
@ -328,7 +337,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_audit_template_name(self):
|
def test_do_audit_create_with_audit_template_name(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_3)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_3)
|
||||||
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
|
audit_template = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
|
||||||
self.m_audit_template_mgr.get.return_value = audit_template
|
self.m_audit_template_mgr.get.return_value = audit_template
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
@ -346,7 +355,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_goal(self):
|
def test_do_audit_create_with_goal(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -363,7 +372,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_goal_and_strategy(self):
|
def test_do_audit_create_with_goal_and_strategy(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -382,7 +391,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_type(self):
|
def test_do_audit_create_with_type(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -399,7 +408,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_parameter(self):
|
def test_do_audit_create_with_parameter(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -418,7 +427,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_type_continuous(self):
|
def test_do_audit_create_with_type_continuous(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -437,7 +446,7 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_do_audit_create_with_name(self):
|
def test_do_audit_create_with_name(self):
|
||||||
audit = resource.Audit(mock.Mock(), AUDIT_1)
|
audit = resource.Audit(mock.Mock(), self.AUDIT_1)
|
||||||
self.m_audit_mgr.create.return_value = audit
|
self.m_audit_mgr.create.return_value = audit
|
||||||
|
|
||||||
exit_code, result = self.run_cmd(
|
exit_code, result = self.run_cmd(
|
||||||
@ -455,3 +464,13 @@ class AuditShellTest(base.CommandTestCase):
|
|||||||
interval='3600',
|
interval='3600',
|
||||||
name='my_audit'
|
name='my_audit'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuditShellTestv11(AuditShellTest):
|
||||||
|
def setUp(self):
|
||||||
|
super(AuditShellTestv11, self).setUp(os_watcher_api_version='1.1')
|
||||||
|
v11 = dict(start_time=None, end_time=None)
|
||||||
|
for audit in (self.AUDIT_1, self.AUDIT_2, self.AUDIT_3):
|
||||||
|
audit.update(v11)
|
||||||
|
self.FIELDS.extend(['start_time', 'end_time'])
|
||||||
|
self.FIELD_LABELS.extend(['Start Time', 'End Time'])
|
||||||
|
@ -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']
|
'name', 'start_time', 'end_time']
|
||||||
|
|
||||||
|
|
||||||
class Audit(base.Resource):
|
class Audit(base.Resource):
|
||||||
|
@ -13,16 +13,31 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
from watcherclient._i18n import _
|
from watcherclient._i18n import _
|
||||||
|
from watcherclient.common import api_versioning
|
||||||
from watcherclient.common import command
|
from watcherclient.common import command
|
||||||
from watcherclient.common import utils as common_utils
|
from watcherclient.common import utils as common_utils
|
||||||
from watcherclient import exceptions
|
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):
|
||||||
|
fields = copy.copy(fields)
|
||||||
|
field_labels = copy.copy(field_labels)
|
||||||
|
api_ver = app_args.os_watcher_api_version
|
||||||
|
if not api_versioning.allow_start_end_audit_time(api_ver):
|
||||||
|
for field, label in zip(('start_time', 'end_time'),
|
||||||
|
('Start Time', 'End Time')):
|
||||||
|
fields.remove(field)
|
||||||
|
field_labels.remove(label)
|
||||||
|
return fields, field_labels
|
||||||
|
|
||||||
|
|
||||||
class ShowAudit(command.ShowOne):
|
class ShowAudit(command.ShowOne):
|
||||||
"""Show detailed information about a given audit."""
|
"""Show detailed information about a given audit."""
|
||||||
|
|
||||||
@ -47,6 +62,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,
|
||||||
|
column_headers)
|
||||||
|
|
||||||
return column_headers, utils.get_item_properties(audit, columns)
|
return column_headers, utils.get_item_properties(audit, columns)
|
||||||
|
|
||||||
@ -118,6 +135,10 @@ class ListAudit(command.Lister):
|
|||||||
fields = res_fields.AUDIT_SHORT_LIST_FIELDS
|
fields = res_fields.AUDIT_SHORT_LIST_FIELDS
|
||||||
field_labels = res_fields.AUDIT_SHORT_LIST_FIELD_LABELS
|
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)
|
||||||
|
|
||||||
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))
|
||||||
|
|
||||||
@ -187,6 +208,18 @@ class CreateAudit(command.ShowOne):
|
|||||||
dest='name',
|
dest='name',
|
||||||
metavar='<name>',
|
metavar='<name>',
|
||||||
help=_('Name for this audit.'))
|
help=_('Name for this audit.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--start-time',
|
||||||
|
dest='start_time',
|
||||||
|
metavar='<start_time>',
|
||||||
|
help=_('CONTINUOUS audit start time. '
|
||||||
|
'Format: YYYY-MM-DD hh:mm:ss'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--end-time',
|
||||||
|
dest='end_time',
|
||||||
|
metavar='<end_time>',
|
||||||
|
help=_('CONTINUOUS audit end time. '
|
||||||
|
'Format: YYYY-MM-DD hh:mm:ss'))
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -194,7 +227,15 @@ class CreateAudit(command.ShowOne):
|
|||||||
client = getattr(self.app.client_manager, "infra-optim")
|
client = getattr(self.app.client_manager, "infra-optim")
|
||||||
|
|
||||||
field_list = ['audit_template_uuid', 'audit_type', 'parameters',
|
field_list = ['audit_template_uuid', 'audit_type', 'parameters',
|
||||||
'interval', 'goal', 'strategy', 'auto_trigger', 'name']
|
'interval', 'goal', 'strategy', 'auto_trigger',
|
||||||
|
'name']
|
||||||
|
|
||||||
|
api_ver = self.app_args.os_watcher_api_version
|
||||||
|
if api_versioning.allow_start_end_audit_time(api_ver):
|
||||||
|
if parsed_args.start_time is not None:
|
||||||
|
field_list.append('start_time')
|
||||||
|
if parsed_args.end_time is not None:
|
||||||
|
field_list.append('end_time')
|
||||||
|
|
||||||
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)
|
||||||
@ -211,6 +252,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,
|
||||||
|
column_headers)
|
||||||
|
|
||||||
return column_headers, utils.get_item_properties(audit, columns)
|
return column_headers, utils.get_item_properties(audit, columns)
|
||||||
|
|
||||||
@ -252,6 +295,9 @@ 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,
|
||||||
|
column_headers)
|
||||||
|
|
||||||
return column_headers, utils.get_item_properties(audit, columns)
|
return column_headers, utils.get_item_properties(audit, columns)
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ 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']
|
'hostname', 'start_time', 'end_time']
|
||||||
|
|
||||||
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']
|
'Next Run Time', 'Hostname', 'Start Time', 'End Time']
|
||||||
|
|
||||||
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',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user