RANGER-4676, RANGER-5615: Add OpenSearch Dispatcher to Ranger Audit Server#986
RANGER-4676, RANGER-5615: Add OpenSearch Dispatcher to Ranger Audit Server#986paras200 wants to merge 1 commit into
Conversation
| RestClientBuilder restClientBuilder = getRestClientBuilder(urls, protocol, user, password, port); | ||
|
|
||
| client = new RestHighLevelClient(restClientBuilder); | ||
| me = client; |
There was a problem hiding this comment.
Please correct the description.
There was a problem hiding this comment.
Fixed — updated the PR description. The actual change is a bug fix: connect() was not assigning the newly created RestHighLevelClient to the return variable me, so the method could return null on first invocation.
| audit_elasticsearch_password=NONE | ||
| audit_elasticsearch_index=ranger_audits | ||
| audit_elasticsearch_bootstrap_enabled=true | ||
|
|
There was a problem hiding this comment.
How to differentiate whether it is open search or elasticsearch
There was a problem hiding this comment.
From Ranger Admin's perspective, OpenSearch and Elasticsearch use the same REST API (wire-compatible) — there is no separate audit_store=opensearch value. The Admin connects using audit_store=elasticsearch and the audit_elasticsearch_* properties regardless of whether the backend is Elasticsearch or OpenSearch. The differentiation happens at the dispatcher level (separate dispatcher-opensearch module with its own class), not at the Admin level. This properties file is a Docker dev profile where the Admin queries OpenSearch directly for the audit UI — the connection is API-compatible.
| <value>ranger_audits</value> | ||
| </property> | ||
|
|
||
| <property> |
There was a problem hiding this comment.
Description correctly states unauthenticated OpenSearch is allowed. Cross-link to production hardening (require user/password when xasecure.audit.destination.elasticsearch=true).
There was a problem hiding this comment.
Done — updated the user/password property descriptions to explicitly note (dev only) for empty values and added Production: configure user/password or Kerberos keytab guidance.
| private static final String TYPE_OPENSEARCH = | ||
| "opensearch"; | ||
| /** Property controlling OpenSearch destination. */ | ||
| private static final String ES_DEST_PROP = |
There was a problem hiding this comment.
Module is dispatcher-opensearch but config uses xasecure.audit.destination.elasticsearch.*. Intentional for backward compatibility — please document in README/site XML so operators do not search for opensearch.urls.
There was a problem hiding this comment.
Done — added an XML comment block in the site XML explaining this:
<!--
OPENSEARCH DESTINATION CONFIGURATION
NOTE: OpenSearch is wire-compatible with Elasticsearch. Config uses the
xasecure.audit.destination.elasticsearch.* namespace for interoperability
with Ranger Admin audit queries (which read from the same index).
-->This way operators understand why they won't find opensearch.urls and should use the elasticsearch.* keys instead.
| if (clsName != null && clsName.contains( | ||
| "AuditOpenSearchDispatcher")) { | ||
| isEnabled = true; | ||
| props.setProperty(ES_DEST_PROP, "true"); |
There was a problem hiding this comment.
When dispatcher class name contains AuditOpenSearchDispatcher, code sets props.setProperty(ES_DEST_PROP, "true"). Side effect on the shared config object may surprise other components reading the same Properties. Prefer local flag instead of mutating props.
There was a problem hiding this comment.
Good catch — removed props.setProperty(ES_DEST_PROP, "true"). The enablement decision now stays in the local isEnabled boolean without mutating the shared Properties object.
| "type": "long" | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
AuditEventDocMapper indexes additionalInfo (line 93–94) but this schema has no additionalInfo property. Relying on dynamic mapping may cause type conflicts vs security-admin/contrib/elasticsearch_for_audit_setup/conf/ranger_es_schema.json. Align docker schema with contrib schema for Admin audit UI search.
There was a problem hiding this comment.
Fixed — added additionalInfo as a text field to the Docker schema. Note that the contrib schema (security-admin/contrib/elasticsearch_for_audit_setup/conf/ranger_es_schema.json) has the same gap — both were relying on dynamic mapping for this field. I've aligned the Docker schema; the contrib schema fix can be addressed in a follow-up. I can raise a JIRA related to this.
…ted dispatcher module Enhances the Ranger Audit Server with a new OpenSearch dispatcher that consumes audit events from Kafka and bulk-indexes them into OpenSearch, eliminating the Zookeeper dependency required by Solr. - New dispatcher-opensearch module with OpenSearchDispatcherManager and AuditOpenSearchDispatcher - AuditEventDocMapper in dispatcher-common for event-to-document mapping - Configurable thread pool, offset commit strategy, and basic auth - Error handling with partition seek-back and backoff on batch failures - Docker Compose setup and e2e test scripts for local validation
Adds a new OpenSearch dispatcher module to the Ranger Audit Server that consumes audit events from Kafka and bulk-indexes them into OpenSearch, providing an alternative to the Solr-based audit store.
Core dispatcher module (audit-server/audit-dispatcher/dispatcher-opensearch):
Shared mapping (audit-server/audit-dispatcher/dispatcher-common):
Configuration & packaging (distro):
Docker & E2E infrastructure (dev-support/ranger-docker):
Bug fix:
me = clientassignment)How was this patch tested?
Unit tests:
End-to-end test (./scripts/audit/e2e-audit-opensearch.sh):
Pipeline validated: Plugin → Ingestor → Kafka → Dispatcher → OpenSearch