def create_section(self, section, tokeniser): name = tokeniser() if name == '{': raise Raised(tokeniser, 'was expecting section name', self.syntax) self.drop_parenthesis(tokeniser) storage = self.configuration[tokeniser.name][section][name] if storage: raise Raised(tokeniser, 'the section name %s is not unique' % name, self.syntax) return storage
def graceful(self, tokeniser): token = tokeniser() if not token.isdigit(): raise Raised("") duration = int(token) if duration < 0: raise Raised("") if duration > pow(2, 16): raise Raised("") self.content[Capability.ID.GRACEFUL_RESTART] = duration self._drop_colon(tokeniser)
def run(self, tokeniser): command = [] while True: token = tokeniser() if token == ';': break command.append(token) if not command: raise Raised( 'run requires the program to prg as an argument (quoted or unquoted)' ) prg = ' '.join(command) if prg[0] != '/': if prg.startswith('etc/exabgp'): parts = prg.split('/') path = [ os.environ.get('ETC', 'etc'), ] + parts[2:] prg = os.path.join(*path) else: prg = os.path.abspath( os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), prg)) if not os.path.exists(prg): raise Raised('can not locate the the program "%s"' % prg) # XXX: Yep, race conditions are possible, those are sanity checks not security ones ... s = os.stat(prg) if stat.S_ISDIR(s.st_mode): raise Raised('can not execute directories "%s"' % prg) if s.st_mode & stat.S_ISUID: raise Raised('refusing to run setuid programs "%s"' % prg) check = stat.S_IXOTH if s.st_uid == os.getuid(): check |= stat.S_IXUSR if s.st_gid == os.getgid(): check |= stat.S_IXGRP if not check & s.st_mode: raise Raised('exabgp will not be able to run this program "%s"' % prg) self.content['run'] = prg
def encoder(self, tokeniser): token = tokeniser() if token == '}': return if token not in ('text', 'json'): raise Raised('invalid encoder') self.content['encoder'] = token self._drop_colon(tokeniser)
def l2vpn(self, tokeniser): self._check_conflict() safi = tokeniser() if safi == 'vpls': self.content.append((AFI(AFI.l2vpn), SAFI(SAFI.vpls))) else: raise Raised('unknow family safi %s' % safi) self._drop_colon(tokeniser)
def addpath(self, tokeniser): ap = tokeniser() if ap not in ('receive', 'send', 'send/receive', 'disable', 'disabled'): raise Raised("") self.content[Capability.ID.ADD_PATH] = 0 if ap.endswith('receive'): self.content[Capability.ID.ADD_PATH] += 1 if ap.startswith('send'): self.content[Capability.ID.ADD_PATH] += 2 self._drop_colon(tokeniser)
def get_section(self, section, tokeniser): name = tokeniser() if name == '{': tokeniser.rewind(name) tokeniser.rewind(self.unamed) return None storage = self.configuration[tokeniser.name][section][name] if storage is None: raise Raised( tokeniser, 'the section name %s referenced does not exists' % name, self.syntax) return storage
def ipv6(self, tokeniser): self._check_conflict() safi = tokeniser() if safi == 'unicast': self.content.append((AFI(AFI.ipv6), SAFI(SAFI.unicast))) elif safi == 'mpls-vpn': self.content.append((AFI(AFI.ipv6), SAFI(SAFI.mpls_vpn))) elif safi in ('flow'): self.content.append((AFI(AFI.ipv6), SAFI(SAFI.flow_ip))) elif safi == 'flow-vpn': self.content.append((AFI(AFI.ipv6), SAFI(SAFI.flow_vpn))) else: raise Raised('unknow family safi %s' % safi) self._drop_colon(tokeniser)
def _check_duplicate(self, key): if key in self.content: raise Raised("")
def enter(self, tokeniser): token = tokeniser() if token != '{': raise Raised(self.syntax) self.content = dict()
def enter_unamed_section(self, tokeniser): token = tokeniser() if token != '{': raise Raised(tokeniser, 'was expecting {', self.syntax)
def drop_parenthesis(self, tokeniser): if tokeniser() != '{': raise Raised(tokeniser, 'missing opening parenthesis "{"', self.syntax)
def _drop_colon(self, tokeniser): if tokeniser() != ';': raise Raised('missing semi-colon')
def _check_conflict(self): if 'all' in self.content: raise Raised('ipv4 can not be used with all or minimal') if 'minimal' in self.content: raise Raised('ipv4 can not be used with all or minimal')
def inet6(self, tokeniser): raise Raised("the word inet6 is deprecated, please use ipv6 instead", 'error')
def enter(self, tokeniser): token = tokeniser() if token != '{': raise Raised(self.syntax) if 'families' in self.content: raise Raised('duplicate family blocks') self.content = []