Ejemplo n.º 1
0
    def __init__(self, id, type=u'', title=u'', **args):
        MessageSubject.__init__(self, id, type, title, **args)
        self.reset()
        self._callbacks = []
        try:
            self._multiValue = forceBool(args['multiValue'])
        except KeyError:
            pass

        try:
            self._choices = forceUnicodeList(args['choices'])
        except KeyError:
            pass

        try:
            self._selectedIndexes = forceIntList(args['selectedIndexes'])
        except KeyError:
            pass

        try:
            self._callbacks = args['callbacks']
        except KeyError:
            pass

        logger.debug(u"ChoiceSubject '%s' created" % self._id)
Ejemplo n.º 2
0
    def create(self, fileList, baseDir='.', dereference=False):
        try:
            fileList = forceUnicodeList(fileList)
            baseDir = os.path.abspath(forceFilename(baseDir))
            dereference = forceBool(dereference)

            if not os.path.isdir(baseDir):
                raise IOError(u"Base dir '%s' not found" % baseDir)

            command = u'%s --create --quiet --verbose --format crc' % System.which(
                'cpio')
            if dereference:
                command += ' --dereference'
            if self._compression == 'gzip':
                if self.pigz_detected:
                    command += ' | %s --rsyncable' % System.which('pigz')
                else:
                    command += ' | %s --rsyncable' % System.which('gzip')
            elif self._compression == 'bzip2':
                command += ' | %s' % System.which('bzip2')
            command += ' > "%s"' % self._filename

            self._create(fileList, baseDir, command)
        except Exception as e:
            raise RuntimeError(u"Failed to create archive '%s': %s" %
                               (self._filename, e))
Ejemplo n.º 3
0
    def extract(self, targetPath='.', patterns=[]):
        try:
            targetPath = os.path.abspath(forceFilename(targetPath))
            patterns = forceUnicodeList(patterns)
            if not os.path.isdir(targetPath):
                try:
                    os.mkdir(targetPath)
                except Exception as e:
                    raise IOError(u"Failed to create target dir '%s': %s" %
                                  (targetPath, e))

            cat = System.which('cat')
            if self._compression == 'gzip':
                if self.pigz_detected:
                    cat = u'%s --stdout --decompress' % (
                        System.which('pigz'), )
                else:
                    cat = System.which('zcat')
            elif self._compression == 'bzip2':
                cat = System.which('bzcat')

            fileCount = 0
            for filename in self.content():
                match = False
                if not patterns:
                    match = True
                else:
                    for pattern in patterns:
                        try:
                            pattern = pattern.replace('*', '.*')
                            if re.search(pattern, filename):
                                match = True
                                break
                            fileCount += 1
                        except Exception as e:
                            raise ValueError(u"Bad pattern '%s': %s" %
                                             (pattern, e))
                if match:
                    fileCount += 1

            include = ' '.join('"%s"' % pattern for pattern in patterns)

            curDir = os.path.abspath(os.getcwd())
            os.chdir(targetPath)
            try:
                command = u'%s "%s" | %s --quiet --extract --make-directories --unconditional --preserve-modification-time --verbose --no-preserve-owner %s' % (
                    cat, self._filename, System.which('cpio'), include)
                self._extract(command, fileCount)
            finally:
                os.chdir(curDir)
        except Exception as e:
            raise RuntimeError(u"Failed to extract archive '%s': %s" %
                               (self._filename, e))
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    def extract(self, targetPath='.', patterns=[]):
        try:
            targetPath = os.path.abspath(forceFilename(targetPath))
            patterns = forceUnicodeList(patterns)
            if not os.path.isdir(targetPath):
                try:
                    os.mkdir(targetPath)
                except Exception as e:
                    raise IOError(u"Failed to create target dir '%s': %s" %
                                  (targetPath, e))

            options = u''
            if self._compression == 'gzip':
                if self.pigz_detected:
                    options += u'--use-compress-program=pigz'
                else:
                    options += u'--gunzip'
            elif self._compression == 'bzip2':
                options += u'--bzip2'

            fileCount = 0
            for filename in self.content():
                match = False
                if not patterns:
                    match = True
                else:
                    for pattern in patterns:
                        try:
                            pattern = pattern.replace('*', '.*')
                            if re.search(pattern, filename):
                                match = True
                                break
                            fileCount += 1
                        except Exception as e:
                            raise ValueError(u"Bad pattern '%s': %s" %
                                             (pattern, e))

                if match:
                    fileCount += 1
                else:
                    options += u' --exclude="%s"' % filename

            command = u'%s %s --directory "%s" --extract --verbose --file "%s"' % (
                System.which('tar'), options, targetPath, self._filename)
            self._extract(command, fileCount)
        except Exception as e:
            raise RuntimeError(u"Failed to extract archive '%s': %s" %
                               (self._filename, e))
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    def _collectProductPropertyStates(self, clientId, productId, depotId):
        productPropertyStates = self._context.productPropertyState_getObjects(
            objectId=clientId, productId=productId)

        existingPropertyStatePropertyIds = set(
            pps.propertyId for pps in productPropertyStates)

        # Create missing product property states
        for pps in self._context.productPropertyState_getObjects(
                productId=productId, objectId=depotId):
            if pps.propertyId not in existingPropertyStatePropertyIds:
                # Product property for client does not exist => add default (values of depot)
                productPropertyStates.append(
                    ProductPropertyState(productId=pps.productId,
                                         propertyId=pps.propertyId,
                                         objectId=clientId,
                                         values=pps.values))

        return {
            pps.propertyId: u','.join(forceUnicodeList(pps.getValues()))
            for pps in productPropertyStates
        }
Ejemplo n.º 8
0
    def __init__(self,
                 name,
                 baseUrl,
                 dirs=[],
                 username=u"",
                 password=u"",
                 authcertfile=u"",
                 authkeyfile="",
                 opsiDepotId=None,
                 autoInstall=False,
                 autoUpdate=True,
                 autoSetup=False,
                 proxy=None,
                 excludes=[],
                 includes=[],
                 active=False):
        self.name = forceUnicode(name)
        self.baseUrl = forceUnicode(baseUrl)
        self.dirs = forceUnicodeList(dirs)
        self.excludes = excludes
        self.includes = includes
        self.username = forceUnicode(username)
        self.password = forceUnicode(password)
        self.authcertfile = forceUnicode(authcertfile)
        self.authkeyfile = forceUnicode(authkeyfile)
        self.autoInstall = autoInstall
        self.autoUpdate = autoUpdate
        self.autoSetup = autoSetup
        self.opsiDepotId = opsiDepotId
        self.onlyDownload = None
        self.inheritProductProperties = None
        self.description = ''
        self.active = forceBool(active)

        self.proxy = None
        if proxy:
            self.proxy = proxy
        if self.baseUrl.startswith('webdav'):
            self.baseUrl = u'http%s' % self.baseUrl[6:]
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
 def setConfidentialStrings(self, strings):
     strings = forceUnicodeList(strings)
     self.confidentialStrings = []
     for string in strings:
         self.addConfidentialString(string)
Ejemplo n.º 12
0
def editConfigDefaults():
    bmconfig = dict(
        dispatchConfigFile=u'/etc/opsi/backendManager/dispatch.conf',
        backendConfigDir=u'/etc/opsi/backends',
        extensionConfigDir=u'/etc/opsi/backendManager/extend.d',
        depotbackend=False)

    with BackendManager(**bmconfig) as backend:
        configs = backend.config_getObjects()
        configs = [
            config for config in configs
            if not config.id.startswith(u'configed.saved_search.')
        ]

        if not configs:
            raise BackendMissingDataError("Backend misses configurations!")

        maxConfigIdLen = max(len(config.id) for config in configs)
        entryFormat = u"%-10s %-" + str(maxConfigIdLen) + "s = %s"

        with disableConsoleLogging(), _getUI() as ui:
            while True:
                entries = []
                for config in configs:
                    configType = '[unicode]'
                    if config.getType() == 'BoolConfig':
                        configType = '[bool]'

                    values = u', '.join(forceUnicodeList(config.defaultValues))
                    values = shortenStr(values, 60)
                    entries.append({
                        "id":
                        config.id,
                        "name":
                        entryFormat % (configType, config.id, values)
                    })

                selection = ui.getSelection(
                    entries,
                    radio=True,
                    width=100,
                    height=10,
                    title=u'Please select config value to change',
                    okLabel='Change',
                    cancelLabel='Quit')

                if not selection:
                    return

                configId = None
                for entry in entries:
                    if selection[0] == entry['name']:
                        configId = entry['id']
                        break

                selectedConfig = -1
                for index, config in enumerate(configs):
                    if config.id == configId:
                        selectedConfig = index
                        break

                addNewValue = False
                cancelLabel = u'Back'
                title = u'Edit default values for: %s' % configs[
                    selectedConfig].id
                text = configs[selectedConfig].description or u''
                if configs[selectedConfig].possibleValues:
                    entries = []
                    for possibleValue in configs[
                            selectedConfig].possibleValues:
                        entries.append({
                            'name':
                            possibleValue,
                            'value':
                            possibleValue,
                            'selected':
                            possibleValue
                            in configs[selectedConfig].defaultValues
                        })
                    radio = not configs[selectedConfig].multiValue
                    if configs[selectedConfig].editable:
                        entries.append({
                            'name': '<other value>',
                            'value': '<other value>',
                            'selected': False
                        })
                    selection = ui.getSelection(entries,
                                                radio=radio,
                                                width=65,
                                                height=10,
                                                title=title,
                                                text=text,
                                                cancelLabel=cancelLabel)

                    if selection is None:
                        continue
                    if "<other value>" in selection:
                        addNewValue = True
                    else:
                        configs[selectedConfig].setDefaultValues(selection)
                else:
                    addNewValue = True

                if addNewValue:
                    default = u''
                    if configs[selectedConfig].defaultValues:
                        default = configs[selectedConfig].defaultValues[0]
                    value = ui.getValue(width=65,
                                        height=13,
                                        title=title,
                                        default=default,
                                        password=False,
                                        text=text,
                                        cancelLabel=cancelLabel)
                    if value is None:
                        continue

                    possibleValues = configs[selectedConfig].getPossibleValues(
                    )
                    if value not in possibleValues:
                        possibleValues.append(value)
                        configs[selectedConfig].setPossibleValues(
                            possibleValues)
                    configs[selectedConfig].setDefaultValues(value)

                backend.config_updateObjects([configs[selectedConfig]])
Ejemplo n.º 13
0
def testForceUnicodeListResultsInListOfUnicode():
    returned = forceUnicodeList([None, 1, 'x', u'y'])
    assert isinstance(returned, list)

    for i in returned:
        assert isinstance(i, unicode)
Ejemplo n.º 14
0
    def updateConfigFile(self, force=False):  # pylint: disable=too-many-branches
        logger.info("Updating config file: '%s'",
                    self.get('global', 'config_file'))

        if self._config_file_mtime and os.path.getmtime(
                self.get('global', 'config_file')) > self._config_file_mtime:
            msg = "overwriting changes is forced" if force else "keeping file as is"
            logger.warning(
                "The config file '%s' has been changed by another program, %s",
                self.get('global', 'config_file'), msg)
            if not force:
                return

        try:
            configFile = IniFile(filename=self.get('global', 'config_file'),
                                 raw=True)
            configFile.setKeepOrdering(True)
            (config, comments) = configFile.parse(returnComments=True)
            changed = False
            for (section, values) in self._config.items():
                if not isinstance(values, dict):
                    continue
                if section == 'system':
                    continue
                if not config.has_section(section):
                    logger.debug("Config changed - new section: %s", section)
                    config.add_section(section)
                    changed = True

                for (option, value) in values.items():
                    if (section == 'global') and (option == 'config_file'):
                        # Do not store these option
                        continue
                    if isinstance(value, list):
                        value = ', '.join(forceUnicodeList(value))
                    elif isinstance(value, bool):
                        value = str(value).lower()
                    else:
                        value = forceUnicode(value)

                    if value.lower() in ("true", "false"):
                        value = value.lower()

                    if not config.has_option(section, option):
                        logger.debug("Config changed - new option: %s.%s = %s",
                                     section, option, value)
                        config.set(section, option, value)
                        changed = True
                    elif config.get(section, option) != value:
                        logger.debug(
                            "Config changed - changed value: %s.%s = %s => %s",
                            section, option, config.get(section,
                                                        option), value)
                        config.set(section, option, value)
                        changed = True

                for option in config.options(section):
                    if option not in values:
                        logger.info("Removing obsolete config option: %s.%s",
                                    section, option)
                        config.remove_option(section, option)
                        changed = True

            if changed:
                # Write back config file if changed
                configFile.generate(config, comments=comments)
                logger.notice("Config file '%s' written",
                              self.get('global', 'config_file'))
                self._config_file_mtime = os.path.getmtime(
                    self.get('global', 'config_file'))
            else:
                logger.info(
                    "No need to write config file '%s', config file is up to date",
                    self.get('global', 'config_file'))
        except Exception as err:  # pylint: disable=broad-except
            # An error occured while trying to write the config file
            logger.error(err, exc_info=True)
            logger.error("Failed to write config file '%s': %s",
                         self.get('global', 'config_file'), err)
Ejemplo n.º 15
0
 def setChoices(self, choices):
     self._choices = forceUnicodeList(choices)
     if self._choices and not self._selectedIndexes:
         self._selectedIndexes = [0]
     self._notifyChoicesChanged()