def getMachine(self, ctx, h_params): """ return only one machine (the first matching with params) h_params stuct looks like that : {'hostname':name, 'uuid':uuid} """ try: ret = ComputerManager().getComputer(ctx, h_params) self.logger.debug("getMachine: wanted |%s|, got |%s|" % (h_params, ret)) if ret != None: if ret != False: if type(ret) == list: return Machine(ret[1]) else: return Machine(ret) else: return None except KeyError: pass ret = ComputerManager().getComputersList(ctx, h_params) self.logger.debug("getMachine: wanted |%s|, got |%s|" % (h_params, ret)) try: self.logger.debug(ret[h_params['hostname']][1]) return Machine(ret[h_params['hostname']][1]) except: return None
def replyToQueryLen(ctx, query, bool=None, filt=None): if query == None: return 0 if __onlyIn(query, ComputerManager().main): ComputerManager().main filt = __addCtxFilters(ctx, filt) filt['query'] = query return xmlrpcCleanup(ComputerManager().getRestrictedComputersListLen( ctx, filt)) else: return xmlrpcCleanup(QueryManager().replyToQueryLen(ctx, query, bool))
def create_update_commands(): # TODO: ensure that this method is called by taskmanager # and not directly by XMLRPC # Creating root context ctx = SecurityContext() ctx.userid = 'root' # Get active computer manager computer_manager = ComputerManager().getManagerName() if computer_manager == 'inventory': dyngroup_pattern = '%d==inventory::Hardware/OperatingSystem==%s' elif computer_manager == 'glpi': dyngroup_pattern = '%d==glpi::Operating system==%s' else: logging.getLogger().error( 'Update module: Unsupported computer manager %s' % computer_manager) return False # Get all enabled os_classes os_classes = updateDatabase().get_os_classes({'filters': {'enabled': 1}}) # Create update command for enabled os_classes for os_class in os_classes['data']: patterns = os_class['pattern'].split('||') request = [] equ_bool = [] for i in xrange(len(patterns)): request.append(dyngroup_pattern % (i + 1, patterns[i])) equ_bool.append(str(i + 1)) request = '||'.join(request) equ_bool = 'OR(%s)' % ','.join(equ_bool) targets = ComputerManager().getComputersList(ctx, { 'request': request, 'equ_bool': equ_bool }).keys() # Fetching all targets for uuid in targets: machine_id = int(uuid.lower().replace('uuid', '')) updates = updateDatabase().get_eligible_updates_for_host( machine_id) update_list = [update['uuid'] for update in updates] # Create update command for this host with update_list create_update_command(ctx, [uuid], update_list) return True
def _replyToQuery(self, ctx, query, bool = None): raise "DON'T USE _replyToQuery!!!" ret = self.__recursive_query(ctx, query) values = {} values_neg = {} # TODO does not seems to work... #['AND', [['1', 'dyngroup', 'groupname', 'test']]] for qid, module, criterion, value in query: val, neg = self._getPluginReplyToQuery( ctx, self.queryablePlugins[module], [criterion, value] ) values[str(qid)] = [val, neg] self.logger.debug(values) br = BoolRequest() if bool == None or bool == '' or bool == 0 or bool == '0': bool = 'AND('+','.join(map(lambda a:a[0][0], values))+')' all = ComputerManager().getComputersList(ctx) #all = ComputerManager().getRestrictedComputersList(ctx, 0, 50) # for the moment everything is based on names... should be changed into uuids #all = map(lambda a: a[1]['cn'][0], all.values()) all = all.keys() values['A'] = [all, True] bool = 'AND(A, '+bool+')' br.parse(bool) if bool == None or not br.isValid(): # no bool specified = only AND if len(values.keys()) > 0: retour = values.pop() for val in values: neg = val[1] val = val[0] if neg: retour = filter(lambda a,val=val:a in val, retour) else: retour = filter(lambda a,val=val:a not in val, retour) return retour else: return [] # TODO : when plugged on Machines : should return : Machine - values_neg else: retour = br.merge(values) return retour[0]
def _replyToQuery(self, ctx, query, bool = None): raise "DON'T USE _replyToQuery!!!" self.__recursive_query(ctx, query) values = {} # TODO does not seems to work... #['AND', [['1', 'dyngroup', 'groupname', 'test']]] for qid, module, criterion, value in query: val, neg = self._getPluginReplyToQuery( ctx, self.queryablePlugins[module], [criterion, value] ) values[str(qid)] = [val, neg] self.logger.debug(values) br = BoolRequest() if bool == None or bool == '' or bool == 0 or bool == '0': bool = 'AND('+','.join(map(lambda a:a[0][0], values))+')' all = ComputerManager().getComputersList(ctx) #all = ComputerManager().getRestrictedComputersList(ctx, 0, 50) # for the moment everything is based on names... should be changed into uuids #all = map(lambda a: a[1]['cn'][0], all.values()) all = all.keys() values['A'] = [all, True] bool = 'AND(A, '+bool+')' br.parse(bool) if bool == None or not br.isValid(): # no bool specified = only AND if len(values.keys()) > 0: retour = values.pop() for val in values: neg = val[1] val = val[0] if neg: retour = filter(lambda a,val=val:a in val, retour) else: retour = filter(lambda a,val=val:a not in val, retour) return retour else: return [] # TODO : when plugged on Machines : should return : Machine - values_neg else: retour = br.merge(values) return retour[0]
def getMachines(self, ctx, h_params): """ return a list of machine matching with params h_params stuct looks like that : {'hostname':name, 'uuid':uuid} """ ret = ComputerManager().getComputersList(ctx, h_params) return map(lambda m: Machine(ret[m][1]), ret)
def getSubscriptionInfo(): # Creating root context ctx = SecurityContext() ctx.userid = 'root' # Get all machine count count = ComputerManager().getComputerCount(ctx) # Get license max_machines out, err, ec = runInShell('/usr/sbin/pulse-licensed -G /etc/pulse-licensing/installation_id -l /etc/pulse-licensing/license.dat -p /etc/pulse-licensing/license -i') if ec == 0: data = loads(out) for license in data: if license['alias'] == 'pulse': max_machines = int(license['custon_number']) ts_expiration = int(license['licencingtime']) break else: max_machines = 5 else: max_machines = 5 if max_machines == 5: ts_expiration = 0 return [count, max_machines, ts_expiration]
def activate(): config = GlpiConfig("glpi") logger = logging.getLogger() if config.disable: logger.warning("Plugin glpi: disabled by configuration.") return False if not GlpiLocation().init(config): # does Glpi().activate() return False if not Glpi().db_check(): return False ComputerManager().register("glpi", GlpiComputers) ProvisioningManager().register("glpi", GlpiProvisioner) if config.displayLocalisationBar: ComputerLocationManager().register("glpi", GlpiLocation) if config.check_db_enable: scheduleCheckStatus(config.check_db_interval) # Register the panel to the DashboardManager try: from mmc.plugins.dashboard.manager import DashboardManager from mmc.plugins.glpi.panel import GlpiPanel DM = DashboardManager() DM.register_panel(GlpiPanel("glpi")) except ImportError: pass return True
def scheduler_probe_client(self, scheduler, uuid): ctx = self.currentContext computer = ComputerManager().getComputer(ctx, {'uuid': uuid}, True) if not 'fullname' in computer[1]: computer[1]['fullname'] = computer[1]['cn'][0] return xmlrpcCleanup( mmc.plugins.msc.client.scheduler.probe_client(scheduler, computer))
def activate(): """ Read the plugin configuration, initialize it, and run some tests to ensure it is ready to operate. """ logger = logging.getLogger() config = ImagingConfig("imaging") if config.disabled: logger.warning("Plugin imaging: disabled by configuration.") return False # Initialize imaging database if not ImagingDatabase().activate(config): logger.warning( "Plugin imaging: an error occurred during the database initialization" ) return False # register ImagingProfile in ComputerProfileManager but only as a client ComputerProfileManager().register("imaging", ImagingProfile) ComputerImagingManager().register("imaging", ComputerImagingImaging) Pulse2Manager().register('imaging', ImagingPulse2Manager) ComputerManager().register('imaging', InventoryComputers) TaskManager().addTask("imaging.purge_removed_computers", (purge_removed_computers, ), cron_expression=config.purge_interval) return True
def purge_removed_computers(): from mmc.plugins.base.computers import ComputerManager from mmc.plugins.base import LdapUserGroupControl # Get all imaging targets targets = ImagingDatabase().getAllRegisteredComputers() # Creating root context to query ComputerManager ctx = SecurityContext() ctx.userid = 'root' ctx.userdn = LdapUserGroupControl().searchUserDN(ctx.userid) # Init to_delete computer list to_delete = [] for uuid in targets: if ComputerManager().getComputerCount(ctx, {'uuid': uuid}) == 0: # If the target computer is not in ComputerManager database anymore # we unregister it from imaging to_delete.append(uuid) # Unregistering orphan targets without backup if to_delete: logging.getLogger().info('Orphan imaging computer(s) found') logging.getLogger().info('Going to purge %s' % ' '.join(to_delete)) computersUnregister(to_delete, False) return True
def activate(): logger = logging.getLogger() config = InventoryConfig() config.init("inventory") logger.debug("Inventory %s" % str(config.disable)) if config.disable: logger.warning("Plugin inventory: disabled by configuration.") return False # When this module is used by the MMC agent, the global inventory variable is shared. # This means an Inventory instance is not created each time a XML-RPC call is done. if not InventoryLocation().init( config ): # does Inventory().activate() (which does the Inventory().db_check()) return False logger.info("Plugin inventory: Inventory database version is %d" % Inventory().dbversion) ComputerManager().register("inventory", InventoryComputers) ProvisioningManager().register('inventory', InventoryProvisioner) ComputerLocationManager().register('inventory', InventoryLocation) PossibleQueries().init(config) # Register the panel to the DashboardManager try: from mmc.plugins.dashboard.manager import DashboardManager from mmc.plugins.inventory.panel import InventoryPanel DM = DashboardManager() DM.register_panel(InventoryPanel("inventory")) except ImportError: pass return True
def establish_vnc_proxy(self, scheduler, uuid, requestor_ip): ctx = self.currentContext computer = ComputerManager().getComputer(ctx, {'uuid': uuid}, True) try: # FIXME: dirty bugfix, should be factorized upstream computer[1]['fullname'] except KeyError: computer[1]['fullname'] = computer[1]['cn'][0] return xmlrpcCleanup(mmc.plugins.msc.client.scheduler.tcp_sproxy(scheduler, computer, requestor_ip, MscConfig().web_vnc_port))
def _get_updatable_computers(ctx, activated=True): # Get active computer manager computer_manager = ComputerManager().getManagerName() if computer_manager == 'inventory': dyngroup_pattern = '%d==inventory::Hardware/OperatingSystem==%s' elif computer_manager == 'glpi': dyngroup_pattern = '%d==glpi::Operating system==%s' else: logging.getLogger().error( 'Update module: Unsupported computer manager %s' % computer_manager) return False # Get all enabled os_classes if activated: os_classes = updateDatabase().get_os_classes( {'filters': { 'enabled': 1 }}) else: os_classes = updateDatabase().get_os_classes( {'filters': { 'enabled': 0 }}) targets = [] # Create update command for enabled os_classes for os_class in os_classes['data']: patterns = os_class['pattern'].split('||') request = [] equ_bool = [] for i in xrange(len(patterns)): request.append(dyngroup_pattern % (i + 1, patterns[i])) equ_bool.append(str(i + 1)) request = '||'.join(request) equ_bool = 'OR(%s)' % ','.join(equ_bool) targets.extend(ComputerManager().getComputersList( ctx, { 'request': request, 'equ_bool': equ_bool }).keys()) return targets
def importmembers_to_group(self, id, elt, values): ctx = self.currentContext # get machines uuids from values request, bool, optimization = forgeRequest(elt, values) req = {'request':request, 'equ_bool':bool, 'optimization' : optimization} machines = ComputerManager().getRestrictedComputersList(ctx, 0, -1, req) # put in the wanted format uuids = {} if type(machines) == dict: machines = machines.values() for m in machines: uuid = m[1]['objectUUID'][0] hostname = m[1]['cn'][0] uuids[uuid] = {'hostname':hostname, 'uuid':uuid} # insert uuid in group with addmembers_to_group return self.addmembers_to_group(id, uuids)
def replyToQuery(ctx, query, bool=None, min=0, max=10, justId=False, toH=False, filt=None): if query == None: return [] if __onlyIn(query, ComputerManager().main): ComputerManager().main filt = __addCtxFilters(ctx, filt) filt['query'] = query return xmlrpcCleanup(ComputerManager().getRestrictedComputersList( ctx, min, max, filt, False, justId, toH)) else: return xmlrpcCleanup(QueryManager().replyToQuery( ctx, query, bool, min, max))
def get_machines_update_status(not_supported=False): """ Get machine update status as a dict as key and status string as value. commons status values :"not_supported","not_registered", "up-to-date","need_update","update_available","update_planned", "os_update_disabled". The "not_supported" value can be disabled with not_supported param. """ # Creating root context ctx = SecurityContext() ctx.userid = 'root' machines_status = {} uuids = [] # get computer list who returned update machines_update = updateDatabase().get_machines() # get activated os computers: machines_os_enabled = _get_updatable_computers(ctx, activated=True) # get disabled os computers: machines_os_disabled = _get_updatable_computers(ctx, activated=False) # get uuid for all computer ComputerList = ComputerManager().getComputersList(ctx, {}).keys() uuids = [] # convert uuid as string number for uuid in ComputerList: uuids.append(int(uuid.lower().replace('uuid', ''))) machines_os_enabled = [ int(uuid.lower().replace('uuid', '')) for uuid in machines_os_enabled ] machines_os_disabled = [ int(uuid.lower().replace('uuid', '')) for uuid in machines_os_disabled ] # get status of all machines for uuid in uuids: if uuid in machines_os_disabled: machines_status["UUID" + str(uuid)] = "os_update_disabled" elif uuid in machines_os_enabled: if uuid in machines_update: # if no neutral update not installed on this machine if len(updateDatabase().get_neutral_updates_for_host(uuid, 0)) == 0: # if no eligible update if len(updateDatabase().get_eligible_updates_for_host( uuid)) == 0: machines_status["UUID" + str(uuid)] = "up-to-date" else: machines_status["UUID" + str(uuid)] = "update_planned" else: machines_status["UUID" + str(uuid)] = "update_available" else: machines_status["UUID" + str(uuid)] = "not_registered" elif not_supported: machines_status["UUID" + str(uuid)] = "not_supported" return machines_status
def importmembers_to_group(self, id, elt, values): ctx = self.currentContext # get machines uuids from values request, bool, optimization = forgeRequest(elt, values) req = { 'request': request, 'equ_bool': bool, 'optimization': optimization } machines = ComputerManager().getRestrictedComputersList( ctx, 0, -1, req) # put in the wanted format uuids = {} if type(machines) == dict: machines = machines.values() for m in machines: uuid = m[1]['objectUUID'][0] hostname = m[1]['cn'][0] uuids[uuid] = {'hostname': hostname, 'uuid': uuid} # insert uuid in group with addmembers_to_group return self.addmembers_to_group(id, uuids)
def scheduler_choose_client_ip(self, scheduler, uuid): ctx = self.currentContext computer = ComputerManager().getComputer(ctx, {'uuid': uuid}, True) network = computer[1] interfaces = {"uuid" : uuid, "fqdn" : network["cn"][0], "shortname" : network["cn"][0], "ips" : noNoneList(network["ipHostNumber"]), "macs" : noNoneList(network["macAddress"]), "netmasks" : noNoneList(network["subnetMask"]), } return xmlrpcCleanup2(mmc.plugins.msc.client.scheduler.choose_client_ip(scheduler, interfaces))
def forgeRequest(elt, values): i = 1 module = ComputerManager().main crit = elt requests = [] bools = [] optimization = True for val in values: # If there is a wildcard in a value, we don't flag this request for # possible optimization if optimization: optimization = not "*" in val requests.append("%i==%s::%s==%s" % (i, module, crit, val)) bools.append(str(i)) i += 1 request = '||'.join(requests) bools = "OR(" + ",".join(bools) + ")" if optimization and ComputerManager().getManagerName() == "inventory": optim = {"criterion": crit, "data": values} else: optim = {} return (request, bools, optim)
def get_active_convergence_for_host(self, host_uuid): all_convergences = DyngroupDatabase().get_active_convergences() host_convergences = [] for cv in all_convergences: # Do next with root context ctx = self.getContext() if ComputerManager().getRestrictedComputersList( ctx, 0, -1, { 'uuid': host_uuid, 'gid': cv['gid'] }, False, False, True): host_convergences.append(cv) return host_convergences
def get_all_commands_for_consult(self, min=0, max=10, filt='', expired=True): ctx = self.currentContext size, ret1 = MscDatabase().getAllCommandsConsult( ctx, min, max, filt, expired) ret = [] logger = logging.getLogger() cache = {} for c in ret1: if c['gid']: if cache.has_key("G%s" % (c['gid'])): #if "G%s"%(c['gid']) in cache: c['target'] = cache["G%s" % (c['gid'])] else: group = DyngroupDatabase().get_group(ctx, c['gid'], True) if type( group ) == bool: # we dont have the permission to view the group c['target'] = 'UNVISIBLEGROUP' # TODO! elif group == None: c['target'] = 'this group has been deleted' elif hasattr(group, 'ro') and group.ro: logger.debug("user %s access to group %s in RO mode" % (ctx.userid, group.name)) c['target'] = group.name else: c['target'] = group.name cache["G%s" % (c['gid'])] = c['target'] else: if cache.has_key("M%s" % (c['uuid'])): #if "M%s"%(c['uuid']) in cache: c['target'] = cache["M%s" % (c['uuid'])] else: if not ComputerLocationManager( ).doesUserHaveAccessToMachine(ctx, c['uuid']): c['target'] = "UNVISIBLEMACHINE" elif not ComputerManager().getComputer( ctx, {'uuid': c['uuid']}): c['target'] = "UNVISIBLEMACHINE" cache["M%s" % (c['uuid'])] = c['target'] # treat c['title'] to remove the date when possible # "Bundle (1) - 2009/12/14 10:22:24" => "Bundle (1)" date_re = re.compile(" - \d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d") c['title'] = date_re.sub('', c['title']) ret.append(c) return xmlrpcCleanup((size, ret))
def hasMoreThanOneEthCard(self, uuids): ctx = self.currentContext moreThanOneEthCard = [] # Exclude computers who have more than one network card nets = ComputerManager().getComputersNetwork(ctx, {'uuids': uuids}) for net in nets: net = net[1] if len(net['macAddress']) > 1: if net['objectUUID'] not in moreThanOneEthCard: logging.getLogger().debug( "Computer %s (%s) has more than one network card, it won't be added to profile" % (net['cn'], net['objectUUID'])) moreThanOneEthCard.append(net['objectUUID'][0]) return moreThanOneEthCard
def update_machine_cache(self): ctx = self.currentContext dyndatabase = DyngroupDatabase() cache = dyndatabase.getAllMachinesUuid() machines = ComputerManager().getRestrictedComputersList( ctx, 0, -1, {'uuids': cache.keys()}, False, False, True) need_update = {} for m in machines: if m['hostname'] != cache[m['uuid']]: need_update[m['uuid']] = m['hostname'] dyndatabase.updateNewNames(need_update) return len(need_update)
def pull_target_awake(self, hostname, macs): """ Gets the requested machine for UUID. @param hostname: hostname of computer @type hostname: str @param macs: MAC addresses of computer @type macs: list @return: UUID @rtype: str """ ctx = self.currentContext return xmlrpcCleanup(ComputerManager().getComputerByHostnameAndMacs( ctx, hostname, macs))
def download_file(self, uuid): path = MscConfig().web_dlpath ctx = self.currentContext if not path: ret = False else: bwlimit = MscConfig().web_def_dlmaxbw ctx = self.currentContext computer = ComputerManager().getComputer(ctx, {'uuid': uuid}, True) try: # FIXME: dirty bugfix, should be factorized upstream computer[1]['fullname'] except KeyError: computer[1]['fullname'] = computer[1]['cn'][0] mscdlp = MscDownloadProcess(ctx.userid, computer, path, bwlimit) ret = mscdlp.startDownload() return ret
def _get_convergence_new_machines_to_add(self, session, ctx, cmd_id, convergence_deploy_group_id): """ Check if machines will be added to convergence command Return machines who are part of deploy group, but not already present in convergence command, except these who are in done step in phase table. @see http://projects.mandriva.org/issues/2255: if package were already deployed, but was manually removed by a user, it must be redeployed """ machines_in_command = self._get_machines_in_command(session, cmd_id) machines_in_deploy_group = ComputerManager( ).getRestrictedComputersList(ctx, filt={'gid': convergence_deploy_group_id}, justId=True) return [ x for x in machines_in_deploy_group if x not in machines_in_command ]
def activate(): """ Read the plugin configuration, initialize it, and run some tests to ensure it is ready to operate. """ logger = logging.getLogger() config = BackuppcConfig("backuppc") # Registering BackupComputers in ComputerManager ComputerManager().register('backuppc', BackupComputers) if config.disable: logger.warning("Plugin backuppc: disabled by configuration.") return False if not BackuppcDatabase().activate(config): logger.warning("Plugin backuppc: an error occurred during the database initialization") return False return True
def _replyToQueryXML(self, ctx, query, bool = None): values = {} for qid, module, criterion, value in query: val, neg = self._getPluginReplyToQuery( ctx, self.queryablePlugins[module], [criterion, value] ) values[str(qid)] = [val, neg] self.logger.debug(values) br = BoolRequest() if bool == None or bool == '': bool = "<AND><p>"+('</p><p>'.join(map(lambda a:a[0][0], values)))+"</p></AND>" all = ComputerManager().getComputersList(ctx) # for the moment everything is based on names... should be changed into uuids all = map(lambda a: a[1]['cn'][0], all) values['A'] = [all, True] bool = '<AND><p>A</p><p>'+bool+'</p></AND>' br.parseXML(bool) if bool == None or not br.isValid(): # no bool specified = only AND if len(values.keys()) > 0: retour = values.pop() for val in values: neg = val[1] val = val[0] if neg: retour = filter(lambda a,val=val:a in val, retour) else: retour = filter(lambda a,val=val:a not in val, retour) return retour else: return [] # TODO : when plugged on Machines : should return : Machine - values_neg else: retour = br.merge(values) return retour[0]
def activate(): config = GlpiConfig("glpi") logger = logging.getLogger() if config.disable: logger.warning("Plugin glpi: disabled by configuration.") return False if not GlpiLocation().init(config): # does Glpi().activate() return False if not Glpi().db_check(): return False ComputerManager().register("glpi", GlpiComputers) ProvisioningManager().register("glpi", GlpiProvisioner) if config.displayLocalisationBar: ComputerLocationManager().register("glpi", GlpiLocation) if config.check_db_enable: scheduleCheckStatus(config.check_db_interval) return True
def activate(): logger = logging.getLogger() global config config = DGConfig() config.init("dyngroup") if config.disable: logger.warning("Plugin dyngroup: disabled by configuration.") return False DyngroupDatabase().activate(config) if not DyngroupDatabase().db_check(): return False ComputerGroupManager().register("dyngroup", DyngroupGroup) ComputerProfileManager().register("dyngroup", DyngroupProfile) ComputerManager().register("dyngroup", DyngroupComputers) if config.check_db_enable: scheduleCheckStatus(config.check_db_interval) return True
def getComputersData(self, ctx, targets, group_id): """ Get all targets network information """ start_time = time.time() computers = ComputerManager().getComputersNetwork( ctx, {"uuids": targets}) middle_time = time.time() # Rebuild the targets list, and get computers data tmp = [] targetsdata = [] for computer in computers: if 'fullname' in computer[1]: hostname = computer[1]['fullname'] else: hostname = computer[1]['cn'][0] tmp.append([computer[1]['objectUUID'][0], hostname]) targetsdata.append(self.prepareTarget(computer, group_id)) targets = tmp[:] end_time = time.time() self.logger.debug( "msc.database.getComputersData took %ss to get network data and %ss to treat it" % (middle_time - start_time, end_time - middle_time)) return tmp, targetsdata