diff --git a/api/bases/nova.openstack.org_nova.yaml b/api/bases/nova.openstack.org_nova.yaml index 322c6ee19..f2c0f5de7 100644 --- a/api/bases/nova.openstack.org_nova.yaml +++ b/api/bases/nova.openstack.org_nova.yaml @@ -75,7 +75,7 @@ spec: additionalProperties: type: string description: DefaultConfigOverwrite - interface to overwrite default - config files like e.g. api-paste.ini or policy.yaml. + config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment diff --git a/api/bases/nova.openstack.org_novaapis.yaml b/api/bases/nova.openstack.org_novaapis.yaml index da1464453..c414ad5bd 100644 --- a/api/bases/nova.openstack.org_novaapis.yaml +++ b/api/bases/nova.openstack.org_novaapis.yaml @@ -89,7 +89,7 @@ spec: additionalProperties: type: string description: DefaultConfigOverwrite - interface to overwrite default - config files like e.g. api-paste.ini or policy.yaml. + config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. type: object keystoneAuthURL: description: |- diff --git a/api/nova/v1beta1/novaapi_types.go b/api/nova/v1beta1/novaapi_types.go index dfa416fac..b5a1c5f9e 100644 --- a/api/nova/v1beta1/novaapi_types.go +++ b/api/nova/v1beta1/novaapi_types.go @@ -54,7 +54,7 @@ type NovaAPITemplate struct { CustomServiceConfig string `json:"customServiceConfig"` // +kubebuilder:validation:Optional - // DefaultConfigOverwrite - interface to overwrite default config files like e.g. api-paste.ini or policy.yaml. + // DefaultConfigOverwrite - interface to overwrite default config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. DefaultConfigOverwrite map[string]string `json:"defaultConfigOverwrite,omitempty"` // +kubebuilder:validation:Optional @@ -171,7 +171,7 @@ type NovaAPISpec struct { TLS tls.API `json:"tls,omitempty"` // +kubebuilder:validation:Optional - // DefaultConfigOverwrite - interface to overwrite default config files like e.g. api-paste.ini or policy.yaml. + // DefaultConfigOverwrite - interface to overwrite default config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. DefaultConfigOverwrite map[string]string `json:"defaultConfigOverwrite,omitempty"` // +kubebuilder:validation:Required diff --git a/api/nova/v1beta1/novaapi_webhook.go b/api/nova/v1beta1/novaapi_webhook.go index 705c398ea..5e708db24 100644 --- a/api/nova/v1beta1/novaapi_webhook.go +++ b/api/nova/v1beta1/novaapi_webhook.go @@ -148,7 +148,7 @@ func ValidateAPIDefaultConfigOverwrite( return ValidateDefaultConfigOverwrite( basePath, defaultConfigOverwrite, - []string{"policy.yaml", "api-paste.ini"}) + []string{"policy.yaml", "api-paste.ini", "nova_api_audit_map.conf"}) } // ValidateTopology validates the referenced TopoRef.Namespace. diff --git a/ci/nova-operator-tempest-multinode/control_plane_hook.yaml b/ci/nova-operator-tempest-multinode/control_plane_hook.yaml index ad83a4e0f..6a93c72f8 100644 --- a/ci/nova-operator-tempest-multinode/control_plane_hook.yaml +++ b/ci/nova-operator-tempest-multinode/control_plane_hook.yaml @@ -82,3 +82,174 @@ - op: add path: /spec/nova/template/metadataServiceTemplate/enabled value: false + + - op: add + path: /spec/nova/template/apiServiceTemplate + value: + defaultConfigOverride: + api-paste.ini: | + ############ + # Metadata # + ############ + [composite:metadata] + use = egg:Paste#urlmap + /: meta + + [pipeline:meta] + pipeline = cors http_proxy_to_wsgi metaapp + + [app:metaapp] + paste.app_factory = nova.api.metadata.handler:MetadataRequestHandler.factory + + ############# + # OpenStack # + ############# + + [composite:osapi_compute] + use = call:nova.api.openstack.urlmap:urlmap_factory + /: oscomputeversions + /v2: oscomputeversion_legacy_v2 + /v2.1: oscomputeversion_v2 + /v2/+: openstack_compute_api_v21_legacy_v2_compatible + /v2.1/+: openstack_compute_api_v21 + + [composite:openstack_compute_api_v21] + use = call:nova.api.auth:pipeline_factory_v21 + keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext audit osapi_compute_app_v21 + noauth2 = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler noauth2 audit osapi_compute_app_v21 + + [composite:openstack_compute_api_v21_legacy_v2_compatible] + use = call:nova.api.auth:pipeline_factory_v21 + keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext legacy_v2_compatible audit osapi_compute_app_v21 + noauth2 = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler noauth2 legacy_v2_compatible audit osapi_compute_app_v21 + + [filter:request_log] + paste.filter_factory = nova.api.openstack.requestlog:RequestLog.factory + + [filter:compute_req_id] + paste.filter_factory = nova.api.compute_req_id:ComputeReqIdMiddleware.factory + + [filter:faultwrap] + paste.filter_factory = nova.api.openstack:FaultWrapper.factory + + [filter:noauth2] + paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory + + [filter:osprofiler] + paste.filter_factory = nova.profiler:WsgiMiddleware.factory + + [filter:sizelimit] + paste.filter_factory = oslo_middleware:RequestBodySizeLimiter.factory + + [filter:http_proxy_to_wsgi] + paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory + + [filter:legacy_v2_compatible] + paste.filter_factory = nova.api.openstack:LegacyV2CompatibleWrapper.factory + + [app:osapi_compute_app_v21] + paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory + + [pipeline:oscomputeversions] + pipeline = cors faultwrap request_log http_proxy_to_wsgi oscomputeversionapp + + [pipeline:oscomputeversion_v2] + pipeline = cors compute_req_id faultwrap request_log http_proxy_to_wsgi oscomputeversionapp_v2 + + [pipeline:oscomputeversion_legacy_v2] + pipeline = cors compute_req_id faultwrap request_log http_proxy_to_wsgi legacy_v2_compatible oscomputeversionapp_v2 + + [app:oscomputeversionapp] + paste.app_factory = nova.api.openstack.compute.versions:Versions.factory + + [app:oscomputeversionapp_v2] + paste.app_factory = nova.api.openstack.compute.versions:VersionsV2.factory + + ########## + # Shared # + ########## + + [filter:cors] + paste.filter_factory = oslo_middleware.cors:filter_factory + oslo_config_project = nova + + [filter:keystonecontext] + paste.filter_factory = nova.api.auth:NovaKeystoneContext.factory + + [filter:authtoken] + paste.filter_factory = keystonemiddleware.auth_token:filter_factory + + [filter:audit] + paste.filter_factory = keystonemiddleware.audit:filter_factory + audit_map_file = /etc/nova/nova_api_audit_map.conf + use_oslo_messaging = false + log_name = nova.audit + nova_api_audit_map.conf: | + [DEFAULT] + target_endpoint_type = None + + [custom_actions] + enable = enable + disable = disable + delete = delete + startup = start/startup + shutdown = stop/shutdown + reboot = start/reboot + os-migrations/get = read + os-server-password/post = update + + [path_keywords] + add = None + action = None + enable = None + disable = None + configure-project = None + defaults = None + delete = None + detail = None + diagnostics = None + entries = entry + extensions = alias + flavors = flavor + images = image + ips = label + limits = None + metadata = key + os-agents = os-agent + os-aggregates = os-aggregate + os-availability-zone = None + os-certificates = None + os-cloudpipe = None + os-fixed-ips = ip + os-extra_specs = key + os-flavor-access = None + os-floating-ip-dns = domain + os-floating-ips-bulk = host + os-floating-ip-pools = None + os-floating-ips = floating-ip + os-hosts = host + os-hypervisors = hypervisor + os-instance-actions = instance-action + os-keypairs = keypair + os-migrations = None + os-networks = network + os-quota-sets = tenant + os-security-groups = security_group + os-security-group-rules = rule + os-server-password = None + os-services = None + os-simple-tenant-usage = tenant + os-virtual-interfaces = None + os-volume_attachments = attachment + os-volumes_boot = None + os-volumes = volume + os-volume-types = volume-type + os-snapshots = snapshot + reboot = None + servers = server + shutdown = None + startup = None + statistics = None + + [service_endpoints] + compute = service/compute diff --git a/config/crd/bases/nova.openstack.org_nova.yaml b/config/crd/bases/nova.openstack.org_nova.yaml index 322c6ee19..f2c0f5de7 100644 --- a/config/crd/bases/nova.openstack.org_nova.yaml +++ b/config/crd/bases/nova.openstack.org_nova.yaml @@ -75,7 +75,7 @@ spec: additionalProperties: type: string description: DefaultConfigOverwrite - interface to overwrite default - config files like e.g. api-paste.ini or policy.yaml. + config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment diff --git a/config/crd/bases/nova.openstack.org_novaapis.yaml b/config/crd/bases/nova.openstack.org_novaapis.yaml index da1464453..c414ad5bd 100644 --- a/config/crd/bases/nova.openstack.org_novaapis.yaml +++ b/config/crd/bases/nova.openstack.org_novaapis.yaml @@ -89,7 +89,7 @@ spec: additionalProperties: type: string description: DefaultConfigOverwrite - interface to overwrite default - config files like e.g. api-paste.ini or policy.yaml. + config files like e.g. api-paste.ini, policy.yaml or nova_api_audit_map.conf. type: object keystoneAuthURL: description: |- diff --git a/templates/nova/api/config/nova-api-config.json b/templates/nova/api/config/nova-api-config.json index 545ba3c5a..864334a72 100644 --- a/templates/nova/api/config/nova-api-config.json +++ b/templates/nova/api/config/nova-api-config.json @@ -83,6 +83,13 @@ "dest": "/etc/my.cnf", "owner": "nova", "perm": "0644" + }, + { + "source": "/var/lib/openstack/config/nova_api_audit_map.conf", + "dest": "/etc/nova/nova_api_audit_map.conf", + "owner": "nova", + "perm": "0600", + "optional": true } ], "permissions": [ diff --git a/templates/nova/nova.conf b/templates/nova/nova.conf index d76c3137b..2fb17a1bc 100644 --- a/templates/nova/nova.conf +++ b/templates/nova/nova.conf @@ -433,6 +433,14 @@ compute = auto [oslo_reports] # api services need file based GMR trigger as apache disables signal handling file_event_handler=/var/lib/nova + +[audit_middleware_notifications] +{{ if (index . "notification_transport_url") }} +use_oslo_messaging = true +{{ else }} +use_oslo_messaging = false +{{ end }} + {{end}} {{- $var := execTempl "nova-template" . | removeNewLinesInSections -}} {{$var -}} diff --git a/test/functional/nova/validation_webhook_test.go b/test/functional/nova/validation_webhook_test.go index d249752f8..3645b9804 100644 --- a/test/functional/nova/validation_webhook_test.go +++ b/test/functional/nova/validation_webhook_test.go @@ -726,7 +726,7 @@ var _ = Describe("Nova validation", func() { ContainSubstring( "invalid: spec.defaultConfigOverwrite: " + "Invalid value: \"foo.conf\": Only the following keys " + - "are valid: policy.yaml, api-paste.ini", + "are valid: policy.yaml, api-paste.ini, nova_api_audit_map.conf", ), ) }) @@ -764,7 +764,7 @@ var _ = Describe("Nova validation", func() { ContainSubstring( "invalid: spec.apiServiceTemplate.defaultConfigOverwrite: " + "Invalid value: \"provider.yaml\": Only the following " + - "keys are valid: policy.yaml, api-paste.ini"), + "keys are valid: policy.yaml, api-paste.ini, nova_api_audit_map.conf"), ) }) diff --git a/test/kuttl/test-suites/default/config-tests/01-assert.yaml b/test/kuttl/test-suites/default/config-tests/01-assert.yaml index fce353578..669f742e3 100644 --- a/test/kuttl/test-suites/default/config-tests/01-assert.yaml +++ b/test/kuttl/test-suites/default/config-tests/01-assert.yaml @@ -142,3 +142,7 @@ commands: set -euxo pipefail RP_UUID=$(oc exec -n $NAMESPACE openstackclient -- openstack resource provider list --name nova-kuttl-cell1-compute-fake1-compute-0 -f value -c uuid) oc exec -n $NAMESPACE openstackclient -- openstack resource provider trait list $RP_UUID | grep CUSTOM_FOO + - script: | + set -euxo pipefail + # Check for audit logs created by the openstack flavor create command above + oc logs -n $NAMESPACE nova-kuttl-api-0 | grep "http://schemas.dmtf.org/cloud/audit/1.0/event" diff --git a/test/kuttl/test-suites/default/config-tests/01-deploy-with-default-config-overwrite.yaml b/test/kuttl/test-suites/default/config-tests/01-deploy-with-default-config-overwrite.yaml index 31545f0bf..cdb422226 100644 --- a/test/kuttl/test-suites/default/config-tests/01-deploy-with-default-config-overwrite.yaml +++ b/test/kuttl/test-suites/default/config-tests/01-deploy-with-default-config-overwrite.yaml @@ -8,6 +8,172 @@ spec: defaultConfigOverwrite: policy.yaml: | "os_compute_api:os-flavor-manage:create": "!" + api-paste.ini: | + ############ + # Metadata # + ############ + [composite:metadata] + use = egg:Paste#urlmap + /: meta + + [pipeline:meta] + pipeline = cors http_proxy_to_wsgi metaapp + + [app:metaapp] + paste.app_factory = nova.api.metadata.handler:MetadataRequestHandler.factory + + ############# + # OpenStack # + ############# + + [composite:osapi_compute] + use = call:nova.api.openstack.urlmap:urlmap_factory + /: oscomputeversions + /v2: oscomputeversion_legacy_v2 + /v2.1: oscomputeversion_v2 + /v2/+: openstack_compute_api_v21_legacy_v2_compatible + /v2.1/+: openstack_compute_api_v21 + + [composite:openstack_compute_api_v21] + use = call:nova.api.auth:pipeline_factory_v21 + keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext audit osapi_compute_app_v21 + noauth2 = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler noauth2 audit osapi_compute_app_v21 + + [composite:openstack_compute_api_v21_legacy_v2_compatible] + use = call:nova.api.auth:pipeline_factory_v21 + keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext legacy_v2_compatible audit osapi_compute_app_v21 + noauth2 = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler noauth2 legacy_v2_compatible audit osapi_compute_app_v21 + + [filter:request_log] + paste.filter_factory = nova.api.openstack.requestlog:RequestLog.factory + + [filter:compute_req_id] + paste.filter_factory = nova.api.compute_req_id:ComputeReqIdMiddleware.factory + + [filter:faultwrap] + paste.filter_factory = nova.api.openstack:FaultWrapper.factory + + [filter:noauth2] + paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory + + [filter:osprofiler] + paste.filter_factory = nova.profiler:WsgiMiddleware.factory + + [filter:sizelimit] + paste.filter_factory = oslo_middleware:RequestBodySizeLimiter.factory + + [filter:http_proxy_to_wsgi] + paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory + + [filter:legacy_v2_compatible] + paste.filter_factory = nova.api.openstack:LegacyV2CompatibleWrapper.factory + + [app:osapi_compute_app_v21] + paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory + + [pipeline:oscomputeversions] + pipeline = cors faultwrap request_log http_proxy_to_wsgi oscomputeversionapp + + [pipeline:oscomputeversion_v2] + pipeline = cors compute_req_id faultwrap request_log http_proxy_to_wsgi oscomputeversionapp_v2 + + [pipeline:oscomputeversion_legacy_v2] + pipeline = cors compute_req_id faultwrap request_log http_proxy_to_wsgi legacy_v2_compatible oscomputeversionapp_v2 + + [app:oscomputeversionapp] + paste.app_factory = nova.api.openstack.compute.versions:Versions.factory + + [app:oscomputeversionapp_v2] + paste.app_factory = nova.api.openstack.compute.versions:VersionsV2.factory + + ########## + # Shared # + ########## + + [filter:cors] + paste.filter_factory = oslo_middleware.cors:filter_factory + oslo_config_project = nova + + [filter:keystonecontext] + paste.filter_factory = nova.api.auth:NovaKeystoneContext.factory + + [filter:authtoken] + paste.filter_factory = keystonemiddleware.auth_token:filter_factory + + [filter:audit] + paste.filter_factory = keystonemiddleware.audit:filter_factory + audit_map_file = /etc/nova/nova_api_audit_map.conf + use_oslo_messaging = false + log_name = nova.audit + nova_api_audit_map.conf: | + [DEFAULT] + target_endpoint_type = None + + [custom_actions] + enable = enable + disable = disable + delete = delete + startup = start/startup + shutdown = stop/shutdown + reboot = start/reboot + os-migrations/get = read + os-server-password/post = update + + [path_keywords] + add = None + action = None + enable = None + disable = None + configure-project = None + defaults = None + delete = None + detail = None + diagnostics = None + entries = entry + extensions = alias + flavors = flavor + images = image + ips = label + limits = None + metadata = key + os-agents = os-agent + os-aggregates = os-aggregate + os-availability-zone = None + os-certificates = None + os-cloudpipe = None + os-fixed-ips = ip + os-extra_specs = key + os-flavor-access = None + os-floating-ip-dns = domain + os-floating-ips-bulk = host + os-floating-ip-pools = None + os-floating-ips = floating-ip + os-hosts = host + os-hypervisors = hypervisor + os-instance-actions = instance-action + os-keypairs = keypair + os-migrations = None + os-networks = network + os-quota-sets = tenant + os-security-groups = security_group + os-security-group-rules = rule + os-server-password = None + os-services = None + os-simple-tenant-usage = tenant + os-virtual-interfaces = None + os-volume_attachments = attachment + os-volumes_boot = None + os-volumes = volume + os-volume-types = volume-type + os-snapshots = snapshot + reboot = None + servers = server + shutdown = None + startup = None + statistics = None + + [service_endpoints] + compute = service/compute cellTemplates: cell0: cellDatabaseInstance: openstack