blob: c7d6e3d03402a4b881285145ca05ccb0b05fc875 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <string>
#include "kudu/gutil/strings/substitute.h"
namespace kudu {
namespace ranger {
// Gets the contents of the install.properties file used by the db_setup.py
// script.
inline std::string GetRangerInstallProperties(const std::string& bin_dir,
const std::string& pg_host,
uint16_t pg_port) {
// Taken and modified from:
// https://github.com/apache/ranger/blob/master/security-admin/scripts/install.properties
//
// $0: directory containing postgresql.jar
// $1: postgres host
// $2: postgres port
const char* kInstallProperties = R"(
DB_FLAVOR=POSTGRES
SQL_CONNECTOR_JAR=$0/postgresql.jar
db_root_user=postgres
db_host=$1:$2
db_root_password=
db_ssl_enabled=false
db_ssl_required=false
db_ssl_verifyServerCertificate=false
db_name=ranger
db_user=miniranger
db_password=
rangerAdmin_password=admin
rangerTagsync_password=admin
rangerUsersync_password=admin
keyadmin_password=admin
mysql_core_file=db/mysql/optimized/current/ranger_core_db_mysql.sql
oracle_core_file=db/oracle/optimized/current/ranger_core_db_oracle.sql
postgres_core_file=db/postgres/optimized/current/ranger_core_db_postgres.sql
sqlserver_core_file=db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
sqlanywhere_core_file=db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
)";
return strings::Substitute(kInstallProperties, bin_dir, pg_host, pg_port);
}
// Gets the contents of the ranger-admin-site.xml config that has most of the
// configuration needed to start Ranger.
inline std::string GetRangerAdminSiteXml(const std::string& admin_host,
uint16_t admin_port,
const std::string& pg_host,
uint16_t pg_port,
const std::string& admin_keytab,
const std::string& lookup_keytab,
const std::string& spnego_keytab) {
// For port info, see:
// https://docs.cloudera.com/HDPDocuments/HDP2/HDP-2.6.5/bk_reference/content/ranger-ports.html
//
// postgres DB hardcoded as "ranger"
// ranger jdbc user: miniranger
// ranger jdbc pw: miniranger
// hardcoded auth NONE
//
// $0: postgres host
// $1: postgres port
// $2: admin host
// $3: admin port/RPC (REST API) port
// $4: admin keytab
// $5: lookup keytab
// $6: spnego keytab
const char* kRangerAdminSiteTemplate = R"(
<configuration>
<!-- DB config -->
<property>
<name>ranger.jpa.jdbc.driver</name>
<value>org.postgresql.Driver</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.url</name>
<value>jdbc:postgresql://$0:$1/ranger</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.user</name>
<value>miniranger</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.password</name>
<value>miniranger</value>
<description/>
</property>
<!-- Service config -->
<property>
<name>ranger.externalurl</name>
<value>http://$2:$3</value>
<description/>
</property>
<property>
<name>ranger.service.http.enabled</name>
<value>true</value>
<description/>
</property>
<property>
<name>ranger.authentication.method</name>
<value>NONE</value>
<description/>
</property>
<property>
<name>ranger.service.host</name>
<value>$2</value>
</property>
<property>
<name>ranger.service.http.port</name>
<value>$3</value>
</property>
<property>
<name>ranger.admin.cookie.name</name>
<value>RANGERADMINSESSIONID</value>
</property>
<property>
<name>ranger.plugins.kudu.serviceuser</name>
<value>kudu</value>
</property>
<!-- Kerberos config -->
<property>
<name>ranger.admin.kerberos.keytab</name>
<value>$4</value>
</property>
<property>
<name>ranger.admin.kerberos.principal</name>
<value>rangeradmin/_HOST@KRBTEST.COM</value>
</property>
<property>
<name>ranger.lookup.kerberos.keytab</name>
<value>$5</value>
</property>
<property>
<name>ranger.lookup.kerberos.principal</name>
<value>rangerlookup/_HOST@KRBTEST.COM</value>
</property>
<property>
<name>ranger.spnego.kerberos.keytab</name>
<value>$6</value>
</property>
<property>
<name>ranger.spnego.kerberos.principal</name>
<value>HTTP/_HOST@KRBTEST.COM</value>
</property>
</configuration>
)";
return strings::Substitute(kRangerAdminSiteTemplate, pg_host, pg_port,
admin_host, admin_port, admin_keytab,
lookup_keytab, spnego_keytab);
}
// Gets the ranger-admin-default-site.xml that has some additional configuration
// needed to start Ranger. It's unclear why this has to be a separate file.
inline std::string GetRangerAdminDefaultSiteXml(const std::string& pg_driver,
uint16_t shutdown_port) {
// ranger-admin-default-site.xml
// - postgres JDBC driver path
// - RANGER_HOME (needed for jceks/KMS), impala says this is ranger-home, but the
// conf/jcsks directory doesn't exist for us.
//
// $0: postgres JDBC driver path
// $1: ranger shutdown port
const char* kRangerAdminDefaultSiteTemplate = R"(
<configuration>
<!-- Actual config we need -->
<property>
<name>ranger.jdbc.sqlconnectorjar</name>
<value>$0</value>
<description/>
</property>
<property>
<name>ranger.service.shutdown.port</name>
<value>$1</value>
</property>
<!-- JPA config we can't remove because Ranger fails to start due to config resolution issues -->
<property>
<name>ranger.jpa.showsql</name>
<value>false</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.dialect</name>
<value>org.eclipse.persistence.platform.database.PostgreSQLPlatform</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.maxpoolsize</name>
<value>40</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.minpoolsize</name>
<value>5</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.initialpoolsize</name>
<value>5</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.maxidletime</name>
<value>300</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.maxstatements</name>
<value>500</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.preferredtestquery</name>
<value>select 1;</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.idleconnectiontestperiod</name>
<value>60</value>
<description/>
</property>
<property>
<name>ranger.jpa.jdbc.credential.alias</name>
<value>ranger.db.password</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.dialect</name>
<value>org.eclipse.persistence.platform.database.PostgreSQLPlatform</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.credential.alias</name>
<value>ranger.auditdb.password</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.driver</name>
<value>org.postgresql.Driver</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.url</name>
<value>jdbc:log4jdbc:mysql://localhost/rangeraudit</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.user</name>
<value>rangerlogger</value>
<description/>
</property>
<property>
<name>ranger.jpa.audit.jdbc.password</name>
<value>rangerlogger</value>
<description/>
</property>
<property>
<name>ranger.users.roles.list</name>
<value>ROLE_SYS_ADMIN, ROLE_USER, ROLE_OTHER, ROLE_ANON, ROLE_KEY_ADMIN, ROLE_ADMIN_AUDITOR, ROLE_KEY_ADMIN_AUDITOR</value>
</property>
</configuration>
)";
return strings::Substitute(kRangerAdminDefaultSiteTemplate, pg_driver,
shutdown_port);
}
// Gets the contents of the log4j.properties file which is used to set up the
// logging in Ranger. The only modification to the default log4j.properties is
// the configurable log level.
inline std::string GetRangerLog4jProperties(const std::string& log_level) {
// log4j.properties file.
//
// This is the default log4j.properties with the only difference that rootLogger
// is made configurable if it's needed for debugging.
//
// $0: log level
const char *kLog4jPropertiesTemplate = R"(
log4j.rootLogger = $0,xa_log_appender
# xa_logger
log4j.appender.xa_log_appender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.xa_log_appender.file=$${logdir}/ranger-admin-$${hostname}-$${user}.log
log4j.appender.xa_log_appender.datePattern='.'yyyy-MM-dd
log4j.appender.xa_log_appender.append=true
log4j.appender.xa_log_appender.layout=org.apache.log4j.PatternLayout
log4j.appender.xa_log_appender.layout.ConversionPattern=%d [%t] %-5p %C{6} (%F:%L) - %m%n
# xa_log_appender : category and additivity
log4j.category.org.springframework=warn,xa_log_appender
log4j.additivity.org.springframework=false
log4j.category.org.apache.ranger=info,xa_log_appender
log4j.additivity.org.apache.ranger=false
log4j.category.xa=info,xa_log_appender
log4j.additivity.xa=false
# perf_logger
log4j.appender.perf_appender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.perf_appender.file=$${logdir}/ranger_admin_perf.log
log4j.appender.perf_appender.datePattern='.'yyyy-MM-dd
log4j.appender.perf_appender.append=true
log4j.appender.perf_appender.layout=org.apache.log4j.PatternLayout
log4j.appender.perf_appender.layout.ConversionPattern=%d [%t] %m%n
# sql_appender
log4j.appender.sql_appender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.sql_appender.file=$${logdir}/ranger_admin_sql.log
log4j.appender.sql_appender.datePattern='.'yyyy-MM-dd
log4j.appender.sql_appender.append=true
log4j.appender.sql_appender.layout=org.apache.log4j.PatternLayout
log4j.appender.sql_appender.layout.ConversionPattern=%d [%t] %-5p %C{6} (%F:%L) - %m%n
# sql_appender : category and additivity
log4j.category.org.hibernate.SQL=warn,sql_appender
log4j.additivity.org.hibernate.SQL=false
log4j.category.jdbc.sqlonly=fatal,sql_appender
log4j.additivity.jdbc.sqlonly=false
log4j.category.jdbc.sqltiming=warn,sql_appender
log4j.additivity.jdbc.sqltiming=false
log4j.category.jdbc.audit=fatal,sql_appender
log4j.additivity.jdbc.audit=false
log4j.category.jdbc.resultset=fatal,sql_appender
log4j.additivity.jdbc.resultset=false
log4j.category.jdbc.connection=fatal,sql_appender
log4j.additivity.jdbc.connection=false
)";
return strings::Substitute(kLog4jPropertiesTemplate, log_level);
}
// Gets the core-site.xml that configures authentication.
inline std::string GetRangerCoreSiteXml(bool secure) {
// core-site.xml containing authentication method.
//
// $0: authn method (simple or kerberos)
const char* kCoreSiteTemplate = R"(
<configuration>
<property>
<name>hadoop.security.authentication</name>
<value>$0</value>
</property>
<property>
<name>hadoop.security.group.mapping</name>
<value>org.apache.hadoop.security.NullGroupsMapping</value>
</property>
<property>
<name>hadoop.security.auth_to_local</name>
<value>RULE:[2:$$1@$$0](rangeradmin@KRBTEST.COM)s/(.*)@KRBTEST.COM/ranger/
RULE:[2:$$1@$$0](rangertagsync@KRBTEST.COM)s/(.*)@KRBTEST.COM/rangertagsync/
RULE:[2:$$1@$$0](rangerusersync@KRBTEST.COM)s/(.*)@KRBTEST.COM/rangerusersync/
RULE:[2:$$1@$$0](rangerkms@KRBTEST.COM)s/(.*)@KRBTEST.COM/keyadmin/
RULE:[2:$$1@$$0](atlas@KRBTEST.COM)s/(.*)@KRBTEST.COM/atlas/
DEFAULT</value>
</property>
</configuration>
)";
if (secure) {
return strings::Substitute(kCoreSiteTemplate, "kerberos", "true");
}
return strings::Substitute(kCoreSiteTemplate, "simple", "false");
}
// Gets the contents of ranger-kudu-security.xml for configuring the client.
inline std::string GetRangerKuduSecurityXml(const std::string& policy_cache_dir,
const std::string& service_name,
const std::string& admin_url,
uint32_t policy_poll_interval_ms ) {
// ranger-kudu-security.xml (client configuration file).
//
// $0: Range policy cache dir
// $1: Kudu service name
// $2: Ranger admin URL
// $3: Policy poll interval (ms)
const char* kRangerKuduSecurity = R"(
<configuration>
<property>
<name>ranger.plugin.kudu.policy.cache.dir</name>
<value>$0</value>
</property>
<property>
<name>ranger.plugin.kudu.service.name</name>
<value>$1</value>
</property>
<property>
<name>ranger.plugin.kudu.policy.rest.url</name>
<value>$2</value>
</property>
<property>
<name>ranger.plugin.kudu.policy.source.impl</name>
<value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
</property>
<property>
<name>ranger.plugin.kudu.policy.rest.ssl.config.file</name>
<value></value>
</property>
<property>
<name>ranger.plugin.kudu.policy.pollIntervalMs</name>
<value>$3</value>
</property>
<property>
<name>ranger.plugin.kudu.access.cluster.name</name>
<value>Cluster 1</value>
</property>
</configuration>
)";
return strings::Substitute(kRangerKuduSecurity, policy_cache_dir,
service_name, admin_url, policy_poll_interval_ms);
}
} // namespace ranger
} // namespace kudu