def cuso_menu(): menu = [ '1. Clean up and start over (Except Users)', '2. Clean up and start over (Everything)', '\n 3. Uninstall Mobility', '\n 0. Back' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner() if ds.askYesOrNo("Clean up and start over (Except Users)"): ds.cuso('user') print ds.eContinue() elif choice == '2': ds.datasyncBanner() if ds.askYesOrNo("Clean up and start over (Everything)"): ds.cuso('everything') print ds.eContinue() elif choice == '3': ds.datasyncBanner() print "Please run 'sh /opt/novell/datasync/uninstall.sh' first" if ds.askYesOrNo("Uninstall Mobility"): ds.cuso('uninstall') elif choice == '0': loop = False return
def performance_menu(): menu = ['1. Top device requests','2. Check manual syncing devices', '\n 0. Back'] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner(dsappversion) if ds.askYesOrNo("Parse debug log for top device requests"): log = ds.getFilePath("Enter path to mobility-agent log file: ") if log is None: return dsPerformance.getDeviceCommands(log) ds.eContinue() elif choice == '2': ds.datasyncBanner(dsappversion) if ds.askYesOrNo("Parse debug log for devices set to manual sync"): log = ds.getFilePath("Enter path to mobility-agent log file: ") if log is None: return dsPerformance.getPinglessDevices(log) ds.eContinue() elif choice == '0': loop = False return
def cuso_menu(): menu = ['1. Clean up and start over (Except Users)', '2. Clean up and start over (Everything)', '\n 3. Uninstall Mobility', '\n 0. Back'] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner(dsappversion) if ds.askYesOrNo("Clean up and start over (Except Users)"): ds.cuso(dbConfig, 'user') print; ds.eContinue() elif choice == '2': ds.datasyncBanner(dsappversion) if ds.askYesOrNo("Clean up and start over (Everything)"): ds.cuso(dbConfig, 'everything') print; ds.eContinue() elif choice == '3': ds.datasyncBanner(dsappversion) print "Please run 'sh /opt/novell/datasync/uninstall.sh' first" if ds.askYesOrNo("Uninstall Mobility"): ds.cuso(dbConfig, 'uninstall') elif choice == '0': loop = False return
def remove_device_menu(): menu = [ '1. Remove all devices', '2. Remove user devices', '\n 0. Back' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner() if ds.askYesOrNo("Remove all users devices"): ds.removeDevice() elif choice == '2': userConfig = ds.verifyUser()[0] if ds.confirm_user(userConfig, 'mobility'): if ds.askYesOrNo("Remove all devices for %s" % userConfig['name']): ds.removeDevice(userConfig) else: ds.eContinue() elif choice == '0': loop = False return
def groupwiseChecks_menu(): menu = ['1. Check user over SOAP', '2. Check GroupWise folder structure', '\n 3. Count user shared folders', '4. Count all users shared folders', '\n 0. Back'] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': userConfig = ds.verifyUser(dbConfig)[0] if userConfig['name'] != None: if userConfig['type'] != 'group': dsSOAP.soap_printUser(trustedConfig, gwConfig, userConfig) else: print ("Input '%(name)s' is not a user. Type='%(type)s'" % userConfig) print; ds.eContinue() elif choice == '2': dsSOAP.soap_checkFolderList(trustedConfig, gwConfig, ds.verifyUser(dbConfig)[0]) elif choice == '3': userConfig = ds.verifyUser(dbConfig)[0] if userConfig['name'] != None: if userConfig['type'] != 'group': shared_list = dsSOAP.soap_check_sharedFolders(trustedConfig, gwConfig, userConfig) if shared_list is not None: pydoc.pager(shared_list) if ds.askYesOrNo("Save to file"): with open(dsappdata + '/shared_folder_list.txt', 'w') as file: file.write(shared_list) file.write('\n') logger.info("Saving shared list to %s" % (dsappdata + '/shared_folder_list.txt')) print ("Saved to %s" % (dsappdata + '/shared_folder_list.txt')) print; ds.eContinue() elif choice == '4': ds.datasyncBanner(dsappversion) print ("This can take some time to check every user in mobility") if ds.askYesOrNo("Warning! CPU may become busy. Continue"): userList = ds.getMobilityUserList(dbConfig) shared_list = dsSOAP.soap_check_allSharedFolders(trustedConfig, gwConfig, userList) if shared_list is not None: pydoc.pager(shared_list) if ds.askYesOrNo("Save to file"): with open(dsappdata + '/shared_folder_list-allUsers.txt', 'w') as file: file.write(shared_list) file.write('\n') logger.info("Saving shared list to %s" % (dsappdata + '/shared_folder_list-allUsers.txt')) print ("Saved to %s" % (dsappdata + '/shared_folder_list-allUsers.txt')) print; ds.eContinue() elif choice == '0': loop = False return
def database_menu(): ds.datasyncBanner(dsappversion) print "The database menu will require Mobility to be stopped" if ds.askYesOrNo("Stop Mobility now"): ds.datasyncBanner(dsappversion) ds.rcDS('stop') menu = ['1. Vacuum Databases', '2. Re-Index Databases', '\n 3. Back up Databases', '4. Restore Databases', '\n 5. Recreate Global Address Book (GAL)', '6. Fix targets/membershipCache', '\n 7. CUSO Clean-Up Start-Over', '\n 0. Back -- Start Mobility'] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner(dsappversion) print textwrap.fill("The amount of time this takes can vary depending on the last time it was completed. It is recommended that this be run every 6 months.", 80) print if ds.askYesOrNo("Do you want to continue"): ds.vacuumDB(dbConfig) print ds.eContinue() elif choice == '2': ds.datasyncBanner(dsappversion) print textwrap.fill("The amount of time this takes can vary depending on the last time it was completed. It is recommended that this be run after a database vacuum.", 80) print if ds.askYesOrNo("Do you want to continue"): ds.indexDB(dbConfig) print ds.eContinue() elif choice == '3': ds.backupDatabase(dbConfig) print; ds.eContinue() elif choice == '4': ds.restoreDatabase(dbConfig) print; ds.eContinue() elif choice == '5': ds.fix_gal(dbConfig) print; ds.eContinue() elif choice == '6': ds.addGroup(dbConfig, ldapConfig) print; ds.eContinue() elif choice == '7': cuso_menu() elif choice == '0': loop = False ds.datasyncBanner(dsappversion) ds.rcDS('start') main_menu() else: main_menu()
def viewAttachments_menu(): menu = [ '1. View user attachments', '2. View total attachment size by users', '3. Check Mobility attachments count', '\n 0. Back' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.view_users_attach() elif choice == '2': ds.view_attach_byUser() elif choice == '3': ds.datasyncBanner() print( "Compare the mobility database ID count, with the mobility filestore ID count" ) if ds.askYesOrNo("This may take some time to complete, continue"): ds.check_mob_attachments() print ds.eContinue() elif choice == '0': loop = False return
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 performance_menu(): menu = [ '1. Top device requests', '2. Check manual syncing devices', '\n 0. Back' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) ds.print_there(23, 6, "DEBUG logging required. Logs parsed for data") choice = get_choice(available) if choice == '1': ds.datasyncBanner() if ds.askYesOrNo("Parse debug log for top device requests"): log = ds.getFilePath( "mobility-agent log file", '/var/log/datasync/connectors/mobility-agent.log') if log is None: return dsPerformance.getDeviceCommands(log) ds.eContinue() elif choice == '2': ds.datasyncBanner() if ds.askYesOrNo("Parse debug log for devices set to manual sync"): log = ds.getFilePath( "mobility-agent log file", '/var/log/datasync/connectors/mobility-agent.log') if log is None: return dsPerformance.getPinglessDevices(log) ds.eContinue() elif choice == '0': loop = False return
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): 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 autoIssue(self, forced=False): # Make sure socat is installed if not self.installSocat(): return # Make sure acme root is setup if not os.path.isdir(self.acmeRoot): print("acme.sh is not installed. Please install") logger.error("acme.sh is not installed. Please install") return if not os.path.isfile(self.acmeRoot + '/acme.sh'): print("Unable to find %s" % (self.acmeRoot + 'acme.sh')) print("Reinstall acme.sh") logger.error("Unable to find %s" % (self.acmeRoot + 'acme.sh')) logger.error("Reinstall acme.sh") return if not int(glb.mobilityConfig['mSecure']): print( "Unable to auto issue LetsEncrypt on unsecure connection using port %s" % glb.mobilityConfig['mPort']) return print("This will shutdown mobility to free up port %s" % glb.mobilityConfig['mPort']) if not ds.askYesOrNo("Start auto LetsEncrypt now"): return ds.rcDS('stop') # Stop mobility to clear TLS port self.setDNS() print("Requesting new certificate from LetsEncrypt with DNS: %s" % self.DNS) if self.issueCertificate(forced): self.setCertPath() self.setCertificates() self.createPem() ds.configureMobilityCerts(self.certPath, prompts=False) else: print("Problem requesting certificate") print("See %s" % self.acmeLog) ds.rcDS('start')
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 viewAttachments_menu(): menu = ['1. View user attachments','2. View total attachment size by users', '3. Check Mobility attachments count', '\n 0. Back'] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.view_users_attach(dbConfig) elif choice == '2': ds.view_attach_byUser(dbConfig) elif choice == '3': ds.datasyncBanner(dsappversion) print ("Compare the mobility database ID count, with the mobility filestore ID count") if ds.askYesOrNo("This may take some time to complete, continue"): ds.check_mob_attachments(dbConfig) print; ds.eContinue() elif choice == '0': loop = False return
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 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")
def dumpConfigs(): ds.datasyncBanner() if not ds.askYesOrNo("Backup mobility configuration"): return DATE = datetime.datetime.now().strftime("%m.%d.%y-%s") # Create folder for backup data new_folder = glb.dsappdata + '/mobility_backup-%s' % DATE if not os.path.exists(new_folder): os.makedirs(new_folder) print("Dumping settings to %s" % new_folder) logger.info("Dumping settings to %s" % new_folder) dump_folder = new_folder + '/dumpSettings' if not os.path.exists(dump_folder): os.makedirs(dump_folder) # Dump dsapp settings with open(dump_folder + '/glb.dbConfig.p', 'wb') as handle: pickle.dump(glb.dbConfig, handle) logger.debug("Created %s/glb.dbConfig.p" % dump_folder) with open(dump_folder + '/ldapConfig.p', 'wb') as handle: pickle.dump(glb.ldapConfig, handle) logger.debug("Created %s/ldapConfig.p" % dump_folder) with open(dump_folder + '/mobilityConfig.p', 'wb') as handle: pickle.dump(glb.mobilityConfig, handle) logger.debug("Created %s/mobilityConfig.p" % dump_folder) with open(dump_folder + '/gwConfig.p', 'wb') as handle: pickle.dump(glb.gwConfig, handle) logger.debug("Created %s/gwConfig.p" % dump_folder) with open(dump_folder + '/trustedConfig.p', 'wb') as handle: pickle.dump(glb.trustedConfig, handle) logger.debug("Created %s/trustedConfig.p" % dump_folder) with open(dump_folder + '/config_files.p', 'wb') as handle: pickle.dump(glb.config_files, handle) logger.debug("Created %s/config_files.p" % dump_folder) with open(dump_folder + '/webConfig.p', 'wb') as handle: pickle.dump(glb.webConfig, handle) logger.debug("Created %s/webConfig.p" % dump_folder) with open(dump_folder + '/authConfig.p', 'wb') as handle: pickle.dump(glb.authConfig, handle) logger.debug("Created %s/authConfig.p" % dump_folder) # Dumping target, and membershipCache table skip_db = False for key in glb.dbConfig: if glb.dbConfig[key] is None: skip_db = True if not skip_db: print("\nGetting database tables..") logger.info("Getting database tables..") sql_folder = new_folder + '/SQLsettings' if not os.path.exists(sql_folder): os.makedirs(sql_folder) ds.dumpTable('datasync', 'membershipCache', sql_folder) ds.dumpTable('datasync', 'targets', sql_folder) else: print("\nUnable to dump database table..") logger.warning("Unable to dump database table..") # Dumping certificate print("Getting mobility certificates..") logger.info("Getting mobility certificates..") cert_folder = new_folder + '/certificates/' if not os.path.exists(cert_folder): os.makedirs(cert_folder) shutil.copy(mobCert, cert_folder) shutil.copy(webCert, cert_folder) print("Settings have been dumped") logger.info("Settings have been dumped") # Compress setting directory tarSettings(new_folder) # Remove setting folder shutil.rmtree(new_folder)
logger.debug('Building %s tree from: %s' % ('econfXML', config_files['econf'])) XMLconfig['econf'] = ds.getXMLTree(config_files['econf']) logger.debug('Building %s tree from: %s' % ('ceconfXML', config_files['ceconf'])) XMLconfig['ceconf'] = ds.getXMLTree(config_files['ceconf']) logger.debug('Building %s tree from: %s' % ('wconfXML', config_files['wconf'])) XMLconfig['wconf'] = ds.getXMLTree(config_files['wconf']) logger.debug('Building %s tree from: %s' % ('gconfXML', config_files['gconf'])) XMLconfig['gconf'] = ds.getXMLTree(config_files['gconf']) time2 = time.time() logger.info('Building XML trees complete') logger.info("Operation took %0.3f ms" % ((time2 - time1) * 1000)) # Check current hostname with stored hostname if args.host: print ("This should only be used if the hostname encryption is not detected by dsapp") if ds.askYesOrNo("Continue to fix encryption"): old_host = raw_input("Previous hostname: ") print ds.check_hostname(old_host, XMLconfig, config_files, forceFix=True) print; sys.exit(0) elif not args.host: logger.info('Checking hostname') if not ds.check_hostname(dsHostname, XMLconfig, config_files): new_host = os.popen('echo `hostname -f`').read().rstrip() print ("\nUnable to read encryption with current hostname '%s'\n" % new_host) logger.error("Unable to read encryption with current hostname '%s'" % new_host) ds.eContinue() sys.exit(1) print "Loading settings.. ",
def soap_checkFolderList(userConfig): if userConfig['name'] is None: return soap_userConfig = soap_getUserInfo(userConfig) # Log output for users folder structure folderStructure_Log = glb.dsappLogs + '/folderStructure/%s_folderStructure.log' % userConfig[ 'name'] # Set up IDs for fixing structure systemIDs = dict() system_problemIDs = dict() subContact_problemIDs = dict() subCalendar_problemIDs = dict() problem = False print("Getting folder list..") logger.info("Getting folder list..") soap_folderList = soap_getFolderList(userConfig, soap_userConfig=soap_userConfig) if soap_folderList == None: logger.debug("SOAP folder list is None") print() ds.eContinue() return # Write folder list to log if not os.path.exists(glb.dsappLogs + '/folderStructure'): os.makedirs(glb.dsappLogs + '/folderStructure') with open(folderStructure_Log, 'w') as file: file.write(str(soap_folderList)) # Get root folder ID if soap_folderList[0][0][0]['sid'] == 1: root_id = soap_folderList[0][0][0]['id'] else: foundRoot = False for folder in soap_folderList[0][ 0]: # for loop to find the root folder id try: if folder['sid'] == 1 or folder['folderType'] == 'Root': root_id = folder['id'] foundRoot = True break except AttributeError: logger.error("AttributeError - No sid or folderType") logger.error(folder) if not foundRoot: print("Unable to find the root folder for %s" % userConfig['name']) logger.warning("Unable to find the root folder for %s" % userConfig['name']) return systemIDs['root'] = root_id logger.debug('root {id: %s}' % root_id) print("Checking %s folder structure..\n" % userConfig['name']) logger.info("Checking %s folder structure" % userConfig['name']) folder_check = ['Mailbox', 'Calendar', 'Contacts'] for folder in soap_folderList[0][0]: if 'folderType' in folder: if folder['folderType'] in folder_check: if folder['parent'] != root_id: print( "Problem with system folder structure [%s]\n%s not found under root\n" % (folder['folderType'], folder['name'])) logger.debug( "%s {id: %s, parent: %s}" % (folder['name'], folder['id'], folder['parent'])) logger.error( "Problem with system folder [%s] structure - %s not found under root" % (folder['folderType'], folder['name'])) system_problemIDs[folder['folderType']] = { folder['name']: folder['id'] } problem = True # Check sub folders if folder['folderType'] == 'Contacts': systemIDs['Contacts'] = folder['id'] if check_subContacts(soap_folderList, folder['id'], subContact_problemIDs): problem = True if folder['folderType'] == 'Calendar': systemIDs['Calendar'] = folder['id'] if check_subCalendars(soap_folderList, folder['id'], subCalendar_problemIDs): problem = True if not problem: print("No problems found with GroupWise folder structure") logger.info("No problems found with GroupWise folder structure") else: if ds.askYesOrNo("Fix %s folder structure" % userConfig['name']): fixFolderStructure(soap_userConfig, systemIDs, system_problemIDs, subCalendar_problemIDs, subContact_problemIDs) soap_logout(soap_userConfig) print() ds.eContinue()
('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)) # Check current hostname with stored hostname if args.host: logger.info("Running switch: changeHost") print( "This should only be used if the hostname encryption is not detected by dsapp" ) if ds.askYesOrNo("Continue to fix encryption"): old_host = raw_input("Previous hostname: ") print ds.check_hostname(old_host, forceFix=True) print sys.exit(0) elif not args.host: logger.info('Checking hostname') if not ds.check_hostname(dsHostname): new_host = os.popen('echo `hostname -f`').read().rstrip() print("\nUnable to read encryption with current hostname '%s'\n" % new_host) logger.error("Unable to read encryption with current hostname '%s'" % new_host) ds.eContinue()
def setAutoRenew(self): cronFile = "/etc/cron.d/dsapp_acme" cronFormat = "0 %s * * %s /root/.acme.sh/auto-renew.sh %s %s %s >/dev/null 2>&1" print( "Auto renew will shutdown mobility if certificate need to update") if not ds.askYesOrNo("Set up auto renew now"): return # Make sure acme root is setup if not os.path.isdir(self.acmeRoot): print("acme.sh is not installed. Please install") logger.error("acme.sh is not installed. Please install") return if not os.path.isfile(self.acmeRoot + '/acme.sh'): print("Unable to find %s" % (self.acmeRoot + 'acme.sh')) print("Reinstall acme.sh") logger.error("Unable to find %s" % (self.acmeRoot + 'acme.sh')) logger.error("Reinstall acme.sh") return if self.DNS is None: self.setDNS() day = self.getDay() # Get hour from 0-23 for when crontab should run (will restart mobility if needed) hour = raw_input("\nHour to check certificates (0-23): ") if hour == "" or not 0 <= int(hour) <= 23: print("Invalid hour %s" % hour) logger.error("Invalid hour %s" % hour) return # # Get date to rewnew # defaultrenewDate = 20 # renewDate = raw_input ("Day tolerance for renew (below 60) [%s]: " % defaultrenewDate) # if renewDate == "": # renewDate = defaultrenewDate # default to 14 days renewDate = 20 # if not renewDate >= 1 or not renewDate <= 59: if not 1 <= int(renewDate) <= 59: print("Invalid tolerance") logger.error("Invalid tolerance") return # Copy auto-renew.sh into place print("\nCopying %s to %s" % (glb.dsapplib + "/scripts/auto-renew.sh", self.acmeRoot)) logger.info("Copying %s to %s" % (glb.dsapplib + "/scripts/auto-renew.sh", self.acmeRoot)) shutil.copy(glb.dsapplib + "/scripts/auto-renew.sh", self.acmeRoot) # Write new cron.d file cron = cronFormat % (hour, day, self.DNS, renewDate, glb.mobilityConfig['mPort']) logger.info("Cron will run at [0 %s * * %s]" % (hour, day)) print("Creating new cron file at %s" % cronFile) logger.info("Creating new file at %s" % cronFile) logger.debug("Writing to file: %s" % cron) with open(cronFile, 'w') as newCron: newCron.write(cron)
def database_menu(): ds.datasyncBanner() print "The database menu will require Mobility to be stopped" if ds.askYesOrNo("Stop Mobility now"): ds.datasyncBanner() ds.rcDS('stop') menu = [ '1. Vacuum Databases', '2. Re-Index Databases', '\n 3. Back up Databases', '4. Restore Databases', '\n 5. Recreate Global Address Book (GAL)', '6. Fix targets/membershipCache', '\n 7. CUSO Clean-Up Start-Over', '\n 0. Back -- Start Mobility' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': ds.datasyncBanner() print textwrap.fill( "The amount of time this takes can vary depending on the last time it was completed. It is recommended that this be run every 6 months.", 80) print if ds.askYesOrNo("Do you want to continue"): ds.vacuumDB() print ds.eContinue() elif choice == '2': ds.datasyncBanner() print textwrap.fill( "The amount of time this takes can vary depending on the last time it was completed. It is recommended that this be run after a database vacuum.", 80) print if ds.askYesOrNo("Do you want to continue"): ds.indexDB() print ds.eContinue() elif choice == '3': ds.backupDatabase() print ds.eContinue() elif choice == '4': ds.restoreDatabase() print ds.eContinue() elif choice == '5': ds.fix_gal() print ds.eContinue() elif choice == '6': ds.addGroup() print ds.eContinue() elif choice == '7': cuso_menu() elif choice == '0': loop = False ds.datasyncBanner() ds.rcDS('start') main_menu() else: main_menu()
def soap_checkFolderList(trustedConfig, gwConfig, userConfig): if userConfig['name'] is None: return soap_userConfig = soap_getUserInfo(trustedConfig, gwConfig, userConfig) # Log output for users folder structure folderStructure_Log = dsappLogs + '/folderStructure/%s_folderStructure.log' % userConfig['name'] # Set up IDs for fixing structure systemIDs = dict() system_problemIDs = dict() subContact_problemIDs = dict() subCalendar_problemIDs = dict() problem = False print ("Getting folder list..") logger.info("Getting folder list..") soap_folderList = soap_getFolderList(trustedConfig, gwConfig, userConfig, soap_userConfig=soap_userConfig) if soap_folderList == None: logger.debug("SOAP folder list is None") print(); ds.eContinue() return # Write folder list to log if not os.path.exists(dsappLogs + '/folderStructure'): os.makedirs(dsappLogs + '/folderStructure') with open(folderStructure_Log, 'w') as file: file.write(str(soap_folderList)) # Get root folder ID if soap_folderList[0][0][0]['sid'] == 1: root_id = soap_folderList[0][0][0]['id'] else: foundRoot = False for folder in soap_folderList[0][0]: if folder['sid'] == 1 or folder['folderType'] == 'Root': root_id = folder['id'] foundRoot = True if not foundRoot: print ("Unable to find the root folder for %s" % userConfig['name']) logger.warning("Unable to find the root folder for %s" % userConfig['name']) return systemIDs['root'] = root_id logger.debug('root {id: %s}' % root_id) print ("Checking %s folder structure..\n" % userConfig['name']) logger.info("Checking %s folder structure" % userConfig['name']) folder_check = ['Mailbox', 'Calendar', 'Contacts'] for folder in soap_folderList[0][0]: if 'folderType' in folder: if folder['folderType'] in folder_check: if folder['parent'] != root_id: print ("Problem with system folder structure [%s]\n%s not found under root\n" % (folder['folderType'], folder['name'])) logger.debug("%s {id: %s, parent: %s}" % (folder['name'], folder['id'], folder['parent'])) logger.error("Problem with system folder [%s] structure - %s not found under root" % (folder['folderType'], folder['name'])) system_problemIDs[folder['folderType']] = {folder['name']: folder['id']} problem = True # Check sub folders if folder['folderType'] == 'Contacts': systemIDs['Contacts'] = folder['id'] if check_subContacts(soap_folderList, folder['id'], subContact_problemIDs): problem = True if folder['folderType'] == 'Calendar': systemIDs['Calendar'] = folder['id'] if check_subCalendars(soap_folderList, folder['id'], subCalendar_problemIDs): problem = True if not problem: print ("No problems found with GroupWise folder structure") logger.info("No problems found with GroupWise folder structure") else: if ds.askYesOrNo("Fix %s folder structure" % userConfig['name']): fixFolderStructure(soap_userConfig, systemIDs, system_problemIDs, subCalendar_problemIDs, subContact_problemIDs) print(); ds.eContinue()
def groupwiseChecks_menu(): menu = [ '1. Check user over SOAP', '2. Check GroupWise folder structure', '\n 3. Count user shared folders', '4. Count all users shared folders', '\n 0. Back' ] available = build_avaialbe(menu) loop = True while loop: show_menu(menu) choice = get_choice(available) if choice == '1': userConfig = ds.verifyUser()[0] if userConfig['name'] != None: if userConfig['type'] != 'group': dsSOAP.soap_printUser(userConfig) else: print("Input '%(name)s' is not a user. Type='%(type)s'" % userConfig) print ds.eContinue() elif choice == '2': dsSOAP.soap_checkFolderList(ds.verifyUser()[0]) elif choice == '3': userConfig = ds.verifyUser()[0] if userConfig['name'] != None: if userConfig['type'] != 'group': shared_list = dsSOAP.soap_check_sharedFolders(userConfig) if shared_list is not None: pydoc.pager(shared_list) if ds.askYesOrNo("Save to file"): with open( glb.dsappdata + '/shared_folder_list.txt', 'w') as file: file.write(shared_list) file.write('\n') logger.info( "Saving shared list to %s" % (glb.dsappdata + '/shared_folder_list.txt')) print("Saved to %s" % (glb.dsappdata + '/shared_folder_list.txt')) print ds.eContinue() elif choice == '4': ds.datasyncBanner() print("This can take some time to check every user in mobility") if ds.askYesOrNo("Warning! CPU may become busy. Continue"): userList = ds.getMobilityUserList() shared_list = dsSOAP.soap_check_allSharedFolders(userList) if shared_list is not None: pydoc.pager(shared_list) if ds.askYesOrNo("Save to file"): with open( glb.dsappdata + '/shared_folder_list-allUsers.txt', 'w') as file: file.write(shared_list) file.write('\n') logger.info("Saving shared list to %s" % (glb.dsappdata + '/shared_folder_list-allUsers.txt')) print("Saved to %s" % (glb.dsappdata + '/shared_folder_list-allUsers.txt')) print ds.eContinue() elif choice == '0': loop = False return