github.com/osrg/gobgp@v2.0.0+incompatible/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  from __future__ import absolute_import
    17  
    18  import time
    19  
    20  from fabric import colors
    21  from fabric.api import local
    22  from fabric.utils import indent
    23  
    24  from lib.base import (
    25      BGPContainer,
    26      CmdBuffer,
    27      try_several_times,
    28      wait_for_completion,
    29  )
    30  
    31  
    32  class BirdContainer(BGPContainer):
    33  
    34      WAIT_FOR_BOOT = 1
    35      SHARED_VOLUME = '/etc/bird'
    36  
    37      def __init__(self, name, asn, router_id, ctn_image_name='osrg/bird'):
    38          super(BirdContainer, self).__init__(name, asn, router_id,
    39                                              ctn_image_name)
    40          self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME))
    41  
    42      def _start_bird(self):
    43          c = CmdBuffer()
    44          c << '#!/bin/sh'
    45          c << 'bird'
    46          cmd = 'echo "{0:s}" > {1}/start.sh'.format(c, self.config_dir)
    47          local(cmd)
    48          cmd = 'chmod 755 {0}/start.sh'.format(self.config_dir)
    49          local(cmd)
    50          self.local('{0}/start.sh'.format(self.SHARED_VOLUME))
    51  
    52      def _wait_for_boot(self):
    53          def _f():
    54              ret = self.local('birdc show status > /dev/null 2>&1; echo $?', capture=True)
    55              return ret == '0'
    56  
    57          return wait_for_completion(_f)
    58  
    59      def run(self):
    60          super(BirdContainer, self).run()
    61          self.reload_config()
    62          return self.WAIT_FOR_BOOT
    63  
    64      def create_config(self):
    65          c = CmdBuffer()
    66          c << 'router id {0};'.format(self.router_id)
    67          for peer, info in self.peers.iteritems():
    68              c << 'protocol bgp {'
    69              c << '  local as {0};'.format(self.asn)
    70              n_addr = info['neigh_addr'].split('/')[0]
    71              c << '  neighbor {0} as {1};'.format(n_addr, peer.asn)
    72              c << '  multihop;'
    73              c << '}'
    74  
    75          with open('{0}/bird.conf'.format(self.config_dir), 'w') as f:
    76              print colors.yellow('[{0}\'s new bird.conf]'.format(self.name))
    77              print colors.yellow(indent(str(c)))
    78              f.writelines(str(c))
    79  
    80      def reload_config(self):
    81          if len(self.peers) == 0:
    82              return
    83  
    84          def _reload():
    85              def _is_running():
    86                  ps = self.local('ps', capture=True)
    87                  running = False
    88                  for line in ps.split('\n')[1:]:
    89                      if 'bird' in line:
    90                          running = True
    91                  return running
    92  
    93              if _is_running():
    94                  self.local('birdc configure')
    95              else:
    96                  self._start_bird()
    97  
    98              self._wait_for_boot()
    99              if not _is_running():
   100                  raise RuntimeError()
   101  
   102          try_several_times(_reload)
   103  
   104  
   105  class RawBirdContainer(BirdContainer):
   106      def __init__(self, name, config, ctn_image_name='osrg/bird'):
   107          asn = None
   108          router_id = None
   109          for line in config.split('\n'):
   110              line = line.strip()
   111              if line.startswith('local as'):
   112                  asn = int(line[len('local as'):].strip('; '))
   113              if line.startswith('router id'):
   114                  router_id = line[len('router id'):].strip('; ')
   115          if not asn:
   116              raise Exception('asn not in bird config')
   117          if not router_id:
   118              raise Exception('router-id not in bird config')
   119          self.config = config
   120          super(RawBirdContainer, self).__init__(name, asn, router_id,
   121                                                 ctn_image_name)
   122  
   123      def create_config(self):
   124          with open('{0}/bird.conf'.format(self.config_dir), 'w') as f:
   125              print colors.yellow('[{0}\'s new bird.conf]'.format(self.name))
   126              print colors.yellow(indent(self.config))
   127              f.writelines(self.config)