def __init__(self, sessionName=u'OPSISID', sessionMaxInactiveInterval=120, maxSessionsPerIp=0, sessionDeletionTimeout=60): self.sessionName = forceUnicode(sessionName) self.sessionMaxInactiveInterval = forceInt(sessionMaxInactiveInterval) self.maxSessionsPerIp = forceInt(maxSessionsPerIp) self.sessionDeletionTimeout = forceInt(sessionDeletionTimeout) self.sessions = {}
def showMessage(self, text, title=_(u'Message'), okLabel=_(u'OK'), width=-1, height=-1, seconds=0): try: text = forceUnicode(text) title = forceUnicode(title) okLabel = forceUnicode(okLabel) width = forceInt(width) height = forceInt(height) seconds = forceInt(seconds) for string in self.confidentialStrings: text = text.replace(string, u'*** confidential ***') if width <= 0: width = self.getScreen().width - 15 if height <= 0: height = len(text.split(u'\n')) + 2 textBox = Textbox(width=width, height=height, text=text.encode(encoding, 'replace'), scroll=1, wrap=1) button = Button(okLabel.encode(encoding, 'replace')) rows = 2 if seconds: rows = 1 gridForm = GridForm(self._screen, title.encode(encoding, 'replace'), 1, rows) gridForm.add(textBox, 0, 0) if seconds: gridForm.draw() self.refresh() time.sleep(seconds) self._screen.popWindow() else: gridForm.add(button, 0, 1) helpLine = _( u"<F12> %s | <Space> select | <Up/Down> scroll text" ) % okLabel self.getScreen().pushHelpLine( forceUnicode(helpLine).encode(encoding, 'replace')) return gridForm.runOnce() except Exception as e: self.exit() logger.logException(e) raise
def _configureHostcontrolBackend(backend, kwargs): """ Configure `backend` to the values given in `kwargs`. Keys in `kwargs` will be treated as lowercase. Supported keys are 'broadcastaddresses', 'hostrpctimeout', \ 'maxconnections' opsiclientdport' and 'resolvehostaddress'. Unrecognized options will be ignored. :type backend: HostControlBackend or HostControlSafeBackend :type kwargs: dict """ for option, value in kwargs.items(): option = option.lower() if option == 'opsiclientdport': backend._opsiclientdPort = forceInt(value) elif option == 'hostrpctimeout': backend._hostRpcTimeout = forceInt(value) elif option == 'resolvehostaddress': backend._resolveHostAddress = forceBool(value) elif option == 'maxconnections': backend._maxConnections = forceInt(value) elif option == 'broadcastaddresses': try: backend._broadcastAddresses = forceDict(value) except ValueError: # This is an old-style configuraton. Old default # port was 12287 so we assume this as the default # and convert everything to the new format. backend._broadcastAddresses = { bcAddress: (12287, ) for bcAddress in forceUnicodeList(value) } logger.warning( "Your hostcontrol backend configuration uses the old " "format for broadcast addresses. The new format " "allows to also set a list of ports to send the " "broadcast to.\nPlease use this new " "value in the future: {0!r}", backend._broadcastAddresses) newAddresses = { bcAddress: tuple(forceInt(port) for port in ports) for bcAddress, ports in backend._broadcastAddresses.items() } backend._broadcastAddresses = newAddresses if backend._maxConnections < 1: backend._maxConnections = 1
def __init__(self, hostControlBackend, hostId, address, username, password, method, params=[], hostPort=0): KillableThread.__init__(self) self.hostControlBackend = hostControlBackend self.hostId = forceHostId(hostId) self.address = forceIpAddress(address) self.username = forceUnicode(username) self.password = forceUnicode(password) self.method = forceUnicode(method) self.params = forceList(params) self.error = None self.result = None self.started = 0 self.ended = 0 if hostPort: self.hostPort = forceInt(hostPort) else: self.hostPort = self.hostControlBackend._opsiclientdPort
def _parseArguments(self, kwargs): for (option, value) in kwargs.items(): option = option.lower() if option == 'port': self._port = value elif option == 'timeout': self._timeout = forceInt(value)
def setState(self, state): state = forceInt(state) if state <= 0: state = 0 self._percent = 0 if state > self._end: state = self._end self._percent = 100 self._state = state now = int(time.time()) if self._fireAlways or (self._timeFired != now) or (self._state in (0, self._end)): if self._state == 0: self._percent = 0 elif self._end == 0: self._percent = 100 else: self._percent = float(100) * (float(self._state) / float(self._end)) self._timeSpend = now - self._timeStarted if self._timeSpend: self._speed = int(float(self._state) / float(self._timeSpend)) if self._speed < 0: self._speed = 0 elif self._speed > 0: self._timeLeft = int( ((float(self._timeLeft) * 2.0) + (float(self._end) - float(self._state)) / float(self._speed)) / 3.0) self._timeFired = now self._notifyProgressChanged()
def hostControl_reachable(self, hostIds=[], timeout=None): hostIds = self._context.host_getIdents(id=hostIds, returnType='unicode') # pylint: disable=maybe-no-member if not hostIds: raise BackendMissingDataError(u"No matching host ids found") hostIds = forceHostIdList(hostIds) if not timeout: timeout = self._hostReachableTimeout timeout = forceInt(timeout) result = {} threads = [] for host in self._context.host_getObjects(id=hostIds): # pylint: disable=maybe-no-member try: address = self._getHostAddress(host) threads.append( ConnectionThread(hostControlBackend=self, hostId=host.id, address=address)) except Exception as e: logger.debug("Problem found: '%s'" % e) result[host.id] = False runningThreads = 0 while threads: newThreads = [] for thread in threads: if thread.ended: result[thread.hostId] = thread.result runningThreads -= 1 continue if not thread.started: if runningThreads < self._maxConnections: logger.debug(u"Trying to check host reachable %s" % thread.hostId) thread.start() runningThreads += 1 else: timeRunning = time.time() - thread.started if timeRunning >= timeout + 5: # thread still alive 5 seconds after timeout => kill logger.error( u"Reachable check to host %s address %s timed out after %0.2f seconds, terminating" % (thread.hostId, thread.address, timeRunning)) result[thread.hostId] = False if not thread.ended: try: thread.terminate() except Exception as e: logger.error( u"Failed to terminate reachable thread: %s" % e) runningThreads -= 1 continue newThreads.append(thread) threads = newThreads time.sleep(0.1) return result
def createMessageBox(self, width=-1, height=-1, title=_(u'Text'), text=u''): width = forceInt(width) height = forceInt(height) title = forceUnicode(title) text = forceUnicode(text) self.messageBox = SnackMessageBox(ui=self, width=width, height=height, title=title, text=text) return self.messageBox
def __init__(self, ui, width=0, height=0, total=100, title=_(u'Title'), text=u''): ProgressObserver.__init__(self) self._ui = ui width = forceInt(width) height = forceInt(height) total = forceInt(total) title = forceUnicode(title) text = forceUnicode(text) if (width <= 0): width = self._ui.getScreen().width - 7 if (height <= 0): height = self._ui.getScreen().height - 7 SnackMessageBox.__init__(self, ui, width, height - 4, title, text) self._overallTotal = total self._overallState = -1 self._overallFactor = 1 self._overallProgressSubject = None self._currentTotal = 100 self._currentState = -1 self._currentFactor = 1 self._currentProgressSubject = None self._width = width self._height = height self._gridForm = GridForm(self._ui.getScreen(), title.encode(encoding, 'replace'), 1, 3) self._currentScale = Scale(self._width, self._currentTotal) self._overallScale = Scale(self._width, self._overallTotal) self._gridForm.add(self._textbox, 0, 0) self._gridForm.add(self._currentScale, 0, 1) self._gridForm.add(self._overallScale, 0, 2) self._ui.getScreen().pushHelpLine("")
def adjustSize(self, maxsize): if maxsize < 1: raise ValueError(u"Connection pool size %d is invalid" % maxsize) self.maxsize = forceInt(maxsize) self.delPool() self.pool = Queue(self.maxsize) # Fill the queue up so that doing get() on it will block properly for _ in range(self.maxsize): self.pool.put(None)
def setEnd(self, end): if not self._endChangable: return self._end = forceInt(end) if self._end < 0: self._end = 0 self.setState(self._state) self._notifyEndChanged()
def __init__(self, ui, width=0, height=0, title=_(u'Title'), text=u''): MessageObserver.__init__(self) try: self._ui = ui width = forceInt(width) height = forceInt(height) title = forceUnicode(title) text = forceUnicode(text) self._visible = False self._title = title self._text = text for string in self._ui.confidentialStrings: self._text = self._text.replace(string, u'*** confidential ***') if (width <= 0): width = self._ui.getScreen().width - 7 if (height <= 0): height = self._ui.getScreen().height - 7 self._width = width self._height = self._textHeight = height self._gridForm = GridForm(self._ui.getScreen(), title.encode(encoding, 'replace'), 1, 1) self._textbox = Textbox(self._width, self._height, self._text.encode(encoding, 'replace'), scroll=0, wrap=1) self._gridForm.add(self._textbox, 0, 0) # help line self._ui.getScreen().pushHelpLine(u"") except Exception as e: self._ui.exit() logger.logException(e) raise
def __init__(self, address, port, subjects): threading.Thread.__init__(self) self._address = forceIpAddress(address) if not self._address: self._address = u'0.0.0.0' self._port = forceInt(port) self._factory = NotificationServerFactory() self._factory.setSubjects(subjects) self._server = None self._listening = False self._error = None
def __init__(self, id, type=u'', title=u'', **args): MessageSubject.__init__(self, id, type, title, **args) self.reset() self._fireAlways = True self._endChangable = True try: self._end = forceInt(args['end']) if self._end < 0: self._end = 0 except KeyError: pass try: self._percent = args['percent'] except KeyError: pass try: self._state = args['state'] except KeyError: pass try: self._timeStarted = args['timeStarted'] except KeyError: pass try: self._timeSpend = args['timeSpend'] except KeyError: pass try: self._timeLeft = args['timeLeft'] except KeyError: pass try: self._timeFired = args['timeFired'] except KeyError: pass try: self._speed = args['speed'] except KeyError: pass try: self._fireAlways = forceBool(args['fireAlways']) except KeyError: pass logger.debug(u"ProgressSubject {0!r} created", self._id)
def __init__(self, **kwargs): self._address = u'localhost' self._username = u'opsi' self._password = u'opsi' self._database = u'opsi' self._databaseCharset = 'utf8' self._connectionPoolSize = 20 self._connectionPoolMaxOverflow = 10 self._connectionPoolTimeout = 30 self._connectionPoolRecyclingSeconds = -1 self.autoCommit = True # Parse arguments for (option, value) in kwargs.items(): option = option.lower() if option == 'address': self._address = forceUnicode(value) elif option == 'username': self._username = forceUnicode(value) elif option == 'password': self._password = forceUnicode(value) elif option == 'database': self._database = forceUnicode(value) elif option == 'databasecharset': self._databaseCharset = str(value) elif option == 'connectionpoolsize': self._connectionPoolSize = forceInt(value) elif option == 'connectionpoolmaxoverflow': self._connectionPoolMaxOverflow = forceInt(value) elif option == 'connectionpooltimeout': self._connectionPoolTimeout = forceInt(value) elif option == 'connectionpoolrecycling': self._connectionPoolRecyclingSeconds = forceInt(value) self._transactionLock = threading.Lock() self._pool = None self._createConnectionPool() logger.debug(u'MySQL created: %s' % self)
def __init__(self, id, type=u'', title=u'', **args): Subject.__init__(self, id, type, title, **args) self.reset() try: self._message = forceUnicode(args['message']) except KeyError: pass # no matching key try: self._severity = forceInt(args['severity']) except KeyError: pass # no matching key logger.debug(u"MessageSubject {0!r} created", self._id)
def __init__(self, **kwargs): self._address = u'localhost' self._username = u'opsi' self._password = u'opsi' self._database = u'opsi' self._databaseCharset = 'utf8' self._connectionPoolSize = 20 self._connectionPoolMaxOverflow = 10 self._connectionPoolTimeout = 30 # Parse arguments for (option, value) in kwargs.items(): option = option.lower() if option == 'address': self._address = forceUnicode(value) elif option == 'username': self._username = forceUnicode(value) elif option == 'password': self._password = forceUnicode(value) elif option == 'database': self._database = forceUnicode(value) elif option == 'databasecharset': self._databaseCharset = str(value) elif option == 'connectionpoolsize': self._connectionPoolSize = forceInt(value) elif option == 'connectionpoolmaxoverflow': self._connectionPoolMaxOverflow = forceInt(value) elif option == 'connectionpooltimeout': self._connectionPoolTimeout = forceInt(value) self._transactionLock = threading.Lock() self._pool = None self._createConnectionPool() logger.debug(u'PgSQL created: %s' % self)
def createCopyDualProgressBox(self, width=-1, height=-1, total=100, title=_(u'Copy progress'), text=u''): try: width = forceInt(width) height = forceInt(height) total = forceInt(total) title = forceUnicode(title) text = forceUnicode(text) progressBox = SnackCopyDualProgressBox(ui=self, width=width, height=height, total=total, title=title, text=text) return progressBox except Exception as e: self.exit() logger.logException(e) raise
def ipAddressInNetwork(ipAddress, networkAddress): """ Checks if the given IP address is in the given network range. Returns ``True`` if the given address is part of the network. Returns ``False`` if the given address is not part of the network. :param ipAddress: The IP which we check. :type ipAddress: str :param networkAddress: The network address written with slash notation. :type networkAddress: str """ def createBytemaskFromAddress(address): "Returns an int representation of an bytemask of an ipAddress." num = [forceInt(part) for part in address.split('.')] return (num[0] << 24) + (num[1] << 16) + (num[2] << 8) + num[3] ipAddress = forceIPAddress(ipAddress) networkAddress = forceNetworkAddress(networkAddress) ip = createBytemaskFromAddress(ipAddress) network, netmask = networkAddress.split(u'/') if '.' not in netmask: netmask = forceUnicode( socket.inet_ntoa( struct.pack('>I', 0xffffffff ^ (1 << 32 - forceInt(netmask)) - 1))) while netmask.count('.') < 3: netmask = netmask + u'.0' logger.debug(u"Testing if ip {ipAddress} is part of network " u"{network}/{netmask}".format(ipAddress=ipAddress, network=network, netmask=netmask)) network = createBytemaskFromAddress(network) netmask = createBytemaskFromAddress(netmask) wildcard = netmask ^ 0xFFFFFFFF if wildcard | ip == wildcard | network: return True return False
def __init__(self, smtphost=u'localhost', smtpport=25, subject=u'opsi product updater', sender=u'', receivers=[]): super(EmailNotifier, self).__init__() self.receivers = forceUnicodeList(receivers) if not self.receivers: raise ValueError(u"List of mail recipients empty") self.smtphost = forceUnicode(smtphost) self.smtpport = forceInt(smtpport) self.sender = forceUnicode(sender) self.subject = forceUnicode(subject) self.username = None self.password = None self.useStarttls = False
def setEventEnd(self, eventId, end=None): if self._stopped: return -1 with self._db_lock, self._sql.session() as session: try: eventId = forceInt(eventId) if not end: end = timestamp() end = forceOpsiTimestamp(end) return self._sql.update(session, 'EVENT', f'`id` = {eventId}', { 'end': end, 'durationEvent': True }) except Exception as end_error: # pylint: disable=broad-except logger.error("Failed to set end of event '%s': %s", eventId, end_error) return -1
def __init__(self, sessionHandler, name=u'OPSISID', sessionMaxInactiveInterval=120): self.sessionHandler = sessionHandler self.name = forceUnicode(name) self.sessionMaxInactiveInterval = forceInt(sessionMaxInactiveInterval) self.created = time.time() self.lastModified = time.time() self.sessionTimer = None self.uid = randomString(32) self.ip = u'' self.userAgent = u'' self.hostname = u'' self.user = u'' self.password = u'' self.authenticated = False self.postpath = [] self.usageCount = 0 self.usageCountLock = threading.Lock() self.markedForDeletion = False self.deleted = False self.touch()
def switchDesktop(self, desktop, sessionId=None): # pylint: disable=no-self-use if not ('opsiclientd_rpc' in config.getDict() and 'command' in config.getDict()['opsiclientd_rpc']): raise Exception("opsiclientd_rpc command not defined") desktop = forceUnicode(desktop) if sessionId is None: sessionId = System.getActiveSessionId() if sessionId is None: sessionId = System.getActiveConsoleSessionId() sessionId = forceInt(sessionId) rpc = f"noop(System.switchDesktop('{desktop}'))" cmd = f'{config.get("opsiclientd_rpc", "command")} "{rpc}"' try: System.runCommandInSession(command=cmd, sessionId=sessionId, desktop=desktop, waitForProcessEnding=True, timeoutSeconds=60, noWindow=True) except Exception as err: # pylint: disable=broad-except logger.error(err)
def getSharedConnectionPool(scheme, host, port, **kw): scheme = forceUnicodeLower(scheme) host = forceUnicode(host) port = forceInt(port) poolKey = u'httplib:%s:%d' % (host, port) global connectionPools if poolKey not in connectionPools: if scheme in ('https', 'webdavs'): connectionPools[poolKey] = HTTPSConnectionPool(host, port=port, **kw) else: connectionPools[poolKey] = HTTPConnectionPool(host, port=port, **kw) else: connectionPools[poolKey].increaseUsageCount() maxsize = kw.get('maxsize', 0) if maxsize > connectionPools[poolKey].maxsize: connectionPools[poolKey].adjustSize(maxsize) return connectionPools[poolKey]
def connectConfigService(self, allowTemporaryConfigServiceUrls=True): # pylint: disable=too-many-locals,too-many-branches,too-many-statements try: # pylint: disable=too-many-nested-blocks configServiceUrls = config.getConfigServiceUrls( allowTemporaryConfigServiceUrls=allowTemporaryConfigServiceUrls ) if not configServiceUrls: raise Exception("No service url defined") if self._loadBalance and (len(configServiceUrls) > 1): random.shuffle(configServiceUrls) for urlIndex, configServiceURL in enumerate(configServiceUrls): self._configServiceUrl = configServiceURL kwargs = self.connectionThreadOptions() logger.debug("Creating ServiceConnectionThread (url: %s)", self._configServiceUrl) serviceConnectionThread = ServiceConnectionThread( configServiceUrl=self._configServiceUrl, username=config.get('global', 'host_id'), password=config.get('global', 'opsi_host_key'), **kwargs) serviceConnectionThread.daemon = True self.connectionStart(self._configServiceUrl) cancellableAfter = forceInt( config.get('config_service', 'user_cancelable_after')) timeout = forceInt( config.get('config_service', 'connection_timeout')) logger.info( "Starting ServiceConnectionThread, timeout is %d seconds", timeout) serviceConnectionThread.start() for _unused in range(5): if serviceConnectionThread.running: break time.sleep(1) logger.debug("ServiceConnectionThread started") while serviceConnectionThread.running and timeout > 0: if self._should_stop: return logger.debug( "Waiting for ServiceConnectionThread (timeout: %d, alive: %s, cancellable in: %d)", timeout, serviceConnectionThread.is_alive(), cancellableAfter) self.connectionTimeoutChanged(timeout) if cancellableAfter > 0: cancellableAfter -= 1 if cancellableAfter == 0: self.connectionCancelable( serviceConnectionThread.stopConnectionCallback) time.sleep(1) timeout -= 1 if serviceConnectionThread.cancelled: self.connectionCanceled() elif serviceConnectionThread.running: serviceConnectionThread.stop() if urlIndex + 1 < len(configServiceUrls): # Try next url continue self.connectionTimedOut() if not serviceConnectionThread.connected: self.connectionFailed( serviceConnectionThread.connectionError) if serviceConnectionThread.connected and ( serviceConnectionThread.getUsername() != config.get( 'global', 'host_id')): config.set('global', 'host_id', serviceConnectionThread.getUsername().lower()) logger.info("Updated host_id to '%s'", config.get('global', 'host_id')) config.updateConfigFile() if serviceConnectionThread.connected and forceBool( config.get('config_service', 'sync_time_from_service')): logger.info("Syncing local system time from service") try: System.setLocalSystemTime( serviceConnectionThread.configService. getServiceTime(utctime=True)) # pylint: disable=no-member except Exception as err: # pylint: disable=broad-except logger.error("Failed to sync time: '%s'", err) if ("localhost" not in configServiceURL and "127.0.0.1" not in configServiceURL): try: config.set( 'depot_server', 'master_depot_id', serviceConnectionThread.configService.getDepotId( config.get('global', 'host_id')) # pylint: disable=no-member ) config.updateConfigFile() except Exception as err: # pylint: disable=broad-except logger.warning(err) self._configService = serviceConnectionThread.configService self.connectionEstablished() except Exception: self.disconnectConfigService() raise
def getHardwareInformationFromWMI(conf): wmiObj = wmi.WMI() opsiValues = {} for oneClass in conf: if not oneClass.get('Class') or not oneClass['Class'].get('Opsi') or not oneClass['Class'].get('WMI'): continue opsiName = oneClass['Class']['Opsi'] wmiQuery = oneClass['Class']['WMI'] mapClass = '' mapSep = '&' temp = wmiQuery.split(mapSep) if len(temp) == 2: wmiQuery, mapClass = temp logger.info(u"Querying: %s" % wmiQuery) objects = [] try: objects = wmiObj.query(wmiQuery) except Exception as error: logger.error(u"Query failed: %s" % error) continue # first element? make new array for multiple devices if opsiName not in opsiValues: opsiValues[opsiName] = [] for obj in objects: wmiClass = obj.ole_object.GetObjectText_().split()[2] obj2 = None if mapClass: assoc = obj.associators(mapClass) if len(assoc) > 0: obj2 = assoc[0] opsiValues[opsiName].append({}) for item in oneClass['Values']: v = None if item.get('WMI'): for a in item['WMI'].split('||'): a = a.strip() c = wmiClass if '::' in a: (c, a) = a.split('::', 1) meth = None if '.' in a: (a, meth) = a.split('.', 1) op = None match = re.search('^(\w+)([\*\/\+\-\%]\d.*)$', a) if match: a = match.group(1) op = match.group(2) if c == wmiClass and hasattr(obj, a): v = getattr(obj, a) elif obj2 and hasattr(obj2, a): v = getattr(obj2, a) else: try: if obj2: logger.warning(u"%s.%s: failed to get attribute '%s' from objects %s" % (opsiName, item['Opsi'], a, [obj.__repr__(), obj2.__repr__()])) else: logger.warning(u"%s.%s: failed to get attribute '%s' from object '%s'" % (opsiName, item['Opsi'], a, obj.__repr__())) except Exception as error: logger.error(error) continue if isinstance(v, tuple) and len(v) == 1: v = v[0] if meth and v is not None: try: v = eval('v.%s' % meth) except Exception as evalError: logger.debug("Method {0!r} on function value {1!r} failed: {2!r}", meth, v, evalError) logger.warning(u"Method '{0}' failed on value '{1}'", meth, v) if op and v is not None: try: v = eval('v%s' % op) except Exception as evalError: logger.debug("Operation {0!r} on function value {1!r} failed: {2!r}", op, v, evalError) logger.warning(u"Operation '{0}' failed on value '{1}'", op, v) if item['Opsi'] in ('vendorId', 'subsystemVendorId'): try: v = forceHardwareVendorId(v) except Exception as hwVendError: logger.debug("Forcing hardware vendor id on {!r} failed: {}", v, hwVendError) v = None elif item['Opsi'] in ('deviceId', 'subsystemDeviceId'): try: v = forceHardwareDeviceId(v) except Exception as hwDevError: logger.debug("Forcing hardware device id on {!r} failed: {}", v, hwDevError) v = None if v is None: continue if isinstance(v, str): v = forceUnicode(v) if isinstance(v, unicode): v = v.strip() valueMappingKey = "%s.%s" % (c, a) logger.debug(u"Searching mapping for {!r}", valueMappingKey) if valueMappingKey in VALUE_MAPPING: v = forceList(v) for i in range(len(v)): v[i] = VALUE_MAPPING[valueMappingKey].get(str(v[i]), v[i]) if len(v) == 1: v = v[0] logger.debug("Mapping applied. Value: {!r}", v) if isinstance(v, (list, tuple)): v = u', '.join(forceUnicodeList(v)) if item['Type'].startswith('varchar'): v = forceUnicode(v) maxLen = forceInt(item['Type'].split('(')[1].split(')')[0].strip()) if len(v) > maxLen: logger.warning(u"Truncating value {!r}: string is too long (maximum length: {})", v, maxLen) v = v[:maxLen] logger.debug(u"New value: {!r}", v) if v is not None: break opsiValues[opsiName][-1][item['Opsi']] = v logger.debug(u"Hardware object is now: {!r}", opsiValues[opsiName][-1]) if not opsiValues[opsiName][-1]: logger.info(u"Skipping empty object") opsiValues[opsiName].pop() return opsiValues
def createBytemaskFromAddress(address): "Returns an int representation of an bytemask of an ipAddress." num = [forceInt(part) for part in address.split('.')] return (num[0] << 24) + (num[1] << 16) + (num[2] << 8) + num[3]
def _opsiclientdRpc(self, hostIds, method, params=[], timeout=None): if not hostIds: raise BackendMissingDataError(u"No matching host ids found") hostIds = forceHostIdList(hostIds) method = forceUnicode(method) params = forceList(params) if not timeout: timeout = self._hostRpcTimeout timeout = forceInt(timeout) result = {} rpcts = [] for host in self._context.host_getObjects(id=hostIds): # pylint: disable=maybe-no-member try: port = None try: configState = self._context.configState_getObjects( configId="opsiclientd.control_server.port", objectId=host.id) port = int(configState[0].values[0]) logger.info("Using port {} for opsiclientd at {}", port, host.id) except IndexError: pass # No values found except Exception as portError: logger.warning( "Failed to read custom opsiclientd port for {}: {!r}", host.id, portError) address = self._getHostAddress(host) rpcts.append( RpcThread(hostControlBackend=self, hostId=host.id, hostPort=port, address=address, username=u'', password=host.opsiHostKey, method=method, params=params)) except Exception as e: result[host.id] = {"result": None, "error": forceUnicode(e)} runningThreads = 0 while rpcts: newRpcts = [] for rpct in rpcts: if rpct.ended: if rpct.error: logger.error(u"Rpc to host %s failed, error: %s" % (rpct.hostId, rpct.error)) result[rpct.hostId] = { "result": None, "error": rpct.error } else: logger.info(u"Rpc to host %s successful, result: %s" % (rpct.hostId, rpct.result)) result[rpct.hostId] = { "result": rpct.result, "error": None } runningThreads -= 1 continue if not rpct.started: if runningThreads < self._maxConnections: logger.debug(u"Starting rpc to host %s" % rpct.hostId) rpct.start() runningThreads += 1 else: timeRunning = time.time() - rpct.started if timeRunning >= timeout + 5: # thread still alive 5 seconds after timeout => kill logger.error( u"Rpc to host %s (address: %s) timed out after %0.2f seconds, terminating" % (rpct.hostId, rpct.address, timeRunning)) result[rpct.hostId] = { "result": None, "error": u"timed out after %0.2f seconds" % timeRunning } if not rpct.ended: try: rpct.terminate() except Exception as e: logger.error( u"Failed to terminate rpc thread: %s" % e) runningThreads -= 1 continue newRpcts.append(rpct) rpcts = newRpcts time.sleep(0.1) return result
def __init__(self, prior, posterior, fulfilled=False): self.prior = forceInt(prior) self.posterior = forceInt(posterior) self.fulfilled = forceBool(fulfilled)
def yesno(self, text, title=_(u'Question'), okLabel=_(u'OK'), cancelLabel=_(u'Cancel'), width=-1, height=-1): try: text = forceUnicode(text) title = forceUnicode(title) okLabel = forceUnicode(okLabel) cancelLabel = forceUnicode(cancelLabel) width = forceInt(width) height = forceInt(height) for string in self.confidentialStrings: text = text.replace(string, u'*** confidential ***') if (width <= 0): width = self.getScreen().width - 15 if width > len(text) + 5: width = len(text) + 5 if (height <= 0): height = 10 gridForm = GridForm(self._screen, title.encode(encoding, 'replace'), 1, 2) textBox = Textbox(width=width, height=height - 6, text=text.encode(encoding, 'replace'), scroll=1, wrap=1) gridForm.add(textBox, col=0, row=0) grid = Grid(2, 1) cancelButton = Button(cancelLabel.encode(encoding, 'replace')) grid.setField(cancelButton, 0, 0, (0, 0, 5, 0)) okButton = Button(okLabel.encode(encoding, 'replace')) grid.setField(okButton, 1, 0, (5, 0, 0, 0)) gridForm.add(grid, col=0, row=1) # help line helpLine = _( u"<ESC> %s | <F12> %s | <Tab> move cursor | <Space> select" ) % (cancelLabel, okLabel) if text: helpLine += _(u" | <Up/Down> scroll text") self.getScreen().pushHelpLine( forceUnicode(helpLine).encode(encoding, 'replace')) # run gridForm.addHotKey('ESC') gridForm.draw() buttonPressed = None while buttonPressed not in (okButton, 'F12', cancelButton, 'ESC'): buttonPressed = gridForm.run() self._screen.popWindow() if buttonPressed in (okButton, 'F12'): return True return False except Exception as e: self.exit() logger.logException(e) raise
def getValues(self, entries, width=-1, height=-1, title=_(u'Please fill in'), text=u'', okLabel=_(u'OK'), cancelLabel=_(u'Cancel')): try: entries = forceList(entries) width = forceInt(width) height = forceInt(height) title = forceUnicode(title) text = forceUnicode(text) okLabel = forceUnicode(okLabel) cancelLabel = forceUnicode(cancelLabel) for string in self.confidentialStrings: text = text.replace(string, u'*** confidential ***') if (width <= 0): width = self.getScreen().width - 15 if (height <= 0): height = 11 + len(entries) if text: height += len(text.split(u'\n')) if (height > self.getScreen().height - 10): height = self.getScreen().height - 10 # create text grid textGrid = Grid(1, 1) if text: textHeight = len(text.split(u'\n')) diff = textHeight + len(entries) + 11 - height if (diff > 0): textHeight -= diff if (textHeight > 0): textBox = Textbox(width=width, height=textHeight, text=text.encode(encoding, 'replace'), scroll=1, wrap=1) textGrid.setField(textBox, col=0, row=0) # create grid for entries entriesGrid = Grid(2, len(entries)) row = 0 labelWidth = 10 for entry in entries: l = len(entry.get('name', u'')) if (l > labelWidth): labelWidth = l width = width - labelWidth if (width < 5): width = 5 for entry in entries: label = Label( forceUnicode(entry.get('name', u'???')).encode( encoding, 'replace')) value = forceUnicodeList(entry.get('value')) value = u', '.join(value) entry['entry'] = Entry(width=width, text=value.encode(encoding, 'replace'), hidden=entry.get('hidden', False), password=entry.get('password', False), scroll=1, returnExit=0) entriesGrid.setField(label, col=0, row=row, anchorLeft=1, padding=(2, 0, 1, 0)) entriesGrid.setField(entry['entry'], col=1, row=row, anchorRight=1, padding=(1, 0, 2, 0)) row += 1 # create grid for buttons buttonsGrid = Grid(2, 1) cancelButton = Button(cancelLabel.encode(encoding, 'replace')) buttonsGrid.setField(cancelButton, col=0, row=0, padding=(0, 0, 10, 0)) okButton = Button(okLabel.encode(encoding, 'replace')) buttonsGrid.setField(okButton, col=1, row=0, padding=(10, 0, 0, 0)) gridForm = GridForm(self._screen, title.encode(encoding, 'replace'), 1, 3) gridForm.add(textGrid, col=0, row=0, padding=(0, 0, 0, 1)) gridForm.add(entriesGrid, col=0, row=1, padding=(0, 0, 0, 1)) gridForm.add(buttonsGrid, col=0, row=2, padding=(0, 0, 0, 0)) # help line helpLine = _( u"<ESC> %s | <F12> %s | <Tab> move cursor | <Space> select" ) % (cancelLabel, okLabel) if text: helpLine += _(u" | <Up/Down> scroll text") self.getScreen().pushHelpLine( forceUnicode(helpLine).encode(encoding, 'replace')) # run gridForm.addHotKey('ESC') gridForm.draw() buttonPressed = None while (buttonPressed not in [okButton, 'F12', cancelButton, 'ESC']): buttonPressed = gridForm.run() self._screen.popWindow() if (buttonPressed not in [okButton, 'F12']): return None for i in range(len(entries)): value = unicode(entries[i]['entry'].value(), encoding) if entries[i].get('multivalue') and (value.find(u',') != -1): value = map(lambda x: x.strip(), value.split(u',')) entries[i]['value'] = value del (entries[i]['entry']) return entries except Exception as e: self.exit() logger.logException(e) raise