Source code for paradrop.backend.pdconfd.config.base

[docs]class ConfigObject(object): nextId = 0 typename = None options = [] def __init__(self): self.id = ConfigObject.nextId ConfigObject.nextId += 1 self.source = None self.name = "s{:08x}".format(self.id) self.comment = None self.dependents = set() # Will be a running list of commands executed by request of this config # object. self.executed = list() for option in self.options: setattr(self, option['name'], option['default']) def __hash__(self): return hash(self.getTypeAndName()) def __repr__(self): return "{}({}:{}:{})".format(self.__class__.__name__, self.source, self.typename, self.name) def __str__(self): return "{}:{}".format(self.typename, self.name)
[docs] def addDependent(self, dep): self.dependents.add(dep)
[docs] def commands(self, allConfigs): """ Return a list of commands to execute. Each one is a Command object. """ return []
[docs] def getTypeAndName(self): """ Return tuple (section type, section name). """ return (self.typename, self.name)
[docs] def lookup(self, allConfigs, sectionType, sectionName, addDependent=True): """ Look up a section by type and name. If addDependent is True (default), the current object will be added as a dependent of the found section. Will raise an exception if the section is not found. """ config = allConfigs[(sectionType, sectionName)] if addDependent: config.addDependent(self) return config
[docs] def undoCommands(self, allConfigs): """ Return a list of commands to execute. Each one is a Command object. """ return []
[docs] def optionsMatch(self, other): """ Test equality of config sections by comparing option values. """ if not isinstance(other, self.__class__): return False for opdef in self.options: if getattr(self, opdef['name']) != getattr(other, opdef['name']): return False return True
@classmethod
[docs] def build(cls, manager, source, name, options, comment): """ Build a config object instance from the UCI section. Arguments: source -- file containing this configuration section name -- name of the configuration section If None, a unique name will be generated. options -- dictionary of options loaded from the section comment -- comment string or None """ obj = cls() obj.manager = manager obj.source = source obj.comment = comment if name is not None: obj.name = name for opdef in cls.options: found = False if opdef['type'] == list: if "list" in options and opdef['name'] in options['list']: value = options['list'][opdef['name']] found = True elif opdef['name'] in options: # Sometimes we expect a list but get a single value instead. # Example: # ... # option network 'lan' # ... # instead of # ... # list network 'lan' # ... value = [options[opdef['name']]] found = True elif opdef['type'] == bool: if opdef['name'] in options: value = options[opdef['name']] != '0' found = True else: if opdef['name'] in options: value = opdef['type'](options[opdef['name']]) found = True if not found: if opdef['required']: raise Exception("Missing required option {} in {}:{}:{}".format( opdef['name'], source, cls.typename, name)) else: value = opdef['default'] setattr(obj, opdef['name'], value) return obj