Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.tools.node_daemon_setup_unittest.py @ 595149d5

History | View | Annotate | Download (6.7 kB)

1 69e5fefc Michael Hanselmann
#!/usr/bin/python
2 69e5fefc Michael Hanselmann
#
3 69e5fefc Michael Hanselmann
4 69e5fefc Michael Hanselmann
# Copyright (C) 2012 Google Inc.
5 69e5fefc Michael Hanselmann
#
6 69e5fefc Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 69e5fefc Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 69e5fefc Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 69e5fefc Michael Hanselmann
# (at your option) any later version.
10 69e5fefc Michael Hanselmann
#
11 69e5fefc Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 69e5fefc Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 69e5fefc Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 69e5fefc Michael Hanselmann
# General Public License for more details.
15 69e5fefc Michael Hanselmann
#
16 69e5fefc Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 69e5fefc Michael Hanselmann
# along with this program; if not, write to the Free Software
18 69e5fefc Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 69e5fefc Michael Hanselmann
# 02110-1301, USA.
20 69e5fefc Michael Hanselmann
21 69e5fefc Michael Hanselmann
22 69e5fefc Michael Hanselmann
"""Script for testing ganeti.tools.node_daemon_setup"""
23 69e5fefc Michael Hanselmann
24 69e5fefc Michael Hanselmann
import unittest
25 69e5fefc Michael Hanselmann
import shutil
26 69e5fefc Michael Hanselmann
import tempfile
27 69e5fefc Michael Hanselmann
import os.path
28 69e5fefc Michael Hanselmann
import OpenSSL
29 69e5fefc Michael Hanselmann
30 69e5fefc Michael Hanselmann
from ganeti import errors
31 69e5fefc Michael Hanselmann
from ganeti import constants
32 69e5fefc Michael Hanselmann
from ganeti import serializer
33 69e5fefc Michael Hanselmann
from ganeti import pathutils
34 69e5fefc Michael Hanselmann
from ganeti import compat
35 69e5fefc Michael Hanselmann
from ganeti import utils
36 69e5fefc Michael Hanselmann
from ganeti.tools import node_daemon_setup
37 69e5fefc Michael Hanselmann
38 69e5fefc Michael Hanselmann
import testutils
39 69e5fefc Michael Hanselmann
40 69e5fefc Michael Hanselmann
41 69e5fefc Michael Hanselmann
_SetupError = node_daemon_setup.SetupError
42 69e5fefc Michael Hanselmann
43 69e5fefc Michael Hanselmann
44 69e5fefc Michael Hanselmann
class TestLoadData(unittest.TestCase):
45 69e5fefc Michael Hanselmann
  def testNoJson(self):
46 69e5fefc Michael Hanselmann
    for data in ["", "{", "}"]:
47 69e5fefc Michael Hanselmann
      self.assertRaises(errors.ParseError, node_daemon_setup.LoadData, data)
48 69e5fefc Michael Hanselmann
49 69e5fefc Michael Hanselmann
  def testInvalidDataStructure(self):
50 69e5fefc Michael Hanselmann
    raw = serializer.DumpJson({
51 69e5fefc Michael Hanselmann
      "some other thing": False,
52 69e5fefc Michael Hanselmann
      })
53 69e5fefc Michael Hanselmann
    self.assertRaises(errors.ParseError, node_daemon_setup.LoadData, raw)
54 69e5fefc Michael Hanselmann
55 69e5fefc Michael Hanselmann
    raw = serializer.DumpJson([])
56 69e5fefc Michael Hanselmann
    self.assertRaises(errors.ParseError, node_daemon_setup.LoadData, raw)
57 69e5fefc Michael Hanselmann
58 69e5fefc Michael Hanselmann
  def testValidData(self):
59 69e5fefc Michael Hanselmann
    raw = serializer.DumpJson({})
60 69e5fefc Michael Hanselmann
    self.assertEqual(node_daemon_setup.LoadData(raw), {})
61 69e5fefc Michael Hanselmann
62 69e5fefc Michael Hanselmann
63 69e5fefc Michael Hanselmann
class TestVerifyCertificate(testutils.GanetiTestCase):
64 69e5fefc Michael Hanselmann
  def setUp(self):
65 69e5fefc Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
66 69e5fefc Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
67 69e5fefc Michael Hanselmann
68 69e5fefc Michael Hanselmann
  def tearDown(self):
69 69e5fefc Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
70 69e5fefc Michael Hanselmann
    shutil.rmtree(self.tmpdir)
71 69e5fefc Michael Hanselmann
72 69e5fefc Michael Hanselmann
  def testNoCert(self):
73 69e5fefc Michael Hanselmann
    self.assertRaises(_SetupError, node_daemon_setup.VerifyCertificate,
74 69e5fefc Michael Hanselmann
                      {}, _verify_fn=NotImplemented)
75 69e5fefc Michael Hanselmann
76 69e5fefc Michael Hanselmann
  def testVerificationSuccessWithCert(self):
77 69e5fefc Michael Hanselmann
    node_daemon_setup.VerifyCertificate({
78 69e5fefc Michael Hanselmann
      constants.NDS_NODE_DAEMON_CERTIFICATE: "something",
79 69e5fefc Michael Hanselmann
      }, _verify_fn=lambda _: None)
80 69e5fefc Michael Hanselmann
81 69e5fefc Michael Hanselmann
  def testNoPrivateKey(self):
82 00ef625c Michael Hanselmann
    cert_filename = testutils.TestDataFilename("cert1.pem")
83 69e5fefc Michael Hanselmann
    cert_pem = utils.ReadFile(cert_filename)
84 69e5fefc Michael Hanselmann
85 69e5fefc Michael Hanselmann
    self.assertRaises(errors.X509CertError,
86 69e5fefc Michael Hanselmann
                      node_daemon_setup._VerifyCertificate,
87 69e5fefc Michael Hanselmann
                      cert_pem, _check_fn=NotImplemented)
88 69e5fefc Michael Hanselmann
89 69e5fefc Michael Hanselmann
  def testInvalidCertificate(self):
90 69e5fefc Michael Hanselmann
    self.assertRaises(errors.X509CertError,
91 69e5fefc Michael Hanselmann
                      node_daemon_setup._VerifyCertificate,
92 69e5fefc Michael Hanselmann
                      "Something that's not a certificate",
93 69e5fefc Michael Hanselmann
                      _check_fn=NotImplemented)
94 69e5fefc Michael Hanselmann
95 69e5fefc Michael Hanselmann
  @staticmethod
96 69e5fefc Michael Hanselmann
  def _Check(cert):
97 69e5fefc Michael Hanselmann
    assert cert.get_subject()
98 69e5fefc Michael Hanselmann
99 69e5fefc Michael Hanselmann
  def testSuccessfulCheck(self):
100 00ef625c Michael Hanselmann
    cert_filename = testutils.TestDataFilename("cert2.pem")
101 69e5fefc Michael Hanselmann
    cert_pem = utils.ReadFile(cert_filename)
102 69e5fefc Michael Hanselmann
    result = \
103 69e5fefc Michael Hanselmann
      node_daemon_setup._VerifyCertificate(cert_pem, _check_fn=self._Check)
104 e712e5b8 Michael Hanselmann
105 e712e5b8 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, result)
106 e712e5b8 Michael Hanselmann
    self.assertTrue(cert)
107 e712e5b8 Michael Hanselmann
108 e712e5b8 Michael Hanselmann
    key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, result)
109 e712e5b8 Michael Hanselmann
    self.assertTrue(key)
110 69e5fefc Michael Hanselmann
111 69e5fefc Michael Hanselmann
  def testMismatchingKey(self):
112 00ef625c Michael Hanselmann
    cert1_path = testutils.TestDataFilename("cert1.pem")
113 00ef625c Michael Hanselmann
    cert2_path = testutils.TestDataFilename("cert2.pem")
114 69e5fefc Michael Hanselmann
115 69e5fefc Michael Hanselmann
    # Extract certificate
116 69e5fefc Michael Hanselmann
    cert1 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
117 69e5fefc Michael Hanselmann
                                            utils.ReadFile(cert1_path))
118 69e5fefc Michael Hanselmann
    cert1_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
119 69e5fefc Michael Hanselmann
                                                cert1)
120 69e5fefc Michael Hanselmann
121 69e5fefc Michael Hanselmann
    # Extract mismatching key
122 69e5fefc Michael Hanselmann
    key2 = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
123 69e5fefc Michael Hanselmann
                                          utils.ReadFile(cert2_path))
124 69e5fefc Michael Hanselmann
    key2_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM,
125 69e5fefc Michael Hanselmann
                                              key2)
126 69e5fefc Michael Hanselmann
127 69e5fefc Michael Hanselmann
    try:
128 69e5fefc Michael Hanselmann
      node_daemon_setup._VerifyCertificate(cert1_pem + key2_pem,
129 69e5fefc Michael Hanselmann
                                           _check_fn=NotImplemented)
130 69e5fefc Michael Hanselmann
    except errors.X509CertError, err:
131 69e5fefc Michael Hanselmann
      self.assertEqual(err.args,
132 69e5fefc Michael Hanselmann
                       ("(stdin)", "Certificate is not signed with given key"))
133 69e5fefc Michael Hanselmann
    else:
134 69e5fefc Michael Hanselmann
      self.fail("Exception was not raised")
135 69e5fefc Michael Hanselmann
136 69e5fefc Michael Hanselmann
137 69e5fefc Michael Hanselmann
class TestVerifyClusterName(unittest.TestCase):
138 69e5fefc Michael Hanselmann
  def setUp(self):
139 69e5fefc Michael Hanselmann
    unittest.TestCase.setUp(self)
140 69e5fefc Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
141 69e5fefc Michael Hanselmann
142 69e5fefc Michael Hanselmann
  def tearDown(self):
143 69e5fefc Michael Hanselmann
    unittest.TestCase.tearDown(self)
144 69e5fefc Michael Hanselmann
    shutil.rmtree(self.tmpdir)
145 69e5fefc Michael Hanselmann
146 69e5fefc Michael Hanselmann
  def testNoName(self):
147 69e5fefc Michael Hanselmann
    self.assertRaises(_SetupError, node_daemon_setup.VerifyClusterName,
148 69e5fefc Michael Hanselmann
                      {}, _verify_fn=NotImplemented)
149 69e5fefc Michael Hanselmann
150 69e5fefc Michael Hanselmann
  @staticmethod
151 69e5fefc Michael Hanselmann
  def _FailingVerify(name):
152 69e5fefc Michael Hanselmann
    assert name == "somecluster.example.com"
153 69e5fefc Michael Hanselmann
    raise errors.GenericError()
154 69e5fefc Michael Hanselmann
155 69e5fefc Michael Hanselmann
  def testFailingVerification(self):
156 69e5fefc Michael Hanselmann
    data = {
157 69e5fefc Michael Hanselmann
      constants.NDS_CLUSTER_NAME: "somecluster.example.com",
158 69e5fefc Michael Hanselmann
      }
159 69e5fefc Michael Hanselmann
160 69e5fefc Michael Hanselmann
    self.assertRaises(errors.GenericError, node_daemon_setup.VerifyClusterName,
161 69e5fefc Michael Hanselmann
                      data, _verify_fn=self._FailingVerify)
162 69e5fefc Michael Hanselmann
163 69e5fefc Michael Hanselmann
  def testSuccess(self):
164 69e5fefc Michael Hanselmann
    data = {
165 69e5fefc Michael Hanselmann
      constants.NDS_CLUSTER_NAME: "cluster.example.com",
166 69e5fefc Michael Hanselmann
      }
167 69e5fefc Michael Hanselmann
168 69e5fefc Michael Hanselmann
    result = \
169 69e5fefc Michael Hanselmann
      node_daemon_setup.VerifyClusterName(data, _verify_fn=lambda _: None)
170 69e5fefc Michael Hanselmann
171 69e5fefc Michael Hanselmann
    self.assertEqual(result, "cluster.example.com")
172 69e5fefc Michael Hanselmann
173 69e5fefc Michael Hanselmann
174 69e5fefc Michael Hanselmann
class TestVerifySsconf(unittest.TestCase):
175 69e5fefc Michael Hanselmann
  def testNoSsconf(self):
176 69e5fefc Michael Hanselmann
    self.assertRaises(_SetupError, node_daemon_setup.VerifySsconf,
177 69e5fefc Michael Hanselmann
                      {}, NotImplemented, _verify_fn=NotImplemented)
178 69e5fefc Michael Hanselmann
179 69e5fefc Michael Hanselmann
    for items in [None, {}]:
180 69e5fefc Michael Hanselmann
      self.assertRaises(_SetupError, node_daemon_setup.VerifySsconf, {
181 69e5fefc Michael Hanselmann
        constants.NDS_SSCONF: items,
182 69e5fefc Michael Hanselmann
        }, NotImplemented, _verify_fn=NotImplemented)
183 69e5fefc Michael Hanselmann
184 69e5fefc Michael Hanselmann
  def _Check(self, names):
185 69e5fefc Michael Hanselmann
    self.assertEqual(frozenset(names), frozenset([
186 69e5fefc Michael Hanselmann
      constants.SS_CLUSTER_NAME,
187 69e5fefc Michael Hanselmann
      constants.SS_INSTANCE_LIST,
188 69e5fefc Michael Hanselmann
      ]))
189 69e5fefc Michael Hanselmann
190 69e5fefc Michael Hanselmann
  def testSuccess(self):
191 69e5fefc Michael Hanselmann
    ssdata = {
192 69e5fefc Michael Hanselmann
      constants.SS_CLUSTER_NAME: "cluster.example.com",
193 69e5fefc Michael Hanselmann
      constants.SS_INSTANCE_LIST: [],
194 69e5fefc Michael Hanselmann
      }
195 69e5fefc Michael Hanselmann
196 69e5fefc Michael Hanselmann
    result = node_daemon_setup.VerifySsconf({
197 69e5fefc Michael Hanselmann
      constants.NDS_SSCONF: ssdata,
198 69e5fefc Michael Hanselmann
      }, "cluster.example.com", _verify_fn=self._Check)
199 69e5fefc Michael Hanselmann
200 69e5fefc Michael Hanselmann
    self.assertEqual(result, ssdata)
201 69e5fefc Michael Hanselmann
202 69e5fefc Michael Hanselmann
    self.assertRaises(_SetupError, node_daemon_setup.VerifySsconf, {
203 69e5fefc Michael Hanselmann
      constants.NDS_SSCONF: ssdata,
204 69e5fefc Michael Hanselmann
      }, "wrong.example.com", _verify_fn=self._Check)
205 69e5fefc Michael Hanselmann
206 69e5fefc Michael Hanselmann
  def testInvalidKey(self):
207 69e5fefc Michael Hanselmann
    self.assertRaises(errors.GenericError, node_daemon_setup.VerifySsconf, {
208 69e5fefc Michael Hanselmann
      constants.NDS_SSCONF: {
209 69e5fefc Michael Hanselmann
        "no-valid-ssconf-key": "value",
210 69e5fefc Michael Hanselmann
        },
211 69e5fefc Michael Hanselmann
      }, NotImplemented)
212 69e5fefc Michael Hanselmann
213 69e5fefc Michael Hanselmann
214 69e5fefc Michael Hanselmann
if __name__ == "__main__":
215 69e5fefc Michael Hanselmann
  testutils.GanetiTestProgram()