def issueCertificate(self, forced=False): if not self.installSocat(): return success = False if self.DNS is None: if not self.setDNS(): return if forced: cmd = "%s --issue -d %s --debug --tls --tlsport %s --force --no-color --log %s" % ( self.acmeScript, self.DNS, glb.mobilityConfig['mPort'], self.acmeLog) else: cmd = "%s --issue -d %s --debug --tls --tlsport %s --no-color --log %s" % ( self.acmeScript, self.DNS, glb.mobilityConfig['mPort'], self.acmeLog) out = ds.util_subprocess(cmd, True) logger.debug("Running cmd: %s" % cmd) for line in out[1].splitlines(): if 'on_issue_success' in line.lower(): success = True if not success: print("\nFailed to setup LetsEncrypt certificate") logger.error("Failed to setup LetsEncrypt certificate") return success
def setupAcme(self): if ds.askYesOrNo("Install ache.sh onto server"): cmd = "%s --install --nocron --debug --no-color --log %s" % ( self.acmeScript, self.acmeLog) out = ds.util_subprocess(cmd, True) logger.debug("Running cmd: %s" % cmd) if 'Installed' in out[0]: print("acme.sh successfully installed") logger.info("acme.sh successfully installed") if 'Install failed' in out[1]: print("ache.sh failed to install. See %s" % self.acmeLog)
def removeAcme(self): print("This will also remove any cron setup") if ds.askYesOrNo("Remove ache.sh from server"): cmd = "%s --uninstall --debug --no-color --log %s" % ( self.acmeScript, self.acmeLog) out = ds.util_subprocess(cmd, True) logger.debug("Running cmd: %s" % cmd) ds.removeAllFolders(self.acmeRoot) ds.removeAllFiles(self.acmeRoot) if os.path.isfile("/etc/cron.d/dsapp_acme"): logger.info("Removing cron file") os.remove("/etc/cron.d/dsapp_acme") print("Uninstall complete") logger.info("Uninstall complete")
def getPinglessDevices(log): create_QueryString_table(log) # Create tempfile for large tables name = tempfile.TemporaryFile(mode='w+b') select_cmd ="sqlite3 -column -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\" from data where deviceid not in (select deviceid from data where cmd=\"Ping\") group by deviceid;'" % environ_db p = subprocess.Popen(select_cmd, shell=True, stdout=name) p.wait() name.seek(0) out = name.read() pydoc.pager(out) if ds.askYesOrNo("Output results to CSV"): select_cmd ="sqlite3 -csv -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\" from data where deviceid not in (select deviceid from data where cmd=\"Ping\") group by deviceid;' > %s/manualSync_devices.csv" % (environ_db, dsappdata) out = ds.util_subprocess(select_cmd) print ("Data exported to %s/manualSync_devices.csv" % dsappdata) print()
def getDeviceCommands(log): create_QueryString_table(log) # Create tempfile for large tables name = tempfile.TemporaryFile(mode='w+b') select_cmd = "sqlite3 -column -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\", cmd as \"Command\", count(cmd) as \"Count\" from data group by userKey, cmd order by \"Count\" desc;'" % environ_db p = subprocess.Popen(select_cmd, shell=True, stdout=name) p.wait() name.seek(0) out = name.read() pydoc.pager(out) if ds.askYesOrNo("Output results to CSV"): select_cmd = "sqlite3 -csv -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\", cmd as \"Command\", count(cmd) as \"Count\" from data group by userKey, cmd order by \"Count\" desc;' > %s/device_requests.csv" % (environ_db, dsappdata) out = ds.util_subprocess(select_cmd) print ("Data exported to %s/device_requests.csv" % dsappdata) print()
def getPinglessDevices(log): if create_QueryString_table(log): # Create tempfile for large tables with tempfile.TemporaryFile(mode='w+b') as name: select_cmd = "sqlite3 -column -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\" from data where deviceid not in (select deviceid from data where cmd=\"Ping\") group by deviceid;'" % environ_db p = subprocess.Popen(select_cmd, shell=True, stdout=name) p.wait() name.seek(0) out = name.read() pydoc.pager(out) if ds.askYesOrNo("Output results to CSV"): DATE = datetime.datetime.now().strftime('%Y%m%dT%H%M%S') select_cmd = "sqlite3 -csv -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\" from data where deviceid not in (select deviceid from data where cmd=\"Ping\") group by deviceid;' > %s/manualSync_devices-%s.csv" % ( environ_db, glb.dsappdata, DATE) out = ds.util_subprocess(select_cmd) print("Data exported to %s/manualSync_devices-%s.csv" % (glb.dsappdata, DATE)) print()
def getDeviceCommands(log): if create_QueryString_table(log): # Create tempfile for large tables with tempfile.TemporaryFile(mode='w+b') as name: select_cmd = "sqlite3 -column -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\", cmd as \"Command\", count(cmd) as \"Count\" from data group by userKey, cmd order by \"Count\" desc;'" % environ_db p = subprocess.Popen(select_cmd, shell=True, stdout=name) p.wait() name.seek(0) out = name.read() pydoc.pager(out) if ds.askYesOrNo("Output results to CSV"): DATE = datetime.datetime.now().strftime('%Y%m%dT%H%M%S') select_cmd = "sqlite3 -csv -header %s 'select user as \"User\", deviceid as \"DeviceId\", address as \"Address\", cmd as \"Command\", count(cmd) as \"Count\" from data group by userKey, cmd order by \"Count\" desc;' > %s/device_requests-%s.csv" % ( environ_db, glb.dsappdata, DATE) out = ds.util_subprocess(select_cmd) print("Data exported to %s/device_requests-%s.csv" % (glb.dsappdata, DATE)) print()
def installSocat(self): installed = False if not self.is_socatInstalled(): print("Please install socat first") logger.warning("Please install socat first") if ds.askYesOrNo("Install socat now"): cmd = "zypper --non-interactive install socat" out = ds.util_subprocess(cmd) logger.debug("Running cmd: %s" % cmd) if not self.is_socatInstalled(): print('Failed to install socat') logger.error('Failed to install socat') installed = False else: print("socat successfully installed\n") logger.info("socat successfully installed") installed = True else: installed = False else: installed = True return installed
def is_socatInstalled(self): cmd = "which socat >/dev/null 2>&1; echo $?" out = ds.util_subprocess(cmd) return not bool(int(out[0]))
if args.vacuum: ds.vacuumDB(dbConfig) ds.rcDS('start') ds.eContinue() sys.exit(0) # Show Users if args.users: if args.devices: data = ds.getUsers_and_Devices(dbConfig, showBoth=True) count_out = "Number of users: %s\nCount of devices: %s\n" % (data['userCount'][0]['count'], data['deviceCount'][0]['count']) else: data = ds.getUsers_and_Devices(dbConfig, showUsers=True) count_out = "Number of users: %s\n" % data['userCount'][0]['count'] out = ds.util_subprocess(data['cmd']) pydoc.pager(count_out + '\n' + out[0]) sys.exit(0) # Show Devices if args.devices: if args.users: data = ds.getUsers_and_Devices(dbConfig, showBoth=True) count_out = "Number of users: %s\nCount of devices: %s\n" % (data['userCount'][0]['count'], data['deviceCount'][0]['count']) else: data = ds.getUsers_and_Devices(dbConfig, showDevices=True) count_out = "Number of devices: %s\n" % data['deviceCount'][0]['count'] out = ds.util_subprocess(data['cmd']) pydoc.pager(count_out + '\n' + out[0]) sys.exit(0)
ds.eContinue() sys.exit(0) # Show Users if args.users: logger.info("Running switch: users") if args.devices: logger.info("Running switch: devices") data = ds.getUsers_and_Devices(showBoth=True) count_out = "Number of users: %s\nCount of devices: %s\n" % ( data['userCount'][0]['count'], data['deviceCount'][0]['count']) else: data = ds.getUsers_and_Devices(showUsers=True) count_out = "Number of users: %s\n" % data['userCount'][0]['count'] out = ds.util_subprocess(data['cmd']) pydoc.pager(count_out + '\n' + out[0]) sys.exit(0) # Show Devices if args.devices: logger.info("Running switch: devices") if args.users: logger.info("Running switch: users") data = ds.getUsers_and_Devices(showBoth=True) count_out = "Number of users: %s\nCount of devices: %s\n" % ( data['userCount'][0]['count'], data['deviceCount'][0]['count']) else: data = ds.getUsers_and_Devices(showDevices=True) count_out = "Number of devices: %s\n" % data['deviceCount'][0]['count']
def install_settings(): # TODO : DEV : Prompt to continue print("This feature is currently under development:\n\nTasks to complete:") print( "LDAP settings import\nCertificate check / import\nUsers and group import\n" ) if not ds.askYesOrNo("Continue with restore"): return ds.datasyncBanner() # Is mobility already installed? Return if YES if os.path.isfile(glb.installedConnector): print( "Mobility already installed\nOnly use 'restore' to install Mobility from backup" ) logger.warning("Mobility already installed") return setupDir = glb.dirOptMobility + '/syncengine/connectors/mobility/cli' path = getConfig() if path is None: return fileName = ds.file_content(path)[0] ds.untar_file(path, extractPath=glb.dsapptmp) readConfigs(glb.dsapptmp + '/' + fileName) # Validate all needed variabes are NOT None missingAttribute = False if glb.dbConfig['pass'] is None: print(ERROR_MSG) logger.error("glb.dbConfig['pass'] = None") missingAttribute = True if gwConfig['sListenAddress'] is None: print(ERROR_MSG) logger.error("gwConfig['sListenAddress'] = None") missingAttribute = True if mobilityConfig['galUserName'] is None: print(ERROR_MSG) logger.error("mobilityConfig['galUserName'] = None") missingAttribute = True if mobilityConfig['mPort'] is None: print(ERROR_MSG) logger.error("mobilityConfig['mPort'] = None") missingAttribute = True if mobilityConfig['mSecure'] is None: print(ERROR_MSG) logger.error("mobilityConfig['mSecure'] = None") missingAttribute = True if gwConfig['gport'] is None: print(ERROR_MSG) logger.error("gwConfig['gport'] = None") missingAttribute = True if gwConfig['gListenAddress'] is None: print(ERROR_MSG) logger.error("gwConfig['gListenAddress'] = None") missingAttribute = True if gwConfig['sPort'] is None: print(ERROR_MSG) logger.error("gwConfig['sPort'] = None") missingAttribute = True if gwConfig['sSecure'] is None: print(ERROR_MSG) logger.error("gwConfig['sSecure'] = None") missingAttribute = True if trustedConfig['name'] is None: print(ERROR_MSG) logger.error("trustedConfig['name'] = None") missingAttribute = True if trustedConfig['key'] is None: print(ERROR_MSG) logger.error("trustedConfig['key'] = None") missingAttribute = True if missingAttribute: return # Get local IP, and validate IP is NOT 127.0.0.1 local_IP = socket.gethostbyname(socket.gethostname()) logger.debug("Detected local address: %s" % local_IP) if '127.0.0' in local_IP: logger.warning( "Detected address defaulted to localhost. Setting to 'None'") local_IP = None if local_IP is None: print("Unable to detect server address") logger.warning("Unable to detect server address, or set to None") if ds.askYesOrNo("Manually enter server address"): local_IP = raw_input("Server address: ") else: return # Does local_IP match sListenAddress if local_IP != gwConfig['sListenAddress']: print( "\nSever address does not match stored backup address\nLocal: %s\nBackup: %s\n" % (local_IP, gwConfig['sListenAddress'])) if not ds.askYesOrNo( "Is detected local server address correct (%s)" % local_IP): if ds.askYesOrNo("Manually enter server address"): local_IP = raw_input("Server address: ") else: return if ds.askYesOrNo("Install with local server address (%s)" % local_IP): gwConfig['sListenAddress'] = local_IP else: if not ds.askYesOrNo("Install with backup address (%s)" % gwConfig['sListenAddress']): return # Create a trusted application key trustedKey = glb.dsapptmp + '/' + fileName + '/trustedKey.key' with open(trustedKey, 'a') as key: key.write(trustedConfig['key']) logger.info("Created trusted key at: %s" % trustedKey) # Get path / file isoPath = ds.getMobilityISO() # Verify ISO is mobility iso if not ds.checkISO_content(isoPath): return # Prompt to run install ds.datasyncBanner() print("Mobility Backup: %s" % fileName) print("Mobility ISO: %s" % os.path.basename(isoPath)) if not ds.askYesOrNo("Install with settings"): return # All checks paasses - Add isoPath as 'mobility' repo print("\nSetting up mobility repository..") logger.info("Setting up mobility repository") cmd = "zypper rr mobility" logger.debug("Running: %s" % cmd) out = ds.util_subprocess(cmd, True) cmd = "zypper addrepo 'iso:///?iso=%s&url=file://%s' mobility" % ( os.path.basename(isoPath), os.path.dirname(isoPath)) logger.debug("Running: %s" % cmd) out = ds.util_subprocess(cmd, True) # Refresh Repo print("Refreshing mobility repository") logger.info("Refreshing mobility repository") cmd = "zypper --gpg-auto-import-keys ref -f mobility" logger.debug("Running: %s" % cmd) out = ds.util_subprocess(cmd, True) # Install mobility pattern cmd = "zypper -x pt --repo mobility" logger.debug("Running: %s" % cmd) out = ds.util_subprocess(cmd, True) try: patternName = out[0].split('pattern name=')[1].split('"')[1] logger.debug("Found Mobility pattern: %s" % patternName) except: print("Unable to find Mobility pattern") logger.error("Unable to find Mobility pattern") return print("Installing Mobility pattern: %s" % patternName) logger.info("Installing Mobility pattern: %s" % patternName) cmd = "zypper --non-interactive install -t pattern %s" % patternName logger.debug("Running: %s" % cmd) out = ds.util_subprocess(cmd, True) # Get version of GMS installed if gwConfig['sSecure'] == 'https': gwConfig['sSecure'] = 'yes' elif gwConfig['sSecure'] == 'http': gwConfig['sSecure'] = 'no' # Swtich msecure 1 or 0 to true or false if bool(mobilityConfig['mSecure']): mobilityConfig['mSecure'] = 'true' else: mobilityConfig['mSecure'] = 'false' # Create variables for gms installs setup_one = "sh " + setupDir + "/postgres_setup_1.sh" setup_two = "python " + setupDir + "/odbc_setup_2.pyc" setup_three = "python " + setupDir + "/mobility_setup_3.pyc --provision 'groupwise' --dbpass '%s'" % glb.dbConfig[ 'pass'] setup_four = "sh " + setupDir + "/enable_setup_4.sh" setup_five = "python " + setupDir + "/mobility_setup_5.pyc --provision 'groupwise' --galuser '%(galUserName)s' --block false --selfsigned true --path '' --lport '%(mPort)s' --secure %(mSecure)s" % mobilityConfig setup_six = "python " + setupDir + "/groupwise_setup_6.pyc --keypath '%s' --lport '%s' --lip '%s' --version '802' --soap %s --key '%s' --sport %s --psecure '%s'" % ( trustedKey, gwConfig['gport'], gwConfig['sListenAddress'], gwConfig['gListenAddress'], trustedConfig['name'], gwConfig['sPort'], gwConfig['sSecure']) setup_seven = "python " + setupDir + "/start_mobility.pyc" # Run through install with all setups print("\nConfiguring and extending database..") logger.info("Configuring and extending database..") logger.debug("Running: %s" % setup_one) out = ds.util_subprocess(setup_one, True) logger.debug("Running: %s" % setup_two) out = ds.util_subprocess(setup_two, True) print("Configuring GroupWise Mobility Service..") logger.info("Configuring GroupWise Mobility Service..") logger.debug("Running: %s" % setup_three) out = ds.util_subprocess(setup_three, True) print("Enabling and Starting GroupWise Mobility Service..") logger.info("Enabling and Starting GroupWise Mobility Service..") logger.debug("Running: %s" % setup_four) out = ds.util_subprocess(setup_four, True) # Manually start mobility as the init script will detect a running [p]ython pid, and fail to start ds.rcDS('start', op='nocron', show_spinner=False, show_print=False) print("Configuring Device Sync Agent..") logger.info("Configuring Device Sync Agent..") logger.debug("Running: %s" % setup_five) out = ds.util_subprocess(setup_five, True) print("Configuring GroupWise Sync Agent..") logger.info("Configuring GroupWise Sync Agent..") logger.debug("Running: %s" % setup_six) out = ds.util_subprocess(setup_six, True) print("Starting Sync Agents..") logger.info("Starting Sync Agents..") logger.debug("Running: %s" % setup_seven) out = ds.util_subprocess(setup_seven, True) # Build XMLconfigs logger.info('Building XML trees started') time1 = time.time() logger.debug('Building %s tree from: %s' % ('mconfXML', glb.config_files['mconf'])) glb.XMLconfig['mconf'] = ds.getXMLTree(glb.config_files['mconf']) logger.debug('Building %s tree from: %s' % ('econfXML', glb.config_files['econf'])) glb.XMLconfig['econf'] = ds.getXMLTree(glb.config_files['econf']) logger.debug('Building %s tree from: %s' % ('ceconfXML', glb.config_files['ceconf'])) glb.XMLconfig['ceconf'] = ds.getXMLTree(glb.config_files['ceconf']) logger.debug('Building %s tree from: %s' % ('wconfXML', glb.config_files['wconf'])) glb.XMLconfig['wconf'] = ds.getXMLTree(glb.config_files['wconf']) logger.debug('Building %s tree from: %s' % ('gconfXML', glb.config_files['gconf'])) glb.XMLconfig['gconf'] = ds.getXMLTree(glb.config_files['gconf']) time2 = time.time() logger.info('Building XML trees complete') logger.info("Operation took %0.3f ms" % ((time2 - time1) * 1000)) # Prompt to match backup ldap settings finalChange = False if ldapConfig['enabled'] == 'true': finalChange = True if ds.askYesOrNo("\nRestore LDAP settings"): # Restore groups print("Restoring group container(s)..") logger.info("Restoring group container(s)..") if len(ldapConfig['group']) == 1: ds.setXML('.//configengine/ldap/groupContainer', glb.XMLconfig['ceconf'], ldapConfig['group'][0], glb.config_files['ceconf']) elif len(ldapConfig['group']) > 1: ds.setXML('.//configengine/ldap/groupContainer', glb.XMLconfig['ceconf'], ldapConfig['group'][0], glb.config_files['ceconf']) groups = iter(ldapConfig['group']) next(groups, None) for group in groups: ds.insertXML( './/configengine/ldap/groupContainer', glb.XMLconfig['ceconf'], '<groupContainer>' + group + '</groupContainer>', glb.config_files['ceconf']) else: logger.warning("No group container(s)") # Restore users print("Restoring user container(s)..") logger.info("Restoring user container(s)..") # Create base userContainer to insert into ds.createXML_tag('.//configengine/ldap', glb.XMLconfig['ceconf'], "userContainer", glb.config_files['ceconf'], value="o=GroupWise") if len(ldapConfig['user']) == 1: ds.setXML('.//configengine/ldap/userContainer', glb.XMLconfig['ceconf'], ldapConfig['user'][0], glb.config_files['ceconf']) elif len(ldapConfig['user']) > 1: ds.setXML('.//configengine/ldap/userContainer', glb.XMLconfig['ceconf'], ldapConfig['user'][0], glb.config_files['ceconf']) users = iter(ldapConfig['user']) next(users, None) for user in users: ds.insertXML('.//configengine/ldap/userContainer', glb.XMLconfig['ceconf'], '<userContainer>' + user + '</userContainer>', glb.config_files['ceconf']) else: logger.warning("No user container(s)") # Restore admins print("Restoring admin(s)..") logger.info("Restoring admin(s)..") if len(ldapConfig['admins']) == 1: ds.setXML('.//configengine/ldap/admins/dn', glb.XMLconfig['ceconf'], ldapConfig['admins'][0], glb.config_files['ceconf']) elif len(ldapConfig['admins']) > 1: ds.setXML('.//configengine/ldap/admins/dn', glb.XMLconfig['ceconf'], ldapConfig['admins'][0], glb.config_files['ceconf']) admins = iter(ldapConfig['admins']) next(admins, None) for admin in admins: ds.insertXML('.//configengine/ldap/admins/dn', glb.XMLconfig['ceconf'], '<admins>' + admin + '</admins>', glb.config_files['ceconf']) else: logger.warning("No admin(s)") # Server settings print("Restoring server settings..") logger.info("Restoring server settings..") ds.setXML('.//configengine/ldap/secure', glb.XMLconfig['ceconf'], ldapConfig['secure'], glb.config_files['ceconf']) ds.setXML('.//configengine/ldap/enabled', glb.XMLconfig['ceconf'], ldapConfig['enabled'], glb.config_files['ceconf']) ds.setXML('.//configengine/ldap/hostname', glb.XMLconfig['ceconf'], ldapConfig['host'], glb.config_files['ceconf']) ds.setXML('.//configengine/ldap/port', glb.XMLconfig['ceconf'], ldapConfig['port'], glb.config_files['ceconf']) ds.setXML('.//configengine/ldap/login/dn', glb.XMLconfig['ceconf'], ldapConfig['login'], glb.config_files['ceconf']) ds.setXML('.//configengine/source/provisioning', glb.XMLconfig['ceconf'], authConfig['provisioning'], glb.config_files['ceconf']) ds.setXML('.//configengine/source/authentication', glb.XMLconfig['ceconf'], authConfig['authentication'], glb.config_files['ceconf']) hostname = os.popen('echo `hostname -f`').read().rstrip() ldapPass = ds.getEncrypted(ldapConfig['pass'], glb.XMLconfig['ceconf'], './/configengine/ldap/login/protected', hostname) ds.setXML('.//configengine/ldap/login/password', glb.XMLconfig['ceconf'], ldapPass, glb.config_files['ceconf'], hideValue=True) # Prompt for users and group to be imported if ds.askYesOrNo("\nRestore users and groups"): finalChange = True sqlPath = glb.dsapptmp + '/' + fileName + '/SQLsettings' conn = ds.getConn('datasync') cur = conn.cursor() print("Restoring users..") cur.execute(open(sqlPath + '/targets.sql', 'r').read()) logger.info('Imported targets.sql into datasync database') print("Restoring groups..") cur.execute(open(sqlPath + '/membershipCache.sql', 'r').read()) logger.info('Imported membershipCache.sql into datasync database') cur.close() conn.close() # Prompt for backup certs to be applied # TODO: Will this be needed? # if ds.askYesOrNo("\nRestore backup certificates"): # finalChange = True if finalChange: ds.rcDS('restart', show_spinner=False, show_print=False) print("Restore complete") logger.info("Restore complete")