root / test / ganeti.tools.prepare_node_join_unittest.py @ cefd4a4a
History | View | Annotate | Download (8.7 kB)
1 | d12b9f66 | Michael Hanselmann | #!/usr/bin/python
|
---|---|---|---|
2 | d12b9f66 | Michael Hanselmann | #
|
3 | d12b9f66 | Michael Hanselmann | |
4 | d12b9f66 | Michael Hanselmann | # Copyright (C) 2012 Google Inc.
|
5 | d12b9f66 | Michael Hanselmann | #
|
6 | d12b9f66 | Michael Hanselmann | # This program is free software; you can redistribute it and/or modify
|
7 | d12b9f66 | Michael Hanselmann | # it under the terms of the GNU General Public License as published by
|
8 | d12b9f66 | Michael Hanselmann | # the Free Software Foundation; either version 2 of the License, or
|
9 | d12b9f66 | Michael Hanselmann | # (at your option) any later version.
|
10 | d12b9f66 | Michael Hanselmann | #
|
11 | d12b9f66 | Michael Hanselmann | # This program is distributed in the hope that it will be useful, but
|
12 | d12b9f66 | Michael Hanselmann | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | d12b9f66 | Michael Hanselmann | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | d12b9f66 | Michael Hanselmann | # General Public License for more details.
|
15 | d12b9f66 | Michael Hanselmann | #
|
16 | d12b9f66 | Michael Hanselmann | # You should have received a copy of the GNU General Public License
|
17 | d12b9f66 | Michael Hanselmann | # along with this program; if not, write to the Free Software
|
18 | d12b9f66 | Michael Hanselmann | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | d12b9f66 | Michael Hanselmann | # 02110-1301, USA.
|
20 | d12b9f66 | Michael Hanselmann | |
21 | d12b9f66 | Michael Hanselmann | |
22 | d12b9f66 | Michael Hanselmann | """Script for testing ganeti.tools.prepare_node_join"""
|
23 | d12b9f66 | Michael Hanselmann | |
24 | d12b9f66 | Michael Hanselmann | import unittest |
25 | d12b9f66 | Michael Hanselmann | import shutil |
26 | d12b9f66 | Michael Hanselmann | import tempfile |
27 | d12b9f66 | Michael Hanselmann | import os.path |
28 | d12b9f66 | Michael Hanselmann | import OpenSSL |
29 | d12b9f66 | Michael Hanselmann | |
30 | d12b9f66 | Michael Hanselmann | from ganeti import errors |
31 | d12b9f66 | Michael Hanselmann | from ganeti import constants |
32 | d12b9f66 | Michael Hanselmann | from ganeti import serializer |
33 | d12b9f66 | Michael Hanselmann | from ganeti import pathutils |
34 | d12b9f66 | Michael Hanselmann | from ganeti import compat |
35 | d12b9f66 | Michael Hanselmann | from ganeti import utils |
36 | d12b9f66 | Michael Hanselmann | from ganeti.tools import prepare_node_join |
37 | d12b9f66 | Michael Hanselmann | |
38 | d12b9f66 | Michael Hanselmann | import testutils |
39 | d12b9f66 | Michael Hanselmann | |
40 | d12b9f66 | Michael Hanselmann | |
41 | d12b9f66 | Michael Hanselmann | _JoinError = prepare_node_join.JoinError |
42 | d12b9f66 | Michael Hanselmann | |
43 | d12b9f66 | Michael Hanselmann | |
44 | d12b9f66 | Michael Hanselmann | class TestLoadData(unittest.TestCase): |
45 | d12b9f66 | Michael Hanselmann | def testNoJson(self): |
46 | d12b9f66 | Michael Hanselmann | self.assertRaises(errors.ParseError, prepare_node_join.LoadData, "") |
47 | d12b9f66 | Michael Hanselmann | self.assertRaises(errors.ParseError, prepare_node_join.LoadData, "}") |
48 | d12b9f66 | Michael Hanselmann | |
49 | d12b9f66 | Michael Hanselmann | def testInvalidDataStructure(self): |
50 | d12b9f66 | Michael Hanselmann | raw = serializer.DumpJson({ |
51 | d12b9f66 | Michael Hanselmann | "some other thing": False, |
52 | d12b9f66 | Michael Hanselmann | }) |
53 | d12b9f66 | Michael Hanselmann | self.assertRaises(errors.ParseError, prepare_node_join.LoadData, raw)
|
54 | d12b9f66 | Michael Hanselmann | |
55 | d12b9f66 | Michael Hanselmann | raw = serializer.DumpJson([]) |
56 | d12b9f66 | Michael Hanselmann | self.assertRaises(errors.ParseError, prepare_node_join.LoadData, raw)
|
57 | d12b9f66 | Michael Hanselmann | |
58 | d12b9f66 | Michael Hanselmann | def testValidData(self): |
59 | d12b9f66 | Michael Hanselmann | raw = serializer.DumpJson({}) |
60 | d12b9f66 | Michael Hanselmann | self.assertEqual(prepare_node_join.LoadData(raw), {})
|
61 | d12b9f66 | Michael Hanselmann | |
62 | d12b9f66 | Michael Hanselmann | |
63 | d12b9f66 | Michael Hanselmann | class TestVerifyCertificate(testutils.GanetiTestCase): |
64 | d12b9f66 | Michael Hanselmann | def setUp(self): |
65 | d12b9f66 | Michael Hanselmann | testutils.GanetiTestCase.setUp(self)
|
66 | d12b9f66 | Michael Hanselmann | self.tmpdir = tempfile.mkdtemp()
|
67 | d12b9f66 | Michael Hanselmann | |
68 | d12b9f66 | Michael Hanselmann | def tearDown(self): |
69 | d12b9f66 | Michael Hanselmann | testutils.GanetiTestCase.tearDown(self)
|
70 | d12b9f66 | Michael Hanselmann | shutil.rmtree(self.tmpdir)
|
71 | d12b9f66 | Michael Hanselmann | |
72 | d12b9f66 | Michael Hanselmann | def testNoCert(self): |
73 | d12b9f66 | Michael Hanselmann | prepare_node_join.VerifyCertificate({}, _verify_fn=NotImplemented)
|
74 | d12b9f66 | Michael Hanselmann | |
75 | d12b9f66 | Michael Hanselmann | def testGivenPrivateKey(self): |
76 | d12b9f66 | Michael Hanselmann | cert_filename = self._TestDataFilename("cert2.pem") |
77 | d12b9f66 | Michael Hanselmann | cert_pem = utils.ReadFile(cert_filename) |
78 | d12b9f66 | Michael Hanselmann | |
79 | d12b9f66 | Michael Hanselmann | self.assertRaises(_JoinError, prepare_node_join._VerifyCertificate,
|
80 | 0602cef3 | Michael Hanselmann | cert_pem, _check_fn=NotImplemented)
|
81 | d12b9f66 | Michael Hanselmann | |
82 | d12b9f66 | Michael Hanselmann | def testInvalidCertificate(self): |
83 | d12b9f66 | Michael Hanselmann | self.assertRaises(errors.X509CertError,
|
84 | d12b9f66 | Michael Hanselmann | prepare_node_join._VerifyCertificate, |
85 | d12b9f66 | Michael Hanselmann | "Something that's not a certificate",
|
86 | 0602cef3 | Michael Hanselmann | _check_fn=NotImplemented)
|
87 | d12b9f66 | Michael Hanselmann | |
88 | 0602cef3 | Michael Hanselmann | @staticmethod
|
89 | 0602cef3 | Michael Hanselmann | def _Check(cert): |
90 | 0602cef3 | Michael Hanselmann | assert cert.get_subject()
|
91 | 0602cef3 | Michael Hanselmann | |
92 | 0602cef3 | Michael Hanselmann | def testSuccessfulCheck(self): |
93 | 0602cef3 | Michael Hanselmann | cert_filename = self._TestDataFilename("cert1.pem") |
94 | 0602cef3 | Michael Hanselmann | cert_pem = utils.ReadFile(cert_filename) |
95 | 0602cef3 | Michael Hanselmann | prepare_node_join._VerifyCertificate(cert_pem, _check_fn=self._Check)
|
96 | d12b9f66 | Michael Hanselmann | |
97 | d12b9f66 | Michael Hanselmann | |
98 | d12b9f66 | Michael Hanselmann | class TestVerifyClusterName(unittest.TestCase): |
99 | d12b9f66 | Michael Hanselmann | def setUp(self): |
100 | d12b9f66 | Michael Hanselmann | unittest.TestCase.setUp(self)
|
101 | d12b9f66 | Michael Hanselmann | self.tmpdir = tempfile.mkdtemp()
|
102 | d12b9f66 | Michael Hanselmann | |
103 | d12b9f66 | Michael Hanselmann | def tearDown(self): |
104 | d12b9f66 | Michael Hanselmann | unittest.TestCase.tearDown(self)
|
105 | d12b9f66 | Michael Hanselmann | shutil.rmtree(self.tmpdir)
|
106 | d12b9f66 | Michael Hanselmann | |
107 | d12b9f66 | Michael Hanselmann | def testNoName(self): |
108 | d12b9f66 | Michael Hanselmann | self.assertRaises(_JoinError, prepare_node_join.VerifyClusterName,
|
109 | d12b9f66 | Michael Hanselmann | {}, _verify_fn=NotImplemented)
|
110 | d12b9f66 | Michael Hanselmann | |
111 | dffa96d6 | Michael Hanselmann | @staticmethod
|
112 | dffa96d6 | Michael Hanselmann | def _FailingVerify(name): |
113 | dffa96d6 | Michael Hanselmann | assert name == "cluster.example.com" |
114 | dffa96d6 | Michael Hanselmann | raise errors.GenericError()
|
115 | dffa96d6 | Michael Hanselmann | |
116 | dffa96d6 | Michael Hanselmann | def testFailingVerification(self): |
117 | dffa96d6 | Michael Hanselmann | data = { |
118 | dffa96d6 | Michael Hanselmann | constants.SSHS_CLUSTER_NAME: "cluster.example.com",
|
119 | dffa96d6 | Michael Hanselmann | } |
120 | dffa96d6 | Michael Hanselmann | |
121 | dffa96d6 | Michael Hanselmann | self.assertRaises(errors.GenericError, prepare_node_join.VerifyClusterName,
|
122 | dffa96d6 | Michael Hanselmann | data, _verify_fn=self._FailingVerify)
|
123 | d12b9f66 | Michael Hanselmann | |
124 | d12b9f66 | Michael Hanselmann | |
125 | d12b9f66 | Michael Hanselmann | class TestUpdateSshDaemon(unittest.TestCase): |
126 | d12b9f66 | Michael Hanselmann | def setUp(self): |
127 | d12b9f66 | Michael Hanselmann | unittest.TestCase.setUp(self)
|
128 | d12b9f66 | Michael Hanselmann | self.tmpdir = tempfile.mkdtemp()
|
129 | d12b9f66 | Michael Hanselmann | |
130 | d12b9f66 | Michael Hanselmann | self.keyfiles = {
|
131 | d12b9f66 | Michael Hanselmann | constants.SSHK_RSA: |
132 | 340ae7da | Michael Hanselmann | (utils.PathJoin(self.tmpdir, "rsa.private"), |
133 | 340ae7da | Michael Hanselmann | utils.PathJoin(self.tmpdir, "rsa.public")), |
134 | d12b9f66 | Michael Hanselmann | constants.SSHK_DSA: |
135 | 340ae7da | Michael Hanselmann | (utils.PathJoin(self.tmpdir, "dsa.private"), |
136 | 340ae7da | Michael Hanselmann | utils.PathJoin(self.tmpdir, "dsa.public")), |
137 | d12b9f66 | Michael Hanselmann | } |
138 | d12b9f66 | Michael Hanselmann | |
139 | d12b9f66 | Michael Hanselmann | def tearDown(self): |
140 | d12b9f66 | Michael Hanselmann | unittest.TestCase.tearDown(self)
|
141 | d12b9f66 | Michael Hanselmann | shutil.rmtree(self.tmpdir)
|
142 | d12b9f66 | Michael Hanselmann | |
143 | d12b9f66 | Michael Hanselmann | def testNoKeys(self): |
144 | d12b9f66 | Michael Hanselmann | data_empty_keys = { |
145 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_HOST_KEY: [], |
146 | d12b9f66 | Michael Hanselmann | } |
147 | d12b9f66 | Michael Hanselmann | |
148 | d12b9f66 | Michael Hanselmann | for data in [{}, data_empty_keys]: |
149 | d12b9f66 | Michael Hanselmann | for dry_run in [False, True]: |
150 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshDaemon(data, dry_run, |
151 | d12b9f66 | Michael Hanselmann | _runcmd_fn=NotImplemented,
|
152 | d12b9f66 | Michael Hanselmann | _keyfiles=NotImplemented)
|
153 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.tmpdir), []) |
154 | d12b9f66 | Michael Hanselmann | |
155 | d12b9f66 | Michael Hanselmann | def _TestDryRun(self, data): |
156 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshDaemon(data, True, _runcmd_fn=NotImplemented, |
157 | d12b9f66 | Michael Hanselmann | _keyfiles=self.keyfiles)
|
158 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.tmpdir), []) |
159 | d12b9f66 | Michael Hanselmann | |
160 | d12b9f66 | Michael Hanselmann | def testDryRunRsa(self): |
161 | d12b9f66 | Michael Hanselmann | self._TestDryRun({
|
162 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_HOST_KEY: [ |
163 | 340ae7da | Michael Hanselmann | (constants.SSHK_RSA, "rsapriv", "rsapub"), |
164 | d12b9f66 | Michael Hanselmann | ], |
165 | d12b9f66 | Michael Hanselmann | }) |
166 | d12b9f66 | Michael Hanselmann | |
167 | d12b9f66 | Michael Hanselmann | def testDryRunDsa(self): |
168 | d12b9f66 | Michael Hanselmann | self._TestDryRun({
|
169 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_HOST_KEY: [ |
170 | 340ae7da | Michael Hanselmann | (constants.SSHK_DSA, "dsapriv", "dsapub"), |
171 | d12b9f66 | Michael Hanselmann | ], |
172 | d12b9f66 | Michael Hanselmann | }) |
173 | d12b9f66 | Michael Hanselmann | |
174 | d12b9f66 | Michael Hanselmann | def _RunCmd(self, fail, cmd, interactive=NotImplemented): |
175 | d12b9f66 | Michael Hanselmann | self.assertTrue(interactive)
|
176 | d12b9f66 | Michael Hanselmann | self.assertEqual(cmd, [pathutils.DAEMON_UTIL, "reload-ssh-keys"]) |
177 | d12b9f66 | Michael Hanselmann | if fail:
|
178 | d12b9f66 | Michael Hanselmann | exit_code = constants.EXIT_FAILURE |
179 | d12b9f66 | Michael Hanselmann | else:
|
180 | d12b9f66 | Michael Hanselmann | exit_code = constants.EXIT_SUCCESS |
181 | d12b9f66 | Michael Hanselmann | return utils.RunResult(exit_code, None, "stdout", "stderr", |
182 | d12b9f66 | Michael Hanselmann | utils.ShellQuoteArgs(cmd), |
183 | d12b9f66 | Michael Hanselmann | NotImplemented, NotImplemented) |
184 | d12b9f66 | Michael Hanselmann | |
185 | d12b9f66 | Michael Hanselmann | def _TestUpdate(self, failcmd): |
186 | d12b9f66 | Michael Hanselmann | data = { |
187 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_HOST_KEY: [ |
188 | 340ae7da | Michael Hanselmann | (constants.SSHK_DSA, "dsapriv", "dsapub"), |
189 | 340ae7da | Michael Hanselmann | (constants.SSHK_RSA, "rsapriv", "rsapub"), |
190 | d12b9f66 | Michael Hanselmann | ], |
191 | d12b9f66 | Michael Hanselmann | } |
192 | d12b9f66 | Michael Hanselmann | runcmd_fn = compat.partial(self._RunCmd, failcmd)
|
193 | d12b9f66 | Michael Hanselmann | if failcmd:
|
194 | d12b9f66 | Michael Hanselmann | self.assertRaises(_JoinError, prepare_node_join.UpdateSshDaemon,
|
195 | d12b9f66 | Michael Hanselmann | data, False, _runcmd_fn=runcmd_fn,
|
196 | d12b9f66 | Michael Hanselmann | _keyfiles=self.keyfiles)
|
197 | d12b9f66 | Michael Hanselmann | else:
|
198 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshDaemon(data, False, _runcmd_fn=runcmd_fn,
|
199 | d12b9f66 | Michael Hanselmann | _keyfiles=self.keyfiles)
|
200 | d12b9f66 | Michael Hanselmann | self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted([ |
201 | 340ae7da | Michael Hanselmann | "rsa.public", "rsa.private", |
202 | 340ae7da | Michael Hanselmann | "dsa.public", "dsa.private", |
203 | d12b9f66 | Michael Hanselmann | ])) |
204 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.tmpdir, "rsa.public")), |
205 | d12b9f66 | Michael Hanselmann | "rsapub")
|
206 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.tmpdir, "rsa.private")), |
207 | d12b9f66 | Michael Hanselmann | "rsapriv")
|
208 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.tmpdir, "dsa.public")), |
209 | d12b9f66 | Michael Hanselmann | "dsapub")
|
210 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.tmpdir, "dsa.private")), |
211 | d12b9f66 | Michael Hanselmann | "dsapriv")
|
212 | d12b9f66 | Michael Hanselmann | |
213 | d12b9f66 | Michael Hanselmann | def testSuccess(self): |
214 | d12b9f66 | Michael Hanselmann | self._TestUpdate(False) |
215 | d12b9f66 | Michael Hanselmann | |
216 | d12b9f66 | Michael Hanselmann | def testFailure(self): |
217 | d12b9f66 | Michael Hanselmann | self._TestUpdate(True) |
218 | d12b9f66 | Michael Hanselmann | |
219 | d12b9f66 | Michael Hanselmann | |
220 | d12b9f66 | Michael Hanselmann | class TestUpdateSshRoot(unittest.TestCase): |
221 | d12b9f66 | Michael Hanselmann | def setUp(self): |
222 | d12b9f66 | Michael Hanselmann | unittest.TestCase.setUp(self)
|
223 | d12b9f66 | Michael Hanselmann | self.tmpdir = tempfile.mkdtemp()
|
224 | d12b9f66 | Michael Hanselmann | self.sshdir = utils.PathJoin(self.tmpdir, ".ssh") |
225 | d12b9f66 | Michael Hanselmann | |
226 | d12b9f66 | Michael Hanselmann | def tearDown(self): |
227 | d12b9f66 | Michael Hanselmann | unittest.TestCase.tearDown(self)
|
228 | d12b9f66 | Michael Hanselmann | shutil.rmtree(self.tmpdir)
|
229 | d12b9f66 | Michael Hanselmann | |
230 | d12b9f66 | Michael Hanselmann | def _GetHomeDir(self, user): |
231 | d12b9f66 | Michael Hanselmann | self.assertEqual(user, constants.SSH_LOGIN_USER)
|
232 | d12b9f66 | Michael Hanselmann | return self.tmpdir |
233 | d12b9f66 | Michael Hanselmann | |
234 | d12b9f66 | Michael Hanselmann | def testNoKeys(self): |
235 | d12b9f66 | Michael Hanselmann | data_empty_keys = { |
236 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_ROOT_KEY: [], |
237 | d12b9f66 | Michael Hanselmann | } |
238 | d12b9f66 | Michael Hanselmann | |
239 | d12b9f66 | Michael Hanselmann | for data in [{}, data_empty_keys]: |
240 | d12b9f66 | Michael Hanselmann | for dry_run in [False, True]: |
241 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshRoot(data, dry_run, |
242 | d12b9f66 | Michael Hanselmann | _homedir_fn=NotImplemented)
|
243 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.tmpdir), []) |
244 | d12b9f66 | Michael Hanselmann | |
245 | d12b9f66 | Michael Hanselmann | def testDryRun(self): |
246 | d12b9f66 | Michael Hanselmann | data = { |
247 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_ROOT_KEY: [ |
248 | d12b9f66 | Michael Hanselmann | (constants.SSHK_RSA, "aaa", "bbb"), |
249 | d12b9f66 | Michael Hanselmann | ] |
250 | d12b9f66 | Michael Hanselmann | } |
251 | d12b9f66 | Michael Hanselmann | |
252 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshRoot(data, True,
|
253 | d12b9f66 | Michael Hanselmann | _homedir_fn=self._GetHomeDir)
|
254 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.tmpdir), [".ssh"]) |
255 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.sshdir), []) |
256 | d12b9f66 | Michael Hanselmann | |
257 | d12b9f66 | Michael Hanselmann | def testUpdate(self): |
258 | d12b9f66 | Michael Hanselmann | data = { |
259 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_ROOT_KEY: [ |
260 | 340ae7da | Michael Hanselmann | (constants.SSHK_DSA, "privatedsa", "ssh-dss pubdsa"), |
261 | d12b9f66 | Michael Hanselmann | ] |
262 | d12b9f66 | Michael Hanselmann | } |
263 | d12b9f66 | Michael Hanselmann | |
264 | d12b9f66 | Michael Hanselmann | prepare_node_join.UpdateSshRoot(data, False,
|
265 | d12b9f66 | Michael Hanselmann | _homedir_fn=self._GetHomeDir)
|
266 | d12b9f66 | Michael Hanselmann | self.assertEqual(os.listdir(self.tmpdir), [".ssh"]) |
267 | d12b9f66 | Michael Hanselmann | self.assertEqual(sorted(os.listdir(self.sshdir)), |
268 | d12b9f66 | Michael Hanselmann | sorted(["authorized_keys", "id_dsa", "id_dsa.pub"])) |
269 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.sshdir, "id_dsa")), |
270 | d12b9f66 | Michael Hanselmann | "privatedsa")
|
271 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.sshdir, "id_dsa.pub")), |
272 | 910ef222 | Michael Hanselmann | "ssh-dss pubdsa")
|
273 | d12b9f66 | Michael Hanselmann | self.assertEqual(utils.ReadFile(utils.PathJoin(self.sshdir, |
274 | d12b9f66 | Michael Hanselmann | "authorized_keys")),
|
275 | d12b9f66 | Michael Hanselmann | "ssh-dss pubdsa\n")
|
276 | d12b9f66 | Michael Hanselmann | |
277 | d12b9f66 | Michael Hanselmann | |
278 | d12b9f66 | Michael Hanselmann | if __name__ == "__main__": |
279 | d12b9f66 | Michael Hanselmann | testutils.GanetiTestProgram() |