diff --git a/charmhelpers/contrib/openstack/context.py b/charmhelpers/contrib/openstack/context.py index 1e667fb03..cd70b55ce 100644 --- a/charmhelpers/contrib/openstack/context.py +++ b/charmhelpers/contrib/openstack/context.py @@ -202,6 +202,21 @@ def get_related(self): return self.related +class KeystoneAuditMiddleware(OSContextGenerator): + def __init__(self, service: str) -> None: + self.service_name = service + + def __call__(self): + """Return context dictionary containing configuration status of + audit-middleware and the charm service name. + """ + ctxt = { + 'audit_middleware': config('audit-middleware') or False, + 'service_name': self.service_name + } + return ctxt + + class SharedDBContext(OSContextGenerator): interfaces = ['shared-db'] diff --git a/charmhelpers/contrib/openstack/templates/section-audit-middleware-notifications b/charmhelpers/contrib/openstack/templates/section-audit-middleware-notifications new file mode 100644 index 000000000..1f88014fe --- /dev/null +++ b/charmhelpers/contrib/openstack/templates/section-audit-middleware-notifications @@ -0,0 +1,4 @@ +{% if audit_middleware -%} +[audit_middleware_notifications] +driver = log +{% endif -%} \ No newline at end of file diff --git a/charmhelpers/contrib/openstack/templates/section-filter-audit b/charmhelpers/contrib/openstack/templates/section-filter-audit new file mode 100644 index 000000000..11512aeed --- /dev/null +++ b/charmhelpers/contrib/openstack/templates/section-filter-audit @@ -0,0 +1,6 @@ +{% if audit_middleware and service_name -%} +[filter:audit] +paste.filter_factory = keystonemiddleware.audit:filter_factory +audit_map_file = /etc/{{ service_name }}/api_audit_map.conf +service_name = {{ service_name }} +{% endif -%} \ No newline at end of file diff --git a/tests/contrib/openstack/test_os_contexts.py b/tests/contrib/openstack/test_os_contexts.py index 8b7a56d9f..cc8e99a4b 100644 --- a/tests/contrib/openstack/test_os_contexts.py +++ b/tests/contrib/openstack/test_os_contexts.py @@ -824,6 +824,30 @@ def test_shared_db_context_with_data(self, os_codename): } self.assertEquals(result, expected) + @patch.object(context, 'config') + def test_keystone_audit_middleware_ctxt_enabled(self, mock_config): + '''Test KeystoneAuditMiddleware ctxt contents when enabled''' + mock_config.return_value = True + audit_middleware = context.KeystoneAuditMiddleware(service='cinder') + ctxt = audit_middleware() + expected_ctxt = { + 'audit_middleware': True, + 'service_name': 'cinder' + } + self.assertEqual(ctxt, expected_ctxt) + + @patch.object(context, 'config') + def test_keystone_audit_middleware_ctxt_disabled(self, mock_config): + '''Test KeystoneAuditMiddleware ctxt contents when disabled''' + mock_config.return_value = False + audit_middleware = context.KeystoneAuditMiddleware(service='cinder') + ctxt = audit_middleware() + expected_ctxt = { + 'audit_middleware': False, + 'service_name': 'cinder' + } + self.assertEqual(ctxt, expected_ctxt) + def test_shared_db_context_with_data_and_access_net_mismatch(self): """Mismatch between hostname and hostname for access net - defers execution"""