#!/usr/bin/python
# -*- coding: utf-8 -*-

# 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 os
import sys
import subprocess
import glob
from random import choice
import string
from optparse import OptionParser
import commands
import shutil

# squelch mysqldb spurious warnings
import warnings
warnings.simplefilter('ignore')
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
# ---- We do this so cloud_utils can be looked up in the following order:
# ---- 1) Sources directory
# ---- 2) waf configured PYTHONDIR
# ---- 3) System Python path
for pythonpath in (
        "@PYTHONDIR@",
        os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
    ):
        if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
# ---- End snippet of code ----

def runCmd(cmds):
    process = subprocess.Popen(' '.join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    if process.returncode != 0:
        raise Exception(stderr)
    return stdout

class DBDeployer(object):
    parser = None
    options = None
    args = None
    isDebug = False
    mgmtsecretkey = None
    dbsecretkey = None
    keyStorePassphrase = "vmops.com"
    encryptiontype = None
    dbConfPath = r"@MSCONF@"
    dbDotProperties = {}
    dbDotPropertiesIndex = 0
    encryptionKeyFile = '@MSCONF@/key'
    encryptionJarPath = '@COMMONLIBDIR@/lib/jasypt-1.9.2.jar'
    success = False
    magicString = 'This_is_a_magic_string_i_think_no_one_will_duplicate'

    def preRun(self):
        def backUpDbDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
            
            if os.path.isfile(dbpPath):
                shutil.copy2(dbpPath, copyPath)
        
        backUpDbDotProperties()
    
    def postRun(self):
        def cleanOrRecoverDbDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
            if os.path.isfile(copyPath):
                if not self.success:
                    shutil.copy2(copyPath, dbpPath)
                os.remove(copyPath)
        
        cleanOrRecoverDbDotProperties()
                
        
    def info(self, msg, result=None):
        output = ""
        if msg is not None:
            output = "%-80s"%msg
            
        if result is True:
            output += "[ \033[92m%-2s\033[0m ]\n"%"OK"
        elif result is False:
            output += "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
        sys.stdout.write(output)
        sys.stdout.flush()
    
    def debug(self, msg):
        msg = "DEBUG:%s"%msg
        sys.stdout.write(msg)
        sys.stdout.flush()

    def putDbProperty(self, key, value):
        if self.dbDotProperties.has_key(key):
            (oldValue, index) = self.dbDotProperties[key]
            self.dbDotProperties[key] = (value, index)
        else:
            self.dbDotProperties[key] = (value, self.dbDotPropertiesIndex)
            self.dbDotPropertiesIndex += 1
    
    def getDbProperty(self, key):
        if not self.dbDotProperties.has_key(key):
            return None
        (value, index) = self.dbDotProperties[key]
        return value
        
    def errorAndExit(self, msg):
        self.postRun()
        err = '''\n\nWe apologize for below error:
***************************************************************      
%s
*************************************************************** 
Please run:

    cloud-setup-encryption -h

for full help
''' % msg
        sys.stderr.write(err)
        sys.stderr.flush()
        sys.exit(1)

    def prepareDBFiles(self):
        def prepareDBDotProperties():
            dbpPath = os.path.join(self.dbConfPath, 'db.properties')
            dbproperties = file(dbpPath).read().splitlines()
            newdbp = []
            emptyLine = 0
            for line in dbproperties:
                passed = False
                line = line.strip()
                if line.startswith("#"): key = line; value = ''; passed = True
                if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True
                
                try:
                    if not passed:
                        (key, value) = line.split('=', 1)
                except Exception, e:
                    err = '''Wrong format in %s (%s):
Besides comments beginning "#" and empty line, all key-value pairs must be in formula of
                    key=value
for example:
                    db.cloud.username = cloud
                    ''' % (dbpPath, line)
                    self.errorAndExit(err)
                self.putDbProperty(key, value)
            self.info("Preparing %s"%dbpPath, True)
        
        prepareDBDotProperties()    
    
    def finalize(self):
        def finalizeDbProperties():
            entries = []
            for key in self.dbDotProperties.keys():
                (value, index) = self.dbDotProperties[key]
                if key.startswith("#"):
                    entries.insert(index, key)
                elif key.startswith(self.magicString):
                    entries.insert(index, '')
                else:
                    entries.insert(index, "%s=%s"%(key, value))
            file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries))
        
        self.info("Finalizing setup ...", None)
        finalizeDbProperties()
        self.info(None, True)
        self.success = True # At here, we have done successfully and nothing more after this flag is set
                        
    def processEncryptionStuff(self):
        def encrypt(input):
            cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=\'%s\''%input, 'password=%s'%self.mgmtsecretkey,'verbose=false']
            return runCmd(cmd).strip('\n')
        
        def saveMgmtServerSecretKey():
            if self.encryptiontype == 'file':
                file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey)
                
        def formatEncryptResult(value):
            return 'ENC(%s)'%value
        
        def encryptDBSecretKey():
            self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey)))

        def encryptKeyStorePassphrase():
            self.putDbProperty('db.cloud.keyStorePassphrase', formatEncryptResult(encrypt(self.keyStorePassphrase)))
        
        def encryptDBPassword():
            dbPassword = self.getDbProperty('db.cloud.password')       
            if dbPassword == '': return # Don't encrypt empty password
            if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
            self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword)))
            
            usagePassword = self.getDbProperty('db.usage.password')
            if usagePassword == '': return # Don't encrypt empty password
            if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
            self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword)))
        
        self.info("Processing encryption ...", None)
        self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
        saveMgmtServerSecretKey()
        encryptDBSecretKey()
	encryptKeyStorePassphrase()
        encryptDBPassword()
        self.info(None, True)
        
    def parseOptions(self):
        def parseOtherOptions():                     
            self.encryptiontype = self.options.encryptiontype
            self.mgmtsecretkey = self.options.mgmtsecretkey
            self.dbsecretkey = self.options.dbsecretkey
	    self.keyStorePassphrase = self.options.keyStorePassphrase
            self.isDebug = self.options.debug
            
            
        def validateParameters():
            if self.encryptiontype != 'file' and self.encryptiontype != 'web':
                self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype)
            
    #---------------------- option parsing and command line checks ------------------------
        usage = """%prog [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug]
    
    This command sets up the CloudStack Encryption.    
    
    """
        self.parser = OptionParser(usage=usage)
        self.parser.add_option("-v", "--debug", action="store_true", dest="debug", default=False,
                          help="If enabled, print the commands it will run as they run")
        self.parser.add_option("-e", "--encrypt-type", action="store", type="string", dest="encryptiontype", default="file",
                          help="Encryption method used for db password encryption. Valid values are file, web. Default is file.")
        self.parser.add_option("-m", "--managementserver-secretkey", action="store", type="string", dest="mgmtsecretkey", default="password",
                          help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password")
        self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password",
                          help="Secret key used to encrypt sensitive database values. A string, default is password")
        self.parser.add_option("-p", "--keystore-passphrase", action="store", type="string", dest="keyStorePassphrase", default="vmops.com",
                          help="Passphrase used while generating jks file for ssl communication. A string, default is vmops.com")
        
        (self.options, self.args) = self.parser.parse_args()
        parseOtherOptions()
        validateParameters()
    
    def run(self):
        try:
            self.preRun()
            self.parseOptions()
            self.prepareDBFiles()            
            self.processEncryptionStuff()
            self.finalize()
        finally:
            self.postRun()
        
        print ''
        print "CloudStack has successfully setup Encryption"
        print ''

if __name__ == "__main__":
   o = DBDeployer()
   o.run()
        
