From 586863bf3a9cb1dd1c0d74b628d00096b905740f Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Sat, 3 Feb 2024 21:43:20 +0100
Subject: rpki: T6011: known-hosts-file is no longer supported by FRR

---
 data/templates/frr/rpki.frr.j2                     |  2 +-
 .../include/version/rpki-version.xml.i             |  2 +-
 interface-definitions/protocols_rpki.xml.in        |  8 ----
 smoketest/scripts/cli/test_protocols_rpki.py       | 10 +----
 src/conf_mode/protocols_rpki.py                    |  6 +--
 src/migration-scripts/rpki/1-to-2                  | 51 ++++++++++++++++++++++
 6 files changed, 58 insertions(+), 21 deletions(-)
 create mode 100755 src/migration-scripts/rpki/1-to-2

diff --git a/data/templates/frr/rpki.frr.j2 b/data/templates/frr/rpki.frr.j2
index 9a549d6de..384cbbe52 100644
--- a/data/templates/frr/rpki.frr.j2
+++ b/data/templates/frr/rpki.frr.j2
@@ -5,7 +5,7 @@ rpki
 {%     for peer, peer_config in cache.items() %}
 {#         port is mandatory and preference uses a default value #}
 {%         if peer_config.ssh.username is vyos_defined %}
- 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 }}
+ rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} preference {{ peer_config.preference }}
 {%         else %}
  rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }}
 {%         endif %}
diff --git a/interface-definitions/include/version/rpki-version.xml.i b/interface-definitions/include/version/rpki-version.xml.i
index 2fff259a8..45ff4fbfb 100644
--- a/interface-definitions/include/version/rpki-version.xml.i
+++ b/interface-definitions/include/version/rpki-version.xml.i
@@ -1,3 +1,3 @@
 <!-- include start from include/version/rpki-version.xml.i -->
-<syntaxVersion component='rpki' version='1'></syntaxVersion>
+<syntaxVersion component='rpki' version='2'></syntaxVersion>
 <!-- include end -->
diff --git a/interface-definitions/protocols_rpki.xml.in b/interface-definitions/protocols_rpki.xml.in
index e9fd04b5f..6a38b2961 100644
--- a/interface-definitions/protocols_rpki.xml.in
+++ b/interface-definitions/protocols_rpki.xml.in
@@ -46,14 +46,6 @@
                   <help>RPKI SSH connection settings</help>
                 </properties>
                 <children>
-                  <leafNode name="known-hosts-file">
-                    <properties>
-                      <help>RPKI SSH known hosts file</help>
-                      <constraint>
-                        <validator name="file-path"/>
-                      </constraint>
-                    </properties>
-                  </leafNode>
                   <leafNode name="private-key-file">
                     <properties>
                       <help>RPKI SSH private key file</help>
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
index ab3f076ac..b43c626c4 100755
--- a/smoketest/scripts/cli/test_protocols_rpki.py
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2024 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
@@ -26,7 +26,6 @@ from vyos.utils.process 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'
 
@@ -91,7 +90,6 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
             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' : {
@@ -114,7 +112,6 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
             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()
@@ -127,7 +124,7 @@ class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
             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)
+            self.assertIn(f'rpki cache {peer} {port} {username} {rpki_ssh_key} {rpki_ssh_pub} preference {preference}', frrconfig)
 
 
     def test_rpki_verify_preference(self):
@@ -156,7 +153,4 @@ if __name__ == '__main__':
     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 05e876f3b..0fc14e868 100755
--- a/src/conf_mode/protocols_rpki.py
+++ b/src/conf_mode/protocols_rpki.py
@@ -63,11 +63,11 @@ def verify(rpki):
                 preferences.append(preference)
 
             if 'ssh' in peer_config:
-                files = ['private_key_file', 'public_key_file', 'known_hosts_file']
+                files = ['private_key_file', 'public_key_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!')
+                        raise ConfigError('RPKI+SSH requires username and public/private ' \
+                                          'key file to be defined!')
 
                     filename = peer_config['ssh'][file]
                     if not os.path.exists(filename):
diff --git a/src/migration-scripts/rpki/1-to-2 b/src/migration-scripts/rpki/1-to-2
new file mode 100755
index 000000000..559440bba
--- /dev/null
+++ b/src/migration-scripts/rpki/1-to-2
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 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/>.
+
+# T6011: rpki: known-hosts-file is no longer supported bxy FRR CLI,
+#        remove VyOS CLI node
+
+from sys import exit
+from sys import argv
+from vyos.configtree import ConfigTree
+
+if len(argv) < 2:
+    print("Must specify file name!")
+    exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+    config_file = f.read()
+
+base = ['protocols', 'rpki']
+config = ConfigTree(config_file)
+
+# Nothing to do
+if not config.exists(base):
+    exit(0)
+
+if config.exists(base + ['cache']):
+    for cache in config.list_nodes(base + ['cache']):
+        ssh_node = base + ['cache', cache, 'ssh']
+        if config.exists(ssh_node + ['known-hosts-file']):
+            config.delete(ssh_node + ['known-hosts-file'])
+
+try:
+    with open(file_name, 'w') as f:
+        f.write(config.to_string())
+except OSError as e:
+    print("Failed to save the modified config: {}".format(e))
+    exit(1)
-- 
cgit v1.2.3