def install(self): """install() detects the os of the server and calls the appropriate function to install redis on that server. Returns: boolean status of the install process """ try: self.rc.startup() except Exception as e: wlogger.log(self.tid, "Could not connect to {0}".format(e), "error", server_id=self.server.id) return False cin, cout, cerr = self.rc.run("ls /etc/*release") files = cout.split() cin, cout, cerr = self.rc.run("cat " + files[0]) status = False if "Ubuntu" in cout: status = self.install_in_ubuntu() elif "CentOS" in cout: status = self.install_in_centos() else: wlogger.log(self.tid, "Server OS is not supported. {0}".format( cout), "error", server_id=self.server.id) self.rc.close() return status
def get_cache_methods(self): tid = self.request.id servers = Server.query.all() methods = [] for server in servers: try: dbm = DBManager(server.hostname, 1636, server.ldap_password, ssl=True, ip=server.ip) except LDAPSocketOpenError as e: wlogger.log( tid, "Couldn't connect to server {0}. Error: " "{1}".format(server.hostname, e), "error") continue entry = dbm.get_appliance_attributes('oxCacheConfiguration') cache_conf = json.loads(entry.oxCacheConfiguration.value) server.cache_method = cache_conf['cacheProviderType'] if server.cache_method == 'REDIS': method = cache_conf['redisConfiguration']['redisProviderType'] server.cache_method += " - " + method db.session.commit() methods.append({"id": server.id, "method": server.cache_method}) wlogger.log(tid, "Cache Methods of servers have been updated.", "success") return methods
def install_in_ubuntu(self): self.run_command("apt-get update") if self.server.os in ('Ubuntu 14', 'Debian 8'): version_number = 14 else: version_number = 16 cmd_list = [ 'wget https://github.com/mbaser/gluu/raw/master/redis/ubuntu{}/redis-tools_4.0.11-1_amd64.deb -O /tmp/redis-tools_4.0.11-1_amd64.deb' .format(version_number), 'wget https://github.com/mbaser/gluu/raw/master/redis/ubuntu{}/redis-server_4.0.11-1_amd64.deb -O /tmp/redis-server_4.0.11-1_amd64.deb' .format(version_number), 'DEBIAN_FRONTEND=noninteractive dpkg -i /tmp/redis*.deb', ] for cmd in cmd_list: cin, cout, cerr = self.run_command(cmd) if cerr and not 'Saving to:' in cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) return False else: wlogger.log(self.tid, cout, "debug", server_id=self.server.id) return True
def check_installed(self): si = self.rc.exists('/usr/bin/stunnel') or self.rc.exists('/bin/stunnel') if si: wlogger.log(self.tid, "stunnel was already installed.", "debug", server_id=self.server.id) return si
def upload_service_file(self): local = os.path.join(app.root_path, 'templates', 'stunnel', 'stunnel.service') remote = '/lib/systemd/system/stunnel.service' wlogger.log(self.tid, "Uploading systemd file", "info", server_id=self.server.id) self.rc.upload(local, remote) self.rc.run("mkdir -p /var/log/stunnel4")
def install_in_centos(self): self.run_command("yum update -y") cin, cout, cerr = self.run_command("yum install stunnel -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # TODO find the successful install message and return True if cerr: return False return True
def __get_remote_client(server, tid): rc = RemoteClient(server.hostname, ip=server.ip) try: rc.startup() wlogger.log(tid, "Connecting to server: {0}".format(server.hostname), "success", server_id=server.id) except Exception as e: wlogger.log(tid, "Could not connect to the server over SSH. Error:" "\n{0}".format(e), "error", server_id=server.id) return None return rc
def install_in_centos(self): self.run_command("yum update -y") cin, cout, cerr = self.run_command("yum install stunnel -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # verifying installation cin, cout, cerr = self.rc.run("yum install stunnel -y") if "already installed" in cout: return True else: return False
def log(self, result): if self.logger_tid: if result[1]: wlogger.log(self.logger_tid, result[1], 'debug', server_id=self.server_id) if result[2]: wlogger.log(self.logger_tid, result[2], 'debug', server_id=self.server_id)
def download_file(tid, c, remote, local): """Shorthand for RemoteClient.download(). This function automatically handles the logging of events to the WebLogger Args: tid (string): id of the task running the command c (:object:`clustermgr.core.remote.RemoteClient`): client to be used for the SSH communication remote (string): location of the file in remote server local (string): local location of the file to upload """ out = c.download(remote, local) wlogger.log(tid, out, 'error' if 'Error' in out else 'success')
def install_in_ubuntu(self): self.run_command("apt-get update") cin, cout, cerr = self.run_command("apt-get install stunnel4 -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # Verifying installation by trying to reinstall cin, cout, cerr = self.rc.run("apt-get install stunnel4 -y") if "stunnel4 is already the newest version" in cout: return True else: return False
def run_and_log(c, cmd, tid, sid): """Shorthand for FakeRemote.run(). This function automatically logs the commands output to be shared in the web frontend. Args: c (:object:`FakeRemote`): class to be used to run cammand cmd (string): the command to be run on local server tid (string): task id of the task to store the log sid (integer): id of the server Returns: the output of the command or the err thrown by the command as a string """ wlogger.log(tid, "Running {}".format(cmd)) result = c.run(cmd) if result[2].strip(): if "Redirecting to /bin/systemctl" in result[2]: wlogger.log(tid, result[2].strip(), "debug", server_id=sid) else: wlogger.log(tid, "An error occurrued while executing " "{}: {}".format(cmd, result[2]), "error", server_id=sid) else: wlogger.log(tid, "Command was run successfully: {}".format(cmd), "success", server_id=sid) return result
def run_command(tid, c, command, container=None): """Shorthand for RemoteClient.run(). This function automatically logs the commands output at appropriate levels to the WebLogger to be shared in the web frontend. Args: tid (string): task id of the task to store the log c (:object:`clustermgr.core.remote.RemoteClient`): client to be used for the SSH communication command (string): the command to be run on the remote server container (string, optional): location where the Gluu Server container is installed. For standalone LDAP servers this is not necessary. Returns: the output of the command or the err thrown by the command as a string """ if container: command = 'chroot {0} /bin/bash -c "{1}"'.format(container, command) wlogger.log(tid, command, "debug") cin, cout, cerr = c.run(command) output = '' if cout: wlogger.log(tid, cout, "debug") output = cout if cerr: # For some reason slaptest decides to send success message as err, so if 'config file testing succeeded' in cerr: wlogger.log(tid, cerr, "success") else: wlogger.log(tid, cerr, "error") output += "\n" + cerr return output
def __update_LDAP_cache_method(tid, server, server_string, method): """Connects to LDAP and updates the cache method and the cache servers :param tid: task id for log identification :param server: :object:`clustermgr.models.Server` to connect to :param server_string: the server string pointing to the redis servers :param method: STANDALONE for proxied and SHARDED for client sharding :return: boolean status of the LDAP update operation """ wlogger.log(tid, "Updating oxCacheConfiguration ...", "debug", server_id=server.id) try: dbm = DBManager(server.hostname, 1636, server.ldap_password, ssl=True, ip=server.ip, ) except Exception as e: wlogger.log(tid, "Couldn't connect to LDAP. Error: {0}".format(e), "error", server_id=server.id) wlogger.log(tid, "Make sure your LDAP server is listening to " "connections from outside", "debug", server_id=server.id) return entry = dbm.get_appliance_attributes('oxCacheConfiguration') cache_conf = json.loads(entry.oxCacheConfiguration.value) cache_conf['cacheProviderType'] = 'REDIS' cache_conf['redisConfiguration']['redisProviderType'] = method cache_conf['redisConfiguration']['servers'] = server_string result = dbm.set_applicance_attribute('oxCacheConfiguration', [json.dumps(cache_conf)]) if not result: wlogger.log(tid, "oxCacheConfigutaion update failed", "fail", server_id=server.id)
def install_in_centos(self): # To automatically start redis on boot # systemctl enable redis self.run_command("yum update -y") self.run_command("yum install epel-release -y") self.run_command("yum update -y") cin, cout, cerr = self.run_command("yum install redis -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # TODO find the successful install message and return True if cerr: return False return True
def install(self): """install() detects the os of the server and calls the appropriate function to install redis on that server. Returns: boolean status of the install process """ status = False if self.os_type == 'deb': status = self.install_in_ubuntu() elif self.os_type == 'rpm': status = self.install_in_centos() else: wlogger.log(self.tid, "Server OS is not supported. {0}".format( cout), "error", server_id=self.server.id) return status
def install_in_centos(self): # To automatically start redis on boot # systemctl enable redis self.run_command("yum update -y") self.run_command("yum install epel-release -y") self.run_command("yum update -y") cin, cout, cerr = self.run_command("yum install redis -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # verifying installation cin, cout, cerr = self.rc.run("yum install redis -y") if "already installed" in cout: return True else: return False
def install_in_ubuntu(self): self.run_command("apt-get update") self.run_command("apt-get upgrade -y") self.run_command("apt-get install software-properties-common -y") self.run_command("add-apt-repository ppa:chris-lea/redis-server -y") self.run_command("apt-get update") cin, cout, cerr = self.run_command("apt-get install redis-server -y") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) # verifying that redis-server is succesfully installed cin, cout, cerr = self.rc.run("apt-get install redis-server -y") if "redis-server is already the newest version" in cout: return True else: return False
def import_ldif(taskid, ldiffile, server): wlogger.log(taskid, "Copying {0} to /tmp/init.ldif".format(ldiffile), "debug") if server.gluu_server: sloc = "gluu-server-" + server.gluu_version put(ldiffile, '/opt/' + sloc + '/tmp/init.ldif') run_command(taskid, chcmd(sloc, 'service solserver stop')) run_command( taskid, chcmd(sloc, '/opt/symas/bin/slapadd -b o=gluu -l /tmp/init.ldif')) run_command(taskid, chcmd(sloc, 'service solserver start')) run_command(taskid, 'rm /opt/' + sloc + '/tmp/init.ldif') else: put(ldiffile, '/tmp/init.ldif') run_command(taskid, 'service solserver stop') run_command(taskid, '/opt/symas/bin/slapadd -b o=gluu -l /tmp/init.ldif') run_command(taskid, 'service solserver start') run_command(taskid, 'rm /tmp/init.ldif')
def setup_redis_cluster(tid): servers = Server.query.filter(Server.redis.is_(True)).filter( Server.stunnel.is_(True)).all() appconf = AppConfiguration.query.first() master_conf = [ "port 7000", "cluster-enabled yes", "cluster-config-file nodes_7000.conf", "cluster-node-timeout 5000", "appendonly yes" ] slave_conf = [ "port 7001", "cluster-enabled yes", "cluster-config-file nodes_7001.conf", "cluster-node-timeout 5000", "appendonly yes" ] for server in servers: rc = RemoteClient(server.hostname, ip=server.ip) try: rc.startup() wlogger.log(tid, "Connecting to server ...", "success", server_id=server.id) except Exception as e: wlogger.log(tid, "Could not connect to the server over SSH. Error:" "{0}\nRedis configuration failed.".format(e), "error", server_id=server.id) continue chdir = '/' if server.gluu_server: chdir = "/opt/gluu-server-{0}".format(appconf.gluu_version) # upload the conf files wlogger.log(tid, "Uploading redis conf files...", "debug", server_id=server.id) rc.put_file(os.path.join(chdir, "etc/redis/redis_7000.conf"), "\n".join(master_conf)) rc.put_file(os.path.join(chdir, "etc/redis/redis_7001.conf"), "\n".join(slave_conf)) # upload the modified init.d file rc.upload( os.path.join(app.root_path, "templates", "redis", "redis-server"), os.path.join(chdir, "etc/init.d/redis-server")) wlogger.log(tid, "Configuration upload complete.", "success", server_id=server.id) return True
def install_in_centos(self): # To automatically start redis on boot # systemctl enable redis # MB: Do we need to update ? #self.run_command("yum update -y") self.run_command("yum install epel-release -y") #self.run_command("yum update -y") if self.server.os in ('CentOS 6', 'RHEL 6'): cmd_list = ( 'yum install -y https://github.com/mbaser/gluu/raw/master/redis/centos6/redis-4.0.11-1.centos6.x86_64.rpm', 'yum install -y http://dl.fedoraproject.org/pub/epel/6/x86_64/Packages/j/jemalloc-3.6.0-1.el6.x86_64.rpm', ) else: cmd_list = ( 'yum install -y https://github.com/mbaser/gluu/raw/master/redis/centos7/redis-4.0.11-1.centos7.x86_64.rpm', 'yum install -y http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/j/jemalloc-3.6.0-1.el7.x86_64.rpm', ) for install_cmd in cmd_list: cin, cout, cerr = self.run_command(install_cmd) wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) return False if self.server.os in ('CentOS 6', 'RHEL 6'): cin, cout, cerr = self.run_command("chkconfig --add redis") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) cin, cout, cerr = self.run_command( "chkconfig --level 345 redis on") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) else: cin, cout, cerr = self.run_command("systemctl enable redis") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) return True
def install_in_centos(self): self.config_file = '/etc/redis.conf' if self.check_installed(): return True cmd_list = ('yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm', 'yum clean all', 'yum install -y redis' ) err = '' for install_cmd in cmd_list: cin, cout, cerr = self.run_command(install_cmd) wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if '/var/cache/yum' in cerr: wlogger.log(self.tid, cerr, "debug", server_id=self.server.id) else: wlogger.log(self.tid, cerr, "error", server_id=self.server.id) return True
def install_in_ubuntu(self): self.config_file = '/etc/redis/redis.conf' if self.check_installed(): return True self.run_command("apt-get update") cmd_list = [ 'DEBIAN_FRONTEND=noninteractive apt-get install -y redis-server', ] for cmd in cmd_list: cin, cout, cerr = self.run_command(cmd) if cerr and not 'Saving to:' in cerr: wlogger.log(self.tid, cerr, "cerror", server_id=self.server.id) return False else: wlogger.log(self.tid, cout, "debug", server_id=self.server.id) return True
def run_command(taskid, command): outlog = StringIO.StringIO() errlog = StringIO.StringIO() wlogger.log(taskid, command, "debug") output = run(command, stdout=outlog, stderr=errlog, timeout=10) if outlog.getvalue(): wlogger.log(taskid, outlog.getvalue(), "debug") if errlog.getvalue(): wlogger.log(taskid, errlog.getvalue(), "error") return output
def run_and_log(rc, cmd, tid, server_id=None): """Runs a command using the provided RemoteClient instance and logs the cout and cerr to the wlogger using the task id and server id :param rc: the remote client to run the command :param cmd: command that has to be executed :param tid: the task id of the celery task for logging :param server_id: OPTIONAL id of the server in which the cmd is executed :return: nothing """ wlogger.log(tid, cmd, "debug", server_id=server_id) _, cout, cerr = rc.run(cmd) if cout: wlogger.log(tid, cout, "debug", server_id=server_id) if cerr: wlogger.log(tid, cerr, "cerror", server_id=server_id)
def install_in_centos(self): #self.run_command("yum update -y") cin, cout, cerr = self.run_command("yum install -y stunnel") wlogger.log(self.tid, cout, "debug", server_id=self.server.id) if cerr.strip(): if '/var/cache/yum' in cerr: wlogger.log(self.tid, cerr, "debug", server_id=self.server.id) else: wlogger.log(self.tid, cerr, "error", server_id=self.server.id) # verifying installation cin, cout, cerr = self.rc.run("yum install -y stunnel") if "already installed" in cout: return True else: return False
def __init__(self, c, gluu_version, server_os=None, logger_tid=None, server_id=None): self.c = c self.logger_tid = logger_tid self.gluu_version = gluu_version self.server_os = server_os self.server_id = server_id if not "RemoteClient" in str(type(c)): self.server_os = c.os self.server_id = c.id self.c = RemoteClient(c.hostname, c.ip) wlogger.log( self.logger_tid, "Making SSH connection to {} ...".format(c.hostname), 'info', server_id=self.server_id, ) try: self.c.startup() wlogger.log( self.logger_tid, "SSH connection to {} was successful.".format(c.hostname), 'success', server_id=self.server_id, ) except: self.c = None wlogger.log( self.logger_tid, "Can't make SSH connection to {}".format(c.hostname), 'fail', server_id=self.server_id, ) if self.server_os: self.appy_config()
def run_command(self, cmd): wlogger.log(self.tid, cmd, "debug", server_id=self.server.id) return self.rc.run(cmd)
def restart_services(self, method): tid = self.request.id servers = Server.query.filter(Server.redis.is_(True)).filter( Server.stunnel.is_(True)).all() appconf = AppConfiguration.query.first() chdir = "/opt/gluu-server-" + appconf.gluu_version ips = [] for server in servers: ips.append(server.ip) wlogger.log(tid, "(Re)Starting services ... ", "info", server_id=server.id) rc = __get_remote_client(server, tid) if not rc: continue def get_cmd(cmd): if server.gluu_server and not server.os == "CentOS 7": return 'chroot {0} /bin/bash -c "{1}"'.format(chdir, cmd) elif "CentOS 7" == server.os: parts = ["ssh", "-o IdentityFile=/etc/gluu/keys/gluu-console", "-o Port=60022", "-o LogLevel=QUIET", "-o StrictHostKeyChecking=no", "-o UserKnownHostsFile=/dev/null", "-o PubkeyAuthentication=yes", "root@localhost", "'{0}'".format(cmd)] return " ".join(parts) return cmd # Common restarts for all if server.os == 'CentOS 6': run_and_log(rc, 'service redis restart', tid, server.id) run_and_log(rc, 'service stunnel4 restart', tid, server.id) elif server.os == 'CentOS 7' or server.os == 'RHEL 7': run_and_log(rc, 'systemctl restart redis', tid, server.id) run_and_log(rc, 'systemctl restart stunnel', tid, server.id) else: run_and_log(rc, 'service redis-server restart', tid, server.id) run_and_log(rc, 'service stunnel4 restart', tid, server.id) # sometime apache service is stopped (happened in Ubuntu 16) # when install_cache_components task is executed; hence we also need to # restart the service run_and_log(rc, get_cmd('service apache2 restart'), tid, server.id) run_and_log(rc, get_cmd('service oxauth restart'), tid, server.id) run_and_log(rc, get_cmd('service identity restart'), tid, server.id) rc.close() if method != 'STANDALONE': wlogger.log(tid, "All services restarted.", "success") return host = appconf.nginx_host mock_server = Server() mock_server.hostname = host rc = __get_remote_client(mock_server, tid) if not rc: wlogger.log(tid, "Couldn't connect to proxy server to restart services" "fail") return mock_server.os = get_os_type(rc) if mock_server.os in ['Ubuntu 14', 'Ubuntu 16', 'CentOS 6']: run_and_log(rc, "service stunnel4 restart", tid, None) run_and_log(rc, "service nutcracker restart", tid, None) if mock_server.os in ["CentOS 7", "RHEL 7"]: run_and_log(rc, "systemctl restart stunnel", tid, None) run_and_log(rc, "systemctl restart nutcracker", tid, None) rc.close()
def setup_redis_cluster(tid): servers = Server.query.filter(Server.redis.is_(True)).filter( Server.stunnel.is_(True)).all() master_conf = ["port 7000", "cluster-enabled yes", "daemonize yes", "dir /var/lib/redis", "dbfilename dump_7000.rdb", "cluster-config-file nodes_7000.conf", "cluster-node-timeout 5000", "appendonly yes", "appendfilename node_7000.aof", "logfile /var/log/redis/redis-7000.log", "save 900 1", "save 300 10", "save 60 10000", ] slave_conf = ["port 7001", "cluster-enabled yes", "daemonize yes", "dir /var/lib/redis", "dbfilename dump_7001.rdb", "cluster-config-file nodes_7001.conf", "cluster-node-timeout 5000", "appendonly yes", "appendfilename node_7001.aof", "logfile /var/log/redis/redis-7001.log", "save 900 1", "save 300 10", "save 60 10000", ] for server in servers: rc = __get_remote_client(server, tid) if not rc: continue # upload the conf files wlogger.log(tid, "Uploading redis conf files...", "debug", server_id=server.id) rc.put_file("/etc/redis/redis_7000.conf", "\n".join(master_conf)) rc.put_file("/etc/redis/redis_7001.conf", "\n".join(slave_conf)) # upload the modified init.d file rc.upload(os.path.join( app.root_path, "templates", "redis", "redis-server"), "/etc/init.d/redis-server") wlogger.log(tid, "Configuration upload complete.", "success", server_id=server.id) wlogger.log(tid, "Updating the oxCacheConfiguration in LDAP", "debug", server_id=server.id) try: dbm = DBManager(server.hostname, 1636, server.ldap_password, ssl=True, ip=server.ip) except Exception as e: wlogger.log(tid, "Failed to connect to LDAP server. Error: \n" "{0}".format(e), "error") continue entry = dbm.get_appliance_attributes('oxCacheConfiguration') cache_conf = json.loads(entry.oxCacheConfiguration.value) cache_conf['cacheProviderType'] = 'REDIS' cache_conf['redisConfiguration']['redisProviderType'] = 'CLUSTER' result = dbm.set_applicance_attribute('oxCacheConfiguration', [json.dumps(cache_conf)]) if not result: wlogger.log(tid, "oxCacheConfiguration update failed", "error", server_id=server.id) else: wlogger.log(tid, "Cache configuration update successful in LDAP", "success", server_id=server.id) return True