github.com/osrg/gobgp/v3@v3.30.0/test/lib/bird.py (about)

     1  # Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #    http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  # implied.
    13  # See the License for the specific language governing permissions and
    14  # limitations under the License.
    15  
    16  
    17  
    18  import time
    19  
    20  from lib.base import (
    21      BGPContainer,
    22      CmdBuffer,
    23      try_several_times,
    24      wait_for_completion,
    25      yellow,
    26      indent,
    27      local,
    28  )
    29  
    30  
    31  class BirdContainer(BGPContainer):
    32  
    33      WAIT_FOR_BOOT = 1
    34      SHARED_VOLUME = '/etc/bird'
    35  
    36      def __init__(self, name, asn, router_id, ctn_image_name='osrg/bird'):
    37          super(BirdContainer, self).__init__(name, asn, router_id,
    38                                              ctn_image_name)
    39          self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME))
    40  
    41      def _start_bird(self):
    42          c = CmdBuffer()
    43          c << '#!/bin/sh'
    44          c << 'bird'
    45          cmd = 'echo "{0:s}" > {1}/start.sh'.format(c, self.config_dir)
    46          local(cmd)
    47          cmd = 'chmod 755 {0}/start.sh'.format(self.config_dir)
    48          local(cmd)
    49          self.local('{0}/start.sh'.format(self.SHARED_VOLUME))
    50  
    51      def _wait_for_boot(self):
    52          def _f():
    53              ret = self.local('birdc show status > /dev/null 2>&1; echo $?', capture=True)
    54              return ret == '0'
    55  
    56          return wait_for_completion(_f)
    57  
    58      def run(self):
    59          super(BirdContainer, self).run()
    60          self.reload_config()
    61          return self.WAIT_FOR_BOOT
    62  
    63      def create_config(self):
    64          c = CmdBuffer()
    65          c << 'router id {0};'.format(self.router_id)
    66          for peer, info in self.peers.items():
    67              c << 'protocol bgp {'
    68              c << '  local as {0};'.format(self.asn)
    69              n_addr = info['neigh_addr'].split('/')[0]
    70              c << '  neighbor {0} as {1};'.format(n_addr, peer.asn)
    71              c << '  multihop;'
    72              c << '}'
    73  
    74          with open('{0}/bird.conf'.format(self.config_dir), 'w') as f:
    75              print(yellow('[{0}\'s new bird.conf]'.format(self.name)))
    76              print(yellow(indent(str(c))))
    77              f.writelines(str(c))
    78  
    79      def reload_config(self):
    80          if len(self.peers) == 0:
    81              return
    82  
    83          def _reload():
    84              def _is_running():
    85                  ps = self.local('ps', capture=True)
    86                  running = False
    87                  for line in ps.split('\n')[1:]:
    88                      if 'bird' in line:
    89                          running = True
    90                  return running
    91  
    92              if _is_running():
    93                  self.local('birdc configure')
    94              else:
    95                  self._start_bird()
    96  
    97              self._wait_for_boot()
    98              if not _is_running():
    99                  raise RuntimeError()
   100  
   101          try_several_times(_reload)
   102  
   103  
   104  class RawBirdContainer(BirdContainer):
   105      def __init__(self, name, config, ctn_image_name='osrg/bird'):
   106          asn = None
   107          router_id = None
   108          for line in config.split('\n'):
   109              line = line.strip()
   110              if line.startswith('local as'):
   111                  asn = int(line[len('local as'):].strip('; '))
   112              if line.startswith('router id'):
   113                  router_id = line[len('router id'):].strip('; ')
   114          if not asn:
   115              raise Exception('asn not in bird config')
   116          if not router_id:
   117              raise Exception('router-id not in bird config')
   118          self.config = config
   119          super(RawBirdContainer, self).__init__(name, asn, router_id,
   120                                                 ctn_image_name)
   121  
   122      def create_config(self):
   123          with open('{0}/bird.conf'.format(self.config_dir), 'w') as f:
   124              print(yellow('[{0}\'s new bird.conf]'.format(self.name)))
   125              print(yellow(indent(self.config)))
   126              f.writelines(self.config)