From cc4e40c9944fc0828f19d3868f236bddd492ff61 Mon Sep 17 00:00:00 2001
From: Jan Mach <jan.mach@cesnet.cz>
Date: Wed, 4 Jul 2018 15:43:25 +0200
Subject: [PATCH] Implemented new user-add command to mentat-dbmngr.py module.

This command will be very usefull to insert initial admin user account after first Mentat installation. (Redmine issue: #3383,#3387)
---
 etc/bash_completion.d/mentat |  2 +-
 lib/mentat/module/dbmngr.py  | 84 +++++++++++++++++++++++++++++++-----
 2 files changed, 74 insertions(+), 12 deletions(-)

diff --git a/etc/bash_completion.d/mentat b/etc/bash_completion.d/mentat
index 52a23c5fc..05c65014d 100644
--- a/etc/bash_completion.d/mentat
+++ b/etc/bash_completion.d/mentat
@@ -256,7 +256,7 @@ _mentat_dbmngr_py()
     opts="--regular --shell --debug --verbosity --runlog-dump --action --command --input --interval --config-file --config-dir --log-file --log-level --state-file --runlog-dir --watchdog-delta --mail-subject --mail-from --mail-to"
 
     # Command options
-    optscommand="init fixtures-add fixtures-remove reinit-main reindex-event watchdog"
+    optscommand="init fixtures-add fixtures-remove reinit-main reindex-event user-add watchdog"
 
     # Action options
     optsaction="config-view runlog-dump runlog-view runlogs-dump runlogs-evaluate runlogs-list"
diff --git a/lib/mentat/module/dbmngr.py b/lib/mentat/module/dbmngr.py
index 296d3455b..5ce287d56 100644
--- a/lib/mentat/module/dbmngr.py
+++ b/lib/mentat/module/dbmngr.py
@@ -55,6 +55,12 @@ Usage examples
     # mode.
     mentat-dbmngr.py --command watchdog-events --nagios-plugin --log-level warning
 
+    # Add new user account to the database. Usefull for creating initial account
+    # after fresh installation. Note the use of double quotes to pass values
+    # containing spaces (name, organization) and the use of commas to pass multiple
+    # roles:
+    mentat-dbmngr.py --command user-add login=admin "fullname=Clark Kent" email=kent@dailyplanet.com "organization=Daily Planet, inc." roles=user,admin
+
 
 Available script commands
 -------------------------
@@ -75,6 +81,9 @@ Available script commands
 ``reindex-event``
     Rebuild event database indices (drop all indices and recreate).
 
+``user-add``
+    Add new user account into the database.
+
 ``watchdog-events``
     Check IDEA event database table for last message storage time and send out
     warning email in a case the last message stored is way too old. This simple
@@ -129,6 +138,7 @@ from email.mime.text import MIMEText
 #
 # Custom libraries
 #
+import pyzenkit.zenscript
 import mentat.script.fetcher
 import mentat.const
 
@@ -147,11 +157,12 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
     #
 
     # List of configuration keys.
-    CONFIG_WATCHDOG_DELTA = 'watchdog_delta'
-    CONFIG_MAIL_SUBJECT   = 'mail_subject'
-    CONFIG_MAIL_FROM      = 'mail_from'
-    CONFIG_MAIL_TO        = 'mail_to'
-    CONFIG_NAGIOS_PLUGIN  = 'nagios_plugin'
+    CONFIG_WATCHDOG_DELTA  = 'watchdog_delta'
+    CONFIG_MAIL_SUBJECT    = 'mail_subject'
+    CONFIG_MAIL_FROM       = 'mail_from'
+    CONFIG_MAIL_TO         = 'mail_to'
+    CONFIG_NAGIOS_PLUGIN   = 'nagios_plugin'
+    CONFIG_ADDITIONAL_ARGS = 'additional_args'
 
     def __init__(self):
         """
@@ -208,7 +219,7 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         arggroup_script.add_argument('--mail-from',      type = str, default = None, help = 'source email address for the database watchdog emails')
         arggroup_script.add_argument('--mail-to',        type = str, default = None, help = 'target email address for the database watchdog emails')
         arggroup_script.add_argument('--nagios-plugin',  help = 'execute as Nagios plugin (flag)', action='store_true', default = None)
-        arggroup_script.add_argument('addargs', help = 'optional additional arguments', nargs='*')
+        arggroup_script.add_argument('additional_args',  help = 'optional additional arguments', nargs='*')
 
         return argparser
 
@@ -227,11 +238,12 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         :rtype: dict
         """
         cfgs = (
-            (self.CONFIG_WATCHDOG_DELTA, 900),
-            (self.CONFIG_MAIL_SUBJECT,   'Mentat database watchdog alert'),
-            (self.CONFIG_MAIL_FROM,      'root'),
-            (self.CONFIG_MAIL_TO,        'root'),
-            (self.CONFIG_NAGIOS_PLUGIN,  False)
+            (self.CONFIG_WATCHDOG_DELTA,  900),
+            (self.CONFIG_MAIL_SUBJECT,    'Mentat database watchdog alert'),
+            (self.CONFIG_MAIL_FROM,       'root'),
+            (self.CONFIG_MAIL_TO,         'root'),
+            (self.CONFIG_NAGIOS_PLUGIN,   False),
+            (self.CONFIG_ADDITIONAL_ARGS, [])
         ) + cfgs
         return super()._init_config(cfgs, **kwargs)
 
@@ -423,6 +435,56 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
 
         return self.RESULT_SUCCESS
 
+    def cbk_command_user_add(self):
+        """
+        Implementation of the **user-add** command.
+
+        Add new user account into the database.
+        """
+        self.logger.info("Creating new user account.")
+
+        account_user = UserModel(
+            enabled = True
+        )
+
+        for attr in self.c(self.CONFIG_ADDITIONAL_ARGS):
+            key, value = attr.split('=', 2)
+            if not key or not value:
+                raise pyzenkit.zenscript.ZenScriptException(
+                    "Invalid user account attribute: {}".format(str(attr))
+                )
+
+            if key == 'login':
+                account_user.login = value
+            elif key == 'fullname':
+                account_user.fullname = value
+            elif key == 'email':
+                account_user.email = value
+            elif key == 'organization':
+                account_user.organization = value
+            elif key == 'roles':
+                account_user.roles = value.split(',')
+
+        for attrname in ('login', 'fullname', 'email', 'organization', 'roles'):
+            if not getattr(account_user, attrname, None):
+                raise pyzenkit.zenscript.ZenScriptException(
+                    "Please provide user`s {} as \"{}=value\" command line argument".format(
+                        attrname,
+                        attrname
+                    )
+                )
+
+        try:
+            self.sqlservice.session.add(account_user)
+            self.sqlservice.session.commit()
+            self.logger.info("Added user account to database: '%s'", str(account_user))
+            return self.RESULT_SUCCESS
+
+        except Exception as exc:
+            self.sqlservice.session.rollback()
+            self.logger.info("Unable to add user account to database: '%s' (%s)", str(account_user), str(exc))
+            return self.RESULT_FAILURE
+
     def cbk_command_watchdog_events(self):
         """
         Implementation of the **watchdog-events** command.
-- 
GitLab