From 33566dd0d3baff5a8a7d3760d4c8013351abb043 Mon Sep 17 00:00:00 2001 From: pushkargogte Date: Wed, 26 Aug 2026 17:47:32 +0530 Subject: [PATCH] RANGER-5758 : Support for Openldap service for ranger usersync in ranger docker --- dev-support/ranger-docker/ldap_us_setup.sh | 216 ++++++++++++++++++ dev-support/ranger-docker/ldapusergroup.ldif | 18 ++ .../ranger-docker/openldap-usersync-setup.md | 206 +++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100755 dev-support/ranger-docker/ldap_us_setup.sh create mode 100644 dev-support/ranger-docker/ldapusergroup.ldif create mode 100644 dev-support/ranger-docker/openldap-usersync-setup.md diff --git a/dev-support/ranger-docker/ldap_us_setup.sh b/dev-support/ranger-docker/ldap_us_setup.sh new file mode 100755 index 0000000000..5c66a44015 --- /dev/null +++ b/dev-support/ranger-docker/ldap_us_setup.sh @@ -0,0 +1,216 @@ +#!/bin/bash + +# ============================================================================== +# Ranger Complete Master Alignment Script (Streamlined Fallback Engine) +# Description: Synchronizes all LDAP settings across four layout layers: +# 1. Ranger Admin Install Properties +# 2. Ranger UserSync Install Properties (with Search Base Fallbacks) +# 3. Docker Compose Privilege Overrides +# 4. Dynamically Generates docker-compose.local-ldap.yml +# ============================================================================== + +# --- Target Configuration Blueprints --- +ADMIN_PROP="./scripts/admin/ranger-admin-install-postgres.properties" +USERSYNC_PROP="./scripts/usersync/ranger-usersync-install.properties" +COMPOSE_FILE="docker-compose.ranger.yml" +LDAP_COMPOSE_FILE="docker-compose.local-ldap.yml" + +# --- Core Top-Level Configuration Blueprint --- +AUTH_METHOD="LDAP" +LDAP_HOST="local-ldap" +LDAP_PORT="389" +LDAP_DOMAIN="example.com" +BASE_DN="dc=example,dc=com" +BIND_DN="cn=admin,dc=example,dc=com" +BIND_PASS="p@ssw0rd" +USER_BASE="ou=People,dc=example,dc=com" +GROUP_BASE="ou=People,dc=example,dc=com" +LARGE_GROUP_SYNC_ENABLED="true" + +# Derived Values +LDAP_URL="ldap://${LDAP_HOST}:${LDAP_PORT}" +USER_PATTERN="cn={0},${USER_BASE}" +USER_FILTER="(cn={0})" +GROUP_FILTER="(member=cn={0},${GROUP_BASE})" + +# --- Color Definitions for Logging --- +C_RESET='\033[0m' +C_GREEN='\033[0;32m' +C_YELLOW='\033[0;33m' +C_CYAN='\033[0;36m' +C_RED='\033[0;31m' + +log_info() { echo -e "${C_CYAN}[INFO]${C_RESET} $1"; } +log_ok() { echo -e "${C_GREEN}[OK]${C_RESET} $1"; } +log_warn() { echo -e "${C_YELLOW}[WARN]${C_RESET} $1"; } +log_err() { echo -e "${C_RED}[ERROR]${C_RESET} $1"; exit 1; } + +# --- Pre-flight Validation Checks --- +[[ ! -f "$ADMIN_PROP" ]] && log_err "Target missing: $ADMIN_PROP" +[[ ! -f "$USERSYNC_PROP" ]] && log_err "Target missing: $USERSYNC_PROP" +[[ ! -f "$COMPOSE_FILE" ]] && log_err "Target missing: $COMPOSE_FILE" + +# Handle cross-platform in-place sed adjustments (macOS vs standard Linux) +if [[ "$OSTYPE" == "darwin"* ]]; then + sed_cmd() { sed -i '' "$@"; } +else + sed_cmd() { sed -i "$@"; } +fi + +# Helper function for flat Key-Value file overrides +update_property() { + local key="$1" local val="$2" local file="$3" + local escaped_val=$(printf '%s\n' "$val" | sed 's/[&/\]/\\&/g') + if grep -q "^[[:space:]]*$key[[:space:]]*=" "$file"; then + sed_cmd -E "s|^([[:space:]]*$key[[:space:]]*=[[:space:]]*).*|\1$escaped_val|" "$file" + else + echo "$key = $val" >> "$file" + fi +} + +# ============================================================================== +# Execution Lifecycle +# ============================================================================== + +log_info "Initiating deployment update for all Ranger environment files..." + +# ------------------------------------------------------------------------------ +# Phase 1: Modify ranger-admin-install-postgres.properties +# ------------------------------------------------------------------------------ +log_info "Processing configuration properties inside $ADMIN_PROP..." + +update_property "authentication_method" "$AUTH_METHOD" "$ADMIN_PROP" + +if ! grep -q "Corporate OpenLDAP Authentication Setup" "$ADMIN_PROP"; then + echo -e "\n# ====================================================================" >> "$ADMIN_PROP" + echo "# Corporate OpenLDAP Authentication Setup" >> "$ADMIN_PROP" + echo -e "# ====================================================================\n" >> "$ADMIN_PROP" +fi + +update_property "xa_ldap_url" "$LDAP_URL" "$ADMIN_PROP" +update_property "xa_ldap_base_dn" "$BASE_DN" "$ADMIN_PROP" +update_property "xa_ldap_bind_dn" "$BIND_DN" "$ADMIN_PROP" +update_property "xa_ldap_bind_password" "$BIND_PASS" "$ADMIN_PROP" +update_property "xa_ldap_userDNpattern" "$USER_PATTERN" "$ADMIN_PROP" +update_property "xa_ldap_userSearchFilter" "$USER_FILTER" "$ADMIN_PROP" +update_property "xa_ldap_groupSearchBase" "$GROUP_BASE" "$ADMIN_PROP" +update_property "xa_ldap_groupSearchFilter" "$GROUP_FILTER" "$ADMIN_PROP" +update_property "xa_ldap_groupRoleAttribute" "cn" "$ADMIN_PROP" +update_property "xa_ldap_referral" "ignore" "$ADMIN_PROP" + +log_ok "Successfully updated native Admin install properties." + +# ------------------------------------------------------------------------------ +# Phase 2: Modify ranger-usersync-install.properties (With Lean Fallbacks) +# ------------------------------------------------------------------------------ +log_info "Processing configuration properties inside $USERSYNC_PROP..." + +update_property "SYNC_SOURCE" "ldap" "$USERSYNC_PROP" +update_property "SYNC_LDAP_URL" "$LDAP_URL" "$USERSYNC_PROP" +update_property "SYNC_LDAP_BIND_DN" "$BIND_DN" "$USERSYNC_PROP" +update_property "SYNC_LDAP_BIND_PASSWORD" "$BIND_PASS" "$USERSYNC_PROP" + +# The Single Source of Truth Base DN Path +update_property "SYNC_LDAP_USER_SEARCH_BASE" "$USER_BASE" "$USERSYNC_PROP" +update_property "SYNC_LDAP_USER_SEARCH_FILTER" "(objectClass=inetOrgPerson)" "$USERSYNC_PROP" + +# Explicitly clear out broader root to enforce automated hierarchical fallback loops +update_property "SYNC_LDAP_SEARCH_BASE" "" "$USERSYNC_PROP" + +# Group Specific Filtering Strategy +update_property "SYNC_LDAP_GROUP_SEARCH_FILTER" "(objectClass=groupOfNames)" "$USERSYNC_PROP" + +# Normalizations & Performance Scaling Optimizations +update_property "SYNC_USERNAME_CASE_CONVERSION" "lower" "$USERSYNC_PROP" +update_property "SYNC_GROUPNAME_CASE_CONVERSION" "lower" "$USERSYNC_PROP" +update_property "LGSYNC_LDAP_LARGEGROUPSYNC_ENABLED" "$LARGE_GROUP_SYNC_ENABLED" "$USERSYNC_PROP" + +log_ok "Successfully streamlined UserSync configuration properties." + +# ------------------------------------------------------------------------------ +# Phase 3: Streamline docker-compose.ranger.yml +# ------------------------------------------------------------------------------ +log_info "Reviewing permission parameters inside $COMPOSE_FILE..." + +python3 -c " +import re + +with open('$COMPOSE_FILE', 'r') as f: + yaml_content = f.read() + +regex_pattern = r'(user:\s*root\s*\n\s*)?(command|entrypoint):\s*\n\s*-\s*(?:/bin/bash[\s\S]*?)?/home/ranger/scripts/ranger\.sh\"?' + +clean_native_entrypoint = '''user: root + entrypoint: + - /bin/bash + - -c + - | + # Hand execution off directly to the native initialization runtime + chown -R ranger:ranger /opt/ranger/admin/ + su -s /bin/bash ranger -c \"/home/ranger/scripts/ranger.sh\"''' + +yaml_content = re.sub(r'\s*extra_hosts:\s*\n\s*-\s*\"ccycloud.*?:127\.0\.0\.1\"', '', yaml_content) +updated_content, substitutions = re.subn(regex_pattern, clean_native_entrypoint, yaml_content) + +if substitutions > 0: + with open('$COMPOSE_FILE', 'w') as f: + f.write(updated_content) + print('SUCCESS') +else: + print('NO_CHANGE') +" > /tmp/ranger_py_status.tmp + +PY_STATUS=$(cat /tmp/ranger_py_status.tmp) +rm -f /tmp/ranger_py_status.tmp + +if [ "$PY_STATUS" == "SUCCESS" ]; then + log_ok "Successfully synchronized Docker privilege blocks inside $COMPOSE_FILE." +else + log_warn "Docker Compose alignment skipped (already up to date)." +fi + +# ------------------------------------------------------------------------------ +# Phase 4: Auto-Generate docker-compose.local-ldap.yml +# ------------------------------------------------------------------------------ +log_info "Generating infrastructure layer config inside $LDAP_COMPOSE_FILE..." + +cat << EOF > "$LDAP_COMPOSE_FILE" +services: + local-ldap: + image: osixia/openldap:1.5.0 + container_name: ${LDAP_HOST} + hostname: ${LDAP_HOST}.rangernw + ports: + - "${LDAP_PORT}:389" + - "636:636" + environment: + - LDAP_ORGANISATION=RangerNW + - LDAP_DOMAIN=${LDAP_DOMAIN} + - LDAP_ADMIN_PASSWORD=${BIND_PASS} + - LDAP_TLS=false + networks: + - ranger + + local-ldap-admin: + image: osixia/phpldapadmin:0.9.0 + container_name: ${LDAP_HOST}-admin + ports: + - "8080:80" + environment: + - PHPLDAPADMIN_HTTPS=false + - PHPLDAPADMIN_LDAP_HOSTS=${LDAP_HOST} + networks: + - ranger + depends_on: + - local-ldap + +networks: + ranger: + name: rangernw +EOF + +log_ok "Successfully auto-built $LDAP_COMPOSE_FILE with variables alignment." + +echo +log_ok "All Ranger and OpenLDAP configurations are perfectly unified! 🎉" +log_warn "Run your 'down -v' and 'up -d' routine to compile everything into the cluster." diff --git a/dev-support/ranger-docker/ldapusergroup.ldif b/dev-support/ranger-docker/ldapusergroup.ldif new file mode 100644 index 0000000000..e3366a3c80 --- /dev/null +++ b/dev-support/ranger-docker/ldapusergroup.ldif @@ -0,0 +1,18 @@ +# 1. Base Structural Container +dn: ou=People,dc=example,dc=com +objectClass: organizationalUnit +ou: People + +# 2. User Entry +dn: cn=john,ou=People,dc=example,dc=com +cn: john +sn: doe +objectClass: inetOrgPerson +userPassword: password123 +uid: john + +# 3. Group Entry +dn: cn=engineering,ou=People,dc=example,dc=com +cn: engineering +objectClass: groupOfNames +member: cn=john,ou=People,dc=example,dc=com diff --git a/dev-support/ranger-docker/openldap-usersync-setup.md b/dev-support/ranger-docker/openldap-usersync-setup.md new file mode 100644 index 0000000000..4e67a30a93 --- /dev/null +++ b/dev-support/ranger-docker/openldap-usersync-setup.md @@ -0,0 +1,206 @@ +# Containerized Apache Ranger & OpenLDAP Native Integration + +This blueprint covers the implementation, property configurations, and lifecycle operations required to run an integrated Apache Ranger stack synchronized natively with a local OpenLDAP server on Docker. + +## 1. Run the Prerequisite Setup Script + +Execute the setup script (`ldap_us_setup.sh`) to automatically configure the required integration settings for the Docker environment. This script acts as a **Master Alignment Script** that seamlessly synchronizes LDAP settings across four key layers: + +- **Ranger Admin Properties:** Injects the core Corporate OpenLDAP authentication variables into `ranger-admin-install-postgres.properties`. +- **Ranger UserSync Properties:** Configures source targets, lean search base fallbacks, and group synchronization optimizations inside `ranger-usersync-install.properties`. +- **Docker Compose Overrides:** Safely aligns container privilege blocks (`user: root`) and native initialization runtimes within `docker-compose.ranger.yml`. +- **Infrastructure Generation:** Dynamically auto-generates the `docker-compose.local-ldap.yml` file with matching environment variables (domains, passwords, and mapped ports). + +> **IMPORTANT:** Running this script **fully automates the manual configurations described in Step 2 and Step 4**. If you execute this script, please **do not** manually create the Compose file or edit the properties mentioned below—doing both will cause conflicts. Sections 2 and 4 are provided strictly as a reference matrix. After running the script, you can jump straight to Step 3 (LDIF seed) and Step 5 (Deployment Lifecycle). + +```bash +./ldap_us_setup.sh +``` + +--- + +## 2. Infrastructure Layer Setup (Reference) + +Deploy this file (directory: `ranger/dev-support/ranger-docker`) to spin up your ARM64-compatible local directory service daemon and web admin console. It is configured to join the internal network stack natively. + +> **Note:** If you ran `ldap_us_setup.sh` in Step 1, this file is generated automatically. The snippet below is for reference only. + +```yaml +services: + local-ldap: + image: osixia/openldap:1.5.0 + container_name: local-ldap + hostname: local-ldap.rangernw + ports: + - "389:389" + - "636:636" + environment: + - LDAP_ORGANISATION=RangerNW + - LDAP_DOMAIN=example.com + - LDAP_ADMIN_PASSWORD=p@ssw0rd + - LDAP_TLS=false + networks: + - ranger + + local-ldap-admin: + image: osixia/phpldapadmin:0.9.0 + container_name: local-ldap-admin + ports: + - "8080:80" + environment: + - PHPLDAPADMIN_HTTPS=false + - PHPLDAPADMIN_LDAP_HOSTS=local-ldap + networks: + - ranger + depends_on: + - local-ldap + +networks: + ranger: + name: rangernw +``` + +--- + +## 3. Directory Information Tree Seed (`ldapusergroup.ldif`) + +Create this data file to map out your primary directory structures. It creates the required `ou=People` structural organizational unit, seeds the user `john`, and provisions the `engineering` group with `john` assigned as an active member. + +```ldif +# 1. Base Structural Container +dn: ou=People,dc=example,dc=com +objectClass: organizationalUnit +ou: People + +# 2. User Profile +dn: cn=john,ou=People,dc=example,dc=com +cn: john +sn: doe +objectClass: inetOrgPerson +userPassword: password123 +uid: john + +# 3. Group Profile +dn: cn=engineering,ou=People,dc=example,dc=com +cn: engineering +objectClass: groupOfNames +member: cn=john,ou=People,dc=example,dc=com +``` + +--- + +## 4. Configuration Profiles Reference Matrix + +Once fully synchronized via automation, your configuration files must maintain the following parameters to execute native LDAP mapping and container privilege coordination. + +> **Note:** If you ran `ldap_us_setup.sh` in Step 1, these settings are applied automatically. The values below are for reference only. + +### 4.A Docker Compose State (`docker-compose.ranger.yml` Snippet) + +The `ranger:` block utilizes `user: root` to safely bypass folder ownership permission locks while initializing custom execution scripts: + +```yaml + environment: + - RANGER_VERSION + - RANGER_DB_TYPE + - KERBEROS_ENABLED + - DEBUG_ADMIN=${DEBUG_ADMIN:-false} + - JAVA_OPTS + user: root + entrypoint: + - /bin/bash + - -c + - | + # Hand execution off directly to the native initialization runtime + chown -R ranger:ranger /opt/ranger/admin/ + su -s /bin/bash ranger -c "/home/ranger/scripts/ranger.sh" +``` + +### 4.B Ranger Admin Native Properties + +File: `ranger/dev-support/scripts/admin/ranger-admin-install-postgres.properties` + +```properties +authentication_method = LDAP + +xa_ldap_url = ldap://local-ldap:389 +xa_ldap_base_dn = dc=example,dc=com +xa_ldap_bind_dn = cn=admin,dc=example,dc=com +xa_ldap_bind_password = p@ssw0rd +xa_ldap_userDNpattern = cn={0},ou=People,dc=example,dc=com +xa_ldap_userSearchFilter = (cn={0}) +xa_ldap_groupSearchBase = ou=People,dc=example,dc=com +xa_ldap_groupSearchFilter = (member=cn={0},ou=People,dc=example,dc=com) +xa_ldap_groupRoleAttribute = cn +xa_ldap_referral = ignore +``` + +### 4.C Ranger UserSync Native Properties + +File: `ranger/dev-support/scripts/usersync/ranger-usersync-install.properties` + +```properties +SYNC_SOURCE = ldap +SYNC_LDAP_URL = ldap://local-ldap:389 +SYNC_LDAP_BIND_DN = cn=admin,dc=example,dc=com +SYNC_LDAP_BIND_PASSWORD = p@ssw0rd + +SYNC_LDAP_USER_SEARCH_BASE = ou=People,dc=example,dc=com +SYNC_LDAP_USER_SEARCH_FILTER = (objectClass=inetOrgPerson) + +SYNC_LDAP_GROUP_SEARCH_BASE = ou=People,dc=example,dc=com +SYNC_LDAP_GROUP_SEARCH_FILTER = (objectClass=groupOfNames) + +SYNC_USERNAME_CASE_CONVERSION = lower +SYNC_GROUPNAME_CASE_CONVERSION = lower +LGSYNC_LDAP_LARGEGROUPSYNC_ENABLED = true +``` + +--- + +## 5. Deployment Lifecycle Workflow + +To prevent synchronization timeout failures, follow this strict command execution sequence from the `ranger/dev-support/ranger-docker` directory: + +```bash +# Step 1: Tear down existing infrastructure allocations and clear dynamic volumes +docker compose -f docker-compose.ranger.yml -f docker-compose.ranger-usersync.yml -f docker-compose.ranger-tagsync.yml -f docker-compose.ranger-pdp.yml -f docker-compose.ranger-kms.yml -f docker-compose.local-ldap.yml down -v + +# Step 2: Boot the fresh container environment ecosystem clusters simultaneously +docker compose -f docker-compose.ranger.yml -f docker-compose.ranger-usersync.yml -f docker-compose.ranger-tagsync.yml -f docker-compose.ranger-pdp.yml -f docker-compose.ranger-kms.yml -f docker-compose.local-ldap.yml up -d + +# Step 3: Inject directory mappings BEFORE UserSync executes initial lookups +sleep 10 +docker exec -i local-ldap ldapadd -c -x -D "cn=admin,dc=example,dc=com" -w p@ssw0rd < ldapusergroup.ldif + +# Step 4: Allow Admin tables to finish building, then cycle UserSync to force discovery +sleep 60 +docker restart ranger-usersync +``` + +--- + +## 6. Verification Diagnostics + +Execute this log tailing command to track validation states: + +```bash +docker compose -f docker-compose.ranger.yml -f docker-compose.ranger-usersync.yml -f docker-compose.ranger-tagsync.yml -f docker-compose.ranger-pdp.yml -f docker-compose.ranger-kms.yml -f docker-compose.local-ldap.yml exec ranger-usersync sh -c "tail -f /var/log/ranger/usersync/*.log" +``` + +### Successful Sync Signatures + +Look for the following log entries to confirm a healthy synchronization: + +```text +INFO - initializing source: org.apache.ranger.ldapusersync.process.LdapUserGroupBuilder +INFO - LdapUserGroupBuilder.getGroups() completed with group count: 1 +INFO - LdapUserGroupBuilder.getUsers() completed with user count: 1 +INFO - PolicyMgrUserGroupBuilder - API returned: 200, No. of users uploaded to ranger admin = 1 +``` + +--- + +## Restoring Unix-Based User Synchronization + +To restore Unix-based user synchronization, remove the configuration settings listed above.