mirror of https://github.com/apache/cloudstack.git
120 lines
5.2 KiB
Python
Executable File
120 lines
5.2 KiB
Python
Executable File
#!/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")
|