Ranger HDFS Plugin Install
module.exports = header: 'Ranger HDFS Plugin', handler: ({options}) ->
{hdfs_conf_dir} = options
Wait
@call 'ryba/ranger/admin/wait', once: true, options.wait_ranger_admin
HDFS Dependencies
# @call 'ryba/hadoop/hdfs_client/install' #migation solved it with implicy hdfs_client requirement
@registry.register 'hconfigure', 'ryba/lib/hconfigure'
@registry.register 'hdfs_mkdir', 'ryba/lib/hdfs_mkdir'
@registry.register 'ranger_service', 'ryba/ranger/actions/ranger_service'
@registry.register 'ranger_policy', 'ryba/ranger/actions/ranger_policy'
@registry.register 'ranger_user', 'ryba/ranger/actions/ranger_user'
HDP version
version = null
@system.execute
header: 'HDP Version'
shy: true
cmd: """
hdp-select versions | tail -1
"""
, (err, {status, stdout}) ->
throw err if err
version = stdout.trim()
Package
@service
header: 'Package'
name: "ranger-hdfs-plugin"
Layout
The value present in "XAAUDIT.HDFS.DESTINATION_DIRECTORY" contains variables such as "%app-type% and %time:yyyyMMdd%".
migration: wdavidw 170918, NameNodes are not yet started.
@call
if: options.install['XAAUDIT.HDFS.IS_ENABLED'] is 'true'
header: 'Audit HDFS Policy'
, ->
@ranger_policy
header: 'HDFS Audit'
username: options.ranger_admin.username
password: options.ranger_admin.password
url: options.install['POLICY_MGR_URL']
policy: options.policy_hdfs_audit
@system.mkdir
header: 'HDFS Spool Dir'
if: options.install['XAAUDIT.HDFS.IS_ENABLED'] is 'true'
target: options.install['XAAUDIT.HDFS.FILE_SPOOL_DIR']
uid: options.hdfs_user.name
gid: options.hadoop_group.name
mode: 0o0750
@system.mkdir
header: 'SOLR Spool Dir'
if: options.install['XAAUDIT.SOLR.IS_ENABLED'] is 'true'
target: options.install['XAAUDIT.SOLR.FILE_SPOOL_DIR']
uid: options.hdfs_user.name
gid: options.hadoop_group.name
mode: 0o0750
Ranger User
@ranger_user
if: options.master_fqdn is options.fqdn
header: 'Ranger User'
username: options.ranger_admin.username
password: options.ranger_admin.password
url: options.install['POLICY_MGR_URL']
user: options.plugin_user
Service Repository
Based on step 1 in hdfs plugin configuration. Instead of using the web ui we execute this task using the rest api.
@ranger_service
username: options.ranger_admin.username
password: options.ranger_admin.password
url: options.install['POLICY_MGR_URL']
service: options.service_repo
Note, by default, we're are using the same Ranger principal for every plugin and the principal is created by the Ranger Admin service. Chances are that a customer user will need specific ACLs but this hasn't been tested.
# See [#96](https://github.com/ryba-io/ryba/issues/95): Ranger HDFS: should we use a dedicated principal
@krb5.addprinc options.krb5.admin,
header: 'Plugin Principal'
principal: "#{options.service_repo.configs.username}"
password: options.service_repo.configs.password
Properties
@call -> @file
header: 'Properties'
if: -> version?
source: "#{__dirname}/../../resources/plugin-install.properties"
target: "/usr/hdp/#{version}/ranger-hdfs-plugin/install.properties"
local: true
eof: true
backup: true
write: for k, v of options.install
match: RegExp "^#{quote k}=.*$", 'mg'
replace: "#{k}=#{v}"
append: true
Plugin Scripts
From HDP 2.5 (Ranger 0.6) hdfs plugin need a Client JAAS configuration file to talk with kerberized component. The JAAS configuration can be donne with a jaas file and the Namenonde Env property auth.to.login.conf or can be set by properties in ranger-hdfs-audit.xml file. Not documented be taken from github-source
@call (_, callback) ->
files = ['ranger-hdfs-audit.xml','ranger-hdfs-security.xml','ranger-policymgr-ssl.xml', 'hdfs-site.xml']
sources_props = {}
current_props = {}
files_exists = {}
@system.execute
cmd: """
echo '' | keytool -list \
-storetype jceks \
-keystore /etc/ranger/#{options.install['REPOSITORY_NAME']}/cred.jceks | egrep '.*ssltruststore|auditdbcred|sslkeystore'
"""
code_skipped: 1
@call
if: -> @status -1 #do not need this if the cred.jceks file is not provisioned
, ->
@each files, ({options}, cb) ->
file = options.key
target = "#{hdfs_conf_dir}/#{file}"
ssh = @ssh options.ssh
fs.exists ssh, target, (err, exists) ->
return cb err if err
return cb() unless exists
files_exists["#{file}"] = exists
properties.read ssh, target , (err, props) ->
return cb err if err
sources_props["#{file}"] = props
cb()
@system.link
source: hdfs_conf_dir
target: '/usr/hdp/current/hadoop-hdfs-namenode/etc/hadoop'
@file
header: 'Fix'
target: "/usr/hdp/#{version}/ranger-hdfs-plugin/enable-hdfs-plugin.sh"
write: [
match: RegExp "^HCOMPONENT_CONF_DIR=.*$", 'mg'
replace: "HCOMPONENT_CONF_DIR=#{hdfs_conf_dir}"
,
match: RegExp "^HCOMPONENT_INSTALL_DIR_NAME=.*$", 'mg'
replace: "HCOMPONENT_INSTALL_DIR_NAME=/usr/hdp/current/hadoop-hdfs-namenode"
,
match: RegExp "^HCOMPONENT_LIB_DIR=.*$", 'mg'
replace: "HCOMPONENT_LIB_DIR=/usr/hdp/current/hadoop-hdfs-namenode/lib"
,
match: RegExp "^HCOMPONENT_ARCHIVE_CONF_DIR==.*$", 'mg'
replace: "HCOMPONENT_LIB_DIR=#{hdfs_conf_dir}/.archive"
,
match: RegExp "^HCOMPONENT_INSTALL_DIR==.*$", 'mg'
replace: "HCOMPONENT_INSTALL_DIR=/usr/hdp/current/hadoop-hdfs-namenode"
]
backup: true
mode: 0o750
@system.execute
header: 'Execution'
shy: true
cmd: """
export HADOOP_LIBEXEC_DIR=/usr/hdp/current/hadoop-client/libexec
/usr/hdp/#{version}/ranger-hdfs-plugin/enable-hdfs-plugin.sh
"""
@hconfigure
header: 'Fix Conf'
target: "#{hdfs_conf_dir}/ranger-hdfs-security.xml"
merge: true
properties:
'ranger.plugin.hdfs.policy.rest.ssl.config.file': "#{hdfs_conf_dir}/ranger-policymgr-ssl.xml"
@hconfigure
header: 'Solr JAAS'
target: "#{hdfs_conf_dir}/ranger-hdfs-audit.xml"
merge: true
properties: options.audit
@each files, ({options}, cb) ->
file = options.key
target = "#{hdfs_conf_dir}/#{file}"
ssh = @ssh options.ssh
fs.exists ssh, target, (err, exists) ->
return callback err if err
properties.read ssh, target , (err, props) ->
return cb err if err
current_props["#{file}"] = props
cb()
@call
header: 'Diff'
shy: true
, ->
for file in files
#do not need to go further if the file did not exist
return callback null, true unless sources_props["#{file}"]?
for prop, value of current_props["#{file}"]
return callback null, true unless value is sources_props["#{file}"][prop]
for prop, value of sources_props["#{file}"]
return callback null, true unless value is current_props["#{file}"][prop]
return callback null, false
Dependencies
quote = require 'regexp-quote'
properties = require '../../../lib/properties'
fs = require 'ssh2-fs'