#!/usr/bin/python
# 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.
import StringIO
import xml.etree.ElementTree as ET
import ConfigParser
import os,sys,getopt
from os import listdir
from os.path import isfile, join, dirname, basename
from time import strftime, localtime
import shutil

debugLevel = 1
generateXML = 0
installPropFileName = 'install.properties'

tempLibFolder = "./upgrade-temp"

def showUsage():
	print "upgrade_admin.py [-g] [-h]"
	print "This script will generate %s based on currently installed ranger (v0.4.*) configuration." % (installPropFileName)
	print " -g option will generate ranger-admin-site.xml in the current directory."
	print " -h will display help text."

try:
	opts, args = getopt.getopt(sys.argv[1:],"gh")
except getopt.GetoptError:
	showUsage()
	sys.exit(2)
for opt,arg in opts:
	if (opt == '-g'):
		generateXML = 1
	elif (opt == '-h'):
		showUsage()
		sys.exit(0)
#
# configDirectory: where OLD (champlain) configuration exists and NEW (dal) configuration is written to
#
configDirectory = '/etc/ranger/admin/conf' 
rangerJAASDirectoryName = join(configDirectory,'ranger_jaas')

xaSystemPropFile = 'xa_system.properties' 
ldapPropFile = 'xa_ldap.properties'
rangerJAASPropFile = 'unixauth.properties' 
securityContextFile  = 'security-applicationContext.xml' 
webserverConfigFile = 'ranger_webserver.properties'

rangerSiteXMLFile = "ranger-admin-site.xml"


#
# xmlTemplateDirectory: directory where all of the xml templates are kept here
#
templateDirectoryName = './templates-upgrade'
rangerSiteTemplateXMLFile = "ranger-admin-site-template.xml"

#
# Install Properties To Ranger Properties
#
config2xmlMAP = {
	'service.host':'ranger.service.host',
	'http.enabled':'ranger.service.http.enabled',
	'http.service.port':'ranger.service.http.port',
	'service.shutdownPort':'ranger.service.shutdown.port',
	'service.shutdownCommand':'ranger.service.shutdown.command',
	'https.service.port':'ranger.service.https.port',
	'https.attrib.SSLEnabled':'ranger.service.https.attrib.ssl.enabled',
	'https.attrib.sslProtocol':'ranger.service.https.attrib.ssl.protocol',
	'https.attrib.clientAuth':'ranger.service.https.attrib.client.auth',
	'https.attrib.keyAlias':'ranger.service.https.attrib.keystore.keyalias',
	'https.attrib.keystorePass':'ranger.service.https.attrib.keystore.pass',
	'https.attrib.keystoreFile':'ranger.https.attrib.keystore.file',
	'accesslog.dateformat':'ranger.accesslog.dateformat',
	'accesslog.pattern':'ranger.accesslog.pattern',
	'xa.webapp.url.root':'ranger.externalurl',
	'xa.webapp.contextName':'ranger.contextName',
	'xa.jpa.showsql':'ranger.jpa.showsql',
	'xa.env.local':'ranger.env.local',
	'jdbc.dialect':'ranger.jpa.jdbc.dialect',
	'jdbc.driver':'ranger.jpa.jdbc.driver',
	'jdbc.url':'ranger.jpa.jdbc.url',
	'jdbc.user':'ranger.jpa.jdbc.user',
	'jdbc.password':'ranger.jpa.jdbc.password',
	'jdbc.maxPoolSize':'ranger.jpa.jdbc.maxpoolsize',
	'jdbc.minPoolSize':'ranger.jpa.jdbc.minpoolsize',
	'jdbc.initialPoolSize':'ranger.jpa.jdbc.initialpoolsize',
	'jdbc.maxIdleTime':'ranger.jpa.jdbc.maxidletime',
	'jdbc.maxStatements':'ranger.jpa.jdbc.maxstatements',
	'jdbc.preferredTestQuery':'ranger.jpa.jdbc.preferredtestquery',
	'jdbc.idleConnectionTestPeriod':'ranger.jpa.jdbc.idleconnectiontestperiod',
	'xaDB.jdbc.credential.alias':'ranger.jpa.jdbc.credential.alias',
	'xaDB.jdbc.credential.provider.path':'ranger.jpa.jdbc.credential.provider.path',
	'xa.logs.base.dir':'ranger.logs.base.dir',
	'xa.scheduler.enabled':'ranger.scheduler.enabled',
	'xa.audit.store':'ranger.audit.source.type',
	'audit_solr_urls':'ranger.audit.solr.urls',
	'auditDB.jdbc.dialect':'ranger.jpa.audit.jdbc.dialect',
	'auditDB.jdbc.driver':'ranger.jpa.audit.jdbc.driver',
	'auditDB.jdbc.url':'ranger.jpa.audit.jdbc.url',
	'auditDB.jdbc.user':'ranger.jpa.audit.jdbc.user',
	'auditDB.jdbc.password':'ranger.jpa.audit.jdbc.password',
	'auditDB.jdbc.credential.alias':'ranger.jpa.audit.jdbc.credential.alias',
	'auditDB.jdbc.credential.provider.path':'ranger.jpa.audit.jdbc.credential.provider.path',
	'authentication_method':'ranger.authentication.method',
	'xa_ldap_url':'ranger.ldap.url',
	'xa_ldap_userDNpattern':'ranger.ldap.user.dnpattern',
	'xa_ldap_groupSearchBase':'ranger.ldap.group.searchbase',
	'xa_ldap_groupSearchFilter':'ranger.ldap.group.searchfilter',
	'xa_ldap_groupRoleAttribute':'ranger.ldap.group.roleattribute',
	'xa_ldap_ad_domain':'ranger.ldap.ad.domain',
	'xa_ldap_ad_url':'ranger.ldap.ad.url' } 

def archiveFile(originalFileName):
		archiveDir = dirname(originalFileName)
		archiveFileName = "." + basename(originalFileName) + "." + (strftime("%d%m%Y%H%M%S", localtime()))
		movedFileName = join(archiveDir,archiveFileName)
		print "INFO: moving [%s] to [%s] ......." % (originalFileName,movedFileName)
		os.rename(originalFileName, movedFileName)

def getPropertiesConfigMap(configFileName):
	ret = {}
	config = StringIO.StringIO()
	config.write('[dummysection]\n')
	config.write(open(configFileName).read())
	config.seek(0,os.SEEK_SET)
	fcp = ConfigParser.ConfigParser()
	fcp.optionxform = str
	fcp.readfp(config)
	for k,v in fcp.items('dummysection'):
		ret[k] = v
	return ret

def getPropertiesKeyList(configFileName):
	ret = []
	config = StringIO.StringIO()
	config.write('[dummysection]\n')
	config.write(open(configFileName).read())
	config.seek(0,os.SEEK_SET)
	fcp = ConfigParser.ConfigParser()
	fcp.optionxform = str
	fcp.readfp(config)
	for k,v in fcp.items('dummysection'):
		ret.append(k)
	return ret

def	readFromJCKSFile(jcksFileName,propName):
	fn = jcksFileName
	cmd = "java -cp './cred/lib/*' org.apache.ranger.credentialapi.buildks get '" + propName + "' -provider jceks://file" + fn + " 2> /dev/null"
	pwd = os.popen(cmd).read()
	pwd = pwd.strip()
	return pwd

def writeXMLUsingProperties(xmlTemplateFileName,prop,xmlOutputFileName):
	tree = ET.parse(xmlTemplateFileName)
	root = tree.getroot()
	for config in root.iter('property'):
		name = config.find('name').text
		if (name in prop.keys()):
			config.find('value').text = prop[name]
		else:
			print "ERROR: key not found: %s" % (name)
	if isfile(xmlOutputFileName):
		archiveFile(xmlOutputFileName)
	tree.write(xmlOutputFileName)

def main():
	installFileName = join(templateDirectoryName, installPropFileName)
	installProps = {}
	rangerprops = {}
	
	xaSystemPropFileName = join(configDirectory, xaSystemPropFile)
	xaSysProps = getPropertiesConfigMap(xaSystemPropFileName)

	ldapPropFileName = join(configDirectory, ldapPropFile) 
	xaLdapProps = getPropertiesConfigMap (ldapPropFileName)
	
	jaasPropFileName = join(rangerJAASDirectoryName, rangerJAASPropFile)
	unixauthProps = getPropertiesConfigMap (jaasPropFileName)

	webserverConfigFileName = join(configDirectory, webserverConfigFile)
	webconfig = getPropertiesConfigMap(webserverConfigFileName)

	for k in config2xmlMAP.keys():
		xmlKey = config2xmlMAP[k]
		if (k in xaSysProps.keys()):
			xmlVal = xaSysProps[k]
		elif (k in xaLdapProps.keys()):
			xmlVal = xaLdapProps[k]
		elif (k in unixauthProps.keys()):
			xmlVal = unixauthProps[k]
		elif (k in webconfig.keys()):
			xmlVal = webconfig[k]
		else:
			xmlVal = 'Unknown'
		rangerprops[xmlKey] = xmlVal

	jdbcUrl = xaSysProps['jdbc.url']
	auditJcksFileName = xaSysProps['auditDB.jdbc.credential.provider.path']
	jcksFileName = xaSysProps['xaDB.jdbc.credential.provider.path']

	auditJdbcUrl = xaSysProps['auditDB.jdbc.url']
	auditHostTokens = auditJdbcUrl.split("//")
	auditdbTokens = auditHostTokens[1].split("/")

	tokens = jdbcUrl.split(":")
	hostTokens = jdbcUrl.split("//")
	dbTokens = hostTokens[1].split("/")

	libFolderCmd='dirname `readlink -f /usr/bin/ranger-admin`'
	libFolder = os.popen(libFolderCmd).read().strip() + '/webapp/WEB-INF/lib'

	if (tokens[2] == 'mysql'):
		installProps['DB_FLAVOR'] = 'MYSQL'
		installProps['SQL_COMMAND_INVOKER'] = 'mysql'
		installProps['db_host'] = dbTokens[0]
		installProps['db_name'] = dbTokens[1]
		installProps['audit_db_name'] = auditdbTokens[1]
		mysqlConnectorJarFileName = [ f for f in listdir(libFolder) if (isfile(join(libFolder,f)) and f.startswith("mysql") and f.endswith(".jar")) ]
		if (len(mysqlConnectorJarFileName) >  0):
			if not os.path.exists(tempLibFolder):
			    os.makedirs(tempLibFolder)
			tempLibFile=join(tempLibFolder,mysqlConnectorJarFileName[0])
			shutil.copy(join(libFolder,mysqlConnectorJarFileName[0]), tempLibFile)
			installProps['SQL_CONNECTOR_JAR'] = tempLibFile
	elif (tokens[3] == 'odbc'):
		installProps['DB_FLAVOR'] = 'ORACLE'
		installProps['SQL_COMMAND_INVOKER'] = 'sqlplus'
		installProps['db_host'] = dbTokens[0]
		oraConnectorJarFileName = [ f for f in listdir(libFolder) if (isfile(join(libFolder,f)) and f.startswith("ojdbc") and f.endswith(".jar")) ]
		if (len(oraConnectorJarFileName) >  0):
			if not os.path.exists(tempLibFolder):
			    os.makedirs(tempLibFolder)
			tempLibFile=join(tempLibFolder,oraConnectorJarFileName[0])
			shutil.copy(join(libFolder,oraConnectorJarFileName[0]), tempLibFile)
			installProps['SQL_CONNECTOR_JAR'] = tempLibFile
		#
		# TODO: for oracle, need to find out as how to get these values
		#
		installProps['db_name'] = ''
		installProps['audit_db_name'] = ''
	else:
		print "ERROR: Unable to determine the DB_FLAVOR from url [%]" % (jdbcUrl)
		sys.exit(1)

	installProps['db_user'] = xaSysProps['jdbc.user']
	installProps['db_password'] = readFromJCKSFile(jcksFileName, 'policyDB.jdbc.password')
	installProps['db_root_user'] = 'unknown'
	installProps['db_root_password'] = 'unknown'

	installProps['audit_db_user']=xaSysProps['auditDB.jdbc.user'] 
	installProps['audit_db_password']= readFromJCKSFile(auditJcksFileName, 'auditDB.jdbc.password')

	installProps['policymgr_external_url'] = xaSysProps['xa.webapp.url.root']
	installProps['policymgr_http_enabled'] = xaSysProps['http.enabled']

	securityContextFileName = join(configDirectory, securityContextFile)
	tree = ET.parse(securityContextFileName)
	root = tree.getroot()
	ns = {'beans' : 'http://www.springframework.org/schema/beans'}
	if ( len(root.findall(".//*[@id='activeDirectoryAuthenticationProvider']",ns)) > 0):
		installProps['authentication_method'] = 'AD'
		installProps['xa_ldap_ad_domain'] = xaLdapProps['xa_ldap_ad_domain']
		installProps['xa_ldap_ad_url'] = xaLdapProps['xa_ldap_ad_url']
	elif ( len(root.findall(".//*[@id='ldapAuthProvider']",ns)) > 0 ):
		installProps['authentication_method'] = 'LDAP'
		installProps['xa_ldap_url'] = xaLdapProps['xa_ldap_url']
		installProps['xa_ldap_userDNpattern'] = xaLdapProps['xa_ldap_userDNpattern']
		installProps['xa_ldap_groupSearchBase'] = xaLdapProps['xa_ldap_groupSearchBase']
		installProps['xa_ldap_groupSearchFilter'] = xaLdapProps['xa_ldap_groupSearchFilter']
		installProps['xa_ldap_groupRoleAttribute'] = xaLdapProps['xa_ldap_groupRoleAttribute']
	elif ( len(root.findall(".//*[@id='jaasAuthProvider']",ns)) > 0 ):
		installProps['authentication_method'] = 'UNIX'
		installProps['remoteLoginEnabled'] = unixauthProps['remoteLoginEnabled']
		installProps['authServiceHostName'] = unixauthProps['authServiceHostName']
		installProps['authServicePort'] = unixauthProps['authServicePort']
	else:
		installProps['authentication_method'] = 'NONE'

	rangerprops['ranger.authentication.method'] = installProps['authentication_method']

	installProps['cred_keystore_filename'] = jcksFileName

	keylist = getPropertiesKeyList(installFileName)
	defValMap = getPropertiesConfigMap(installFileName)


	for wk,wv in webconfig.iteritems():
		nk = "ranger." + wk
		nk = nk.replace('.','_')  
		installProps[nk] = wv
		keylist.append(nk)

	writeToFile(keylist,defValMap,installProps,installPropFileName) 

	if (generateXML == 1):
		writeXMLUsingProperties(join(templateDirectoryName,rangerSiteTemplateXMLFile), rangerprops, rangerSiteXMLFile)

def writeToFile(keyList, defValMap, props, outFileName):

	if (isfile(outFileName)):
		archiveFile(outFileName)
	
	outf = open(outFileName, 'w')

	print >> outf, "#"
	print >> outf, "# -----------------------------------------------------------------------------------"
	print >> outf, "# This file is generated as part of upgrade script and should be deleted after upgrade"
	print >> outf, "# Generated at %s " % (strftime("%d/%m/%Y %H:%M:%S", localtime()))
	print >> outf, "# -----------------------------------------------------------------------------------"
	print >> outf, "#"

	for key in keyList:
		if (key in props):
			print >> outf, "%s=%s" % (key,props[key])
		else:
			print >> outf,  "# Default value for [%s] is used\n%s=%s\n#---" % (key, key,defValMap[key])
			
	outf.flush()
	outf.close()


main()
