def testFormattingDefaultDict(): normalDict = {u'lastStateChange': u'', u'actionRequest': u'none', u'productVersion': u'', u'productActionProgress': u'', u'packageVersion': u'', u'installationStatus': u'not_installed', u'productId': u'thunderbird'} defaultDict = defaultdict(lambda x: u'') for key, value in normalDict.items(): defaultDict[key] = value normal = objectToBeautifiedText(normalDict) default = objectToBeautifiedText(defaultDict) assert normal == default
def updateConfigFile(backendConfigFile, newConfig, notificationFunction=None): """ Updates a config file with the corresponding new configuration. :param backendConfigFile: path to the backend configuration :param newConfig: the new configuration. :param notificationFunction: A function that log messages will be passed \ on to. Defaults to logger.notice :type notificationFunction: func """ def correctBooleans(text): """ Creating correct JSON booleans - they are all lowercase. """ return text.replace("true", "True").replace("false", "False") if notificationFunction is None: notificationFunction = LOGGER.notice notificationFunction(u"Updating backend config '%s'" % backendConfigFile) lines = [] with codecs.open(backendConfigFile, 'r', 'utf-8') as backendFile: for line in backendFile.readlines(): if re.search(r'^\s*config\s*\=', line): break lines.append(line) with codecs.open(backendConfigFile, 'w', 'utf-8') as backendFile: backendFile.writelines(lines) backendConfigData = correctBooleans(objectToBeautifiedText(newConfig)) backendFile.write("config = %s\n" % backendConfigData) notificationFunction(u"Backend config '%s' updated" % backendConfigFile)
def testWorkingWithSet(): # Exactly one product because set is unordered. obj = set([ LocalbootProduct( id='htmltestproduct', productVersion='3.1', packageVersion='1', name='Product HTML Test', licenseRequired=False, setupScript='setup.ins', uninstallScript='uninstall.ins', updateScript='update.ins', alwaysScript='always.ins', onceScript='once.ins', priority=0, description="asdf", advice="lolnope", changelog=None, windowsSoftwareIds=None ) ]) expected = u'[\n {\n "onceScript": "once.ins", \n "windowsSoftwareIds": null, \n "description": "asdf", \n "advice": "lolnope", \n "alwaysScript": "always.ins", \n "updateScript": "update.ins", \n "productClassIds": null, \n "id": "htmltestproduct", \n "licenseRequired": false, \n "ident": "htmltestproduct;3.1;1", \n "name": "Product HTML Test", \n "changelog": null, \n "customScript": null, \n "uninstallScript": "uninstall.ins", \n "userLoginScript": null, \n "priority": 0, \n "productVersion": "3.1", \n "packageVersion": "1", \n "type": "LocalbootProduct", \n "setupScript": "setup.ins"\n }\n]' assert expected == objectToBeautifiedText(obj)
def getFromService(self, configService): ''' Get settings from service ''' logger.notice("Getting config from service") if not configService: raise Exception("Config service is undefined") query = { "objectId": self.get('global', 'host_id'), "configId": [ 'clientconfig.configserver.url', 'clientconfig.depot.drive', 'clientconfig.depot.id', 'clientconfig.depot.user', 'clientconfig.suspend_bitlocker_on_reboot', 'opsiclientd.*' # everything starting with opsiclientd. ] } configService.backend_setOptions({"addConfigStateDefaults": True}) for configState in configService.configState_getObjects(**query): logger.info("Got config state from service: %r", configState) if not configState.values: logger.debug("No values - skipping %s", configState.configId) continue if configState.configId == 'clientconfig.configserver.url': self.set('config_service', 'url', configState.values) elif configState.configId == 'clientconfig.depot.drive': self.set('depot_server', 'drive', configState.values[0]) elif configState.configId == 'clientconfig.depot.id': self.set('depot_server', 'depot_id', configState.values[0]) elif configState.configId == 'clientconfig.depot.user': self.set('depot_server', 'username', configState.values[0]) elif configState.configId == 'clientconfig.suspend_bitlocker_on_reboot': self.set('global', 'suspend_bitlocker_on_reboot', configState.values[0]) elif configState.configId.startswith('opsiclientd.'): try: parts = configState.configId.lower().split('.') if len(parts) < 3: logger.debug( "Expected at least 3 parts in %s - skipping.", configState.configId) continue value = configState.values if len(value) == 1: value = value[0] self.set(section=parts[1], option=parts[2], value=value) except Exception as err: # pylint: disable=broad-except logger.error("Failed to process configState '%s': %s", configState.configId, err) logger.notice("Got config from service") logger.debug("Config is now:\n %s", objectToBeautifiedText(self.getDict()))
def testObjectToBeautifiedTextGeneratesValidJSON(objectCount): objectsIn = [ProductFactory.generateLocalbootProduct(i) for i in range(objectCount)] text = objectToBeautifiedText(objectsIn) objects = fromJson(text) assert objectCount == len(objects) for obj in objects: assert isinstance(obj, LocalbootProduct)
def testObjectToBeautifiedTextWorksWithGenerators(objectCount): generator = ( ProductFactory.generateLocalbootProduct(i) for i in range(objectCount) ) text = objectToBeautifiedText(generator) assert text.strip().startswith('[') assert text.strip().endswith(']')
def readConfigFile(self): ''' Get settings from config file ''' logger.notice("Trying to read config from file: '%s'", self.get('global', 'config_file')) try: self._config_file_mtime = os.path.getmtime( self.get('global', 'config_file')) # Read Config-File config = IniFile(filename=self.get('global', 'config_file'), raw=True).parse() # Read log settings early if config.has_section('global') and config.has_option( 'global', 'log_level'): self.set('global', 'log_level', config.get('global', 'log_level')) for section in config.sections(): logger.debug("Processing section '%s' in config file: '%s'", section, self.get('global', 'config_file')) for (option, value) in config.items(section): option = option.lower() self.set(section.lower(), option, value) except Exception as err: # pylint: disable=broad-except # An error occured while trying to read the config file logger.error("Failed to read config file '%s': %s", self.get('global', 'config_file'), err) logger.error(err, exc_info=True) return if not self.get("depot_server", "master_depot_id"): self.set("depot_server", "master_depot_id", self.get("depot_server", "depot_id")) logger.notice("Config read") logger.debug("Config is now:\n %s", objectToBeautifiedText(self._config))
def main(argv): if os.path.exists(os.path.join('C:', 'opsi.org', 'log')): logDir = os.path.join('C:', 'opsi.org', 'log') else: logDir = os.path.join('C:', 'tmp') logFile = os.path.join(logDir, 'hwaudit.log') parser = argparse.ArgumentParser( description="Perform hardware audit on a client and sent the result to an opsi server.", add_help=False ) parser.add_argument('--help', action="store_true", help="Display help.") parser.add_argument('--version', action='version', version=__version__) parser.add_argument( '--log-level', '--loglevel', '-l', default=LOG_ERROR, dest="logLevel", type=int, choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], help="Set the desired loglevel." ) parser.add_argument('--log-file', '-f', dest="logFile", default=logFile, help="Path to file where debug logs will be written.") parser.add_argument('--hostid', '-h', help="Hostid that will be used. If nothing is set the value from --username will be used.") parser.add_argument('--username', '-u', help="Username to connect to the service. If nothing is set the value from --hostid will be used.") parser.add_argument('--password', '-p', required=True, help="Password for authentication") parser.add_argument('--address', '-a', required=True, help="Address to connect to. Example: https://server.domain.local:4447") opts = parser.parse_args() if opts.help: parser.print_help() sys.exit(0) password = opts.password logger.addConfidentialString(password) logger.setConsoleLevel(opts.logLevel) logger.setLogFile(opts.logFile) logger.setFileLevel(LOG_DEBUG2) logger.notice("starting hardware audit (script version {})", __version__) address = opts.address if address.startswith(u"https://"): address = address + u"/rpc" if not address: logger.critical(u"Address not set") raise RuntimeError("Address not set") host_id = opts.hostid or opts.username username = opts.username or opts.hostid if not (username and host_id): raise RuntimeError("Host id and username not set") logger.notice(u"Connecting to service at '{}' as '{}'", address, username) backendConfig = dict( username=username, password=password, address=address, application='opsi hwaudit %s' % __version__ ) with JSONRPCBackend(**backendConfig) as backend: logger.notice(u"Connected to opsi server") logger.notice(u"Fetching opsi hw audit configuration") config = backend.auditHardware_getConfig() logger.notice(u"Fetching hardware information from WMI") values = getHardwareInformationFromWMI(config) logger.notice(u"Fetching hardware information from Registry") values = getHardwareInformationFromRegistry(config, values) logger.notice(u"Fetching hardware information from Executing Command") values = getHardwareInformationFromExecuteCommand(config, values) logger.info(u"Hardware information from WMI:\n%s" % objectToBeautifiedText(values)) auditHardwareOnHosts = [] for hardwareClass, devices in values.items(): if hardwareClass == 'SCANPROPERTIES': continue for device in devices: data = {str(attribute): value for attribute, value in device.items()} data['hardwareClass'] = hardwareClass data['hostId'] = host_id auditHardwareOnHosts.append(AuditHardwareOnHost.fromHash(data)) logger.info(u"Obsoleting old hardware audit data") backend.auditHardwareOnHost_setObsolete(host_id) logger.notice(u"Sending hardware information to service") backend.auditHardwareOnHost_updateObjects(auditHardwareOnHosts) logger.notice(u"Exiting...")
def testFormattingEmptyDict(): assert '{}' == objectToBeautifiedText({})
def testFormattingListOfEmptyLists(): expected = '[\n [], \n []\n]' assert expected == objectToBeautifiedText([[], []])
def testFormattingEmptyList(): assert '[]' == objectToBeautifiedText([])