blob: 137279b74a9e63f6d542de3e3bb6d94ec348ae0b [file] [log] [blame]
#!/usr/bin/python
# -- coding: utf-8 --
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import logging
from . import CsHelper
from .CsDatabag import CsDataBag
from .CsFile import CsFile
FRR_DIR = "/etc/frr/"
FRR_DAEMONS = "/etc/frr/daemons"
FRR_CONFIG = "/etc/frr/frr.conf"
class CsBgpPeers(CsDataBag):
def process(self):
logging.info("Processing CsBgpPeers file ==> %s" % self.dbag)
if self.config.is_vpc():
self.public_ip = self.cl.get_source_nat_ip()
else:
self.public_ip = self.cl.get_eth2_ip()
self.peers = {}
for item in self.dbag:
if item == "id":
continue
self._process_dbag_item(self.dbag[item])
restart_frr = False
CsHelper.mkdir(FRR_DIR, 0o755, False)
self.frr_daemon = CsFile(FRR_DAEMONS)
self.frr_daemon.replaceIfFound("bgpd=no", "bgpd=yes")
if self.frr_daemon.commit():
restart_frr = True
self.frr_conf = CsFile(FRR_CONFIG)
self.frr_conf.repopulate()
self._pre_set()
self._process_peers()
self._post_set()
if self.frr_conf.commit():
restart_frr = True
if restart_frr:
CsHelper.execute("systemctl enable frr")
CsHelper.execute("systemctl restart frr")
def _process_dbag_item(self, item):
as_number = item['network_as_number']
if as_number not in self.peers.keys():
self.peers[as_number] = {}
self.peers[as_number]['ip4_peers'] = []
self.peers[as_number]['ip6_peers'] = []
if 'ip4_address' in item and 'guest_ip4_cidr' in item:
self.peers[as_number]['ip4_peers'].append(item)
if 'ip6_address' in item and 'guest_ip6_cidr' in item:
self.peers[as_number]['ip6_peers'].append(item)
def _pre_set(self):
self.frr_conf.add("frr version 6.0")
self.frr_conf.add("frr defaults traditional")
self.frr_conf.add("hostname {}".format(CsHelper.get_hostname()))
self.frr_conf.add("service integrated-vtysh-config")
self.frr_conf.add("ip nht resolve-via-default")
return
def _process_peers(self):
for as_number in self.peers.keys():
self.frr_conf.add("router bgp {}".format(as_number))
self.frr_conf.add(" bgp router-id {}".format(self.public_ip))
if self.peers[as_number]['ip6_peers']:
self.frr_conf.add(" bgp default ipv6-unicast")
for ip4_peer in self.peers[as_number]['ip4_peers']:
self.frr_conf.add(" neighbor {} remote-as {}".format(ip4_peer['ip4_address'], ip4_peer['peer_as_number']))
if 'peer_password' in ip4_peer:
self.frr_conf.add(" neighbor {} password {}".format(ip4_peer['ip4_address'], ip4_peer['peer_password']))
if 'details' in ip4_peer:
if 'EBGP_MultiHop' in ip4_peer['details']:
self.frr_conf.add(" neighbor {} ebgp-multihop {}".format(ip4_peer['ip4_address'], ip4_peer['details']['EBGP_MultiHop']))
for ip6_peer in self.peers[as_number]['ip6_peers']:
self.frr_conf.add(" neighbor {} remote-as {}".format(ip6_peer['ip6_address'], ip6_peer['peer_as_number']))
if 'peer_password' in ip6_peer:
self.frr_conf.add(" neighbor {} password {}".format(ip6_peer['ip6_address'], ip6_peer['peer_password']))
if 'details' in ip6_peer:
if 'EBGP_MultiHop' in ip6_peer['details']:
self.frr_conf.add(" neighbor {} ebgp-multihop {}".format(ip6_peer['ip6_address'], ip6_peer['details']['EBGP_MultiHop']))
if self.peers[as_number]['ip4_peers']:
self.frr_conf.add(" address-family ipv4 unicast")
ip4_cidrs = set({ip4_peer['guest_ip4_cidr'] for ip4_peer in self.peers[as_number]['ip4_peers']})
for ip4_cidr in ip4_cidrs:
self.frr_conf.add(" network {}".format(ip4_cidr))
self.frr_conf.add(" exit-address-family")
if self.peers[as_number]['ip6_peers']:
self.frr_conf.add(" address-family ipv6 unicast")
ip6_cidrs = set({ip6_peer['guest_ip6_cidr'] for ip6_peer in self.peers[as_number]['ip6_peers']})
for ip6_cidr in ip6_cidrs:
self.frr_conf.add(" network {}".format(ip6_cidr))
self.frr_conf.add(" exit-address-family")
def _post_set(self):
self.frr_conf.add("line vty")