Page MenuHomeVyOS Platform

No OneTemporary

Size
10 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/frr/rpki.frr.tmpl b/data/templates/frr/rpki.frr.tmpl
index fbdfa27c3..7f9823f6b 100644
--- a/data/templates/frr/rpki.frr.tmpl
+++ b/data/templates/frr/rpki.frr.tmpl
@@ -1,17 +1,18 @@
!
{# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #}
rpki
{% if cache is defined and cache is not none %}
{% for peer, peer_config in cache.items() %}
{# port is mandatory and preference uses a default value #}
{% if peer_config.ssh is defined and peer_config.ssh.username is defined and peer_config.ssh.username is not none %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} {{ peer_config.ssh.known_hosts_file }} preference {{ peer_config.preference }}
{% else %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }}
{% endif %}
{% endfor %}
{% endif %}
{% if polling_period is defined and polling_period is not none %}
rpki polling_period {{ polling_period }}
{% endif %}
+exit
!
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
index d9792ce8d..e5e45565b 100755
--- a/smoketest/scripts/cli/test_protocols_rpki.py
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -1,154 +1,152 @@
#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import process_named_running
base_path = ['protocols', 'rpki']
PROCESS_NAME = 'bgpd'
rpki_known_hosts = '/config/auth/known_hosts'
rpki_ssh_key = '/config/auth/id_rsa_rpki'
rpki_ssh_pub = f'{rpki_ssh_key}.pub'
class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
self.cli_delete(base_path)
self.cli_commit()
# Nothing RPKI specific should be left over in the config
- #
- # Disabled until T3266 is resolved
# frrconfig = self.getFRRconfig('rpki')
# self.assertNotIn('rpki', frrconfig)
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
def test_rpki(self):
polling = '7200'
cache = {
'192.0.2.1' : {
'port' : '8080',
'preference' : '1'
},
'192.0.2.2' : {
'port' : '9090',
'preference' : '2'
},
'2001:db8::1' : {
'port' : '1234',
'preference' : '3'
},
'2001:db8::2' : {
'port' : '5678',
'preference' : '4'
},
}
self.cli_set(base_path + ['polling-period', polling])
for peer, peer_config in cache.items():
self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
# commit changes
self.cli_commit()
# Verify FRR configuration
frrconfig = self.getFRRconfig('rpki')
self.assertIn(f'rpki polling_period {polling}', frrconfig)
for peer, peer_config in cache.items():
port = peer_config['port']
preference = peer_config['preference']
self.assertIn(f'rpki cache {peer} {port} preference {preference}', frrconfig)
def test_rpki_ssh(self):
self.skipTest('Currently untested, see: https://github.com/FRRouting/frr/issues/7978')
polling = '7200'
cache = {
'192.0.2.3' : {
'port' : '1234',
'username' : 'foo',
'preference' : '10'
},
'192.0.2.4' : {
'port' : '5678',
'username' : 'bar',
'preference' : '20'
},
}
self.cli_set(base_path + ['polling-period', polling])
for peer, peer_config in cache.items():
self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
self.cli_set(base_path + ['cache', peer, 'ssh', 'username', peer_config['username']])
self.cli_set(base_path + ['cache', peer, 'ssh', 'public-key-file', rpki_ssh_pub])
self.cli_set(base_path + ['cache', peer, 'ssh', 'private-key-file', rpki_ssh_key])
self.cli_set(base_path + ['cache', peer, 'ssh', 'known-hosts-file', rpki_known_hosts])
# commit changes
self.cli_commit()
# Verify FRR configuration
frrconfig = self.getFRRconfig('rpki')
self.assertIn(f'rpki polling_period {polling}', frrconfig)
for peer, peer_config in cache.items():
port = peer_config['port']
preference = peer_config['preference']
username = peer_config['username']
self.assertIn(f'rpki cache {peer} {port} {username} {rpki_ssh_key} {rpki_known_hosts} preference {preference}', frrconfig)
def test_rpki_verify_preference(self):
cache = {
'192.0.2.1' : {
'port' : '8080',
'preference' : '1'
},
'192.0.2.2' : {
'port' : '9090',
'preference' : '1'
},
}
for peer, peer_config in cache.items():
self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
# check validate() - preferences must be unique
with self.assertRaises(ConfigSessionError):
self.cli_commit()
if __name__ == '__main__':
# Create OpenSSH keypair used in RPKI tests
if not os.path.isfile(rpki_ssh_key):
cmd(f'ssh-keygen -t rsa -f {rpki_ssh_key} -N ""')
if not os.path.isfile(rpki_known_hosts):
cmd(f'touch {rpki_known_hosts}')
unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_rpki.py b/src/conf_mode/protocols_rpki.py
index 0688e542f..41ce1f1fd 100755
--- a/src/conf_mode/protocols_rpki.py
+++ b/src/conf_mode/protocols_rpki.py
@@ -1,103 +1,108 @@
#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render_to_string
from vyos.util import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'bgpd'
-
def get_config(config=None):
if config:
conf = config
else:
conf = Config()
base = ['protocols', 'rpki']
rpki = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # Bail out early if configuration tree does not exist
if not conf.exists(base):
+ rpki.update({'deleted' : ''})
return rpki
# We have gathered the dict representation of the CLI, but there are default
# options which we need to update into the dictionary retrived.
default_values = defaults(base)
rpki = dict_merge(default_values, rpki)
return rpki
def verify(rpki):
if not rpki:
return None
if 'cache' in rpki:
preferences = []
for peer, peer_config in rpki['cache'].items():
for mandatory in ['port', 'preference']:
if mandatory not in peer_config:
raise ConfigError(f'RPKI cache "{peer}" {mandatory} must be defined!')
if 'preference' in peer_config:
preference = peer_config['preference']
if preference in preferences:
raise ConfigError(f'RPKI cache with preference {preference} already configured!')
preferences.append(preference)
if 'ssh' in peer_config:
files = ['private_key_file', 'public_key_file', 'known_hosts_file']
for file in files:
if file not in peer_config['ssh']:
raise ConfigError('RPKI+SSH requires username, public/private ' \
'keys and known-hosts file to be defined!')
filename = peer_config['ssh'][file]
if not os.path.exists(filename):
raise ConfigError(f'RPKI SSH {file.replace("-","-")} "{filename}" does not exist!')
return None
def generate(rpki):
+ if not rpki:
+ return
rpki['new_frr_config'] = render_to_string('frr/rpki.frr.tmpl', rpki)
return None
def apply(rpki):
+ bgp_daemon = 'bgpd'
+
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section('rpki', '')
- frr_cfg.add_before(frr.default_add_before, rpki['new_frr_config'])
- frr_cfg.commit_configuration(frr_daemon)
+ frr_cfg.load_configuration(bgp_daemon)
+ frr_cfg.modify_section('^rpki')
+ if 'new_frr_config' in rpki:
+ frr_cfg.add_before(frr.default_add_before, rpki['new_frr_config'])
+ frr_cfg.commit_configuration(bgp_daemon)
return None
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 26, 9:45 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4284826
Default Alt Text
(10 KB)

Event Timeline