Alex Lourie has uploaded a new change for review.

Change subject: packaging: setup: remote DB installation over otopi
......................................................................

packaging: setup: remote DB installation over otopi

Change-Id: Ib9b24feb5bf063fb47ab10efaa4f16e1762c8b2c
Signed-off-by: Alex Lourie <[email protected]>
---
M packaging/common_utils.py
M packaging/ovirt-engine-dwh-setup.py
2 files changed, 215 insertions(+), 89 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-dwh refs/changes/13/18813/1

diff --git a/packaging/common_utils.py b/packaging/common_utils.py
index 26dca97..d512552 100755
--- a/packaging/common_utils.py
+++ b/packaging/common_utils.py
@@ -584,7 +584,7 @@
         return True
     return False
 
-def createReadOnlyUser(db_dict, PGPASS_FILE):
+def createReadOnlyUser(database, user, password, secured):
 
     # Check whether we can create DB:
     global DB_ADMIN
@@ -596,34 +596,7 @@
     if not canCreateDb:
         return (False, errorMsg)
 
-    # Ask user how would the user be created
-    createReadUser = askYesNo(
-        question=(
-            '\nThis utility can configure a read only user for DB access. '
-            'Would you like to do so?'
-        )
-    )
-
-    if not createReadUser:
-        logging.debug('Skipping creation of read only DB user.')
-        print 'Skipping creationg of read only DB user.'
-        return (True, '')
-
-    user = askQuestion(
-        question='Provide a username for read-only user'
-    )
-
-    password = getpass.getpass(
-        prompt='Provide a password for read-only user: '
-    )
-
-    secured = askYesNo(
-        question=(
-            'Should postgresql be setup with secure connection?'
-        )
-    )
-
-    updatePgHba(db_dict['name'], user)
+    updatePgHba(database, user)
     configurePostgres(user, secured)
     if secured:
         createCertificate()
@@ -631,11 +604,11 @@
     createUser(
         user=user,
         password=password,
-        database=db_dict['name'],
+        database=database,
     )
     updateReadOnly(
         user=user,
-        database=db_dict['name'],
+        database=database,
     )
     return (True, '')
 
@@ -803,16 +776,16 @@
 
 def getDbSize(db_dict, PGPASS_FILE):
     # Returns db size in MB
-    sql = "SELECT pg_database_size(\'%s\')" % db_dict['name']
+    sql = "SELECT pg_database_size(\'%s\')" % db_dict['dbname']
 
     # Work with db credentials copy, rename db name to template1
     db_copy = db_dict.copy()
-    db_copy['name'] = 'template1'
+    db_copy['dbname'] = 'template1'
     out, rc = parseRemoteSqlCommand(
         db_dict=db_copy,
         sqlQuery=sql,
         failOnError=True,
-        errMsg=ERR_DB_GET_SPACE % db_dict['name'],
+        errMsg=ERR_DB_GET_SPACE % db_dict['dbname'],
         envDict={'ENGINE_PGPASS': PGPASS_FILE}
     )
     size = int(out[0]['pg_database_size'])
@@ -861,7 +834,7 @@
 
     if not proceed or not askYesNo(
         proceed.format(
-            db=db_dict['name']
+            db=db_dict['dbname']
         )
     ):
         raise UserWarning(
@@ -878,7 +851,7 @@
            db_dict = DB connection object
 
     """
-    logging.debug("%s DB Backup started", db_dict['name'])
+    logging.debug("%s DB Backup started", db_dict['dbname'])
 
     # Run backup
     cmd = [
@@ -895,7 +868,7 @@
         '-p', db_dict['port'],
         '-Fc',
         '-f', backup_file,
-        db_dict['name'],
+        db_dict['dbname'],
     ]
     execCmd(
         cmdList=cmd,
@@ -903,7 +876,7 @@
         msg='Error during DB backup.',
         envDict={'ENGINE_PGPASS': PGPASS_FILE}
     )
-    logging.debug("%s DB Backup completed successfully", db_dict['name'])
+    logging.debug("%s DB Backup completed successfully", db_dict['dbname'])
 
 
 def getUsernameId(username):
@@ -930,7 +903,7 @@
             ).format(
                 host=db_dict['host'],
                 port=db_dict['port'],
-                database='*' if mode == 'all' else db_dict['name'],
+                database='*' if mode == 'all' else db_dict['dbname'],
                 user=db_dict['username'],
                 password=db_dict['password'],
             ),
@@ -944,6 +917,24 @@
         ''.join([random.choice(string.digits) for i in xrange(4)]),
         ''.join([random.choice(string.letters) for i in xrange(4)]),
     )
+
+
+def createDB(db_dict):
+    sql_query_set = [
+        (
+            '"DROP DATABASE {database};"'.format(
+                database=db_dict['dbname'],
+            )
+        ),
+        (
+            '"CREATE DATABASE {database} owner {owner};"'.format(
+                database=db_dict['dbname'],
+                owner=db_dict['username'],
+            )
+        ),
+    ]
+    for sql_query in sql_query_set:
+        runPostgresSuQuery(sql_query)
 
 
 def createUser(user, password, option='', database=''):
@@ -1096,26 +1087,7 @@
         ),
     ]
     for sql_query in sql_query_set:
-        sql_command = [
-            EXEC_PSQL,
-            '-U', 'postgres',
-            '-c',
-            sql_query,
-        ]
-        cmd = [
-            EXEC_SU,
-            '-l',
-            'postgres',
-            '-c',
-            '{command}'.format(
-                command=' '.join(sql_command),
-            )
-        ]
-
-        execCmd(
-            cmdList=cmd,
-            failOnError=True
-        )
+        runPostgresSuQuery(sql_query)
 
     return True
 
@@ -1187,3 +1159,34 @@
 def restorePgHba():
     return configHbaIdent('ident', 'md5')
 
+def runPostgresSuQuery(query, database=None, failOnError=True):
+    sql_command = [
+        EXEC_PSQL,
+        '-U', 'postgres',
+    ]
+    if database is not None:
+        sql_command.extend(
+            (
+                '-d', database
+            )
+        )
+    sql_command.extend(
+        (
+            '-c', query,
+        )
+    )
+    cmd = [
+        EXEC_SU,
+        '-l',
+        'postgres',
+        '-c',
+        '{command}'.format(
+            command=' '.join(sql_command),
+        )
+    ]
+
+    return execCmd(
+        cmdList=cmd,
+        failOnError=failOnError
+    )
+
diff --git a/packaging/ovirt-engine-dwh-setup.py 
b/packaging/ovirt-engine-dwh-setup.py
index 56d1e84..8b337fb 100755
--- a/packaging/ovirt-engine-dwh-setup.py
+++ b/packaging/ovirt-engine-dwh-setup.py
@@ -19,6 +19,9 @@
 import glob
 import shutil
 import argparse
+import getpass
+import types
+import cracklib
 import common_utils as utils
 from decorators import transactionDisplay
 log_file = None
@@ -26,7 +29,7 @@
 DWH_PACKAGE_NAME="ovirt-engine-dwh"
 PATH_DB_SCRIPTS="/usr/share/ovirt-engine-dwh/db-scripts"
 PATH_WATCHDOG="/usr/share/ovirt-engine-dwh/etl/ovirt_engine_dwh_watchdog.cron"
-EXEC_CREATE_DB="%s/ovirt-engine-history-db-install.sh" % PATH_DB_SCRIPTS
+EXEC_CREATE_SCHEMA="create_schema.sh"
 EXEC_UPGRADE_DB="upgrade.sh"
 FILE_DB_CONN = "/etc/ovirt-engine/ovirt-engine-dwh/Default.properties"
 FILE_ENGINE_CONF_DEFAULTS = "/usr/share/ovirt-engine/conf/engine.conf.defaults"
@@ -93,19 +96,40 @@
             password=db_dict['password'],
             option='createdb',
         )
-        utils.updatePgHba(db_dict['name'], db_dict['username'])
+        utils.createDB(db_dict['dbname'], db_dict['username'])
+        utils.updatePgHba(db_dict['dbname'], db_dict['username'])
         utils.restartPostgres()
         install = 'local'
     else:
         install = 'remote'
+        print 'Remote installation is selected.\n'
+        (
+            db_dict['host'],
+            db_dict['port'],
+            db_dict['username'],
+            db_dict['password'],
+        ) = getDbCredentials()
+        if not utils.dbExists(db_dict, PGPASS_TEMP):
+            raise RuntimeError (
+                (
+                    'Remote installation failed. Please perform '
+                    '\tcreate role {role} with login '
+                    'encrypted password {password};\n'
+                    '\tcreate {db} owner {role}\n'
+                    'on the remote DB, verify it and rerun the setup.'
+                ).format(
+                    role=db_dict['username'],
+                    db=db_dict['dbname'],
+                    password=db_dict['password'],
+                )
+            )
 
     cmd = [
-        EXEC_CREATE_DB,
+        os.path.join(PATH_DB_SCRIPTS, EXEC_CREATE_SCHEMA),
         '-l', dbLogFilename,
         '-u', db_dict['username'],
         '-s', db_dict['host'],
         '-p', db_dict['port'],
-        '-r', install,
     ]
 
     # Create db using shell command
@@ -131,13 +155,13 @@
     currDir = os.getcwd()
     try:
         cmd = [
-                os.path.join(PATH_DB_SCRIPTS, EXEC_UPGRADE_DB),
-                "-s", db_dict["host"],
-                "-p", db_dict["port"],
-                "-u", db_dict["username"],
-                "-d", db_dict["name"],
-                "-l", "/var/log/ovirt-engine/%s" % dbLogFilename,
-              ]
+            os.path.join(PATH_DB_SCRIPTS, EXEC_UPGRADE_DB),
+            "-s", db_dict["host"],
+            "-p", db_dict["port"],
+            "-u", db_dict["username"],
+            "-d", db_dict["name"],
+            "-l", "/var/log/ovirt-engine/%s" % dbLogFilename,
+        ]
         os.chdir(PATH_DB_SCRIPTS)
         output, rc = utils.execCmd(
             cmdList=cmd,
@@ -149,6 +173,63 @@
         os.chdir(currDir)
         raise
 
+def getPassFromUser(string):
+    """
+    get a single password from the user
+    """
+    userInput = getpass.getpass(string)
+    if type(userInput) != types.StringType or len(userInput) == 0:
+        print "Cannot accept an empty password"
+        return getPassFromUser(string)
+
+    try:
+        cracklib.FascistCheck(userInput)
+    except:
+        print "Warning: Weak Password."
+
+    return userInput
+
+def getDbCredentials(
+    hostdefault='',
+    portdefault='',
+    userdefault='',
+):
+    """
+    get db params from user
+    """
+    print (
+        'Remote installation selected. Make sure that DBA creates a user '
+        'and the database in the following fashion:'
+        '\tcreate role <role> with login '
+        'encrypted password <password>;\n'
+        '\tcreate ovirt_engine_history owner <role>;\n'
+    )
+
+    dbhost = utils.askQuestion(
+        question='Enter the host name for the DB server: ',
+        default=hostdefault,
+    )
+
+    dbport = utils.askQuestion(
+        question='Enter the port of the remote DB server: ',
+        default=portdefault or '5432',
+    )
+
+    dbuser = utils.askQuestion(
+        question='Provide a remote DB user: ',
+        default=userdefault,
+    )
+
+    userInput = getPassFromUser(
+        'Please choose a password for the db user: '
+    )
+    # We do not need verification for the re-entered password
+    userInput2 = getpass.getpass("Re-type password: ")
+    if userInput != userInput2:
+            print "ERROR: passwords don't match"
+            return getDbCredentials(dbhost, dbport, dbuser)
+
+    return (dbhost, dbport, dbuser, userInput)
 
 def getDbDictFromOptions():
     if os.path.exists(FILE_DATABASE_CONFIG):
@@ -159,7 +240,7 @@
             dhandler = utils.TextConfigFileHandler(FILE_DATABASE_DWH_CONFIG)
             dhandler.open()
         db_dict = {
-            'name': (
+            'dbname': (
                 dhandler.getParam('DWH_DATABASE') or
                 DB_NAME
             ),
@@ -173,6 +254,10 @@
                 dhandler.getParam('DWH_PASSWORD') or
                 utils.generatePassword()
             ),
+            'readonly': (
+                dhandler.getParam('DWH_READONLY_USER') or
+                None
+            ),
             'engine_user': handler.getParam('ENGINE_DB_USER'),
             'engine_pass': handler.getParam('ENGINE_DB_PASSWORD').replace('"', 
''),
         }
@@ -180,11 +265,12 @@
         dhandler.close()
     else:
         db_dict = {
-            'name': DB_NAME,
+            'dbname': DB_NAME,
             'host': utils.getDbHostName(),
             'port': utils.getDbPort(),
             'username': utils.getDbAdminUser(),
             'password': utils.getPassFromFile(utils.getDbAdminUser()),
+            'readonly': None,
         }
 
     return db_dict
@@ -265,17 +351,24 @@
                 os.makedirs(dwh_path)
                 os.chmod(dwh_path, 0644)
         with open(FILE_DATABASE_DWH_CONFIG, 'w') as fdwh:
-            fdwh.write(
-                (
-                    'DWH_USER={user}\n'
-                    'DWH_PASSWORD={password}\n'
-                    'DWH_DATABASE={database}'
-                ).format(
-                    user=db_dict['username'],
-                    password=db_dict['password'],
-                    database=db_dict['name'],
-                )
+            content = (
+                'DWH_USER={user}\n'
+                'DWH_PASSWORD={password}\n'
+                'DWH_DATABASE={database}\n'
+            ).format(
+                user=db_dict['username'],
+                password=db_dict['password'],
+                database=db_dict['dbname'],
             )
+
+            if db_dict['readonly'] is not None:
+                content += (
+                    'DWH_READONLY_USER={readonly}\n'
+                ).format(
+                    readonly=db_dict['readonly'],
+                )
+
+            fdwh.write(content)
 
         # Get minimal supported version from oVirt Engine
         minimalVersion = utils.getVDCOption("MinimalETLVersion")
@@ -299,6 +392,43 @@
             PGPASS_TEMP = utils.createTempPgpass(db_dict)
             if utils.localHost(db_dict['host']):
                 pg_updated = utils.configHbaIdent()
+
+                # Handle postgres configuration for the read-only user
+                # on local installations only
+
+                readUserCreated = False
+                errMsg = ''
+                if db_dict['readonly'] is None:
+                    # Ask user how would the user be created
+                    createReadUser = utils.askYesNo(
+                        question=(
+                            '\nThis utility can configure a read only user for 
DB access. '
+                            'Would you like to do so?'
+                        )
+                    )
+
+                    if not createReadUser:
+                        logging.debug('Skipping creation of read only DB 
user.')
+                        print 'Skipping creationg of read only DB user.'
+                    else:
+                        user = utils.askQuestion(
+                            question='Provide a username for read-only user'
+                        )
+                        password = getpass.getpass(
+                            prompt='Provide a password for read-only user: '
+                        )
+                        secured = utils.askYesNo(
+                            question=(
+                                'Should postgresql be setup with secure 
connection?'
+                            )
+                        )
+                        readUserCreated, errMsg = utils.createReadOnlyUser(
+                            db_dict['dbname'],
+                            user,
+                            password,
+                            secured,
+                        )
+
             if dbExists(db_dict):
                 try:
                     doBackup = utils.performBackup(db_dict, DB_BACKUPS_DIR, 
PGPASS_TEMP)
@@ -328,13 +458,6 @@
             else:
                 createDB(db_dict)
 
-            # Handle postgres configuration for the read-only user
-            # on local installations only
-
-            readUserCreated = False
-            errMsg = ''
-            if utils.localHost(db_dict["host"]):
-                readUserCreated, errMsg = utils.createReadOnlyUser(db_dict, 
PGPASS_TEMP)
 
             # Start Services
             utils.startEngine()


-- 
To view, visit http://gerrit.ovirt.org/18813
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib9b24feb5bf063fb47ab10efaa4f16e1762c8b2c
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-dwh
Gerrit-Branch: master
Gerrit-Owner: Alex Lourie <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to