Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / cluster_unittest.py @ 850be460

History | View | Annotate | Download (37.3 kB)

1 19830e88 Thomas Thrainer
#!/usr/bin/python
2 19830e88 Thomas Thrainer
#
3 19830e88 Thomas Thrainer
4 0e1b5262 Thomas Thrainer
# Copyright (C) 2008, 2011, 2012, 2013 Google Inc.
5 19830e88 Thomas Thrainer
#
6 19830e88 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 19830e88 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 19830e88 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 19830e88 Thomas Thrainer
# (at your option) any later version.
10 19830e88 Thomas Thrainer
#
11 19830e88 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 19830e88 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 19830e88 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 19830e88 Thomas Thrainer
# General Public License for more details.
15 19830e88 Thomas Thrainer
#
16 19830e88 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 19830e88 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 19830e88 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 19830e88 Thomas Thrainer
# 02110-1301, USA.
20 19830e88 Thomas Thrainer
21 19830e88 Thomas Thrainer
22 19830e88 Thomas Thrainer
"""Tests for LUCluster*
23 19830e88 Thomas Thrainer

24 19830e88 Thomas Thrainer
"""
25 19830e88 Thomas Thrainer
26 850be460 Thomas Thrainer
import OpenSSL
27 850be460 Thomas Thrainer
28 0e1b5262 Thomas Thrainer
import unittest
29 0e1b5262 Thomas Thrainer
import operator
30 0e1b5262 Thomas Thrainer
import os
31 0e1b5262 Thomas Thrainer
import tempfile
32 0e1b5262 Thomas Thrainer
import shutil
33 0e1b5262 Thomas Thrainer
34 0e1b5262 Thomas Thrainer
from ganeti import constants
35 0e1b5262 Thomas Thrainer
from ganeti import compat
36 a794b8d7 Thomas Thrainer
from ganeti import errors
37 0e1b5262 Thomas Thrainer
from ganeti import ht
38 b730e2a7 Thomas Thrainer
from ganeti import netutils
39 0e1b5262 Thomas Thrainer
from ganeti import objects
40 19830e88 Thomas Thrainer
from ganeti import opcodes
41 0e1b5262 Thomas Thrainer
from ganeti import utils
42 0e1b5262 Thomas Thrainer
from ganeti import pathutils
43 0e1b5262 Thomas Thrainer
from ganeti import rpc
44 eb172e55 Thomas Thrainer
from ganeti import query
45 0e1b5262 Thomas Thrainer
from ganeti.cmdlib import cluster
46 0e1b5262 Thomas Thrainer
from ganeti.hypervisor import hv_xen
47 19830e88 Thomas Thrainer
48 19830e88 Thomas Thrainer
from testsupport import *
49 19830e88 Thomas Thrainer
50 19830e88 Thomas Thrainer
import testutils
51 0e1b5262 Thomas Thrainer
import mocks
52 0e1b5262 Thomas Thrainer
53 0e1b5262 Thomas Thrainer
54 0e1b5262 Thomas Thrainer
class TestCertVerification(testutils.GanetiTestCase):
55 0e1b5262 Thomas Thrainer
  def setUp(self):
56 0e1b5262 Thomas Thrainer
    testutils.GanetiTestCase.setUp(self)
57 0e1b5262 Thomas Thrainer
58 0e1b5262 Thomas Thrainer
    self.tmpdir = tempfile.mkdtemp()
59 0e1b5262 Thomas Thrainer
60 0e1b5262 Thomas Thrainer
  def tearDown(self):
61 0e1b5262 Thomas Thrainer
    shutil.rmtree(self.tmpdir)
62 0e1b5262 Thomas Thrainer
63 0e1b5262 Thomas Thrainer
  def testVerifyCertificate(self):
64 0e1b5262 Thomas Thrainer
    cluster._VerifyCertificate(testutils.TestDataFilename("cert1.pem"))
65 0e1b5262 Thomas Thrainer
66 0e1b5262 Thomas Thrainer
    nonexist_filename = os.path.join(self.tmpdir, "does-not-exist")
67 0e1b5262 Thomas Thrainer
68 0e1b5262 Thomas Thrainer
    (errcode, msg) = cluster._VerifyCertificate(nonexist_filename)
69 0e1b5262 Thomas Thrainer
    self.assertEqual(errcode, cluster.LUClusterVerifyConfig.ETYPE_ERROR)
70 0e1b5262 Thomas Thrainer
71 0e1b5262 Thomas Thrainer
    # Try to load non-certificate file
72 0e1b5262 Thomas Thrainer
    invalid_cert = testutils.TestDataFilename("bdev-net.txt")
73 0e1b5262 Thomas Thrainer
    (errcode, msg) = cluster._VerifyCertificate(invalid_cert)
74 0e1b5262 Thomas Thrainer
    self.assertEqual(errcode, cluster.LUClusterVerifyConfig.ETYPE_ERROR)
75 0e1b5262 Thomas Thrainer
76 0e1b5262 Thomas Thrainer
77 0e1b5262 Thomas Thrainer
class TestClusterVerifySsh(unittest.TestCase):
78 0e1b5262 Thomas Thrainer
  def testMultipleGroups(self):
79 0e1b5262 Thomas Thrainer
    fn = cluster.LUClusterVerifyGroup._SelectSshCheckNodes
80 0e1b5262 Thomas Thrainer
    mygroupnodes = [
81 0e1b5262 Thomas Thrainer
      objects.Node(name="node20", group="my", offline=False),
82 0e1b5262 Thomas Thrainer
      objects.Node(name="node21", group="my", offline=False),
83 0e1b5262 Thomas Thrainer
      objects.Node(name="node22", group="my", offline=False),
84 0e1b5262 Thomas Thrainer
      objects.Node(name="node23", group="my", offline=False),
85 0e1b5262 Thomas Thrainer
      objects.Node(name="node24", group="my", offline=False),
86 0e1b5262 Thomas Thrainer
      objects.Node(name="node25", group="my", offline=False),
87 0e1b5262 Thomas Thrainer
      objects.Node(name="node26", group="my", offline=True),
88 0e1b5262 Thomas Thrainer
      ]
89 0e1b5262 Thomas Thrainer
    nodes = [
90 0e1b5262 Thomas Thrainer
      objects.Node(name="node1", group="g1", offline=True),
91 0e1b5262 Thomas Thrainer
      objects.Node(name="node2", group="g1", offline=False),
92 0e1b5262 Thomas Thrainer
      objects.Node(name="node3", group="g1", offline=False),
93 0e1b5262 Thomas Thrainer
      objects.Node(name="node4", group="g1", offline=True),
94 0e1b5262 Thomas Thrainer
      objects.Node(name="node5", group="g1", offline=False),
95 0e1b5262 Thomas Thrainer
      objects.Node(name="node10", group="xyz", offline=False),
96 0e1b5262 Thomas Thrainer
      objects.Node(name="node11", group="xyz", offline=False),
97 0e1b5262 Thomas Thrainer
      objects.Node(name="node40", group="alloff", offline=True),
98 0e1b5262 Thomas Thrainer
      objects.Node(name="node41", group="alloff", offline=True),
99 0e1b5262 Thomas Thrainer
      objects.Node(name="node50", group="aaa", offline=False),
100 0e1b5262 Thomas Thrainer
      ] + mygroupnodes
101 0e1b5262 Thomas Thrainer
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
102 0e1b5262 Thomas Thrainer
103 0e1b5262 Thomas Thrainer
    (online, perhost) = fn(mygroupnodes, "my", nodes)
104 0e1b5262 Thomas Thrainer
    self.assertEqual(online, ["node%s" % i for i in range(20, 26)])
105 0e1b5262 Thomas Thrainer
    self.assertEqual(set(perhost.keys()), set(online))
106 0e1b5262 Thomas Thrainer
107 0e1b5262 Thomas Thrainer
    self.assertEqual(perhost, {
108 0e1b5262 Thomas Thrainer
      "node20": ["node10", "node2", "node50"],
109 0e1b5262 Thomas Thrainer
      "node21": ["node11", "node3", "node50"],
110 0e1b5262 Thomas Thrainer
      "node22": ["node10", "node5", "node50"],
111 0e1b5262 Thomas Thrainer
      "node23": ["node11", "node2", "node50"],
112 0e1b5262 Thomas Thrainer
      "node24": ["node10", "node3", "node50"],
113 0e1b5262 Thomas Thrainer
      "node25": ["node11", "node5", "node50"],
114 0e1b5262 Thomas Thrainer
      })
115 0e1b5262 Thomas Thrainer
116 0e1b5262 Thomas Thrainer
  def testSingleGroup(self):
117 0e1b5262 Thomas Thrainer
    fn = cluster.LUClusterVerifyGroup._SelectSshCheckNodes
118 0e1b5262 Thomas Thrainer
    nodes = [
119 0e1b5262 Thomas Thrainer
      objects.Node(name="node1", group="default", offline=True),
120 0e1b5262 Thomas Thrainer
      objects.Node(name="node2", group="default", offline=False),
121 0e1b5262 Thomas Thrainer
      objects.Node(name="node3", group="default", offline=False),
122 0e1b5262 Thomas Thrainer
      objects.Node(name="node4", group="default", offline=True),
123 0e1b5262 Thomas Thrainer
      ]
124 0e1b5262 Thomas Thrainer
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
125 0e1b5262 Thomas Thrainer
126 0e1b5262 Thomas Thrainer
    (online, perhost) = fn(nodes, "default", nodes)
127 0e1b5262 Thomas Thrainer
    self.assertEqual(online, ["node2", "node3"])
128 0e1b5262 Thomas Thrainer
    self.assertEqual(set(perhost.keys()), set(online))
129 0e1b5262 Thomas Thrainer
130 0e1b5262 Thomas Thrainer
    self.assertEqual(perhost, {
131 0e1b5262 Thomas Thrainer
      "node2": [],
132 0e1b5262 Thomas Thrainer
      "node3": [],
133 0e1b5262 Thomas Thrainer
      })
134 0e1b5262 Thomas Thrainer
135 0e1b5262 Thomas Thrainer
136 0e1b5262 Thomas Thrainer
class TestClusterVerifyFiles(unittest.TestCase):
137 0e1b5262 Thomas Thrainer
  @staticmethod
138 0e1b5262 Thomas Thrainer
  def _FakeErrorIf(errors, cond, ecode, item, msg, *args, **kwargs):
139 0e1b5262 Thomas Thrainer
    assert ((ecode == constants.CV_ENODEFILECHECK and
140 0e1b5262 Thomas Thrainer
             ht.TNonEmptyString(item)) or
141 0e1b5262 Thomas Thrainer
            (ecode == constants.CV_ECLUSTERFILECHECK and
142 0e1b5262 Thomas Thrainer
             item is None))
143 0e1b5262 Thomas Thrainer
144 0e1b5262 Thomas Thrainer
    if args:
145 0e1b5262 Thomas Thrainer
      msg = msg % args
146 0e1b5262 Thomas Thrainer
147 0e1b5262 Thomas Thrainer
    if cond:
148 0e1b5262 Thomas Thrainer
      errors.append((item, msg))
149 0e1b5262 Thomas Thrainer
150 0e1b5262 Thomas Thrainer
  def test(self):
151 0e1b5262 Thomas Thrainer
    errors = []
152 0e1b5262 Thomas Thrainer
    nodeinfo = [
153 0e1b5262 Thomas Thrainer
      objects.Node(name="master.example.com",
154 0e1b5262 Thomas Thrainer
                   uuid="master-uuid",
155 0e1b5262 Thomas Thrainer
                   offline=False,
156 0e1b5262 Thomas Thrainer
                   vm_capable=True),
157 0e1b5262 Thomas Thrainer
      objects.Node(name="node2.example.com",
158 0e1b5262 Thomas Thrainer
                   uuid="node2-uuid",
159 0e1b5262 Thomas Thrainer
                   offline=False,
160 0e1b5262 Thomas Thrainer
                   vm_capable=True),
161 0e1b5262 Thomas Thrainer
      objects.Node(name="node3.example.com",
162 0e1b5262 Thomas Thrainer
                   uuid="node3-uuid",
163 0e1b5262 Thomas Thrainer
                   master_candidate=True,
164 0e1b5262 Thomas Thrainer
                   vm_capable=False),
165 0e1b5262 Thomas Thrainer
      objects.Node(name="node4.example.com",
166 0e1b5262 Thomas Thrainer
                   uuid="node4-uuid",
167 0e1b5262 Thomas Thrainer
                   offline=False,
168 0e1b5262 Thomas Thrainer
                   vm_capable=True),
169 0e1b5262 Thomas Thrainer
      objects.Node(name="nodata.example.com",
170 0e1b5262 Thomas Thrainer
                   uuid="nodata-uuid",
171 0e1b5262 Thomas Thrainer
                   offline=False,
172 0e1b5262 Thomas Thrainer
                   vm_capable=True),
173 0e1b5262 Thomas Thrainer
      objects.Node(name="offline.example.com",
174 0e1b5262 Thomas Thrainer
                   uuid="offline-uuid",
175 0e1b5262 Thomas Thrainer
                   offline=True),
176 0e1b5262 Thomas Thrainer
      ]
177 0e1b5262 Thomas Thrainer
    files_all = set([
178 0e1b5262 Thomas Thrainer
      pathutils.CLUSTER_DOMAIN_SECRET_FILE,
179 0e1b5262 Thomas Thrainer
      pathutils.RAPI_CERT_FILE,
180 0e1b5262 Thomas Thrainer
      pathutils.RAPI_USERS_FILE,
181 0e1b5262 Thomas Thrainer
      ])
182 0e1b5262 Thomas Thrainer
    files_opt = set([
183 0e1b5262 Thomas Thrainer
      pathutils.RAPI_USERS_FILE,
184 0e1b5262 Thomas Thrainer
      hv_xen.XL_CONFIG_FILE,
185 0e1b5262 Thomas Thrainer
      pathutils.VNC_PASSWORD_FILE,
186 0e1b5262 Thomas Thrainer
      ])
187 0e1b5262 Thomas Thrainer
    files_mc = set([
188 0e1b5262 Thomas Thrainer
      pathutils.CLUSTER_CONF_FILE,
189 0e1b5262 Thomas Thrainer
      ])
190 0e1b5262 Thomas Thrainer
    files_vm = set([
191 0e1b5262 Thomas Thrainer
      hv_xen.XEND_CONFIG_FILE,
192 0e1b5262 Thomas Thrainer
      hv_xen.XL_CONFIG_FILE,
193 0e1b5262 Thomas Thrainer
      pathutils.VNC_PASSWORD_FILE,
194 0e1b5262 Thomas Thrainer
      ])
195 0e1b5262 Thomas Thrainer
    nvinfo = {
196 0e1b5262 Thomas Thrainer
      "master-uuid": rpc.RpcResult(data=(True, {
197 0e1b5262 Thomas Thrainer
        constants.NV_FILELIST: {
198 0e1b5262 Thomas Thrainer
          pathutils.CLUSTER_CONF_FILE: "82314f897f38b35f9dab2f7c6b1593e0",
199 0e1b5262 Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "babbce8f387bc082228e544a2146fee4",
200 0e1b5262 Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
201 0e1b5262 Thomas Thrainer
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
202 0e1b5262 Thomas Thrainer
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
203 0e1b5262 Thomas Thrainer
        }})),
204 0e1b5262 Thomas Thrainer
      "node2-uuid": rpc.RpcResult(data=(True, {
205 0e1b5262 Thomas Thrainer
        constants.NV_FILELIST: {
206 0e1b5262 Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
207 0e1b5262 Thomas Thrainer
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
208 0e1b5262 Thomas Thrainer
          }
209 0e1b5262 Thomas Thrainer
        })),
210 0e1b5262 Thomas Thrainer
      "node3-uuid": rpc.RpcResult(data=(True, {
211 0e1b5262 Thomas Thrainer
        constants.NV_FILELIST: {
212 0e1b5262 Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
213 0e1b5262 Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
214 0e1b5262 Thomas Thrainer
          }
215 0e1b5262 Thomas Thrainer
        })),
216 0e1b5262 Thomas Thrainer
      "node4-uuid": rpc.RpcResult(data=(True, {
217 0e1b5262 Thomas Thrainer
        constants.NV_FILELIST: {
218 0e1b5262 Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
219 0e1b5262 Thomas Thrainer
          pathutils.CLUSTER_CONF_FILE: "conf-a6d4b13e407867f7a7b4f0f232a8f527",
220 0e1b5262 Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
221 0e1b5262 Thomas Thrainer
          pathutils.RAPI_USERS_FILE: "rapiusers-ea3271e8d810ef3",
222 0e1b5262 Thomas Thrainer
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
223 0e1b5262 Thomas Thrainer
          }
224 0e1b5262 Thomas Thrainer
        })),
225 0e1b5262 Thomas Thrainer
      "nodata-uuid": rpc.RpcResult(data=(True, {})),
226 0e1b5262 Thomas Thrainer
      "offline-uuid": rpc.RpcResult(offline=True),
227 0e1b5262 Thomas Thrainer
      }
228 0e1b5262 Thomas Thrainer
    assert set(nvinfo.keys()) == set(map(operator.attrgetter("uuid"), nodeinfo))
229 0e1b5262 Thomas Thrainer
230 0e1b5262 Thomas Thrainer
    verify_lu = cluster.LUClusterVerifyGroup(mocks.FakeProc(),
231 0e1b5262 Thomas Thrainer
                                             opcodes.OpClusterVerify(),
232 0e1b5262 Thomas Thrainer
                                             mocks.FakeContext(),
233 0e1b5262 Thomas Thrainer
                                             None)
234 0e1b5262 Thomas Thrainer
235 0e1b5262 Thomas Thrainer
    verify_lu._ErrorIf = compat.partial(self._FakeErrorIf, errors)
236 0e1b5262 Thomas Thrainer
237 0e1b5262 Thomas Thrainer
    # TODO: That's a bit hackish to mock only this single method. We should
238 0e1b5262 Thomas Thrainer
    # build a better FakeConfig which provides such a feature already.
239 0e1b5262 Thomas Thrainer
    def GetNodeName(node_uuid):
240 0e1b5262 Thomas Thrainer
      for node in nodeinfo:
241 0e1b5262 Thomas Thrainer
        if node.uuid == node_uuid:
242 0e1b5262 Thomas Thrainer
          return node.name
243 0e1b5262 Thomas Thrainer
      return None
244 0e1b5262 Thomas Thrainer
245 0e1b5262 Thomas Thrainer
    verify_lu.cfg.GetNodeName = GetNodeName
246 0e1b5262 Thomas Thrainer
247 0e1b5262 Thomas Thrainer
    verify_lu._VerifyFiles(nodeinfo, "master-uuid", nvinfo,
248 0e1b5262 Thomas Thrainer
                           (files_all, files_opt, files_mc, files_vm))
249 0e1b5262 Thomas Thrainer
    self.assertEqual(sorted(errors), sorted([
250 0e1b5262 Thomas Thrainer
      (None, ("File %s found with 2 different checksums (variant 1 on"
251 0e1b5262 Thomas Thrainer
              " node2.example.com, node3.example.com, node4.example.com;"
252 0e1b5262 Thomas Thrainer
              " variant 2 on master.example.com)" % pathutils.RAPI_CERT_FILE)),
253 0e1b5262 Thomas Thrainer
      (None, ("File %s is missing from node(s) node2.example.com" %
254 0e1b5262 Thomas Thrainer
              pathutils.CLUSTER_DOMAIN_SECRET_FILE)),
255 0e1b5262 Thomas Thrainer
      (None, ("File %s should not exist on node(s) node4.example.com" %
256 0e1b5262 Thomas Thrainer
              pathutils.CLUSTER_CONF_FILE)),
257 0e1b5262 Thomas Thrainer
      (None, ("File %s is missing from node(s) node4.example.com" %
258 0e1b5262 Thomas Thrainer
              hv_xen.XEND_CONFIG_FILE)),
259 0e1b5262 Thomas Thrainer
      (None, ("File %s is missing from node(s) node3.example.com" %
260 0e1b5262 Thomas Thrainer
              pathutils.CLUSTER_CONF_FILE)),
261 0e1b5262 Thomas Thrainer
      (None, ("File %s found with 2 different checksums (variant 1 on"
262 0e1b5262 Thomas Thrainer
              " master.example.com; variant 2 on node4.example.com)" %
263 0e1b5262 Thomas Thrainer
              pathutils.CLUSTER_CONF_FILE)),
264 0e1b5262 Thomas Thrainer
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
265 0e1b5262 Thomas Thrainer
              " found on master.example.com, node2.example.com,"
266 0e1b5262 Thomas Thrainer
              " node3.example.com)" % pathutils.RAPI_USERS_FILE)),
267 0e1b5262 Thomas Thrainer
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
268 0e1b5262 Thomas Thrainer
              " found on node2.example.com)" % hv_xen.XL_CONFIG_FILE)),
269 0e1b5262 Thomas Thrainer
      ("nodata.example.com", "Node did not return file checksum data"),
270 0e1b5262 Thomas Thrainer
      ]))
271 19830e88 Thomas Thrainer
272 19830e88 Thomas Thrainer
273 19830e88 Thomas Thrainer
class TestLUClusterActivateMasterIp(CmdlibTestCase):
274 19830e88 Thomas Thrainer
  def testSuccess(self):
275 19830e88 Thomas Thrainer
    op = opcodes.OpClusterActivateMasterIp()
276 19830e88 Thomas Thrainer
277 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.return_value = \
278 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
279 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master)
280 19830e88 Thomas Thrainer
281 19830e88 Thomas Thrainer
    self.ExecOpCode(op)
282 19830e88 Thomas Thrainer
283 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.assert_called_once_with(
284 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
285 19830e88 Thomas Thrainer
286 19830e88 Thomas Thrainer
  def testFailure(self):
287 19830e88 Thomas Thrainer
    op = opcodes.OpClusterActivateMasterIp()
288 19830e88 Thomas Thrainer
289 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.return_value = \
290 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
291 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master) \
292 19830e88 Thomas Thrainer
293 19830e88 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op)
294 19830e88 Thomas Thrainer
295 19830e88 Thomas Thrainer
296 e0b8df13 Thomas Thrainer
class TestLUClusterDeactivateMasterIp(CmdlibTestCase):
297 e0b8df13 Thomas Thrainer
  def testSuccess(self):
298 e0b8df13 Thomas Thrainer
    op = opcodes.OpClusterDeactivateMasterIp()
299 e0b8df13 Thomas Thrainer
300 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
301 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
302 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master)
303 e0b8df13 Thomas Thrainer
304 e0b8df13 Thomas Thrainer
    self.ExecOpCode(op)
305 e0b8df13 Thomas Thrainer
306 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.assert_called_once_with(
307 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
308 e0b8df13 Thomas Thrainer
309 e0b8df13 Thomas Thrainer
  def testFailure(self):
310 e0b8df13 Thomas Thrainer
    op = opcodes.OpClusterDeactivateMasterIp()
311 e0b8df13 Thomas Thrainer
312 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
313 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
314 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master) \
315 e0b8df13 Thomas Thrainer
316 e0b8df13 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op)
317 e0b8df13 Thomas Thrainer
318 e0b8df13 Thomas Thrainer
319 eb172e55 Thomas Thrainer
class TestLUClusterConfigQuery(CmdlibTestCase):
320 eb172e55 Thomas Thrainer
  def testInvalidField(self):
321 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=["pinky_bunny"])
322 eb172e55 Thomas Thrainer
323 eb172e55 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "pinky_bunny")
324 eb172e55 Thomas Thrainer
325 eb172e55 Thomas Thrainer
  def testAllFields(self):
326 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=query.CLUSTER_FIELDS.keys())
327 eb172e55 Thomas Thrainer
328 eb172e55 Thomas Thrainer
    self.rpc.call_get_watcher_pause.return_value = \
329 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
330 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master, -1)
331 eb172e55 Thomas Thrainer
332 eb172e55 Thomas Thrainer
    ret = self.ExecOpCode(op)
333 eb172e55 Thomas Thrainer
334 eb172e55 Thomas Thrainer
    self.assertEqual(1, self.rpc.call_get_watcher_pause.call_count)
335 eb172e55 Thomas Thrainer
    self.assertEqual(len(ret), len(query.CLUSTER_FIELDS))
336 eb172e55 Thomas Thrainer
337 eb172e55 Thomas Thrainer
  def testEmpytFields(self):
338 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=[])
339 eb172e55 Thomas Thrainer
340 eb172e55 Thomas Thrainer
    self.ExecOpCode(op)
341 eb172e55 Thomas Thrainer
342 eb172e55 Thomas Thrainer
    self.assertFalse(self.rpc.call_get_watcher_pause.called)
343 eb172e55 Thomas Thrainer
344 eb172e55 Thomas Thrainer
345 bd6fb93b Thomas Thrainer
class TestLUClusterDestroy(CmdlibTestCase):
346 bd6fb93b Thomas Thrainer
  def testExistingNodes(self):
347 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
348 bd6fb93b Thomas Thrainer
349 bd6fb93b Thomas Thrainer
    self.cfg.AddNewNode()
350 bd6fb93b Thomas Thrainer
    self.cfg.AddNewNode()
351 bd6fb93b Thomas Thrainer
352 bd6fb93b Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "still 2 node\(s\)")
353 bd6fb93b Thomas Thrainer
354 bd6fb93b Thomas Thrainer
  def testExistingInstances(self):
355 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
356 bd6fb93b Thomas Thrainer
357 bd6fb93b Thomas Thrainer
    self.cfg.AddNewInstance()
358 bd6fb93b Thomas Thrainer
    self.cfg.AddNewInstance()
359 bd6fb93b Thomas Thrainer
360 bd6fb93b Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "still 2 instance\(s\)")
361 bd6fb93b Thomas Thrainer
362 bd6fb93b Thomas Thrainer
  def testEmptyCluster(self):
363 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
364 bd6fb93b Thomas Thrainer
365 bd6fb93b Thomas Thrainer
    self.ExecOpCode(op)
366 bd6fb93b Thomas Thrainer
367 f02733cc Thomas Thrainer
    self.assertSingleHooksCall([self.master.name],
368 812e07ab Thomas Thrainer
                               "cluster-destroy",
369 812e07ab Thomas Thrainer
                               constants.HOOKS_PHASE_POST)
370 bd6fb93b Thomas Thrainer
371 bd6fb93b Thomas Thrainer
372 812e07ab Thomas Thrainer
class TestLUClusterPostInit(CmdlibTestCase):
373 812e07ab Thomas Thrainer
  def testExecuion(self):
374 812e07ab Thomas Thrainer
    op = opcodes.OpClusterPostInit()
375 812e07ab Thomas Thrainer
376 812e07ab Thomas Thrainer
    self.ExecOpCode(op)
377 812e07ab Thomas Thrainer
378 f02733cc Thomas Thrainer
    self.assertSingleHooksCall([self.master.name],
379 812e07ab Thomas Thrainer
                               "cluster-init",
380 812e07ab Thomas Thrainer
                               constants.HOOKS_PHASE_POST)
381 812e07ab Thomas Thrainer
382 b730e2a7 Thomas Thrainer
383 b730e2a7 Thomas Thrainer
class TestLUClusterQuery(CmdlibTestCase):
384 b730e2a7 Thomas Thrainer
  def testSimpleInvocation(self):
385 b730e2a7 Thomas Thrainer
    op = opcodes.OpClusterQuery()
386 b730e2a7 Thomas Thrainer
387 b730e2a7 Thomas Thrainer
    self.ExecOpCode(op)
388 b730e2a7 Thomas Thrainer
389 b730e2a7 Thomas Thrainer
  def testIPv6Cluster(self):
390 b730e2a7 Thomas Thrainer
    op = opcodes.OpClusterQuery()
391 b730e2a7 Thomas Thrainer
392 f02733cc Thomas Thrainer
    self.cluster.primary_ip_family = netutils.IP6Address.family
393 b730e2a7 Thomas Thrainer
394 b730e2a7 Thomas Thrainer
    self.ExecOpCode(op)
395 b730e2a7 Thomas Thrainer
396 b730e2a7 Thomas Thrainer
397 6aac41fa Thomas Thrainer
class TestLUClusterRedistConf(CmdlibTestCase):
398 6aac41fa Thomas Thrainer
  def testSimpleInvocation(self):
399 6aac41fa Thomas Thrainer
    op = opcodes.OpClusterRedistConf()
400 6aac41fa Thomas Thrainer
401 6aac41fa Thomas Thrainer
    self.ExecOpCode(op)
402 6aac41fa Thomas Thrainer
403 6aac41fa Thomas Thrainer
404 08cef8fc Thomas Thrainer
class TestLUClusterRename(CmdlibTestCase):
405 08cef8fc Thomas Thrainer
  NEW_NAME = "new-name.example.com"
406 08cef8fc Thomas Thrainer
  NEW_IP = "1.2.3.4"
407 08cef8fc Thomas Thrainer
408 08cef8fc Thomas Thrainer
  def testNoChanges(self):
409 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.cfg.GetClusterName())
410 08cef8fc Thomas Thrainer
411 08cef8fc Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "name nor the IP address")
412 08cef8fc Thomas Thrainer
413 08cef8fc Thomas Thrainer
  def testReachableIp(self):
414 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
415 08cef8fc Thomas Thrainer
416 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
417 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
418 08cef8fc Thomas Thrainer
    self.netutils_mod.TcpPing.return_value = True
419 08cef8fc Thomas Thrainer
420 08cef8fc Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "is reachable on the network")
421 08cef8fc Thomas Thrainer
422 08cef8fc Thomas Thrainer
  def testValidRename(self):
423 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
424 08cef8fc Thomas Thrainer
425 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
426 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
427 08cef8fc Thomas Thrainer
428 08cef8fc Thomas Thrainer
    self.ExecOpCode(op)
429 08cef8fc Thomas Thrainer
430 08cef8fc Thomas Thrainer
    self.assertEqual(1, self.ssh_mod.WriteKnownHostsFile.call_count)
431 08cef8fc Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.assert_called_once_with(
432 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
433 08cef8fc Thomas Thrainer
    self.rpc.call_node_activate_master_ip.assert_called_once_with(
434 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
435 08cef8fc Thomas Thrainer
436 08cef8fc Thomas Thrainer
  def testRenameOfflineMaster(self):
437 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
438 08cef8fc Thomas Thrainer
439 f02733cc Thomas Thrainer
    self.master.offline = True
440 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
441 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
442 08cef8fc Thomas Thrainer
443 08cef8fc Thomas Thrainer
    self.ExecOpCode(op)
444 08cef8fc Thomas Thrainer
445 08cef8fc Thomas Thrainer
446 c487ae24 Thomas Thrainer
class TestLUClusterRepairDiskSizes(CmdlibTestCase):
447 c487ae24 Thomas Thrainer
  def testNoInstances(self):
448 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes()
449 c487ae24 Thomas Thrainer
450 c487ae24 Thomas Thrainer
    self.ExecOpCode(op)
451 c487ae24 Thomas Thrainer
452 c487ae24 Thomas Thrainer
  def _SetUpInstanceSingleDisk(self, dev_type=constants.LD_LV):
453 f02733cc Thomas Thrainer
    pnode = self.master
454 c487ae24 Thomas Thrainer
    snode = self.cfg.AddNewNode()
455 c487ae24 Thomas Thrainer
456 c487ae24 Thomas Thrainer
    disk = self.cfg.CreateDisk(dev_type=dev_type,
457 c487ae24 Thomas Thrainer
                               primary_node=pnode,
458 c487ae24 Thomas Thrainer
                               secondary_node=snode)
459 a794b8d7 Thomas Thrainer
    inst = self.cfg.AddNewInstance(disks=[disk])
460 c487ae24 Thomas Thrainer
461 c487ae24 Thomas Thrainer
    return (inst, disk)
462 c487ae24 Thomas Thrainer
463 c487ae24 Thomas Thrainer
  def testSingleInstanceOnFailingNode(self):
464 c487ae24 Thomas Thrainer
    (inst, _) = self._SetUpInstanceSingleDisk()
465 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes(instances=[inst.name])
466 c487ae24 Thomas Thrainer
467 c487ae24 Thomas Thrainer
    self.rpc.call_blockdev_getdimensions.return_value = \
468 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
469 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master)
470 c487ae24 Thomas Thrainer
471 c487ae24 Thomas Thrainer
    self.ExecOpCode(op)
472 c487ae24 Thomas Thrainer
473 c487ae24 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Failure in blockdev_getdimensions")
474 c487ae24 Thomas Thrainer
475 c487ae24 Thomas Thrainer
  def _ExecOpClusterRepairDiskSizes(self, node_data):
476 c487ae24 Thomas Thrainer
    # not specifying instances repairs all
477 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes()
478 c487ae24 Thomas Thrainer
479 c487ae24 Thomas Thrainer
    self.rpc.call_blockdev_getdimensions.return_value = \
480 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
481 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master, node_data)
482 c487ae24 Thomas Thrainer
483 c487ae24 Thomas Thrainer
    return self.ExecOpCode(op)
484 c487ae24 Thomas Thrainer
485 c487ae24 Thomas Thrainer
  def testInvalidResultData(self):
486 c487ae24 Thomas Thrainer
    for data in [[], [None], ["invalid"], [("still", "invalid")]]:
487 c487ae24 Thomas Thrainer
      self.ResetMocks()
488 c487ae24 Thomas Thrainer
489 c487ae24 Thomas Thrainer
      self._SetUpInstanceSingleDisk()
490 c487ae24 Thomas Thrainer
      self._ExecOpClusterRepairDiskSizes(data)
491 c487ae24 Thomas Thrainer
492 c487ae24 Thomas Thrainer
      self.mcpu.assertLogContainsRegex("ignoring")
493 c487ae24 Thomas Thrainer
494 c487ae24 Thomas Thrainer
  def testCorrectSize(self):
495 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
496 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
497 c487ae24 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
498 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
499 c487ae24 Thomas Thrainer
500 c487ae24 Thomas Thrainer
  def testWrongSize(self):
501 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
502 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(512 * 1024 * 1024, None)])
503 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
504 c487ae24 Thomas Thrainer
505 c487ae24 Thomas Thrainer
  def testCorrectDRBD(self):
506 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk(dev_type=constants.LD_DRBD8)
507 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
508 c487ae24 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
509 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
510 c487ae24 Thomas Thrainer
511 c487ae24 Thomas Thrainer
  def testWrongDRBDChild(self):
512 c487ae24 Thomas Thrainer
    (_, disk) = self._SetUpInstanceSingleDisk(dev_type=constants.LD_DRBD8)
513 c487ae24 Thomas Thrainer
    disk.children[0].size = 512
514 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
515 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
516 c487ae24 Thomas Thrainer
517 c487ae24 Thomas Thrainer
  def testExclusiveStorageInvalidResultData(self):
518 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
519 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
520 c487ae24 Thomas Thrainer
    self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
521 c487ae24 Thomas Thrainer
522 c487ae24 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
523 c487ae24 Thomas Thrainer
      "did not return valid spindles information")
524 c487ae24 Thomas Thrainer
525 c487ae24 Thomas Thrainer
  def testExclusiveStorageCorrectSpindles(self):
526 c487ae24 Thomas Thrainer
    (_, disk) = self._SetUpInstanceSingleDisk()
527 c487ae24 Thomas Thrainer
    disk.spindles = 1
528 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
529 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, 1)])
530 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
531 c487ae24 Thomas Thrainer
532 c487ae24 Thomas Thrainer
  def testExclusiveStorageWrongSpindles(self):
533 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
534 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
535 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, 1)])
536 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
537 c487ae24 Thomas Thrainer
538 c487ae24 Thomas Thrainer
539 a794b8d7 Thomas Thrainer
class TestLUClusterSetParams(CmdlibTestCase):
540 a794b8d7 Thomas Thrainer
  UID_POOL = [(10, 1000)]
541 a794b8d7 Thomas Thrainer
542 a794b8d7 Thomas Thrainer
  def testUidPool(self):
543 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(uid_pool=self.UID_POOL)
544 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
545 a794b8d7 Thomas Thrainer
    self.assertEqual(self.UID_POOL, self.cluster.uid_pool)
546 a794b8d7 Thomas Thrainer
547 a794b8d7 Thomas Thrainer
  def testAddUids(self):
548 a794b8d7 Thomas Thrainer
    old_pool = [(1, 9)]
549 a794b8d7 Thomas Thrainer
    self.cluster.uid_pool = list(old_pool)
550 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(add_uids=self.UID_POOL)
551 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
552 a794b8d7 Thomas Thrainer
    self.assertEqual(set(self.UID_POOL + old_pool),
553 a794b8d7 Thomas Thrainer
                     set(self.cluster.uid_pool))
554 a794b8d7 Thomas Thrainer
555 a794b8d7 Thomas Thrainer
  def testRemoveUids(self):
556 a794b8d7 Thomas Thrainer
    additional_pool = [(1, 9)]
557 a794b8d7 Thomas Thrainer
    self.cluster.uid_pool = self.UID_POOL + additional_pool
558 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(remove_uids=self.UID_POOL)
559 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
560 a794b8d7 Thomas Thrainer
    self.assertEqual(additional_pool, self.cluster.uid_pool)
561 a794b8d7 Thomas Thrainer
562 a794b8d7 Thomas Thrainer
  def testMasterNetmask(self):
563 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netmask=0xFFFF0000)
564 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
565 a794b8d7 Thomas Thrainer
    self.assertEqual(0xFFFF0000, self.cluster.master_netmask)
566 a794b8d7 Thomas Thrainer
567 a794b8d7 Thomas Thrainer
  def testInvalidDiskparams(self):
568 a794b8d7 Thomas Thrainer
    for diskparams in [{constants.DT_DISKLESS: {constants.LV_STRIPES: 0}},
569 a794b8d7 Thomas Thrainer
                       {constants.DT_DRBD8: {constants.RBD_POOL: "pool"}}]:
570 a794b8d7 Thomas Thrainer
      self.ResetMocks()
571 a794b8d7 Thomas Thrainer
      op = opcodes.OpClusterSetParams(diskparams=diskparams)
572 a794b8d7 Thomas Thrainer
      self.ExecOpCodeExpectOpPrereqError(op, "verify diskparams")
573 a794b8d7 Thomas Thrainer
574 a794b8d7 Thomas Thrainer
  def testValidDiskparams(self):
575 a794b8d7 Thomas Thrainer
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
576 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
577 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
578 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams[constants.DT_RBD],
579 a794b8d7 Thomas Thrainer
                     self.cluster.diskparams[constants.DT_RBD])
580 a794b8d7 Thomas Thrainer
581 a794b8d7 Thomas Thrainer
  def testMinimalDiskparams(self):
582 a794b8d7 Thomas Thrainer
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
583 a794b8d7 Thomas Thrainer
    self.cluster.diskparams = {}
584 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
585 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
586 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams, self.cluster.diskparams)
587 a794b8d7 Thomas Thrainer
588 a794b8d7 Thomas Thrainer
  def testUnsetDrbdHelperWithDrbdDisks(self):
589 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(disks=[
590 a794b8d7 Thomas Thrainer
      self.cfg.CreateDisk(dev_type=constants.LD_DRBD8, create_nodes=True)])
591 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="")
592 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable drbd helper")
593 a794b8d7 Thomas Thrainer
594 a794b8d7 Thomas Thrainer
  def testFileStorageDir(self):
595 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(file_storage_dir="/random/path")
596 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
597 a794b8d7 Thomas Thrainer
598 a794b8d7 Thomas Thrainer
  def testSetFileStorageDirToCurrentValue(self):
599 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
600 a794b8d7 Thomas Thrainer
           file_storage_dir=self.cluster.file_storage_dir)
601 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
602 a794b8d7 Thomas Thrainer
603 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("file storage dir already set to value")
604 a794b8d7 Thomas Thrainer
605 a794b8d7 Thomas Thrainer
  def testValidDrbdHelper(self):
606 a794b8d7 Thomas Thrainer
    node1 = self.cfg.AddNewNode()
607 a794b8d7 Thomas Thrainer
    node1.offline = True
608 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
609 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
610 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/true") \
611 a794b8d7 Thomas Thrainer
        .AddOfflineNode(node1) \
612 a794b8d7 Thomas Thrainer
        .Build()
613 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
614 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
615 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Not checking drbd helper on offline node")
616 a794b8d7 Thomas Thrainer
617 a794b8d7 Thomas Thrainer
  def testDrbdHelperFailingNode(self):
618 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
619 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
620 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
621 a794b8d7 Thomas Thrainer
        .Build()
622 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
623 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Error checking drbd helper")
624 a794b8d7 Thomas Thrainer
625 a794b8d7 Thomas Thrainer
  def testInvalidDrbdHelper(self):
626 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
627 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
628 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/false") \
629 a794b8d7 Thomas Thrainer
        .Build()
630 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
631 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "drbd helper is /bin/false")
632 a794b8d7 Thomas Thrainer
633 a794b8d7 Thomas Thrainer
  def testDrbdHelperWithoutDrbdDiskTemplate(self):
634 a794b8d7 Thomas Thrainer
    drbd_helper = "/bin/random_helper"
635 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
636 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
637 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
638 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, drbd_helper) \
639 a794b8d7 Thomas Thrainer
        .Build()
640 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
641 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
642 a794b8d7 Thomas Thrainer
643 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("but did not enable")
644 a794b8d7 Thomas Thrainer
645 a794b8d7 Thomas Thrainer
  def testResetDrbdHelper(self):
646 a794b8d7 Thomas Thrainer
    drbd_helper = ""
647 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
648 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
649 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
650 a794b8d7 Thomas Thrainer
651 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.drbd_usermode_helper)
652 a794b8d7 Thomas Thrainer
653 a794b8d7 Thomas Thrainer
  def testBeparams(self):
654 a794b8d7 Thomas Thrainer
    beparams = {constants.BE_VCPUS: 32}
655 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(beparams=beparams)
656 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
657 a794b8d7 Thomas Thrainer
    self.assertEqual(32, self.cluster
658 a794b8d7 Thomas Thrainer
                           .beparams[constants.PP_DEFAULT][constants.BE_VCPUS])
659 a794b8d7 Thomas Thrainer
660 a794b8d7 Thomas Thrainer
  def testNdparams(self):
661 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
662 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
663 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
664 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster
665 a794b8d7 Thomas Thrainer
                             .ndparams[constants.ND_EXCLUSIVE_STORAGE])
666 a794b8d7 Thomas Thrainer
667 a794b8d7 Thomas Thrainer
  def testNdparamsResetOobProgram(self):
668 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_OOB_PROGRAM: ""}
669 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
670 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
671 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.NDC_DEFAULTS[constants.ND_OOB_PROGRAM],
672 a794b8d7 Thomas Thrainer
                     self.cluster.ndparams[constants.ND_OOB_PROGRAM])
673 a794b8d7 Thomas Thrainer
674 a794b8d7 Thomas Thrainer
  def testHvState(self):
675 a794b8d7 Thomas Thrainer
    hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
676 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hv_state=hv_state)
677 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
678 a794b8d7 Thomas Thrainer
    self.assertEqual(8, self.cluster.hv_state_static
679 a794b8d7 Thomas Thrainer
                          [constants.HT_FAKE][constants.HVST_CPU_TOTAL])
680 a794b8d7 Thomas Thrainer
681 a794b8d7 Thomas Thrainer
  def testDiskState(self):
682 a794b8d7 Thomas Thrainer
    disk_state = {
683 a794b8d7 Thomas Thrainer
      constants.LD_LV: {
684 a794b8d7 Thomas Thrainer
        "mock_vg": {constants.DS_DISK_TOTAL: 10}
685 a794b8d7 Thomas Thrainer
      }
686 a794b8d7 Thomas Thrainer
    }
687 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(disk_state=disk_state)
688 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
689 a794b8d7 Thomas Thrainer
    self.assertEqual(10, self.cluster
690 a794b8d7 Thomas Thrainer
                           .disk_state_static[constants.LD_LV]["mock_vg"]
691 a794b8d7 Thomas Thrainer
                             [constants.DS_DISK_TOTAL])
692 a794b8d7 Thomas Thrainer
693 a794b8d7 Thomas Thrainer
  def testDefaultIPolicy(self):
694 a794b8d7 Thomas Thrainer
    ipolicy = constants.IPOLICY_DEFAULTS
695 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
696 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
697 a794b8d7 Thomas Thrainer
698 a794b8d7 Thomas Thrainer
  def testIPolicyNewViolation(self):
699 a794b8d7 Thomas Thrainer
    import ganeti.constants as C
700 a794b8d7 Thomas Thrainer
    ipolicy = C.IPOLICY_DEFAULTS
701 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MIN][C.ISPEC_MEM_SIZE] = 128
702 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MAX][C.ISPEC_MEM_SIZE] = 128
703 a794b8d7 Thomas Thrainer
704 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(beparams={C.BE_MINMEM: 512, C.BE_MAXMEM: 512})
705 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
706 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
707 a794b8d7 Thomas Thrainer
708 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instances violate them")
709 a794b8d7 Thomas Thrainer
710 a794b8d7 Thomas Thrainer
  def testNicparamsNoInstance(self):
711 a794b8d7 Thomas Thrainer
    nicparams = {
712 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
713 a794b8d7 Thomas Thrainer
    }
714 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
715 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
716 a794b8d7 Thomas Thrainer
717 a794b8d7 Thomas Thrainer
    self.assertEqual("mock_bridge",
718 a794b8d7 Thomas Thrainer
                     self.cluster.nicparams
719 a794b8d7 Thomas Thrainer
                       [constants.PP_DEFAULT][constants.NIC_LINK])
720 a794b8d7 Thomas Thrainer
721 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidConf(self):
722 a794b8d7 Thomas Thrainer
    nicparams = {
723 850be460 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
724 850be460 Thomas Thrainer
      constants.NIC_LINK: ""
725 a794b8d7 Thomas Thrainer
    }
726 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
727 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectException(op, errors.ConfigurationError, "NIC link")
728 a794b8d7 Thomas Thrainer
729 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidInstanceConf(self):
730 a794b8d7 Thomas Thrainer
    nicparams = {
731 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
732 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
733 a794b8d7 Thomas Thrainer
    }
734 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(nics=[
735 a794b8d7 Thomas Thrainer
      self.cfg.CreateNic(nicparams={constants.NIC_LINK: None})])
736 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
737 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Missing bridged NIC link")
738 a794b8d7 Thomas Thrainer
739 a794b8d7 Thomas Thrainer
  def testNicparamsMissingIp(self):
740 a794b8d7 Thomas Thrainer
    nicparams = {
741 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_ROUTED
742 a794b8d7 Thomas Thrainer
    }
743 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
744 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
745 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "routed NIC with no ip address")
746 a794b8d7 Thomas Thrainer
747 a794b8d7 Thomas Thrainer
  def testNicparamsWithInstance(self):
748 a794b8d7 Thomas Thrainer
    nicparams = {
749 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
750 a794b8d7 Thomas Thrainer
    }
751 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
752 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
753 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
754 a794b8d7 Thomas Thrainer
755 a794b8d7 Thomas Thrainer
  def testDefaultHvparams(self):
756 a794b8d7 Thomas Thrainer
    hvparams = constants.HVC_DEFAULTS
757 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
758 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
759 a794b8d7 Thomas Thrainer
760 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
761 a794b8d7 Thomas Thrainer
762 a794b8d7 Thomas Thrainer
  def testMinimalHvparams(self):
763 a794b8d7 Thomas Thrainer
    hvparams = {
764 a794b8d7 Thomas Thrainer
      constants.HT_FAKE: {
765 a794b8d7 Thomas Thrainer
        constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
766 a794b8d7 Thomas Thrainer
      }
767 a794b8d7 Thomas Thrainer
    }
768 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
769 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
770 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
771 a794b8d7 Thomas Thrainer
772 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
773 a794b8d7 Thomas Thrainer
774 a794b8d7 Thomas Thrainer
  def testOsHvp(self):
775 a794b8d7 Thomas Thrainer
    os_hvp = {
776 a794b8d7 Thomas Thrainer
      "mocked_os": {
777 a794b8d7 Thomas Thrainer
        constants.HT_FAKE: {
778 a794b8d7 Thomas Thrainer
          constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
779 a794b8d7 Thomas Thrainer
        }
780 a794b8d7 Thomas Thrainer
      },
781 a794b8d7 Thomas Thrainer
      "other_os": constants.HVC_DEFAULTS
782 a794b8d7 Thomas Thrainer
    }
783 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
784 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
785 a794b8d7 Thomas Thrainer
786 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HT_MIGRATION_NONLIVE,
787 a794b8d7 Thomas Thrainer
                     self.cluster.os_hvp["mocked_os"][constants.HT_FAKE]
788 a794b8d7 Thomas Thrainer
                       [constants.HV_MIGRATION_MODE])
789 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS, self.cluster.os_hvp["other_os"])
790 a794b8d7 Thomas Thrainer
791 a794b8d7 Thomas Thrainer
  def testRemoveOsHvp(self):
792 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": {constants.HT_FAKE: None}}
793 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
794 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
795 a794b8d7 Thomas Thrainer
796 a794b8d7 Thomas Thrainer
    assert constants.HT_FAKE not in self.cluster.os_hvp["mocked_os"]
797 a794b8d7 Thomas Thrainer
798 a794b8d7 Thomas Thrainer
  def testDefaultOsHvp(self):
799 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": constants.HVC_DEFAULTS.copy()}
800 a794b8d7 Thomas Thrainer
    self.cluster.os_hvp = {"mocked_os": {}}
801 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
802 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
803 a794b8d7 Thomas Thrainer
804 a794b8d7 Thomas Thrainer
    self.assertEqual(os_hvp, self.cluster.os_hvp)
805 a794b8d7 Thomas Thrainer
806 a794b8d7 Thomas Thrainer
  def testOsparams(self):
807 a794b8d7 Thomas Thrainer
    osparams = {
808 a794b8d7 Thomas Thrainer
      "mocked_os": {
809 a794b8d7 Thomas Thrainer
        "param1": "value1",
810 a794b8d7 Thomas Thrainer
        "param2": None
811 a794b8d7 Thomas Thrainer
      },
812 a794b8d7 Thomas Thrainer
      "other_os": {
813 a794b8d7 Thomas Thrainer
        "param1": None
814 a794b8d7 Thomas Thrainer
      }
815 a794b8d7 Thomas Thrainer
    }
816 a794b8d7 Thomas Thrainer
    self.cluster.osparams = {"other_os": {"param1": "value1"}}
817 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(osparams=osparams)
818 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
819 a794b8d7 Thomas Thrainer
820 a794b8d7 Thomas Thrainer
    self.assertEqual({"mocked_os": {"param1": "value1"}}, self.cluster.osparams)
821 a794b8d7 Thomas Thrainer
822 a794b8d7 Thomas Thrainer
  def testEnabledHypervisors(self):
823 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_XEN_HVM, constants.HT_XEN_PVM]
824 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
825 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
826 a794b8d7 Thomas Thrainer
827 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
828 a794b8d7 Thomas Thrainer
829 a794b8d7 Thomas Thrainer
  def testEnabledHypervisorsWithoutHypervisorParams(self):
830 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_FAKE]
831 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
832 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
833 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
834 a794b8d7 Thomas Thrainer
835 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
836 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS[constants.HT_FAKE],
837 a794b8d7 Thomas Thrainer
                     self.cluster.hvparams[constants.HT_FAKE])
838 a794b8d7 Thomas Thrainer
839 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
840 a794b8d7 Thomas Thrainer
  def testValidDefaultIallocator(self, find_file_mock):
841 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = "/random/path"
842 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
843 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
844 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
845 a794b8d7 Thomas Thrainer
846 a794b8d7 Thomas Thrainer
    self.assertEqual(default_iallocator, self.cluster.default_iallocator)
847 a794b8d7 Thomas Thrainer
848 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
849 a794b8d7 Thomas Thrainer
  def testInvalidDefaultIallocator(self, find_file_mock):
850 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = None
851 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
852 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
853 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Invalid default iallocator script")
854 a794b8d7 Thomas Thrainer
855 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplates(self):
856 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS, constants.DT_PLAIN]
857 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
858 a794b8d7 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates)
859 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
860 a794b8d7 Thomas Thrainer
861 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_disk_templates,
862 a794b8d7 Thomas Thrainer
                     self.cluster.enabled_disk_templates)
863 a794b8d7 Thomas Thrainer
864 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplatesWithoutVgName(self):
865 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_PLAIN]
866 a794b8d7 Thomas Thrainer
    self.cluster.volume_group_name = None
867 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
868 a794b8d7 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates)
869 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "specify a volume group")
870 a794b8d7 Thomas Thrainer
871 a794b8d7 Thomas Thrainer
  def testDisableDiskTemplateWithExistingInstance(self):
872 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS]
873 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
874 a794b8d7 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_LV)])
875 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
876 a794b8d7 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates)
877 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable disk template")
878 a794b8d7 Thomas Thrainer
879 a794b8d7 Thomas Thrainer
  def testVgNameNoLvmDiskTemplateEnabled(self):
880 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
881 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
882 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
883 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
884 a794b8d7 Thomas Thrainer
885 a794b8d7 Thomas Thrainer
    self.assertEqual(vg_name, self.cluster.volume_group_name)
886 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("enable any lvm disk template")
887 a794b8d7 Thomas Thrainer
888 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmDiskTemplateEnabled(self):
889 a794b8d7 Thomas Thrainer
    vg_name = ""
890 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_PLAIN]
891 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
892 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot unset volume group")
893 a794b8d7 Thomas Thrainer
894 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmInstance(self):
895 a794b8d7 Thomas Thrainer
    vg_name = ""
896 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
897 a794b8d7 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_LV)])
898 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
899 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable lvm storage")
900 a794b8d7 Thomas Thrainer
901 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithNoLvmDiskTemplateEnabled(self):
902 a794b8d7 Thomas Thrainer
    vg_name = ""
903 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
904 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
905 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
906 a794b8d7 Thomas Thrainer
907 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.volume_group_name)
908 a794b8d7 Thomas Thrainer
909 a794b8d7 Thomas Thrainer
  def testVgNameToOldName(self):
910 a794b8d7 Thomas Thrainer
    vg_name = self.cluster.volume_group_name
911 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
912 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
913 a794b8d7 Thomas Thrainer
914 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("already in desired state")
915 a794b8d7 Thomas Thrainer
916 a794b8d7 Thomas Thrainer
  def testVgNameWithFailingNode(self):
917 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
918 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
919 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
920 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
921 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
922 a794b8d7 Thomas Thrainer
        .Build()
923 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
924 a794b8d7 Thomas Thrainer
925 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Error while gathering data on node")
926 a794b8d7 Thomas Thrainer
927 a794b8d7 Thomas Thrainer
  def testVgNameWithValidNode(self):
928 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
929 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
930 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
931 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
932 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1024 * 1024}) \
933 a794b8d7 Thomas Thrainer
        .Build()
934 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
935 a794b8d7 Thomas Thrainer
936 a794b8d7 Thomas Thrainer
  def testVgNameWithTooSmallNode(self):
937 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
938 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
939 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
940 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
941 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1}) \
942 a794b8d7 Thomas Thrainer
        .Build()
943 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "too small")
944 a794b8d7 Thomas Thrainer
945 a794b8d7 Thomas Thrainer
  def testMiscParameters(self):
946 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(candidate_pool_size=123,
947 a794b8d7 Thomas Thrainer
                                    maintain_node_health=True,
948 a794b8d7 Thomas Thrainer
                                    modify_etc_hosts=True,
949 a794b8d7 Thomas Thrainer
                                    prealloc_wipe_disks=True,
950 a794b8d7 Thomas Thrainer
                                    reserved_lvs=["/dev/mock_lv"],
951 a794b8d7 Thomas Thrainer
                                    use_external_mip_script=True)
952 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
953 a794b8d7 Thomas Thrainer
954 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
955 a794b8d7 Thomas Thrainer
    self.assertEqual(123, self.cluster.candidate_pool_size)
956 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.maintain_node_health)
957 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.modify_etc_hosts)
958 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.prealloc_wipe_disks)
959 a794b8d7 Thomas Thrainer
    self.assertEqual(["/dev/mock_lv"], self.cluster.reserved_lvs)
960 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.use_external_mip_script)
961 a794b8d7 Thomas Thrainer
962 a794b8d7 Thomas Thrainer
  def testAddHiddenOs(self):
963 a794b8d7 Thomas Thrainer
    self.cluster.hidden_os = ["hidden1", "hidden2"]
964 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hidden_os=[(constants.DDM_ADD, "hidden2"),
965 a794b8d7 Thomas Thrainer
                                               (constants.DDM_ADD, "hidden3")])
966 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
967 a794b8d7 Thomas Thrainer
968 a794b8d7 Thomas Thrainer
    self.assertEqual(["hidden1", "hidden2", "hidden3"], self.cluster.hidden_os)
969 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS hidden2 already")
970 a794b8d7 Thomas Thrainer
971 a794b8d7 Thomas Thrainer
  def testRemoveBlacklistedOs(self):
972 a794b8d7 Thomas Thrainer
    self.cluster.blacklisted_os = ["blisted1", "blisted2"]
973 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(blacklisted_os=[
974 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted2"),
975 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted3")])
976 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
977 a794b8d7 Thomas Thrainer
978 a794b8d7 Thomas Thrainer
    self.assertEqual(["blisted1"], self.cluster.blacklisted_os)
979 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS blisted3 not found")
980 a794b8d7 Thomas Thrainer
981 a794b8d7 Thomas Thrainer
  def testMasterNetdev(self):
982 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
983 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
984 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
985 a794b8d7 Thomas Thrainer
986 a794b8d7 Thomas Thrainer
    self.assertEqual(master_netdev, self.cluster.master_netdev)
987 a794b8d7 Thomas Thrainer
988 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailNoForce(self):
989 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
990 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
991 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
992 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
993 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
994 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op, "Could not disable the master ip")
995 a794b8d7 Thomas Thrainer
996 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailForce(self):
997 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
998 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev,
999 a794b8d7 Thomas Thrainer
                                    force=True)
1000 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
1001 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
1002 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
1003 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
1004 a794b8d7 Thomas Thrainer
1005 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Could not disable the master ip")
1006 a794b8d7 Thomas Thrainer
1007 a794b8d7 Thomas Thrainer
1008 c60f7675 Thomas Thrainer
class TestLUClusterVerify(CmdlibTestCase):
1009 c60f7675 Thomas Thrainer
  def testVerifyAllGroups(self):
1010 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify()
1011 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
1012 c60f7675 Thomas Thrainer
1013 c60f7675 Thomas Thrainer
    self.assertEqual(2, len(result["jobs"]))
1014 c60f7675 Thomas Thrainer
1015 c60f7675 Thomas Thrainer
  def testVerifyDefaultGroups(self):
1016 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify(group_name="default")
1017 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
1018 c60f7675 Thomas Thrainer
1019 c60f7675 Thomas Thrainer
    self.assertEqual(1, len(result["jobs"]))
1020 c60f7675 Thomas Thrainer
1021 850be460 Thomas Thrainer
1022 850be460 Thomas Thrainer
class TestLUClusterVerifyConfig(CmdlibTestCase):
1023 850be460 Thomas Thrainer
1024 850be460 Thomas Thrainer
  def setUp(self):
1025 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).setUp()
1026 850be460 Thomas Thrainer
1027 850be460 Thomas Thrainer
    self._load_cert_patcher = testutils \
1028 850be460 Thomas Thrainer
      .patch_object(OpenSSL.crypto, "load_certificate")
1029 850be460 Thomas Thrainer
    self._load_cert_mock = self._load_cert_patcher.start()
1030 850be460 Thomas Thrainer
    self._verify_cert_patcher = testutils \
1031 850be460 Thomas Thrainer
      .patch_object(utils, "VerifyX509Certificate")
1032 850be460 Thomas Thrainer
    self._verify_cert_mock = self._verify_cert_patcher.start()
1033 850be460 Thomas Thrainer
    self._read_file_patcher = testutils.patch_object(utils, "ReadFile")
1034 850be460 Thomas Thrainer
    self._read_file_mock = self._read_file_patcher.start()
1035 850be460 Thomas Thrainer
    self._can_read_patcher = testutils.patch_object(utils, "CanRead")
1036 850be460 Thomas Thrainer
    self._can_read_mock = self._can_read_patcher.start()
1037 850be460 Thomas Thrainer
1038 850be460 Thomas Thrainer
    self._can_read_mock.return_value = True
1039 850be460 Thomas Thrainer
    self._read_file_mock.return_value = True
1040 850be460 Thomas Thrainer
    self._verify_cert_mock.return_value = (None, "")
1041 850be460 Thomas Thrainer
    self._load_cert_mock.return_value = True
1042 850be460 Thomas Thrainer
1043 850be460 Thomas Thrainer
  def tearDown(self):
1044 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).tearDown()
1045 850be460 Thomas Thrainer
1046 850be460 Thomas Thrainer
    self._can_read_patcher.stop()
1047 850be460 Thomas Thrainer
    self._read_file_patcher.stop()
1048 850be460 Thomas Thrainer
    self._verify_cert_patcher.stop()
1049 850be460 Thomas Thrainer
    self._load_cert_patcher.stop()
1050 850be460 Thomas Thrainer
1051 850be460 Thomas Thrainer
  def testSuccessfulRun(self):
1052 850be460 Thomas Thrainer
    self.cfg.AddNewInstance()
1053 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1054 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1055 850be460 Thomas Thrainer
1056 850be460 Thomas Thrainer
    self.assertTrue(result)
1057 850be460 Thomas Thrainer
1058 850be460 Thomas Thrainer
  def testDanglingNode(self):
1059 850be460 Thomas Thrainer
    node = self.cfg.AddNewNode()
1060 850be460 Thomas Thrainer
    self.cfg.AddNewInstance(primary_node=node)
1061 850be460 Thomas Thrainer
    node.group = "invalid"
1062 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1063 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1064 850be460 Thomas Thrainer
1065 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1066 850be460 Thomas Thrainer
      "following nodes \(and their instances\) belong to a non existing group")
1067 850be460 Thomas Thrainer
    self.assertFalse(result)
1068 850be460 Thomas Thrainer
1069 850be460 Thomas Thrainer
  def testDanglingInstance(self):
1070 850be460 Thomas Thrainer
    inst = self.cfg.AddNewInstance()
1071 850be460 Thomas Thrainer
    inst.primary_node = "invalid"
1072 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1073 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1074 850be460 Thomas Thrainer
1075 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1076 850be460 Thomas Thrainer
      "following instances have a non-existing primary-node")
1077 850be460 Thomas Thrainer
    self.assertFalse(result)
1078 850be460 Thomas Thrainer
1079 850be460 Thomas Thrainer
1080 19830e88 Thomas Thrainer
if __name__ == "__main__":
1081 19830e88 Thomas Thrainer
  testutils.GanetiTestProgram()