#!/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 re
import StringIO
import xml.etree.ElementTree as ET
import ConfigParser
import os,errno,sys,getopt
from os import listdir
from os.path import isfile, join, dirname, basename
from urlparse import urlparse
from time import gmtime, 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 (token[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]) 
			val = props[key]
		else:
			print >> outf,  "# Default value for [%s] is used\n%s=%s\n#---" % (key, key,defValMap[key]) 
			val = defValMap[key]
			
	outf.flush()
	outf.close()


main()
