def get_config(): loopback = deepcopy(default_config_data) conf = Config() # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') loopback['intf'] = os.environ['VYOS_TAGNODE_VALUE'] # Check if interface has been removed if not conf.exists('interfaces loopback ' + loopback['intf']): loopback['deleted'] = True # set new configuration level conf.set_level('interfaces loopback ' + loopback['intf']) # retrieve configured interface addresses if conf.exists('address'): loopback['address'] = conf.return_values('address') # retrieve interface description if conf.exists('description'): loopback['description'] = conf.return_value('description') # Determine interface addresses (currently effective) - to determine which # address is no longer valid and needs to be removed from the interface eff_addr = conf.return_effective_values('address') act_addr = conf.return_values('address') loopback['address_remove'] = list_diff(eff_addr, act_addr) return loopback
def get_config(): conf = Config() igmp_conf = {'igmp_conf': False, 'old_ifaces': {}, 'ifaces': {}} if not (conf.exists('protocols igmp') or conf.exists_effective('protocols igmp')): return None if conf.exists('protocols igmp'): igmp_conf['igmp_conf'] = True conf.set_level('protocols igmp') # # Get interfaces for iface in conf.list_effective_nodes('interface'): igmp_conf['old_ifaces'].update({ iface: { 'version': conf.return_effective_value( 'interface {0} version'.format(iface)), 'query_interval': conf.return_effective_value( 'interface {0} query-interval'.format(iface)), 'query_max_resp_time': conf.return_effective_value( 'interface {0} query-max-response-time'.format(iface)), 'gr_join': {} } }) for gr_join in conf.list_effective_nodes( 'interface {0} join'.format(iface)): igmp_conf['old_ifaces'][iface]['gr_join'][ gr_join] = conf.return_effective_values( 'interface {0} join {1} source'.format(iface, gr_join)) for iface in conf.list_nodes('interface'): igmp_conf['ifaces'].update({ iface: { 'version': conf.return_value('interface {0} version'.format(iface)), 'query_interval': conf.return_value( 'interface {0} query-interval'.format(iface)), 'query_max_resp_time': conf.return_value( 'interface {0} query-max-response-time'.format(iface)), 'gr_join': {} } }) for gr_join in conf.list_nodes('interface {0} join'.format(iface)): igmp_conf['ifaces'][iface]['gr_join'][ gr_join] = conf.return_values( 'interface {0} join {1} source'.format(iface, gr_join)) return igmp_conf
def get_config(): opt = deepcopy(default_config_data) conf = Config() conf.set_level('system options') if conf.exists(''): if conf.exists('ctrl-alt-del-action'): opt['ctrl_alt_del'] = conf.return_value('ctrl-alt-del-action') opt['beep_if_fully_booted'] = conf.exists('beep-if-fully-booted') opt['reboot_on_panic'] = conf.exists('reboot-on-panic') return opt
def get_config(): opts = copy.deepcopy(default_config_data) conf = Config() if not conf.exists('firewall options'): # bail out early return opts else: conf.set_level('firewall options') # Parse configuration of each individual instance if conf.exists('interface'): for intf in conf.list_nodes('interface'): conf.set_level('firewall options interface {0}'.format(intf)) config = { 'intf': intf, 'disabled': False, 'mss4': '', 'mss6': '' } # Check if individual option is disabled if conf.exists('disable'): config['disabled'] = True # # Get MSS value IPv4 # if conf.exists('adjust-mss'): config['mss4'] = conf.return_value('adjust-mss') # We need a marker that a new iptables chain needs to be generated if not opts['new_chain4']: opts['new_chain4'] = True # # Get MSS value IPv6 # if conf.exists('adjust-mss6'): config['mss6'] = conf.return_value('adjust-mss6') # We need a marker that a new ip6tables chain needs to be generated if not opts['new_chain6']: opts['new_chain6'] = True # Append interface options to global list opts['intf_opts'].append(config) return opts
def get_config(): tz = deepcopy(default_config_data) conf = Config() if conf.exists('system time-zone'): tz['name'] = conf.return_value('system time-zone') return tz
def get_config(): conf = Config() if not conf.exists('service https certificates certbot'): return None else: conf.set_level('service https certificates certbot') cert = {} if conf.exists('domain-name'): cert['domains'] = conf.return_values('domain-name') if conf.exists('email'): cert['email'] = conf.return_value('email') return cert
def get_config(): interface_list = [] conf = Config() conf.set_level('service mdns repeater') if not conf.exists(''): return interface_list if conf.exists('interface'): intfs_names = [] intfs_names = conf.return_values('interface') for name in intfs_names: interface_list.append(name) return interface_list
def get_config(): conf = Config() conf.set_level("service broadcast-relay id") relay_id = conf.list_nodes("") relays = [] for id in relay_id: interface_list = [] address = conf.return_value("{0} address".format(id)) description = conf.return_value("{0} description".format(id)) port = conf.return_value("{0} port".format(id)) # split the interface name listing and form a list if conf.exists("{0} interface".format(id)): intfs_names = conf.return_values("{0} interface".format(id)) intfs_names = intfs_names.replace("'", "") intfs_names = intfs_names.split() for name in intfs_names: interface_list.append(name) relay = { "id": id, "address": address, "description": description, "interfaces": interface_list, "port": port } relays.append(relay) return relays
def get_config(): vyos_cert = vyos.defaults.vyos_cert_data conf = Config() if not conf.exists( 'service https certificates system-generated-certificate'): return None else: conf.set_level( 'service https certificates system-generated-certificate') if conf.exists('lifetime'): lifetime = conf.return_value('lifetime') vyos_cert['lifetime'] = lifetime return vyos_cert
def get_config(): geneve = deepcopy(default_config_data) conf = Config() # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') geneve['intf'] = os.environ['VYOS_TAGNODE_VALUE'] # Check if interface has been removed if not conf.exists('interfaces geneve ' + geneve['intf']): geneve['deleted'] = True return geneve # set new configuration level conf.set_level('interfaces geneve ' + geneve['intf']) # retrieve configured interface addresses if conf.exists('address'): geneve['address'] = conf.return_values('address') # retrieve interface description if conf.exists('description'): geneve['description'] = conf.return_value('description') # Disable this interface if conf.exists('disable'): geneve['disable'] = True # ARP cache entry timeout in seconds if conf.exists('ip arp-cache-timeout'): geneve['ip_arp_cache_tmo'] = int( conf.return_value('ip arp-cache-timeout')) # Enable proxy-arp on this interface if conf.exists('ip enable-proxy-arp'): geneve['ip_proxy_arp'] = 1 # Maximum Transmission Unit (MTU) if conf.exists('mtu'): geneve['mtu'] = int(conf.return_value('mtu')) # Remote address of GENEVE tunnel if conf.exists('remote'): geneve['remote'] = conf.return_value('remote') # Virtual Network Identifier if conf.exists('vni'): geneve['vni'] = conf.return_value('vni') return geneve
def get_config(): conf = Config() mroute = {'old_mroute': {}, 'mroute': {}} base_path = "protocols static multicast" if not (conf.exists(base_path) or conf.exists_effective(base_path)): return None conf.set_level(base_path) # Get multicast effective routes for route in conf.list_effective_nodes('route'): mroute['old_mroute'][route] = {} for next_hop in conf.list_effective_nodes( 'route {0} next-hop'.format(route)): mroute['old_mroute'][route].update({ next_hop: conf.return_value('route {0} next-hop {1} distance'.format( route, next_hop)) }) # Get multicast effective interface-routes for route in conf.list_effective_nodes('interface-route'): if not route in mroute['old_mroute']: mroute['old_mroute'][route] = {} for next_hop in conf.list_effective_nodes( 'interface-route {0} next-hop-interface'.format(route)): mroute['old_mroute'][route].update({ next_hop: conf.return_value( 'interface-route {0} next-hop-interface {1} distance'. format(route, next_hop)) }) # Get multicast routes for route in conf.list_nodes('route'): mroute['mroute'][route] = {} for next_hop in conf.list_nodes('route {0} next-hop'.format(route)): mroute['mroute'][route].update({ next_hop: conf.return_value('route {0} next-hop {1} distance'.format( route, next_hop)) }) # Get multicast interface-routes for route in conf.list_nodes('interface-route'): if not route in mroute['mroute']: mroute['mroute'][route] = {} for next_hop in conf.list_nodes( 'interface-route {0} next-hop-interface'.format(route)): mroute['mroute'][route].update({ next_hop: conf.return_value( 'interface-route {0} next-hop-interface {1} distance'. format(route, next_hop)) }) return mroute
def get_config(): salt = deepcopy(default_config_data) conf = Config() base = ['service', 'salt-minion'] if not conf.exists(base): return None else: conf.set_level(base) if conf.exists(['hash']): salt['hash'] = conf.return_value(['hash']) if conf.exists(['master']): salt['master'] = conf.return_values(['master']) if conf.exists(['id']): salt['salt_id'] = conf.return_value(['id']) if conf.exists(['user']): salt['user'] = conf.return_value(['user']) if conf.exists(['interval']): salt['interval'] = conf.return_value(['interval']) if conf.exists(['master-key']): salt['master_key'] = conf.return_value(['master-key']) salt['verify_master_pubkey_sign'] = 'true' return salt
def get_config(): ip_opt = deepcopy(default_config_data) conf = Config() conf.set_level('system ip') if conf.exists(''): if conf.exists('arp table-size'): ip_opt['arp_table'] = int(conf.return_value('arp table-size')) if conf.exists('disable-forwarding'): ip_opt['ipv4_forward'] = '0' if conf.exists('multipath ignore-unreachable-nexthops'): ip_opt['mp_unreach_nexthop'] = '1' if conf.exists('multipath layer4-hashing'): ip_opt['mp_layer4_hashing'] = '1' return ip_opt
def get_config(): # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') ifname = os.environ['VYOS_TAGNODE_VALUE'] conf = Config() # Check if interface has been removed cfg_base = ['interfaces', 'pseudo-ethernet', ifname] if not conf.exists(cfg_base): peth = deepcopy(default_config_data) peth['deleted'] = True return peth # set new configuration level conf.set_level(cfg_base) peth, disabled = intf_to_dict(conf, default_config_data) # ARP cache entry timeout in seconds if conf.exists(['ip', 'arp-cache-timeout']): peth['ip_arp_cache_tmo'] = int( conf.return_value(['ip', 'arp-cache-timeout'])) # Enable private VLAN proxy ARP on this interface if conf.exists(['ip', 'proxy-arp-pvlan']): peth['ip_proxy_arp_pvlan'] = 1 # Physical interface if conf.exists(['source-interface']): peth['source_interface'] = conf.return_value(['source-interface']) tmp = conf.return_effective_value(['source-interface']) if tmp != peth['source_interface']: peth['source_interface_changed'] = True # MACvlan mode if conf.exists(['mode']): peth['mode'] = conf.return_value(['mode']) add_to_dict(conf, disabled, peth, 'vif', 'vif') add_to_dict(conf, disabled, peth, 'vif-s', 'vif_s') return peth
def get_config(): dummy = deepcopy(default_config_data) conf = Config() # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') dummy['intf'] = os.environ['VYOS_TAGNODE_VALUE'] # check if we are a member of any bridge dummy['is_bridge_member'] = is_member(conf, dummy['intf'], 'bridge') # Check if interface has been removed if not conf.exists('interfaces dummy ' + dummy['intf']): dummy['deleted'] = True return dummy # set new configuration level conf.set_level('interfaces dummy ' + dummy['intf']) # retrieve configured interface addresses if conf.exists('address'): dummy['address'] = conf.return_values('address') # retrieve interface description if conf.exists('description'): dummy['description'] = conf.return_value('description') # Disable this interface if conf.exists('disable'): dummy['disable'] = True # Determine interface addresses (currently effective) - to determine which # address is no longer valid and needs to be removed from the interface eff_addr = conf.return_effective_values('address') act_addr = conf.return_values('address') dummy['address_remove'] = list_diff(eff_addr, act_addr) # retrieve VRF instance if conf.exists('vrf'): dummy['vrf'] = conf.return_value('vrf') return dummy
def get_config(): c = Config() if not c.exists('system proxy'): return None c.set_level('system proxy') cnf = {'url': None, 'port': None, 'usr': None, 'passwd': None} if c.exists('url'): cnf['url'] = c.return_value('url') if c.exists('port'): cnf['port'] = c.return_value('port') if c.exists('username'): cnf['usr'] = c.return_value('username') if c.exists('password'): cnf['passwd'] = c.return_value('password') return cnf
def get_config(): c = Config() config_data = { 'qat_conf' : None, 'ipsec_conf' : None, 'openvpn_conf' : None, } if c.exists('system acceleration qat'): config_data['qat_conf'] = True if c.exists('vpn ipsec '): gl_ipsec_conf = True config_data['ipsec_conf'] = True if c.exists('interfaces openvpn'): config_data['openvpn_conf'] = True return config_data
def get_config(): mdns = deepcopy(default_config_data) conf = Config() base = ['service', 'mdns', 'repeater'] if not conf.exists(base): return None else: conf.set_level(base) # Service can be disabled by user if conf.exists(['disable']): mdns['disabled'] = True return mdns # Interface to repeat mDNS advertisements if conf.exists(['interface']): mdns['interfaces'] = conf.return_values(['interface']) return mdns
def get_config(): nat = deepcopy(default_config_data) conf = Config() # read in current nftable (once) for further processing tmp = cmd('nft -j list table raw') nftable_json = json.loads(tmp) # condense the full JSON table into a list with only relevand informations pattern = 'nftables[?rule].rule[?expr[].jump].{chain: chain, handle: handle, target: expr[].jump.target | [0]}' condensed_json = jmespath.search(pattern, nftable_json) if not conf.exists(['nat']): nat['helper_functions'] = 'remove' # Retrieve current table handler positions nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_HELPER') nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'NAT_CONNTRACK') nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_HELPER') nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'NAT_CONNTRACK') nat['deleted'] = True return nat # check if NAT connection tracking helpers need to be set up - this has to # be done only once if not get_handler(condensed_json, 'PREROUTING', 'NAT_CONNTRACK'): nat['helper_functions'] = 'add' # Retrieve current table handler positions nat['pre_ct_ignore'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_IGNORE') nat['pre_ct_conntrack'] = get_handler(condensed_json, 'PREROUTING', 'VYATTA_CT_PREROUTING_HOOK') nat['out_ct_ignore'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_IGNORE') nat['out_ct_conntrack'] = get_handler(condensed_json, 'OUTPUT', 'VYATTA_CT_OUTPUT_HOOK') # set config level for parsing in NAT configuration conf.set_level(['nat']) # use a common wrapper function to read in the source / destination # tree from the config - thus we do not need to replicate almost the # same code :-) for tgt in ['source', 'destination', 'nptv6']: nat[tgt] = parse_source_destination(conf, tgt) return nat
def get_config(): lldp = deepcopy(default_config_data) conf = Config() if not conf.exists(base): return None else: lldp['options'] = get_options(conf) lldp['interface_list'] = get_interface_list(conf) lldp['location'] = get_location(conf) return lldp
def get_config(): relay = deepcopy(default_config_data) conf = Config() base = ['service', 'broadcast-relay'] if not conf.exists(base): return None else: conf.set_level(base) # Service can be disabled by user if conf.exists('disable'): relay['disabled'] = True return relay # Parse configuration of each individual instance if conf.exists('id'): for id in conf.list_nodes('id'): conf.set_level(base + ['id', id]) config = { 'id': id, 'disabled': False, 'address': '', 'description': '', 'interfaces': [], 'port': '' } # Check if individual broadcast relay service is disabled if conf.exists(['disable']): config['disabled'] = True # Source IP of forwarded packets, if empty original senders address is used if conf.exists(['address']): config['address'] = conf.return_value(['address']) # A description for each individual broadcast relay service if conf.exists(['description']): config['description'] = conf.return_value(['description']) # UDP port to listen on for broadcast frames if conf.exists(['port']): config['port'] = conf.return_value(['port']) # Network interfaces to listen on for broadcast frames to be relayed if conf.exists(['interface']): config['interfaces'] = conf.return_values(['interface']) relay['instances'].append(config) return relay
def get_config(): regdom = deepcopy(default_config_data) conf = Config() base = ['system', 'wifi-regulatory-domain'] # Check if interface has been removed if not conf.exists(base): regdom['deleted'] = True return regdom else: regdom['regdom'] = conf.return_value(base) return regdom
def get_config(): c = Config() if not c.exists('protocols static arp'): return None c.set_level('protocols static') config_data = {} for ip_addr in c.list_nodes('arp'): config_data.update( {ip_addr: c.return_value('arp ' + ip_addr + ' hwaddr')}) return config_data
def get_config(): tftpd = deepcopy(default_config_data) conf = Config() base = ['service', 'tftp-server'] if not conf.exists(base): return None else: conf.set_level(base) if conf.exists(['directory']): tftpd['directory'] = conf.return_value(['directory']) if conf.exists(['allow-upload']): tftpd['allow_upload'] = True if conf.exists(['port']): tftpd['port'] = conf.return_value(['port']) if conf.exists(['listen-address']): tftpd['listen'] = conf.return_values(['listen-address']) return tftpd
def get_config(): banner = default_config_data conf = Config() base_level = ['system', 'login', 'banner'] if not conf.exists(base_level): return banner else: conf.set_level(base_level) # Post-Login banner if conf.exists(['post-login']): tmp = conf.return_value(['post-login']) # post-login banner can be empty as well if tmp: tmp = tmp.replace('\\n', '\n') tmp = tmp.replace('\\t', '\t') # always add newline character tmp += '\n' else: tmp = '' banner['motd'] = tmp # Pre-Login banner if conf.exists(['pre-login']): tmp = conf.return_value(['pre-login']) # pre-login banner can be empty as well if tmp: tmp = tmp.replace('\\n', '\n') tmp = tmp.replace('\\t', '\t') # always add newline character tmp += '\n' else: tmp = '' banner['issue'] = banner['issue_net'] = tmp return banner
def get_config(): conf = Config() hosts = copy.deepcopy(default_config_data) if conf.exists("system host-name"): hosts['hostname'] = conf.return_value("system host-name") # This may happen if the config is not loaded yet, # e.g. if run by cloud-init if not hosts['hostname']: hosts['hostname'] = default_config_data['hostname'] if conf.exists("system domain-name"): hosts['domain_name'] = conf.return_value("system domain-name") hosts['domain_search'].append(hosts['domain_name']) for search in conf.return_values("system domain-search domain"): hosts['domain_search'].append(search) if conf.exists("system name-server"): hosts['nameserver'] = conf.return_values("system name-server") if conf.exists("system disable-dhcp-nameservers"): hosts['no_dhcp_ns'] = True # system static-host-mapping hosts['static_host_mapping'] = [] if conf.exists('system static-host-mapping host-name'): for hn in conf.list_nodes('system static-host-mapping host-name'): mapping = {} mapping['host'] = hn mapping['address'] = conf.return_value( 'system static-host-mapping host-name {0} inet'.format(hn)) mapping['aliases'] = conf.return_values( 'system static-host-mapping host-name {0} alias'.format(hn)) hosts['static_host_mapping'].append(mapping) return hosts
def verify(bridge): if bridge['dhcpv6_prm_only'] and bridge['dhcpv6_temporary']: raise ConfigError( 'DHCPv6 temporary and parameters-only options are mutually exclusive!' ) vrf_name = bridge['vrf'] if vrf_name and vrf_name not in interfaces(): raise ConfigError(f'VRF "{vrf_name}" does not exist') conf = Config() for br in conf.list_nodes('interfaces bridge'): # it makes no sense to verify ourself in this case if br == bridge['intf']: continue for intf in bridge['member']: tmp = conf.list_nodes( 'interfaces bridge {} member interface'.format(br)) if intf['name'] in tmp: raise ConfigError( 'Interface "{}" belongs to bridge "{}" and can not be enslaved.' .format(intf['name'], bridge['intf'])) # the interface must exist prior adding it to a bridge for intf in bridge['member']: if intf['name'] not in interfaces(): raise ConfigError( 'Can not add non existing interface "{}" to bridge "{}"'. format(intf['name'], bridge['intf'])) if intf['name'] == 'lo': raise ConfigError( 'Loopback interface "lo" can not be added to a bridge') # bridge members are not allowed to be bond members, too for intf in bridge['member']: for bond in conf.list_nodes('interfaces bonding'): if conf.exists('interfaces bonding ' + bond + ' member interface'): if intf['name'] in conf.return_values('interfaces bonding ' + bond + ' member interface'): raise ConfigError( 'Interface {} belongs to bond {}, can not add it to {}' .format(intf['name'], bond, bridge['intf'])) return None
def get_config(): salt = default_config_data conf = Config() if not conf.exists('service salt-minion'): return None else: conf.set_level('service salt-minion') if conf.exists('hash_type'): salt['hash_type'] = conf.return_value('hash_type') if conf.exists('log_file'): salt['log_file'] = conf.return_value('log_file') if conf.exists('log_level'): salt['log_level'] = conf.return_value('log_level') if conf.exists('master'): master = conf.return_values('master') salt['master'] = master if conf.exists('ID'): salt['salt_id'] = conf.return_value('ID') if conf.exists('user'): salt['user'] = conf.return_value('user') if conf.exists('mine_interval'): salt['mine_interval'] = conf.return_value('mine_interval') salt['master-key'] = None if conf.exists('master-key'): salt['master-key'] = conf.return_value('master-key') salt['verify_master_pubkey_sign'] = 'true' return salt
def get_config(): ntp = default_config_data conf = Config() if not conf.exists('system ntp'): return None else: conf.set_level('system ntp') if conf.exists('allow-clients address'): networks = conf.return_values('allow-clients address') for n in networks: addr = ipaddress.ip_network(n) net = { "network": n, "address": addr.network_address, "netmask": addr.netmask } ntp['allowed_networks'].append(net) if conf.exists('listen-address'): ntp['listen_address'] = conf.return_values('listen-address') if conf.exists('server'): for node in conf.list_nodes('server'): options = [] server = {"name": node, "options": []} if conf.exists('server {0} dynamic'.format(node)): options.append('dynamic') if conf.exists('server {0} noselect'.format(node)): options.append('noselect') if conf.exists('server {0} preempt'.format(node)): options.append('preempt') if conf.exists('server {0} prefer'.format(node)): options.append('prefer') server['options'] = options ntp['servers'].append(server) return ntp
def get_config(): bgp = deepcopy(default_config_data) conf = Config() # this lives in the "nbgp" tree until we switch over base = ['protocols', 'nbgp'] if not conf.exists(base): return None bgp = deepcopy(default_config_data) # Get full BGP configuration as dictionary - output the configuration for development # # vyos@vyos# commit # [ protocols nbgp 65000 ] # {'nbgp': {'65000': {'address-family': {'ipv4-unicast': {'aggregate-address': {'1.1.0.0/16': {}, # '2.2.2.0/24': {}}}, # 'ipv6-unicast': {'aggregate-address': {'2001:db8::/32': {}}}}, # 'neighbor': {'192.0.2.1': {'password': '******', # 'remote-as': '100'}}}}} # tmp = conf.get_config_dict(base) # extract base key from dict as this is our AS number bgp['as_number'] = jmespath.search('nbgp | keys(@) [0]', tmp) # adjust level of dictionary returned by get_config_dict() # by using jmesgpath and update dictionary bgp.update(jmespath.search('nbgp.* | [0]', tmp)) from pprint import pprint pprint(bgp) # resulting in e.g. # vyos@vyos# commit # [ protocols nbgp 65000 ] # {'address-family': {'ipv4-unicast': {'aggregate-address': {'1.1.0.0/16': {}, # '2.2.2.0/24': {}}}, # 'ipv6-unicast': {'aggregate-address': {'2001:db8::/32': {}}}}, # 'as_number': '65000', # 'neighbor': {'192.0.2.1': {'password': '******', 'remote-as': '100'}}, # 'timers': {'holdtime': '5'}} return bgp