From 75a5f45659847d623c83f3cf2e2fbbf8e621b15b Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Tue, 18 Mar 2008 13:02:14 +0000 Subject: [PATCH] Add function to write cluster SSH key to known_hosts file The whole Ganeti cluster has a single SSH key. Its fingerprint is written to Ganeti's known_hosts file, together with an alias. This allows us to always use that alias instead of the real hostname, making management of the known_hosts file much easier. This patch does not handle an upgrade from an earlier version. Reviewed-by: ultrotter --- lib/ssh.py | 9 +++++++ test/Makefile.am | 1 + test/ganeti.ssh_unittest.py | 52 +++++++++++++++++++++++++++++++++++++ test/mocks.py | 14 +++++++++- 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100755 test/ganeti.ssh_unittest.py diff --git a/lib/ssh.py b/lib/ssh.py index 43bba94ba..7cc055b75 100644 --- a/lib/ssh.py +++ b/lib/ssh.py @@ -212,3 +212,12 @@ def VerifyNodeHostname(node): return False, "hostname mismatch, got %s" % remotehostname return True, "host matches" + + +def WriteKnownHostsFile(cfg, sstore, file_name): + """Writes the cluster-wide equally known_hosts file. + + """ + utils.WriteFile(file_name, mode=0700, + data="%s ssh-rsa %s\n" % (sstore.GetClusterName(), + cfg.GetHostKey())) diff --git a/test/Makefile.am b/test/Makefile.am index f07885440..6dd716900 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,6 +3,7 @@ TESTS = \ ganeti.hooks_unittest.py \ ganeti.utils_unittest.py \ ganeti.bdev_unittest.py \ + ganeti.ssh_unittest.py \ ganeti.locking_unittest.py TESTS_ENVIRONMENT = PYTHONPATH=.:$(top_builddir) diff --git a/test/ganeti.ssh_unittest.py b/test/ganeti.ssh_unittest.py new file mode 100755 index 000000000..ac5821e76 --- /dev/null +++ b/test/ganeti.ssh_unittest.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# + +# Copyright (C) 2006, 2007, 2008 Google Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + + +"""Script for unittesting the ssh module""" + +import os +import tempfile +import unittest + +import testutils +import mocks + +from ganeti import constants +from ganeti import utils +from ganeti import ssh + + +class TestKnownHosts(testutils.GanetiTestCase): + """Test case for function writing the known_hosts file""" + + def setUp(self): + self.tmpfile = tempfile.NamedTemporaryFile() + + def test(self): + cfg = mocks.FakeConfig() + sstore = mocks.FakeSStore() + ssh.WriteKnownHostsFile(cfg, sstore, self.tmpfile.name) + self.assertFileContent(self.tmpfile.name, + "%s ssh-rsa %s\n" % (sstore.GetClusterName(), + mocks.FAKE_CLUSTER_KEY)) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/mocks.py b/test/mocks.py index 70b6c400d..cfff9c25f 100644 --- a/test/mocks.py +++ b/test/mocks.py @@ -21,9 +21,18 @@ """Module implementing a fake ConfigWriter""" -import socket from ganeti import utils + +FAKE_CLUSTER_KEY = ("AAAAB3NzaC1yc2EAAAABIwAAAQEAsuGLw70et3eApJ/ZEJkAVZogIrm" + "EYPQJvb1ll52Ti0nr80Wztxibaa8bYGzY22rQIAloIlePeTGcJceAYK" + "PZgm0I/Mp2EUGg2NVsQZIzasz6cW0vYuiUbF9GkVlROmvOAykT58RfM" + "L8RhPrjrQxZc+NXgZtgDugYSZcXHDLUyWM1xKUoYy0MqYG6ZXCC/Zno" + "RThhmjOJgEmvwrMcTWQjmzH3NeJAxaBsEHR8tiVZ/Y23C/ULWLyNT6R" + "fB+DE7IovsMQaS+83AK1Teg7RWNyQczachatf/JT8VjUqFYjJepPjMb" + "vYdB2nQds7/+Bf40C/OpbvnAxna1kVtgFHAo18cQ==") + + class FakeConfig: """Fake configuration object""" @@ -36,6 +45,9 @@ class FakeConfig: def GetMaster(self): return utils.HostInfo().name + def GetHostKey(self): + return FAKE_CLUSTER_KEY + class FakeSStore: """Fake simplestore object""" -- GitLab