Storage and the notification of a security report
* New functional test * Fix of bugs Change-Id: I700fb634d4aba47c4996df5d5e59c38a034ddcc7
This commit is contained in:
parent
7d7cc5bf90
commit
0a0ca2cad7
|
@ -85,19 +85,15 @@ class SecurityReportController(base.BaseController):
|
||||||
def __init__(self, report_id):
|
def __init__(self, report_id):
|
||||||
super(SecurityReportController, self).__init__()
|
super(SecurityReportController, self).__init__()
|
||||||
pecan.request.context['report_id'] = report_id
|
pecan.request.context['report_id'] = report_id
|
||||||
try:
|
self._id = report_id
|
||||||
self._id = int(report_id)
|
|
||||||
except ValueError:
|
|
||||||
raise exc.HTTPBadRequest(
|
|
||||||
explanation='Security report id must be an integer')
|
|
||||||
|
|
||||||
def get_security_report(self, id):
|
def get_security_report(self, report_id):
|
||||||
try:
|
try:
|
||||||
security_report = db.security_report_get(id)
|
security_report = db.security_report_get(report_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
raise errors.DbError(
|
raise errors.DbError(
|
||||||
"Security report %s could not be retrieved" % id
|
"Security report %s could not be retrieved" % report_id
|
||||||
)
|
)
|
||||||
return security_report
|
return security_report
|
||||||
|
|
||||||
|
@ -114,6 +110,8 @@ class SecurityReportController(base.BaseController):
|
||||||
security_report = self.get_security_report(self._id)
|
security_report = self.get_security_report(self._id)
|
||||||
except errors.DbError:
|
except errors.DbError:
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
if security_report is None:
|
||||||
|
raise exc.HTTPNotFound()
|
||||||
s_report = models.SecurityReportJsonSerializer().\
|
s_report = models.SecurityReportJsonSerializer().\
|
||||||
serialize(security_report)
|
serialize(security_report)
|
||||||
|
|
||||||
|
@ -131,3 +129,16 @@ class SecurityReportController(base.BaseController):
|
||||||
db.security_report_update_ticket_id(self._id, ticket_id)
|
db.security_report_update_ticket_id(self._id, ticket_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
|
@wsme_pecan.wsexpose()
|
||||||
|
def delete(self):
|
||||||
|
"""Delete the security report stored in db.
|
||||||
|
|
||||||
|
:raises:
|
||||||
|
HTTPNotFound: Report not found or any database error
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
db.security_report_delete(self._id)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception(e)
|
||||||
|
raise exc.HTTPNotFound()
|
||||||
|
|
|
@ -81,6 +81,11 @@ def security_report_get_from_report_id(report_id):
|
||||||
return IMPL.security_report_get_from_report_id(report_id)
|
return IMPL.security_report_get_from_report_id(report_id)
|
||||||
|
|
||||||
|
|
||||||
|
def security_report_delete(report_id):
|
||||||
|
"""Delete security report from its report identifier"""
|
||||||
|
return IMPL.security_report_delete(report_id)
|
||||||
|
|
||||||
|
|
||||||
def plugins_info_get():
|
def plugins_info_get():
|
||||||
"""Get information about plugins stored in db"""
|
"""Get information about plugins stored in db"""
|
||||||
return IMPL.plugins_info_get()
|
return IMPL.plugins_info_get()
|
||||||
|
|
|
@ -154,12 +154,12 @@ def security_report_get_all(project_id=None):
|
||||||
return _security_report_get_all(project_id=project_id)
|
return _security_report_get_all(project_id=project_id)
|
||||||
|
|
||||||
|
|
||||||
def _security_report_get(id):
|
def _security_report_get(report_id):
|
||||||
try:
|
try:
|
||||||
session = get_session()
|
session = get_session()
|
||||||
return model_query(models.SecurityReport, read_deleted="no",
|
return model_query(
|
||||||
session=session).filter(models.SecurityReport.
|
models.SecurityReport, read_deleted="no", session=session).filter(
|
||||||
id == id).first()
|
models.SecurityReport.report_id == report_id).first()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
raise exception.DBException()
|
raise exception.DBException()
|
||||||
|
@ -185,6 +185,21 @@ def security_report_get_from_report_id(report_id):
|
||||||
return _security_report_get_from_report_id(report_id)
|
return _security_report_get_from_report_id(report_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _security_report_delete(report_id):
|
||||||
|
try:
|
||||||
|
session = get_session()
|
||||||
|
report = model_query(models.SecurityReport, read_deleted="no",
|
||||||
|
session=session).filter_by(report_id=report_id)
|
||||||
|
report.delete()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception(e)
|
||||||
|
raise exception.DBException()
|
||||||
|
|
||||||
|
|
||||||
|
def security_report_delete(report_id):
|
||||||
|
return _security_report_delete(report_id)
|
||||||
|
|
||||||
|
|
||||||
def _plugin_info_create(values):
|
def _plugin_info_create(values):
|
||||||
try:
|
try:
|
||||||
plugin_info_ref = models.PluginInfo()
|
plugin_info_ref = models.PluginInfo()
|
||||||
|
|
|
@ -84,6 +84,8 @@ def send_notification(operation, resource_type, payload):
|
||||||
notifier = _get_notifier()
|
notifier = _get_notifier()
|
||||||
if notifier:
|
if notifier:
|
||||||
try:
|
try:
|
||||||
|
LOG.info('Sending %(event_type)s notification...',
|
||||||
|
{'event_type': event_type})
|
||||||
notifier.info(context, event_type, payload)
|
notifier.info(context, event_type, payload)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception(_(
|
LOG.exception(_(
|
||||||
|
|
|
@ -19,7 +19,7 @@ import json
|
||||||
|
|
||||||
from cerberus.common import exception as cerberus_exception
|
from cerberus.common import exception as cerberus_exception
|
||||||
from cerberus.common import json_encoders
|
from cerberus.common import json_encoders
|
||||||
from cerberus.db import api as db_api
|
from cerberus import manager as cerberus_manager
|
||||||
from cerberus.openstack.common import log
|
from cerberus.openstack.common import log
|
||||||
from cerberus.plugins import base
|
from cerberus.plugins import base
|
||||||
|
|
||||||
|
@ -119,35 +119,23 @@ class TestPlugin(base.PluginBase):
|
||||||
'services': [333, 335, 337, 339],
|
'services': [333, 335, 337, 339],
|
||||||
'host_id': 328, 'id': 329}}}
|
'host_id': 328, 'id': 329}}}
|
||||||
|
|
||||||
report_id = 1
|
report_id = 'test_plugin_report_id'
|
||||||
if (security_report.get('stat'), False):
|
if (security_report.get('stat'), False):
|
||||||
vulnerabilities_number = security_report['stat']\
|
vulnerabilities_number = security_report['stat']\
|
||||||
.get('vulns', None)
|
.get('vulns', None)
|
||||||
try:
|
|
||||||
db_api.security_report_create(
|
cerberus_manager.store_report_and_notify(
|
||||||
{'title': 'Security report',
|
'Test security report', self._uuid, report_id,
|
||||||
'plugin_id': self._uuid,
|
'a1d869a1-6ab0-4f02-9e56-f83034bacfcb',
|
||||||
'report_id': report_id,
|
'openstack-test-server', 'instance',
|
||||||
'component_id': 'a1d869a1-6ab0-4f02-9e56-f83034bacfcb',
|
'510c7f4ed14243f09df371bba2561177',
|
||||||
'component_type': 'instance',
|
'openstack-test-server', security_report['stat']['grade'],
|
||||||
'component_name': 'openstack-test-server',
|
json.dumps(security_report['vulns'],
|
||||||
'project_id': '510c7f4ed14243f09df371bba2561177',
|
cls=json_encoders.DateTimeEncoder),
|
||||||
'description': 'openstack-test-server',
|
vulnerabilities_number,
|
||||||
'security_rating': security_report['stat']['grade'],
|
datetime.datetime(2015, 6, 1, 10, 11, 59))
|
||||||
'vulnerabilities': json.dumps(
|
|
||||||
security_report['vulns'],
|
|
||||||
cls=json_encoders.DateTimeEncoder),
|
|
||||||
'vulnerabilities_number': vulnerabilities_number}
|
|
||||||
)
|
|
||||||
except cerberus_exception.DBException as e:
|
|
||||||
LOG.exception(e)
|
|
||||||
pass
|
|
||||||
security_reports.append(security_report)
|
security_reports.append(security_report)
|
||||||
db_report_id = db_api.security_report_get_from_report_id(
|
except cerberus_exception.DBException as e:
|
||||||
report_id).id
|
|
||||||
db_api.security_report_update_last_report_date(
|
|
||||||
db_report_id, datetime.datetime(2015, 5, 6, 16, 19, 29))
|
|
||||||
except Exception as e:
|
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
pass
|
pass
|
||||||
return security_reports
|
return security_reports
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
from tempest import test
|
from tempest import test
|
||||||
from tempest_lib.common.utils import data_utils
|
from tempest_lib.common.utils import data_utils
|
||||||
|
@ -61,3 +62,61 @@ class NotificationTests(base.TestCase):
|
||||||
task_list_2 = json.loads(task_list_2)
|
task_list_2 = json.loads(task_list_2)
|
||||||
self.assertEqual(len(task_list_1.get('tasks', 0)) - 1,
|
self.assertEqual(len(task_list_1.get('tasks', 0)) - 1,
|
||||||
len(task_list_2.get('tasks', 0)))
|
len(task_list_2.get('tasks', 0)))
|
||||||
|
|
||||||
|
def test_notifier(self):
|
||||||
|
|
||||||
|
# Create a task to get security report from test_plugin
|
||||||
|
plugin_id = None
|
||||||
|
resp, body = self.security_client.get(
|
||||||
|
self.security_client._version + '/plugins',
|
||||||
|
)
|
||||||
|
plugins = json.loads(body).get('plugins', None)
|
||||||
|
if plugins is not None:
|
||||||
|
for plugin in plugins:
|
||||||
|
if (plugin.get('name', None) ==
|
||||||
|
'cerberus.plugins.test_plugin.TestPlugin'):
|
||||||
|
plugin_id = plugin.get('uuid', None)
|
||||||
|
|
||||||
|
self.assertIsNotNone(plugin_id,
|
||||||
|
message='cerberus.plugins.test_plugin.TestPlugin '
|
||||||
|
'must exist and have an id')
|
||||||
|
|
||||||
|
# Count the number of security.security_report sample
|
||||||
|
# todo(rza): delete the sample at the end if possible
|
||||||
|
resp = self.mgr.telemetry_client.list_samples(
|
||||||
|
'security.security_report.store')
|
||||||
|
samples_number = len(resp)
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
task = {
|
||||||
|
"name": "get_security_reports_test_plugin",
|
||||||
|
"method": "get_security_reports",
|
||||||
|
"plugin_id": plugin_id,
|
||||||
|
"type": "unique"
|
||||||
|
}
|
||||||
|
headers = {'content-type': 'application/json'}
|
||||||
|
resp, body = self.security_client.post(
|
||||||
|
self.security_client._version + '/tasks', json.dumps(task),
|
||||||
|
headers=headers)
|
||||||
|
self.assertEqual(200, resp.status)
|
||||||
|
|
||||||
|
# Check if secu[rity report has been stored in db and delete it
|
||||||
|
report_id = 'test_plugin_report_id'
|
||||||
|
resp, body = self.security_client.get(
|
||||||
|
self.security_client._version + '/security_reports/' + report_id)
|
||||||
|
report = json.loads(body)
|
||||||
|
self.assertEqual('a1d869a1-6ab0-4f02-9e56-f83034bacfcb',
|
||||||
|
report['component_id'])
|
||||||
|
self.assertEqual(200, resp.status)
|
||||||
|
|
||||||
|
# Delete security report
|
||||||
|
resp, body = self.security_client.delete(
|
||||||
|
self.security_client._version + '/security_reports/' + report_id)
|
||||||
|
|
||||||
|
self.assertEqual(204, resp.status)
|
||||||
|
|
||||||
|
# Check if a sample has been created in Ceilometer
|
||||||
|
resp = self.mgr.telemetry_client.list_samples(
|
||||||
|
'security.security_report.store')
|
||||||
|
self.assertEqual(samples_number + 1, len(resp))
|
||||||
|
|
Loading…
Reference in New Issue