Skip to content

Commit fbc21fb

Browse files
Merge pull request #882 from vyzigold/ci-enable-audit
[OSPRH-29177] Add Zuul job and Ansible role for CADF audit logging
2 parents 82bd3ee + 51c5e13 commit fbc21fb

20 files changed

Lines changed: 761 additions & 0 deletions

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ This operator deploys a multiple telemetry agents, both in the control plane and
7171
oc patch --type merge openstackversions openstack-galera-network-isolation --patch-file=ci/files/master-openstackclient-patch.yaml # required for "openstack metric" commands to work correctly
7272
```
7373

74+
4.e. Enable CADF audit logging for OpenStack services (barbican, cinder, glance, keystone, neutron, nova):
75+
76+
```bash
77+
ansible-playbook ci/enable-audit-logging.yml -e enable_audit_logging_local_apply=true
78+
```
79+
7480
Return to the install_yamls directory before continuing.
7581

7682
5. Deploy dataplane operator

ci/enable-audit-logging.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
- name: "Enable audit logging for OpenStack services"
3+
hosts: "{{ cifmw_target_hook_host | default('localhost') }}"
4+
gather_facts: false
5+
environment:
6+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig | default(ansible_env.HOME + '/.kube/config') }}"
7+
PATH: "{{ cifmw_path | default(ansible_env.PATH) }}"
8+
tasks:
9+
- name: Enable audit logging
10+
ansible.builtin.import_role:
11+
name: enable-audit-logging

ci/enable-audit-logging/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
enable-audit-logging
2+
=========
3+
4+
A role for enabling CADF audit logging on OpenStack services deployed by openstack-k8s-operators. The role creates the necessary audit configuration secrets and applies kustomizations to the OpenStackControlPlane CR.
5+
6+
Currently supported services:
7+
- Cinder
8+
- Glance
9+
- Keystone
10+
- Neutron
11+
12+
Services not yet supported (config files included for future use):
13+
- Barbican (blocked by [OSPRH-25781](https://issues.redhat.com/browse/OSPRH-25781))
14+
- Nova (blocked by a nova-operator issue with audit map file naming)
15+
16+
Audit map files
17+
----------------
18+
The `*_api_audit_map.conf` files in `files/` are copies of the upstream pycadf defaults from https://github.com/openstack/pycadf/tree/master/etc/pycadf. If the upstream files change, the local copies should be updated to match.
19+
20+
Requirements
21+
------------
22+
- An OpenStack deployed with the openstack-k8s-operators
23+
- `oc` CLI configured with cluster access
24+
25+
Side effects
26+
------------
27+
After the role runs, the following secrets are created in the `openstack` namespace:
28+
- `cinder-audit-config-secret`
29+
- `glance-audit-config-secret`
30+
- `neutron-audit-config-secret`
31+
32+
The OpenStackControlPlane CR is patched (via kustomization) to mount these secrets and enable the audit middleware notification driver for each service.
33+
34+
Role Variables
35+
--------------
36+
- enable\_audit\_logging\_local\_apply: When `true`, the role fetches the live OSCP CR and applies the kustomization directly. When `false` (default), the kustomization is copied to the ci-framework kustomizations directory for pre-deploy use.
37+
38+
Example Playbook
39+
----------------
40+
41+
ansible-playbook ci/enable-audit-logging.yml -e enable_audit_logging_local_apply=true
42+
43+
License
44+
-------
45+
46+
Apache 2
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
enable_audit_logging_namespace: "{{ cifmw_openstack_namespace | default('openstack') }}"
2+
# Set to true to apply the kustomization against a live OSCP CR.
3+
# When false (default), the kustomization is only copied to the
4+
# ci-framework kustomizations directory for pre-deploy use.
5+
enable_audit_logging_local_apply: false
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[composite:main]
2+
use = egg:Paste#urlmap
3+
/: barbican_version
4+
/healthcheck: healthcheck
5+
/v1: barbican-api-keystone-audit
6+
7+
# Use this pipeline for Barbican API - versions no authentication
8+
[pipeline:barbican_version]
9+
pipeline = cors http_proxy_to_wsgi microversion versionapp
10+
11+
# Use this pipeline for Barbican API - DEFAULT no authentication
12+
[pipeline:barbican_api]
13+
pipeline = cors http_proxy_to_wsgi unauthenticated-context microversion apiapp
14+
15+
#Use this pipeline to activate a repoze.profile middleware and HTTP port,
16+
# to provide profiling information for the REST API processing.
17+
[pipeline:barbican-profile]
18+
pipeline = cors http_proxy_to_wsgi unauthenticated-context microversion egg:Paste#cgitb egg:Paste#httpexceptions profile apiapp
19+
20+
#Use this pipeline for keystone auth
21+
[pipeline:barbican-api-keystone]
22+
pipeline = cors http_proxy_to_wsgi authtoken context microversion apiapp
23+
24+
#Use this pipeline for keystone auth with audit feature
25+
[pipeline:barbican-api-keystone-audit]
26+
pipeline = http_proxy_to_wsgi authtoken context microversion audit apiapp
27+
28+
[app:apiapp]
29+
paste.app_factory = barbican.api.app:create_main_app
30+
31+
[app:versionapp]
32+
paste.app_factory = barbican.api.app:create_version_app
33+
34+
[filter:simple]
35+
paste.filter_factory = barbican.api.middleware.simple:SimpleFilter.factory
36+
37+
[filter:unauthenticated-context]
38+
paste.filter_factory = barbican.api.middleware.context:UnauthenticatedContextMiddleware.factory
39+
40+
[filter:context]
41+
paste.filter_factory = barbican.api.middleware.context:ContextMiddleware.factory
42+
43+
[filter:microversion]
44+
paste.filter_factory = barbican.api.middleware.microversion:MicroversionMiddleware.factory
45+
46+
[filter:audit]
47+
paste.filter_factory = keystonemiddleware.audit:filter_factory
48+
audit_map_file = /etc/barbican/api_audit_map.conf
49+
use_oslo_messaging = false
50+
log_name = barbican.audit
51+
52+
[filter:authtoken]
53+
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
54+
55+
[filter:profile]
56+
use = egg:repoze.profile
57+
log_filename = myapp.profile
58+
cachegrind_filename = cachegrind.out.myapp
59+
discard_first_request = true
60+
path = /__profile__
61+
flush_at_shutdown = true
62+
unwind = false
63+
64+
[filter:cors]
65+
paste.filter_factory = oslo_middleware.cors:filter_factory
66+
oslo_config_project = barbican
67+
68+
[filter:http_proxy_to_wsgi]
69+
paste.filter_factory = oslo_middleware:HTTPProxyToWSGI.factory
70+
71+
[app:healthcheck]
72+
paste.app_factory = oslo_middleware:Healthcheck.app_factory
73+
backends = disable_by_file
74+
disable_by_file_path = /etc/barbican/healthcheck_disable
75+
76+
[server:main]
77+
use = egg:gunicorn#main
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#############
2+
# OpenStack #
3+
#############
4+
5+
[composite:osapi_volume]
6+
use = call:cinder.api:root_app_factory
7+
/: apiversions
8+
/healthcheck: healthcheck
9+
/v3: openstack_volume_api_v3
10+
11+
[composite:openstack_volume_api_v3]
12+
use = call:cinder.api.middleware.auth:pipeline_factory
13+
noauth = request_id cors http_proxy_to_wsgi faultwrap sizelimit osprofiler noauth apiv3
14+
noauth_include_project_id = request_id cors http_proxy_to_wsgi faultwrap sizelimit osprofiler noauth_include_project_id apiv3
15+
keystone = request_id cors http_proxy_to_wsgi faultwrap sizelimit osprofiler authtoken keystonecontext audit apiv3
16+
keystone_nolimit = request_id cors http_proxy_to_wsgi faultwrap sizelimit osprofiler authtoken keystonecontext audit apiv3
17+
18+
[filter:http_proxy_to_wsgi]
19+
paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory
20+
21+
[filter:cors]
22+
paste.filter_factory = oslo_middleware.cors:filter_factory
23+
oslo_config_project = cinder
24+
25+
[filter:faultwrap]
26+
paste.filter_factory = cinder.api.middleware.fault:FaultWrapper.factory
27+
28+
[filter:osprofiler]
29+
paste.filter_factory = osprofiler.web:WsgiMiddleware.factory
30+
31+
[filter:noauth]
32+
paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory
33+
34+
[filter:noauth_include_project_id]
35+
paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddlewareIncludeProjectID.factory
36+
37+
[filter:sizelimit]
38+
paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory
39+
40+
[app:apiv3]
41+
paste.app_factory = cinder.api.v3.router:APIRouter.factory
42+
43+
[pipeline:apiversions]
44+
pipeline = request_id cors http_proxy_to_wsgi faultwrap osvolumeversionapp
45+
46+
[app:osvolumeversionapp]
47+
paste.app_factory = cinder.api.versions:Versions.factory
48+
49+
[pipeline:healthcheck]
50+
pipeline = request_id healthcheckapp
51+
52+
[app:healthcheckapp]
53+
paste.app_factory = oslo_middleware:Healthcheck.app_factory
54+
backends = disable_by_file
55+
disable_by_file_path = /etc/cinder/healthcheck_disable
56+
57+
##########
58+
# Shared #
59+
##########
60+
61+
[filter:keystonecontext]
62+
paste.filter_factory = cinder.api.middleware.auth:CinderKeystoneContext.factory
63+
64+
[filter:authtoken]
65+
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
66+
67+
[filter:request_id]
68+
paste.filter_factory = cinder.api.middleware.request_id:RequestId.factory
69+
70+
[filter:audit]
71+
paste.filter_factory = keystonemiddleware.audit:filter_factory
72+
audit_map_file = /etc/cinder/custom/cinder_api_audit_map.conf
73+
use_oslo_messaging = false
74+
log_name = cinder.audit
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[DEFAULT]
2+
# default target endpoint type
3+
# should match the endpoint type defined in service catalog
4+
target_endpoint_type = None
5+
6+
# map urls ending with specific text to a unique action
7+
[custom_actions]
8+
associate = update/associate
9+
disassociate = update/disassociate
10+
disassociate_all = update/disassociate_all
11+
associations = read/list/associations
12+
13+
# possible end path of api requests
14+
[path_keywords]
15+
defaults = None
16+
detail = None
17+
limits = None
18+
os-quota-specs = project
19+
qos-specs = qos-spec
20+
snapshots = snapshot
21+
types = type
22+
volumes = volume
23+
24+
# map endpoint type defined in service catalog to CADF typeURI
25+
[service_endpoints]
26+
volumev3 = service/storage/block
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Use this pipeline for no auth or image caching - DEFAULT
2+
[pipeline:glance-api]
3+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler unauthenticated-context rootapp
4+
5+
# Use this pipeline for image caching and no auth
6+
[pipeline:glance-api-caching]
7+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler unauthenticated-context cache rootapp
8+
9+
# Use this pipeline for caching w/ management interface but no auth
10+
[pipeline:glance-api-cachemanagement]
11+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler unauthenticated-context cache cachemanage rootapp
12+
13+
# Use this pipeline for keystone auth
14+
[pipeline:glance-api-keystone]
15+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler authtoken context audit rootapp
16+
17+
# Use this pipeline for keystone auth with image caching
18+
[pipeline:glance-api-keystone+caching]
19+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler authtoken context cache audit rootapp
20+
21+
# Use this pipeline for keystone auth with caching and cache management
22+
[pipeline:glance-api-keystone+cachemanagement]
23+
pipeline = cors healthcheck http_proxy_to_wsgi versionnegotiation osprofiler authtoken context cache cachemanage audit rootapp
24+
25+
[composite:rootapp]
26+
paste.composite_factory = glance.api:root_app_factory
27+
/: apiversions
28+
/v2: apiv2app
29+
30+
[app:apiversions]
31+
paste.app_factory = glance.api.versions:create_resource
32+
33+
[app:apiv2app]
34+
paste.app_factory = glance.api.v2.router:API.factory
35+
36+
[filter:healthcheck]
37+
paste.filter_factory = oslo_middleware:Healthcheck.factory
38+
backends = disable_by_file
39+
disable_by_file_path = /etc/glance/healthcheck_disable
40+
41+
[filter:versionnegotiation]
42+
paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory
43+
44+
[filter:cache]
45+
paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory
46+
47+
[filter:cachemanage]
48+
paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory
49+
50+
[filter:context]
51+
paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory
52+
53+
[filter:unauthenticated-context]
54+
paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory
55+
56+
[filter:authtoken]
57+
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
58+
delay_auth_decision = true
59+
60+
[filter:gzip]
61+
paste.filter_factory = glance.api.middleware.gzip:GzipMiddleware.factory
62+
63+
[filter:osprofiler]
64+
paste.filter_factory = osprofiler.web:WsgiMiddleware.factory
65+
66+
[filter:cors]
67+
paste.filter_factory = oslo_middleware.cors:filter_factory
68+
oslo_config_project = glance
69+
oslo_config_program = glance-api
70+
71+
[filter:http_proxy_to_wsgi]
72+
paste.filter_factory = oslo_middleware:HTTPProxyToWSGI.factory
73+
74+
[filter:audit]
75+
paste.filter_factory = keystonemiddleware.audit:filter_factory
76+
audit_map_file = /etc/glance/custom/glance_api_audit_map.conf
77+
use_oslo_messaging = false
78+
log_name = glance.audit
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[DEFAULT]
2+
# default target endpoint type
3+
# should match the endpoint type defined in service catalog
4+
target_endpoint_type = None
5+
6+
# possible end path of api requests
7+
[path_keywords]
8+
detail = None
9+
file = None
10+
images = image
11+
members = member
12+
tags = tag
13+
14+
# map endpoint type defined in service catalog to CADF typeURI
15+
[service_endpoints]
16+
image = service/storage/image

0 commit comments

Comments
 (0)