From e6c1c5d7809494ced4f7273dac9784b3276c798e Mon Sep 17 00:00:00 2001 From: kshithijiyer Date: Thu, 19 Sep 2019 21:15:31 +0530 Subject: [lib] Adding more check functions and tarssh support - Adding the following check functions: 1. is_passwordless_ssh_configured() - To check if passwordless ssh is configured or not between given nodes with a given user. 2. is_group_exists() - To check if group is present on servers or not. 3. is_user_exists() - To check if a given user is present on servers or not. - Adding functionality to support both sync methods. - Adding nonrootpass parameter to georep_prerequisites() as in the previous logic the password for the non-root and the root user were the same which might not always be the case. - Fixing georep_config_get() and georep_config_set() to take non-root user as well. Change-Id: I8a42d48d56690040dd7f78d1fb919029c0d6e61d Signed-off-by: kshithijiyer --- .../glustolibs/gluster/geo_rep_libs.py | 152 ++++++++++++++------- .../glustolibs/gluster/geo_rep_ops.py | 22 ++- glustolibs-gluster/glustolibs/gluster/lib_utils.py | 78 +++++++++++ 3 files changed, 198 insertions(+), 54 deletions(-) (limited to 'glustolibs-gluster') diff --git a/glustolibs-gluster/glustolibs/gluster/geo_rep_libs.py b/glustolibs-gluster/glustolibs/gluster/geo_rep_libs.py index 17be5e7d2..a850681ce 100644 --- a/glustolibs-gluster/glustolibs/gluster/geo_rep_libs.py +++ b/glustolibs-gluster/glustolibs/gluster/geo_rep_libs.py @@ -32,27 +32,31 @@ from glustolibs.gluster.shared_storage_ops import (enable_shared_storage, is_shared_volume_mounted, check_gluster_shared_volume) from glustolibs.gluster.lib_utils import (group_add, ssh_copy_id, - ssh_keygen, add_user, set_passwd) + ssh_keygen, add_user, set_passwd, + is_group_exists, is_user_exists, + is_passwordless_ssh_configured) from glustolibs.gluster.glusterdir import get_dir_contents def georep_prerequisites(mnode, snode, passwd, user="root", group=None, - mntbroker_dir="/var/mountbroker-root"): + mntbroker_dir="/var/mountbroker-root", + nonrootpass=None): """ Sets up all the prerequisites for geo-rep. Args: mnode(str): The primary master node where the commands are executed snode(str|list): slave nodes on which setup has to be completed. - passwd(str): Password of the specified user. + passwd(str): Password of the root user. Kwargs: user(str): User to be used to setup the geo-rep session. - (Default: root) + (Default: root) mntbroker_dir(str): Mountbroker mount directory. (Default: /var/mountbroker-root) group(str): Group under which geo-rep useraccount is setup. (Default: None) + nonrootpass(str): Password of the non-root user.(Default: None) Returns: bool : True if all the steps are successful, false if there are @@ -60,9 +64,19 @@ def georep_prerequisites(mnode, snode, passwd, user="root", group=None, """ # Converting snode to list if string. - if snode != list: + if not isinstance(snode, list): snode = [snode] + # Checking for blank username. + if not user.strip(): + g.log.error("Blank username isn't possible.") + return False + + # Checking if non-root user is given without userpassword. + if user != "root" and nonrootpass is None: + g.log.error("Non-root user specified without password.") + return False + # Checking and enabling shared storage on master cluster. ret = is_shared_volume_mounted(mnode) if not ret: @@ -89,46 +103,53 @@ def georep_prerequisites(mnode, snode, passwd, user="root", group=None, " user.") return False - # Creating a group on all slave nodes. - ret = group_add(snode, group) - if not ret: - g.log.error("Creating group: %s on all slave nodes failed.", group) - return False - - # Creating a non-root user on all the nodes. - ret = add_user(snode, user, group) - if not ret: - g.log.error("Creating user: %s in group: %s on all slave nodes " - "failed,", user, group) - return False - - # Setting password for user on all the nodes. - ret = set_passwd(snode, user, passwd) - if not ret: - g.log.error("Setting password failed on slaves") - return False - - # Setting up mount broker on first slave node. - ret, _, _ = georep_mountbroker_setup(snode[0], group, mntbroker_dir) - if ret: - g.log.error("Setting up of mount broker directory failed" - " on node: %s", snode[0]) - return False + # Checking and creating a group on all slave nodes. + if not is_group_exists(snode, group): + ret = group_add(snode, group) + if not ret: + g.log.error("Creating group: %s on all slave nodes failed.", + group) + return False + + # Checking and creating a non-root user on all the nodes. + if not is_user_exists(snode, user): + ret = add_user(snode, user, group) + if not ret: + g.log.error("Creating user: %s in group: %s on all slave nodes" + " failed,", user, group) + return False + + # Setting password for user on all the nodes. + ret = set_passwd(snode, user, nonrootpass) + if not ret: + g.log.error("Setting password failed on slaves") + return False + + # Setting up mount broker on first slave node. + ret, _, _ = georep_mountbroker_setup(snode[0], group, + mntbroker_dir) + if ret: + g.log.error("Setting up of mount broker directory" + " failed on node: %s", snode[0]) + return False # Checking if ssh keys are present. - ret = get_dir_contents(mnode, "/root/.ssh/") - ssh_keys = ["id_rsa", "id_rsa.pub"] - if ssh_keys not in ret: + ret = get_dir_contents(mnode, "~/.ssh/") + if "id_rsa" not in ret or "id_rsa.pub" not in ret: ret = ssh_keygen(mnode) if not ret: g.log.error("Failed to create a common pem pub file.") return False # Setting up passwordless ssh to primary slave node. - ret = ssh_copy_id(mnode, snode[0], passwd, user) - if not ret: - g.log.error("Failed to setup passwordless ssh.") - return False + if not is_passwordless_ssh_configured(mnode, snode[0], user): + if user != "root": + ret = ssh_copy_id(mnode, snode[0], nonrootpass, user) + else: + ret = ssh_copy_id(mnode, snode[0], passwd, user) + if not ret: + g.log.error("Failed to setup passwordless ssh.") + return False # Checking if pem files else running gsec_create. ret = get_dir_contents(mnode, "/var/lib/glusterd/geo-replication/") @@ -146,32 +167,40 @@ def georep_prerequisites(mnode, snode, passwd, user="root", group=None, def georep_create_session(mnode, snode, mastervol, slavevol, - user="root", force=False): + user="root", force=False, sync="rsync"): """ Create a geo-replication session between the master and the slave. + Args: mnode(str): The primary master node where the commands are executed snode(str|list): slave node where the commande are executed mastervol(str): The name of the master volume slavevol(str): The name of the slave volume + Kwargs: user (str): User to be used to create geo-rep session.(Default: root) force (bool) : Set to true if session needs to be created with force - else it remains false as the default option - + else it remains false as the default option. + (Default: False) + sync (str): Sync method to be used for geo-rep session.(Default:rsync) Returns: bool : True if all the steps are successful, false if there are any failures in the middle """ # Converting snode to list if string. - if snode != list: + if not isinstance(snode, list): snode = [snode] # Checking for blank username. - if user in ["", " "]: + if not user.strip(): g.log.error("Blank username isn't possible.") return False + if sync not in ["rsync", "tarssh"]: + g.log.error("Invalid sync method used. " + "%s is not a valid sync method.", sync) + return False + # Setting up root geo-rep session. if user == "root": g.log.debug("Creating root geo-rep session.") @@ -181,12 +210,25 @@ def georep_create_session(mnode, snode, mastervol, slavevol, g.log.error("Failed to create geo-rep session") return False - g.log.debug("Setting up meta-volume on %s", mnode) + g.log.debug("Enabling meta-volume for master volume.") ret, _, _ = georep_config_set(mnode, mastervol, snode[0], slavevol, "use_meta_volume", "True") if ret: - g.log.error("Failed to set up meta-volume") + g.log.error("Failed to set up meta-volume for root " + "geo-rep session from %s to %s", + (mastervol, slavevol)) return False + + # Setting up sync method if not rsync. + g.log.debug("Enabling tarssh for master volume.") + if sync == "tarssh": + ret, _, _ = georep_config_set(mnode, mastervol, snode[0], + slavevol, "sync_method", "tarssh") + if ret: + g.log.error("Failed to set sync method to tarssh for root " + "geo-rep session from %s to %s", + (mastervol, slavevol)) + return False return True # Setting up non-root geo-rep session. @@ -228,7 +270,7 @@ def georep_create_session(mnode, snode, mastervol, slavevol, ret, _, _ = georep_create(mnode, mastervol, snode[0], slavevol, user, force) if ret: - g.log.error("Failed to create geo-rep session") + g.log.error("Failed to create geo-rep session.") return False # Setting up pem keys between master and slave node. @@ -239,10 +281,24 @@ def georep_create_session(mnode, snode, mastervol, slavevol, return False # Setting use_meta_volume to true. - g.log.debug("Enabling meta-volume for master volume.") + g.log.debug("Setting use_meta_volume to true.") ret, _, _ = georep_config_set(mnode, mastervol, snode[0], slavevol, - "use_meta_volume", "true") + "use_meta_volume", "true", user) if ret: - g.log.error("Failed to set meta-volume") + g.log.error("Failed to set up meta-volume for %s " + "geo-rep session from %s to %s.", + (user, mastervol, slavevol)) return False + + # Setting up sync method if not rsync. + g.log.debug("Setting sync method to tarssh.") + if sync == "tarssh": + ret, _, _ = georep_config_set(mnode, mastervol, snode[0], + slavevol, "sync_method", "tarssh", + user) + if ret: + g.log.error("Failed to set sync method to tarssh for %s " + "geo-rep session from %s to %s", + (user, mastervol, slavevol)) + return False return True diff --git a/glustolibs-gluster/glustolibs/gluster/geo_rep_ops.py b/glustolibs-gluster/glustolibs/gluster/geo_rep_ops.py index 24161f6ff..7e12113c9 100755 --- a/glustolibs-gluster/glustolibs/gluster/geo_rep_ops.py +++ b/glustolibs-gluster/glustolibs/gluster/geo_rep_ops.py @@ -233,7 +233,8 @@ def georep_create(mnode, mastervol, slaveip, slavevol, user=None, force=False): return g.run(mnode, cmd) -def georep_config_get(mnode, mastervol, slaveip, slavevol, config_key): +def georep_config_get(mnode, mastervol, slaveip, slavevol, config_key, + user=None): """ All the available configurable geo-rep options can be got using the config_key and seeing what it has been set to @@ -256,12 +257,17 @@ def georep_config_get(mnode, mastervol, slaveip, slavevol, config_key): of the command execution. """ - cmd = ("gluster volume geo-replication %s %s::%s config %s" % - (mastervol, slaveip, slavevol, config_key)) + if user: + cmd = ("gluster volume geo-replication %s %s@%s::%s config %s" % + (mastervol, user, slaveip, slavevol, config_key)) + else: + cmd = ("gluster volume geo-replication %s %s::%s config %s" % + (mastervol, slaveip, slavevol, config_key)) return g.run(mnode, cmd) -def georep_config_set(mnode, mastervol, slaveip, slavevol, config, value): +def georep_config_set(mnode, mastervol, slaveip, slavevol, config, value, + user=None): """ All the available configurable geo-rep options can be set with a specific command if required or just with the config parameter @@ -285,8 +291,12 @@ def georep_config_set(mnode, mastervol, slaveip, slavevol, config, value): of the command execution. """ - cmd = ("gluster volume geo-replication %s %s::%s config %s %s" % - (mastervol, slaveip, slavevol, config, value)) + if user: + cmd = ("gluster volume geo-replication %s %s::%s config %s %s" % + (mastervol, user, slaveip, slavevol, config, value)) + else: + cmd = ("gluster volume geo-replication %s %s::%s config %s %s" % + (mastervol, slaveip, slavevol, config, value)) return g.run(mnode, cmd) diff --git a/glustolibs-gluster/glustolibs/gluster/lib_utils.py b/glustolibs-gluster/glustolibs/gluster/lib_utils.py index 516cd76c8..f8b6cc720 100755 --- a/glustolibs-gluster/glustolibs/gluster/lib_utils.py +++ b/glustolibs-gluster/glustolibs/gluster/lib_utils.py @@ -1105,3 +1105,81 @@ def set_passwd(servers, username, passwd): username, server) return False return True + + +def is_user_exists(servers, username): + """ + Checks if user is present on the given servers or not. + + Args: + servers(str|list): list of nodes on which you need to + check if the user is present or not. + username(str): username of user whose presence has to be checked. + + Returns: + bool: True if user is present on all nodes else False. + """ + if not isinstance(servers, list): + servers = [servers] + + cmd = "id %s" % username + results = g.run_parallel(servers, cmd) + + for server, (ret_value, _, _) in results.items(): + if not ret_value: + g.log.error("User %s doesn't exists on server %s.", + (username, server)) + return False + return True + + +def is_group_exists(servers, group): + """ + Checks if group is present on the given servers. + + Args: + servers(str|list): list of nodes on which you need to + check if group is present or not. + group(str): groupname of group whose presence has + to be checked. + + Returns: + bool: True if group is present on all nodes else False. + """ + if not isinstance(servers, list): + servers = [servers] + + cmd = "grep -q %s /etc/group" % group + results = g.run_parallel(servers, cmd) + + for server, (ret_value, _, _) in results.items(): + if not ret_value: + g.log.error("Group %s doesn't exists on server %s.", + (group, server)) + return False + return True + + +def is_passwordless_ssh_configured(fromnode, tonode, username): + """ + Checks if passwordless ssh is configured between nodes or not. + + Args: + fromnode: Server from which passwordless ssh has to be + configured. + tonode: Server to which passwordless ssh has to be + configured. + username: username of user to be used for checking + passwordless ssh. + Returns: + bool: True if configured else false. + """ + cmd = ("ssh %s@%s hostname" % (username, tonode)) + ret, out, _ = g.run(fromnode, cmd) + _, hostname, _ = g.run(tonode, "hostname") + if ret or hostname not in out: + g.log.error("Passwordless ssh not configured " + "from server %s to server %s using user %s.", + (fromnode, tonode, username)) + return False + return True -- cgit