Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.client_unittest.py @ 66d1f035

History | View | Annotate | Download (42.7 kB)

1 95ab4de9 David Knowles
#!/usr/bin/python
2 95ab4de9 David Knowles
#
3 95ab4de9 David Knowles
4 95ab4de9 David Knowles
# Copyright (C) 2010 Google Inc.
5 95ab4de9 David Knowles
#
6 95ab4de9 David Knowles
# This program is free software; you can redistribute it and/or modify
7 95ab4de9 David Knowles
# it under the terms of the GNU General Public License as published by
8 95ab4de9 David Knowles
# the Free Software Foundation; either version 2 of the License, or
9 95ab4de9 David Knowles
# (at your option) any later version.
10 95ab4de9 David Knowles
#
11 95ab4de9 David Knowles
# This program is distributed in the hope that it will be useful, but
12 95ab4de9 David Knowles
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 95ab4de9 David Knowles
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 95ab4de9 David Knowles
# General Public License for more details.
15 95ab4de9 David Knowles
#
16 95ab4de9 David Knowles
# You should have received a copy of the GNU General Public License
17 95ab4de9 David Knowles
# along with this program; if not, write to the Free Software
18 95ab4de9 David Knowles
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 95ab4de9 David Knowles
# 02110-1301, USA.
20 95ab4de9 David Knowles
21 95ab4de9 David Knowles
22 95ab4de9 David Knowles
"""Script for unittesting the RAPI client module"""
23 95ab4de9 David Knowles
24 95ab4de9 David Knowles
25 95ab4de9 David Knowles
import re
26 95ab4de9 David Knowles
import unittest
27 95ab4de9 David Knowles
import warnings
28 2a7c3583 Michael Hanselmann
import pycurl
29 95ab4de9 David Knowles
30 2a7c3583 Michael Hanselmann
from ganeti import constants
31 95ab4de9 David Knowles
from ganeti import http
32 d9b67f70 Michael Hanselmann
from ganeti import serializer
33 70b0d2a2 Michael Hanselmann
from ganeti import utils
34 95ab4de9 David Knowles
35 95ab4de9 David Knowles
from ganeti.rapi import connector
36 95ab4de9 David Knowles
from ganeti.rapi import rlib2
37 9279e986 Michael Hanselmann
from ganeti.rapi import client
38 95ab4de9 David Knowles
39 95ab4de9 David Knowles
import testutils
40 95ab4de9 David Knowles
41 95ab4de9 David Knowles
42 95ab4de9 David Knowles
_URI_RE = re.compile(r"https://(?P<host>.*):(?P<port>\d+)(?P<path>/.*)")
43 95ab4de9 David Knowles
44 70b0d2a2 Michael Hanselmann
# List of resource handlers which aren't used by the RAPI client
45 70b0d2a2 Michael Hanselmann
_KNOWN_UNUSED = set([
46 70b0d2a2 Michael Hanselmann
  connector.R_root,
47 70b0d2a2 Michael Hanselmann
  connector.R_2,
48 70b0d2a2 Michael Hanselmann
  ])
49 70b0d2a2 Michael Hanselmann
50 70b0d2a2 Michael Hanselmann
# Global variable for collecting used handlers
51 70b0d2a2 Michael Hanselmann
_used_handlers = None
52 70b0d2a2 Michael Hanselmann
53 95ab4de9 David Knowles
54 95ab4de9 David Knowles
def _GetPathFromUri(uri):
55 95ab4de9 David Knowles
  """Gets the path and query from a URI.
56 95ab4de9 David Knowles

57 95ab4de9 David Knowles
  """
58 95ab4de9 David Knowles
  match = _URI_RE.match(uri)
59 95ab4de9 David Knowles
  if match:
60 95ab4de9 David Knowles
    return match.groupdict()["path"]
61 95ab4de9 David Knowles
  else:
62 95ab4de9 David Knowles
    return None
63 95ab4de9 David Knowles
64 95ab4de9 David Knowles
65 2a7c3583 Michael Hanselmann
class FakeCurl:
66 2a7c3583 Michael Hanselmann
  def __init__(self, rapi):
67 2a7c3583 Michael Hanselmann
    self._rapi = rapi
68 2a7c3583 Michael Hanselmann
    self._opts = {}
69 2a7c3583 Michael Hanselmann
    self._info = {}
70 9279e986 Michael Hanselmann
71 2a7c3583 Michael Hanselmann
  def setopt(self, opt, value):
72 2a7c3583 Michael Hanselmann
    self._opts[opt] = value
73 95ab4de9 David Knowles
74 2a7c3583 Michael Hanselmann
  def getopt(self, opt):
75 2a7c3583 Michael Hanselmann
    return self._opts.get(opt)
76 95ab4de9 David Knowles
77 2a7c3583 Michael Hanselmann
  def unsetopt(self, opt):
78 2a7c3583 Michael Hanselmann
    self._opts.pop(opt, None)
79 95ab4de9 David Knowles
80 2a7c3583 Michael Hanselmann
  def getinfo(self, info):
81 2a7c3583 Michael Hanselmann
    return self._info[info]
82 95ab4de9 David Knowles
83 2a7c3583 Michael Hanselmann
  def perform(self):
84 2a7c3583 Michael Hanselmann
    method = self._opts[pycurl.CUSTOMREQUEST]
85 2a7c3583 Michael Hanselmann
    url = self._opts[pycurl.URL]
86 2a7c3583 Michael Hanselmann
    request_body = self._opts[pycurl.POSTFIELDS]
87 2a7c3583 Michael Hanselmann
    writefn = self._opts[pycurl.WRITEFUNCTION]
88 95ab4de9 David Knowles
89 2a7c3583 Michael Hanselmann
    path = _GetPathFromUri(url)
90 2a7c3583 Michael Hanselmann
    (code, resp_body) = self._rapi.FetchResponse(path, method, request_body)
91 95ab4de9 David Knowles
92 2a7c3583 Michael Hanselmann
    self._info[pycurl.RESPONSE_CODE] = code
93 2a7c3583 Michael Hanselmann
    if resp_body is not None:
94 2a7c3583 Michael Hanselmann
      writefn(resp_body)
95 95ab4de9 David Knowles
96 95ab4de9 David Knowles
97 95ab4de9 David Knowles
class RapiMock(object):
98 95ab4de9 David Knowles
  def __init__(self):
99 95ab4de9 David Knowles
    self._mapper = connector.Mapper()
100 95ab4de9 David Knowles
    self._responses = []
101 95ab4de9 David Knowles
    self._last_handler = None
102 2a7c3583 Michael Hanselmann
    self._last_req_data = None
103 95ab4de9 David Knowles
104 de4f53e6 Michael Hanselmann
  def AddResponse(self, response, code=200):
105 de4f53e6 Michael Hanselmann
    self._responses.insert(0, (code, response))
106 95ab4de9 David Knowles
107 48436b97 Michael Hanselmann
  def CountPending(self):
108 48436b97 Michael Hanselmann
    return len(self._responses)
109 48436b97 Michael Hanselmann
110 95ab4de9 David Knowles
  def GetLastHandler(self):
111 95ab4de9 David Knowles
    return self._last_handler
112 95ab4de9 David Knowles
113 2a7c3583 Michael Hanselmann
  def GetLastRequestData(self):
114 2a7c3583 Michael Hanselmann
    return self._last_req_data
115 2a7c3583 Michael Hanselmann
116 2a7c3583 Michael Hanselmann
  def FetchResponse(self, path, method, request_body):
117 2a7c3583 Michael Hanselmann
    self._last_req_data = request_body
118 2a7c3583 Michael Hanselmann
119 95ab4de9 David Knowles
    try:
120 70b0d2a2 Michael Hanselmann
      (handler_cls, items, args) = self._mapper.getController(path)
121 70b0d2a2 Michael Hanselmann
122 70b0d2a2 Michael Hanselmann
      # Record handler as used
123 70b0d2a2 Michael Hanselmann
      _used_handlers.add(handler_cls)
124 70b0d2a2 Michael Hanselmann
125 70b0d2a2 Michael Hanselmann
      self._last_handler = handler_cls(items, args, None)
126 95ab4de9 David Knowles
      if not hasattr(self._last_handler, method.upper()):
127 de4f53e6 Michael Hanselmann
        raise http.HttpNotImplemented(message="Method not implemented")
128 de4f53e6 Michael Hanselmann
129 95ab4de9 David Knowles
    except http.HttpException, ex:
130 95ab4de9 David Knowles
      code = ex.code
131 95ab4de9 David Knowles
      response = ex.message
132 de4f53e6 Michael Hanselmann
    else:
133 de4f53e6 Michael Hanselmann
      if not self._responses:
134 de4f53e6 Michael Hanselmann
        raise Exception("No responses")
135 95ab4de9 David Knowles
136 de4f53e6 Michael Hanselmann
      (code, response) = self._responses.pop()
137 95ab4de9 David Knowles
138 95ab4de9 David Knowles
    return code, response
139 95ab4de9 David Knowles
140 95ab4de9 David Knowles
141 2a7c3583 Michael Hanselmann
class TestConstants(unittest.TestCase):
142 2a7c3583 Michael Hanselmann
  def test(self):
143 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_PORT, constants.DEFAULT_RAPI_PORT)
144 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION)
145 2a7c3583 Michael Hanselmann
    self.assertEqual(client.HTTP_APP_JSON, http.HTTP_APP_JSON)
146 2a7c3583 Michael Hanselmann
    self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION)
147 2a7c3583 Michael Hanselmann
    self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1)
148 c744425f Michael Hanselmann
    self.assertEqual(client._INST_REINSTALL_REQV1, rlib2._INST_REINSTALL_REQV1)
149 48436b97 Michael Hanselmann
    self.assertEqual(client._INST_NIC_PARAMS, constants.INIC_PARAMS)
150 2a7c3583 Michael Hanselmann
151 2a7c3583 Michael Hanselmann
152 95ab4de9 David Knowles
class RapiMockTest(unittest.TestCase):
153 95ab4de9 David Knowles
  def test(self):
154 95ab4de9 David Knowles
    rapi = RapiMock()
155 95ab4de9 David Knowles
    path = "/version"
156 2a7c3583 Michael Hanselmann
    self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None))
157 09127904 Michael Hanselmann
    self.assertEqual((501, "Method not implemented"),
158 2a7c3583 Michael Hanselmann
                     rapi.FetchResponse("/version", "POST", None))
159 95ab4de9 David Knowles
    rapi.AddResponse("2")
160 2a7c3583 Michael Hanselmann
    code, response = rapi.FetchResponse("/version", "GET", None)
161 95ab4de9 David Knowles
    self.assertEqual(200, code)
162 95ab4de9 David Knowles
    self.assertEqual("2", response)
163 95ab4de9 David Knowles
    self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version))
164 95ab4de9 David Knowles
165 95ab4de9 David Knowles
166 2a7c3583 Michael Hanselmann
def _FakeNoSslPycurlVersion():
167 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
168 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, None, 0)
169 2a7c3583 Michael Hanselmann
170 2a7c3583 Michael Hanselmann
171 2a7c3583 Michael Hanselmann
def _FakeFancySslPycurlVersion():
172 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
173 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, "FancySSL/1.2.3", 0)
174 2a7c3583 Michael Hanselmann
175 2a7c3583 Michael Hanselmann
176 2a7c3583 Michael Hanselmann
def _FakeOpenSslPycurlVersion():
177 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
178 2a7c3583 Michael Hanselmann
  return (2, "7.15.5", 462597, "othersystem", 668, "OpenSSL/0.9.8c", 0)
179 2a7c3583 Michael Hanselmann
180 2a7c3583 Michael Hanselmann
181 2a7c3583 Michael Hanselmann
def _FakeGnuTlsPycurlVersion():
182 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
183 2a7c3583 Michael Hanselmann
  return (3, "7.18.0", 463360, "somesystem", 1581, "GnuTLS/2.0.4", 0)
184 2a7c3583 Michael Hanselmann
185 2a7c3583 Michael Hanselmann
186 2a7c3583 Michael Hanselmann
class TestExtendedConfig(unittest.TestCase):
187 2a7c3583 Michael Hanselmann
  def testAuth(self):
188 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com",
189 2a7c3583 Michael Hanselmann
                                 username="user", password="pw",
190 a5eba783 Michael Hanselmann
                                 curl_factory=lambda: FakeCurl(RapiMock()))
191 2a7c3583 Michael Hanselmann
192 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
193 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.HTTPAUTH), pycurl.HTTPAUTH_BASIC)
194 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.USERPWD), "user:pw")
195 2a7c3583 Michael Hanselmann
196 2a7c3583 Michael Hanselmann
  def testInvalidAuth(self):
197 2a7c3583 Michael Hanselmann
    # No username
198 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
199 2a7c3583 Michael Hanselmann
                      "master-a.example.com", password="pw")
200 2a7c3583 Michael Hanselmann
    # No password
201 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
202 2a7c3583 Michael Hanselmann
                      "master-b.example.com", username="user")
203 2a7c3583 Michael Hanselmann
204 2a7c3583 Michael Hanselmann
  def testCertVerifyInvalidCombinations(self):
205 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
206 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, cafile="cert1.pem")
207 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
208 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, capath="certs/")
209 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
210 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True,
211 2a7c3583 Michael Hanselmann
                      cafile="cert1.pem", capath="certs/")
212 2a7c3583 Michael Hanselmann
213 2a7c3583 Michael Hanselmann
  def testProxySignalVerifyHostname(self):
214 2a7c3583 Michael Hanselmann
    for use_gnutls in [False, True]:
215 2a7c3583 Michael Hanselmann
      if use_gnutls:
216 2a7c3583 Michael Hanselmann
        pcverfn = _FakeGnuTlsPycurlVersion
217 2a7c3583 Michael Hanselmann
      else:
218 2a7c3583 Michael Hanselmann
        pcverfn = _FakeOpenSslPycurlVersion
219 2a7c3583 Michael Hanselmann
220 2a7c3583 Michael Hanselmann
      for proxy in ["", "http://127.0.0.1:1234"]:
221 2a7c3583 Michael Hanselmann
        for use_signal in [False, True]:
222 2a7c3583 Michael Hanselmann
          for verify_hostname in [False, True]:
223 2a7c3583 Michael Hanselmann
            cfgfn = client.GenericCurlConfig(proxy=proxy, use_signal=use_signal,
224 2a7c3583 Michael Hanselmann
                                             verify_hostname=verify_hostname,
225 2a7c3583 Michael Hanselmann
                                             _pycurl_version_fn=pcverfn)
226 2a7c3583 Michael Hanselmann
227 a5eba783 Michael Hanselmann
            curl_factory = lambda: FakeCurl(RapiMock())
228 2a7c3583 Michael Hanselmann
            cl = client.GanetiRapiClient("master.example.com",
229 a5eba783 Michael Hanselmann
                                         curl_config_fn=cfgfn,
230 a5eba783 Michael Hanselmann
                                         curl_factory=curl_factory)
231 2a7c3583 Michael Hanselmann
232 a5eba783 Michael Hanselmann
            curl = cl._CreateCurl()
233 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.PROXY), proxy)
234 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.NOSIGNAL), not use_signal)
235 2a7c3583 Michael Hanselmann
236 2a7c3583 Michael Hanselmann
            if verify_hostname:
237 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 2)
238 2a7c3583 Michael Hanselmann
            else:
239 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 0)
240 2a7c3583 Michael Hanselmann
241 2a7c3583 Michael Hanselmann
  def testNoCertVerify(self):
242 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig()
243 2a7c3583 Michael Hanselmann
244 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
245 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
246 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
247 2a7c3583 Michael Hanselmann
248 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
249 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.SSL_VERIFYPEER))
250 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
251 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
252 2a7c3583 Michael Hanselmann
253 2a7c3583 Michael Hanselmann
  def testCertVerifyCurlBundle(self):
254 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(use_curl_cabundle=True)
255 2a7c3583 Michael Hanselmann
256 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
257 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
258 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
259 2a7c3583 Michael Hanselmann
260 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
261 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
262 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
263 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
264 2a7c3583 Michael Hanselmann
265 2a7c3583 Michael Hanselmann
  def testCertVerifyCafile(self):
266 2a7c3583 Michael Hanselmann
    mycert = "/tmp/some/UNUSED/cert/file.pem"
267 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(cafile=mycert)
268 2a7c3583 Michael Hanselmann
269 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
270 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
271 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
272 2a7c3583 Michael Hanselmann
273 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
274 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
275 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAINFO), mycert)
276 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
277 2a7c3583 Michael Hanselmann
278 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
279 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
280 2a7c3583 Michael Hanselmann
    pcverfn = _FakeOpenSslPycurlVersion
281 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
282 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
283 2a7c3583 Michael Hanselmann
284 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
285 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
286 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
287 2a7c3583 Michael Hanselmann
288 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
289 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
290 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAPATH), certdir)
291 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
292 2a7c3583 Michael Hanselmann
293 2a7c3583 Michael Hanselmann
  def testCertVerifyCapathGnuTls(self):
294 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
295 2a7c3583 Michael Hanselmann
    pcverfn = _FakeGnuTlsPycurlVersion
296 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
297 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
298 2a7c3583 Michael Hanselmann
299 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
300 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
301 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
302 a5eba783 Michael Hanselmann
303 a5eba783 Michael Hanselmann
    self.assertRaises(client.Error, cl._CreateCurl)
304 2a7c3583 Michael Hanselmann
305 2a7c3583 Michael Hanselmann
  def testCertVerifyNoSsl(self):
306 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
307 2a7c3583 Michael Hanselmann
    pcverfn = _FakeNoSslPycurlVersion
308 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
309 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
310 2a7c3583 Michael Hanselmann
311 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
312 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
313 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
314 a5eba783 Michael Hanselmann
315 a5eba783 Michael Hanselmann
    self.assertRaises(client.Error, cl._CreateCurl)
316 2a7c3583 Michael Hanselmann
317 2a7c3583 Michael Hanselmann
  def testCertVerifyFancySsl(self):
318 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
319 2a7c3583 Michael Hanselmann
    pcverfn = _FakeFancySslPycurlVersion
320 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
321 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
322 2a7c3583 Michael Hanselmann
323 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
324 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
325 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
326 a5eba783 Michael Hanselmann
327 a5eba783 Michael Hanselmann
    self.assertRaises(NotImplementedError, cl._CreateCurl)
328 2a7c3583 Michael Hanselmann
329 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
330 2a7c3583 Michael Hanselmann
    for connect_timeout in [None, 1, 5, 10, 30, 60, 300]:
331 2a7c3583 Michael Hanselmann
      for timeout in [None, 1, 30, 60, 3600, 24 * 3600]:
332 2a7c3583 Michael Hanselmann
        cfgfn = client.GenericCurlConfig(connect_timeout=connect_timeout,
333 2a7c3583 Michael Hanselmann
                                         timeout=timeout)
334 2a7c3583 Michael Hanselmann
335 a5eba783 Michael Hanselmann
        curl_factory = lambda: FakeCurl(RapiMock())
336 2a7c3583 Michael Hanselmann
        cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
337 a5eba783 Michael Hanselmann
                                     curl_factory=curl_factory)
338 2a7c3583 Michael Hanselmann
339 a5eba783 Michael Hanselmann
        curl = cl._CreateCurl()
340 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.CONNECTTIMEOUT), connect_timeout)
341 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.TIMEOUT), timeout)
342 2a7c3583 Michael Hanselmann
343 2a7c3583 Michael Hanselmann
344 d9b67f70 Michael Hanselmann
class GanetiRapiClientTests(testutils.GanetiTestCase):
345 95ab4de9 David Knowles
  def setUp(self):
346 d9b67f70 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
347 d9b67f70 Michael Hanselmann
348 95ab4de9 David Knowles
    self.rapi = RapiMock()
349 2a7c3583 Michael Hanselmann
    self.curl = FakeCurl(self.rapi)
350 2a7c3583 Michael Hanselmann
    self.client = client.GanetiRapiClient("master.example.com",
351 a5eba783 Michael Hanselmann
                                          curl_factory=lambda: self.curl)
352 95ab4de9 David Knowles
353 95ab4de9 David Knowles
  def assertHandler(self, handler_cls):
354 95ab4de9 David Knowles
    self.failUnless(isinstance(self.rapi.GetLastHandler(), handler_cls))
355 95ab4de9 David Knowles
356 95ab4de9 David Knowles
  def assertQuery(self, key, value):
357 95ab4de9 David Knowles
    self.assertEqual(value, self.rapi.GetLastHandler().queryargs.get(key, None))
358 95ab4de9 David Knowles
359 95ab4de9 David Knowles
  def assertItems(self, items):
360 95ab4de9 David Knowles
    self.assertEqual(items, self.rapi.GetLastHandler().items)
361 95ab4de9 David Knowles
362 95ab4de9 David Knowles
  def assertBulk(self):
363 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().useBulk())
364 95ab4de9 David Knowles
365 95ab4de9 David Knowles
  def assertDryRun(self):
366 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().dryRun())
367 95ab4de9 David Knowles
368 4245446f Adeodato Simo
  def assertUseForce(self):
369 4245446f Adeodato Simo
    self.assertTrue(self.rapi.GetLastHandler().useForce())
370 4245446f Adeodato Simo
371 10f5ab6c Michael Hanselmann
  def testEncodeQuery(self):
372 10f5ab6c Michael Hanselmann
    query = [
373 10f5ab6c Michael Hanselmann
      ("a", None),
374 10f5ab6c Michael Hanselmann
      ("b", 1),
375 10f5ab6c Michael Hanselmann
      ("c", 2),
376 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
377 10f5ab6c Michael Hanselmann
      ("e", True),
378 10f5ab6c Michael Hanselmann
      ]
379 10f5ab6c Michael Hanselmann
380 10f5ab6c Michael Hanselmann
    expected = [
381 10f5ab6c Michael Hanselmann
      ("a", ""),
382 10f5ab6c Michael Hanselmann
      ("b", 1),
383 10f5ab6c Michael Hanselmann
      ("c", 2),
384 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
385 10f5ab6c Michael Hanselmann
      ("e", 1),
386 10f5ab6c Michael Hanselmann
      ]
387 10f5ab6c Michael Hanselmann
388 10f5ab6c Michael Hanselmann
    self.assertEqualValues(self.client._EncodeQuery(query),
389 10f5ab6c Michael Hanselmann
                           expected)
390 10f5ab6c Michael Hanselmann
391 10f5ab6c Michael Hanselmann
    # invalid types
392 10f5ab6c Michael Hanselmann
    for i in [[1, 2, 3], {"moo": "boo"}, (1, 2, 3)]:
393 10f5ab6c Michael Hanselmann
      self.assertRaises(ValueError, self.client._EncodeQuery, [("x", i)])
394 10f5ab6c Michael Hanselmann
395 a5eba783 Michael Hanselmann
  def testCurlSettings(self):
396 a5eba783 Michael Hanselmann
    self.rapi.AddResponse("2")
397 a5eba783 Michael Hanselmann
    self.assertEqual(2, self.client.GetVersion())
398 a5eba783 Michael Hanselmann
    self.assertHandler(rlib2.R_version)
399 a5eba783 Michael Hanselmann
400 a5eba783 Michael Hanselmann
    # Signals should be disabled by default
401 a5eba783 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.NOSIGNAL))
402 a5eba783 Michael Hanselmann
403 a5eba783 Michael Hanselmann
    # No auth and no proxy
404 a5eba783 Michael Hanselmann
    self.assertFalse(self.curl.getopt(pycurl.USERPWD))
405 a5eba783 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.PROXY) is None)
406 a5eba783 Michael Hanselmann
407 a5eba783 Michael Hanselmann
    # Content-type is required for requests
408 a5eba783 Michael Hanselmann
    headers = self.curl.getopt(pycurl.HTTPHEADER)
409 a5eba783 Michael Hanselmann
    self.assert_("Content-type: application/json" in headers)
410 a5eba783 Michael Hanselmann
411 8a019a03 Michael Hanselmann
  def testHttpError(self):
412 8a019a03 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
413 8a019a03 Michael Hanselmann
    try:
414 8a019a03 Michael Hanselmann
      self.client.GetJobStatus(15140)
415 8a019a03 Michael Hanselmann
    except client.GanetiApiError, err:
416 8a019a03 Michael Hanselmann
      self.assertEqual(err.code, 404)
417 8a019a03 Michael Hanselmann
    else:
418 8a019a03 Michael Hanselmann
      self.fail("Didn't raise exception")
419 8a019a03 Michael Hanselmann
420 95ab4de9 David Knowles
  def testGetVersion(self):
421 95ab4de9 David Knowles
    self.rapi.AddResponse("2")
422 95ab4de9 David Knowles
    self.assertEqual(2, self.client.GetVersion())
423 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_version)
424 95ab4de9 David Knowles
425 7eac4a4d Michael Hanselmann
  def testGetFeatures(self):
426 7eac4a4d Michael Hanselmann
    for features in [[], ["foo", "bar", "baz"]]:
427 7eac4a4d Michael Hanselmann
      self.rapi.AddResponse(serializer.DumpJson(features))
428 7eac4a4d Michael Hanselmann
      self.assertEqual(features, self.client.GetFeatures())
429 7eac4a4d Michael Hanselmann
      self.assertHandler(rlib2.R_2_features)
430 7eac4a4d Michael Hanselmann
431 48436b97 Michael Hanselmann
  def testGetFeaturesNotFound(self):
432 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
433 48436b97 Michael Hanselmann
    self.assertEqual([], self.client.GetFeatures())
434 48436b97 Michael Hanselmann
435 95ab4de9 David Knowles
  def testGetOperatingSystems(self):
436 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"beos\"]")
437 95ab4de9 David Knowles
    self.assertEqual(["beos"], self.client.GetOperatingSystems())
438 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_os)
439 95ab4de9 David Knowles
440 95ab4de9 David Knowles
  def testGetClusterTags(self):
441 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"tag\"]")
442 95ab4de9 David Knowles
    self.assertEqual(["tag"], self.client.GetClusterTags())
443 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
444 95ab4de9 David Knowles
445 95ab4de9 David Knowles
  def testAddClusterTags(self):
446 cab667cc David Knowles
    self.rapi.AddResponse("1234")
447 cab667cc David Knowles
    self.assertEqual(1234,
448 cab667cc David Knowles
        self.client.AddClusterTags(["awesome"], dry_run=True))
449 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
450 95ab4de9 David Knowles
    self.assertDryRun()
451 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
452 95ab4de9 David Knowles
453 95ab4de9 David Knowles
  def testDeleteClusterTags(self):
454 cd577680 Michael Hanselmann
    self.rapi.AddResponse("5107")
455 cd577680 Michael Hanselmann
    self.assertEqual(5107, self.client.DeleteClusterTags(["awesome"],
456 cd577680 Michael Hanselmann
                                                         dry_run=True))
457 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
458 95ab4de9 David Knowles
    self.assertDryRun()
459 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
460 95ab4de9 David Knowles
461 95ab4de9 David Knowles
  def testGetInfo(self):
462 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
463 95ab4de9 David Knowles
    self.assertEqual({}, self.client.GetInfo())
464 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_info)
465 95ab4de9 David Knowles
466 95ab4de9 David Knowles
  def testGetInstances(self):
467 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
468 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstances(bulk=True))
469 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
470 95ab4de9 David Knowles
    self.assertBulk()
471 95ab4de9 David Knowles
472 591e5103 Michael Hanselmann
  def testGetInstance(self):
473 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
474 591e5103 Michael Hanselmann
    self.assertEqual([], self.client.GetInstance("instance"))
475 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
476 95ab4de9 David Knowles
    self.assertItems(["instance"])
477 95ab4de9 David Knowles
478 591e5103 Michael Hanselmann
  def testGetInstanceInfo(self):
479 591e5103 Michael Hanselmann
    self.rapi.AddResponse("21291")
480 591e5103 Michael Hanselmann
    self.assertEqual(21291, self.client.GetInstanceInfo("inst3"))
481 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
482 591e5103 Michael Hanselmann
    self.assertItems(["inst3"])
483 591e5103 Michael Hanselmann
    self.assertQuery("static", None)
484 591e5103 Michael Hanselmann
485 591e5103 Michael Hanselmann
    self.rapi.AddResponse("3428")
486 591e5103 Michael Hanselmann
    self.assertEqual(3428, self.client.GetInstanceInfo("inst31", static=False))
487 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
488 591e5103 Michael Hanselmann
    self.assertItems(["inst31"])
489 591e5103 Michael Hanselmann
    self.assertQuery("static", ["0"])
490 591e5103 Michael Hanselmann
491 591e5103 Michael Hanselmann
    self.rapi.AddResponse("15665")
492 591e5103 Michael Hanselmann
    self.assertEqual(15665, self.client.GetInstanceInfo("inst32", static=True))
493 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
494 591e5103 Michael Hanselmann
    self.assertItems(["inst32"])
495 591e5103 Michael Hanselmann
    self.assertQuery("static", ["1"])
496 591e5103 Michael Hanselmann
497 8a47b447 Michael Hanselmann
  def testCreateInstanceOldVersion(self):
498 48436b97 Michael Hanselmann
    # No NICs
499 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
500 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
501 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [])
502 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
503 48436b97 Michael Hanselmann
504 48436b97 Michael Hanselmann
    # More than one NIC
505 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
506 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
507 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
508 48436b97 Michael Hanselmann
                      [{}, {}, {}])
509 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
510 48436b97 Michael Hanselmann
511 48436b97 Michael Hanselmann
    # Unsupported NIC fields
512 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
513 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
514 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
515 48436b97 Michael Hanselmann
                      [{"x": True, "y": False}])
516 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
517 48436b97 Michael Hanselmann
518 48436b97 Michael Hanselmann
    # Unsupported disk fields
519 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
520 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
521 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain",
522 48436b97 Michael Hanselmann
                      [{}, {"moo": "foo",}], [{}])
523 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
524 48436b97 Michael Hanselmann
525 48436b97 Michael Hanselmann
    # Unsupported fields
526 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
527 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
528 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
529 48436b97 Michael Hanselmann
                      hello_world=123)
530 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
531 48436b97 Michael Hanselmann
532 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
533 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
534 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
535 48436b97 Michael Hanselmann
                      memory=128)
536 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
537 48436b97 Michael Hanselmann
538 48436b97 Michael Hanselmann
    # Normal creation
539 48436b97 Michael Hanselmann
    testnics = [
540 48436b97 Michael Hanselmann
      [{}],
541 48436b97 Michael Hanselmann
      [{ "mac": constants.VALUE_AUTO, }],
542 48436b97 Michael Hanselmann
      [{ "ip": "192.0.2.99", "mode": constants.NIC_MODE_ROUTED, }],
543 48436b97 Michael Hanselmann
      ]
544 48436b97 Michael Hanselmann
545 48436b97 Michael Hanselmann
    testdisks = [
546 48436b97 Michael Hanselmann
      [],
547 48436b97 Michael Hanselmann
      [{ "size": 128, }],
548 48436b97 Michael Hanselmann
      [{ "size": 321, }, { "size": 4096, }],
549 48436b97 Michael Hanselmann
      ]
550 48436b97 Michael Hanselmann
551 48436b97 Michael Hanselmann
    for idx, nics in enumerate(testnics):
552 48436b97 Michael Hanselmann
      for disks in testdisks:
553 48436b97 Michael Hanselmann
        beparams = {
554 48436b97 Michael Hanselmann
          constants.BE_MEMORY: 512,
555 48436b97 Michael Hanselmann
          constants.BE_AUTO_BALANCE: False,
556 48436b97 Michael Hanselmann
          }
557 48436b97 Michael Hanselmann
        hvparams = {
558 48436b97 Michael Hanselmann
          constants.HV_MIGRATION_PORT: 9876,
559 48436b97 Michael Hanselmann
          constants.HV_VNC_TLS: True,
560 48436b97 Michael Hanselmann
          }
561 48436b97 Michael Hanselmann
562 48436b97 Michael Hanselmann
        self.rapi.AddResponse(None, code=404)
563 48436b97 Michael Hanselmann
        self.rapi.AddResponse(serializer.DumpJson(3122617 + idx))
564 48436b97 Michael Hanselmann
        job_id = self.client.CreateInstance("create", "inst1.example.com",
565 48436b97 Michael Hanselmann
                                            "plain", disks, nics,
566 48436b97 Michael Hanselmann
                                            pnode="node99", dry_run=True,
567 48436b97 Michael Hanselmann
                                            hvparams=hvparams,
568 48436b97 Michael Hanselmann
                                            beparams=beparams)
569 48436b97 Michael Hanselmann
        self.assertEqual(job_id, 3122617 + idx)
570 48436b97 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances)
571 48436b97 Michael Hanselmann
        self.assertDryRun()
572 48436b97 Michael Hanselmann
        self.assertEqual(self.rapi.CountPending(), 0)
573 48436b97 Michael Hanselmann
574 54dc4fdb Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
575 48436b97 Michael Hanselmann
        self.assertEqual(data["name"], "inst1.example.com")
576 48436b97 Michael Hanselmann
        self.assertEqual(data["disk_template"], "plain")
577 48436b97 Michael Hanselmann
        self.assertEqual(data["pnode"], "node99")
578 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_MEMORY], 512)
579 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_AUTO_BALANCE], False)
580 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_MIGRATION_PORT], 9876)
581 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_VNC_TLS], True)
582 48436b97 Michael Hanselmann
        self.assertEqual(data["disks"], [disk["size"] for disk in disks])
583 8a47b447 Michael Hanselmann
584 95ab4de9 David Knowles
  def testCreateInstance(self):
585 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
586 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("23030")
587 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("create", "inst1.example.com",
588 8a47b447 Michael Hanselmann
                                        "plain", [], [], dry_run=True)
589 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 23030)
590 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
591 95ab4de9 David Knowles
    self.assertDryRun()
592 95ab4de9 David Knowles
593 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
594 8a47b447 Michael Hanselmann
595 8a47b447 Michael Hanselmann
    for field in ["dry_run", "beparams", "hvparams", "start"]:
596 8a47b447 Michael Hanselmann
      self.assertFalse(field in data)
597 8a47b447 Michael Hanselmann
598 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst1.example.com")
599 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "plain")
600 8a47b447 Michael Hanselmann
601 8a47b447 Michael Hanselmann
  def testCreateInstance2(self):
602 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
603 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("24740")
604 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("import", "inst2.example.com",
605 8a47b447 Michael Hanselmann
                                        "drbd8", [{"size": 100,}],
606 8a47b447 Michael Hanselmann
                                        [{}, {"bridge": "br1", }],
607 8a47b447 Michael Hanselmann
                                        dry_run=False, start=True,
608 8a47b447 Michael Hanselmann
                                        pnode="node1", snode="node9",
609 8a47b447 Michael Hanselmann
                                        ip_check=False)
610 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 24740)
611 8a47b447 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances)
612 8a47b447 Michael Hanselmann
613 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
614 8a47b447 Michael Hanselmann
    self.assertEqual(data[rlib2._REQ_DATA_VERSION], 1)
615 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst2.example.com")
616 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "drbd8")
617 8a47b447 Michael Hanselmann
    self.assertEqual(data["start"], True)
618 8a47b447 Michael Hanselmann
    self.assertEqual(data["ip_check"], False)
619 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["disks"], [{"size": 100,}])
620 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["nics"], [{}, {"bridge": "br1", }])
621 8a47b447 Michael Hanselmann
622 95ab4de9 David Knowles
  def testDeleteInstance(self):
623 cab667cc David Knowles
    self.rapi.AddResponse("1234")
624 cab667cc David Knowles
    self.assertEqual(1234, self.client.DeleteInstance("instance", dry_run=True))
625 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
626 95ab4de9 David Knowles
    self.assertItems(["instance"])
627 95ab4de9 David Knowles
    self.assertDryRun()
628 95ab4de9 David Knowles
629 95ab4de9 David Knowles
  def testGetInstanceTags(self):
630 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
631 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstanceTags("fooinstance"))
632 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
633 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
634 95ab4de9 David Knowles
635 95ab4de9 David Knowles
  def testAddInstanceTags(self):
636 cab667cc David Knowles
    self.rapi.AddResponse("1234")
637 cab667cc David Knowles
    self.assertEqual(1234,
638 cab667cc David Knowles
        self.client.AddInstanceTags("fooinstance", ["awesome"], dry_run=True))
639 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
640 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
641 95ab4de9 David Knowles
    self.assertDryRun()
642 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
643 95ab4de9 David Knowles
644 95ab4de9 David Knowles
  def testDeleteInstanceTags(self):
645 cd577680 Michael Hanselmann
    self.rapi.AddResponse("25826")
646 cd577680 Michael Hanselmann
    self.assertEqual(25826, self.client.DeleteInstanceTags("foo", ["awesome"],
647 cd577680 Michael Hanselmann
                                                           dry_run=True))
648 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
649 95ab4de9 David Knowles
    self.assertItems(["foo"])
650 95ab4de9 David Knowles
    self.assertDryRun()
651 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
652 95ab4de9 David Knowles
653 95ab4de9 David Knowles
  def testRebootInstance(self):
654 cd577680 Michael Hanselmann
    self.rapi.AddResponse("6146")
655 cd577680 Michael Hanselmann
    job_id = self.client.RebootInstance("i-bar", reboot_type="hard",
656 cd577680 Michael Hanselmann
                                        ignore_secondaries=True, dry_run=True)
657 cd577680 Michael Hanselmann
    self.assertEqual(6146, job_id)
658 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reboot)
659 95ab4de9 David Knowles
    self.assertItems(["i-bar"])
660 95ab4de9 David Knowles
    self.assertDryRun()
661 95ab4de9 David Knowles
    self.assertQuery("type", ["hard"])
662 10f5ab6c Michael Hanselmann
    self.assertQuery("ignore_secondaries", ["1"])
663 95ab4de9 David Knowles
664 95ab4de9 David Knowles
  def testShutdownInstance(self):
665 cd577680 Michael Hanselmann
    self.rapi.AddResponse("1487")
666 cd577680 Michael Hanselmann
    self.assertEqual(1487, self.client.ShutdownInstance("foo-instance",
667 cd577680 Michael Hanselmann
                                                        dry_run=True))
668 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_shutdown)
669 95ab4de9 David Knowles
    self.assertItems(["foo-instance"])
670 95ab4de9 David Knowles
    self.assertDryRun()
671 95ab4de9 David Knowles
672 95ab4de9 David Knowles
  def testStartupInstance(self):
673 cd577680 Michael Hanselmann
    self.rapi.AddResponse("27149")
674 cd577680 Michael Hanselmann
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
675 cd577680 Michael Hanselmann
                                                        dry_run=True))
676 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_startup)
677 95ab4de9 David Knowles
    self.assertItems(["bar-instance"])
678 95ab4de9 David Knowles
    self.assertDryRun()
679 95ab4de9 David Knowles
680 95ab4de9 David Knowles
  def testReinstallInstance(self):
681 c744425f Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([]))
682 cd577680 Michael Hanselmann
    self.rapi.AddResponse("19119")
683 fcee9675 David Knowles
    self.assertEqual(19119, self.client.ReinstallInstance("baz-instance",
684 fcee9675 David Knowles
                                                          os="DOS",
685 cd577680 Michael Hanselmann
                                                          no_startup=True))
686 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
687 95ab4de9 David Knowles
    self.assertItems(["baz-instance"])
688 95ab4de9 David Knowles
    self.assertQuery("os", ["DOS"])
689 95ab4de9 David Knowles
    self.assertQuery("nostartup", ["1"])
690 c744425f Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
691 c744425f Michael Hanselmann
692 c744425f Michael Hanselmann
  def testReinstallInstanceNew(self):
693 c744425f Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_REINSTALL_REQV1]))
694 c744425f Michael Hanselmann
    self.rapi.AddResponse("25689")
695 c744425f Michael Hanselmann
    self.assertEqual(25689, self.client.ReinstallInstance("moo-instance",
696 c744425f Michael Hanselmann
                                                          os="Debian",
697 c744425f Michael Hanselmann
                                                          no_startup=True))
698 c744425f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
699 c744425f Michael Hanselmann
    self.assertItems(["moo-instance"])
700 c744425f Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
701 c744425f Michael Hanselmann
    self.assertEqual(len(data), 2)
702 c744425f Michael Hanselmann
    self.assertEqual(data["os"], "Debian")
703 c744425f Michael Hanselmann
    self.assertEqual(data["start"], False)
704 c744425f Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
705 c744425f Michael Hanselmann
706 c744425f Michael Hanselmann
  def testReinstallInstanceWithOsparams1(self):
707 c744425f Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([]))
708 c744425f Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.ReinstallInstance,
709 c744425f Michael Hanselmann
                      "doo-instance", osparams={"x": "y"})
710 c744425f Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
711 c744425f Michael Hanselmann
712 c744425f Michael Hanselmann
  def testReinstallInstanceWithOsparams2(self):
713 c744425f Michael Hanselmann
    osparams = {
714 c744425f Michael Hanselmann
      "Hello": "World",
715 c744425f Michael Hanselmann
      "foo": "bar",
716 c744425f Michael Hanselmann
      }
717 c744425f Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_REINSTALL_REQV1]))
718 c744425f Michael Hanselmann
    self.rapi.AddResponse("1717")
719 c744425f Michael Hanselmann
    self.assertEqual(1717, self.client.ReinstallInstance("zoo-instance",
720 c744425f Michael Hanselmann
                                                         osparams=osparams))
721 c744425f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
722 c744425f Michael Hanselmann
    self.assertItems(["zoo-instance"])
723 c744425f Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
724 c744425f Michael Hanselmann
    self.assertEqual(len(data), 2)
725 c744425f Michael Hanselmann
    self.assertEqual(data["osparams"], osparams)
726 c744425f Michael Hanselmann
    self.assertEqual(data["start"], True)
727 c744425f Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
728 95ab4de9 David Knowles
729 95ab4de9 David Knowles
  def testReplaceInstanceDisks(self):
730 95ab4de9 David Knowles
    self.rapi.AddResponse("999")
731 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-name",
732 bfc2002f Michael Hanselmann
        disks=[0, 1], dry_run=True, iallocator="hail")
733 95ab4de9 David Knowles
    self.assertEqual(999, job_id)
734 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_replace_disks)
735 95ab4de9 David Knowles
    self.assertItems(["instance-name"])
736 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["0,1"])
737 95ab4de9 David Knowles
    self.assertQuery("mode", ["replace_auto"])
738 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
739 95ab4de9 David Knowles
    self.assertDryRun()
740 95ab4de9 David Knowles
741 95ab4de9 David Knowles
    self.rapi.AddResponse("1000")
742 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-bar",
743 bfc2002f Michael Hanselmann
        disks=[1], mode="replace_on_secondary", remote_node="foo-node",
744 95ab4de9 David Knowles
        dry_run=True)
745 95ab4de9 David Knowles
    self.assertEqual(1000, job_id)
746 95ab4de9 David Knowles
    self.assertItems(["instance-bar"])
747 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["1"])
748 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["foo-node"])
749 95ab4de9 David Knowles
    self.assertDryRun()
750 95ab4de9 David Knowles
751 bfc2002f Michael Hanselmann
    self.rapi.AddResponse("5175")
752 bfc2002f Michael Hanselmann
    self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo"))
753 bfc2002f Michael Hanselmann
    self.assertItems(["instance-moo"])
754 bfc2002f Michael Hanselmann
    self.assertQuery("disks", None)
755 bfc2002f Michael Hanselmann
756 ebeb600f Michael Hanselmann
  def testPrepareExport(self):
757 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("8326")
758 ebeb600f Michael Hanselmann
    self.assertEqual(8326, self.client.PrepareExport("inst1", "local"))
759 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_prepare_export)
760 ebeb600f Michael Hanselmann
    self.assertItems(["inst1"])
761 ebeb600f Michael Hanselmann
    self.assertQuery("mode", ["local"])
762 ebeb600f Michael Hanselmann
763 ebeb600f Michael Hanselmann
  def testExportInstance(self):
764 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("19695")
765 ebeb600f Michael Hanselmann
    job_id = self.client.ExportInstance("inst2", "local", "nodeX",
766 ebeb600f Michael Hanselmann
                                        shutdown=True)
767 ebeb600f Michael Hanselmann
    self.assertEqual(job_id, 19695)
768 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_export)
769 ebeb600f Michael Hanselmann
    self.assertItems(["inst2"])
770 ebeb600f Michael Hanselmann
771 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
772 ebeb600f Michael Hanselmann
    self.assertEqual(data["mode"], "local")
773 ebeb600f Michael Hanselmann
    self.assertEqual(data["destination"], "nodeX")
774 ebeb600f Michael Hanselmann
    self.assertEqual(data["shutdown"], True)
775 ebeb600f Michael Hanselmann
776 e0ac6ce6 Michael Hanselmann
  def testMigrateInstanceDefaults(self):
777 e0ac6ce6 Michael Hanselmann
    self.rapi.AddResponse("24873")
778 e0ac6ce6 Michael Hanselmann
    job_id = self.client.MigrateInstance("inst91")
779 e0ac6ce6 Michael Hanselmann
    self.assertEqual(job_id, 24873)
780 e0ac6ce6 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_migrate)
781 e0ac6ce6 Michael Hanselmann
    self.assertItems(["inst91"])
782 e0ac6ce6 Michael Hanselmann
783 e0ac6ce6 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
784 e0ac6ce6 Michael Hanselmann
    self.assertFalse(data)
785 e0ac6ce6 Michael Hanselmann
786 e0ac6ce6 Michael Hanselmann
  def testMigrateInstance(self):
787 e0ac6ce6 Michael Hanselmann
    for mode in constants.HT_MIGRATION_MODES:
788 e0ac6ce6 Michael Hanselmann
      for cleanup in [False, True]:
789 e0ac6ce6 Michael Hanselmann
        self.rapi.AddResponse("31910")
790 e0ac6ce6 Michael Hanselmann
        job_id = self.client.MigrateInstance("inst289", mode=mode,
791 e0ac6ce6 Michael Hanselmann
                                             cleanup=cleanup)
792 e0ac6ce6 Michael Hanselmann
        self.assertEqual(job_id, 31910)
793 e0ac6ce6 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances_name_migrate)
794 e0ac6ce6 Michael Hanselmann
        self.assertItems(["inst289"])
795 e0ac6ce6 Michael Hanselmann
796 e0ac6ce6 Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
797 e0ac6ce6 Michael Hanselmann
        self.assertEqual(len(data), 2)
798 e0ac6ce6 Michael Hanselmann
        self.assertEqual(data["mode"], mode)
799 e0ac6ce6 Michael Hanselmann
        self.assertEqual(data["cleanup"], cleanup)
800 e0ac6ce6 Michael Hanselmann
801 d654aae1 Michael Hanselmann
  def testRenameInstanceDefaults(self):
802 d654aae1 Michael Hanselmann
    new_name = "newnametha7euqu"
803 d654aae1 Michael Hanselmann
    self.rapi.AddResponse("8791")
804 d654aae1 Michael Hanselmann
    job_id = self.client.RenameInstance("inst18821", new_name)
805 d654aae1 Michael Hanselmann
    self.assertEqual(job_id, 8791)
806 d654aae1 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_rename)
807 d654aae1 Michael Hanselmann
    self.assertItems(["inst18821"])
808 d654aae1 Michael Hanselmann
809 d654aae1 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
810 d654aae1 Michael Hanselmann
    self.assertEqualValues(data, {"new_name": new_name, })
811 d654aae1 Michael Hanselmann
812 d654aae1 Michael Hanselmann
  def testRenameInstance(self):
813 d654aae1 Michael Hanselmann
    new_name = "new-name-yiux1iin"
814 d654aae1 Michael Hanselmann
    for ip_check in [False, True]:
815 d654aae1 Michael Hanselmann
      for name_check in [False, True]:
816 d654aae1 Michael Hanselmann
        self.rapi.AddResponse("24776")
817 d654aae1 Michael Hanselmann
        job_id = self.client.RenameInstance("inst20967", new_name,
818 d654aae1 Michael Hanselmann
                                             ip_check=ip_check,
819 d654aae1 Michael Hanselmann
                                             name_check=name_check)
820 d654aae1 Michael Hanselmann
        self.assertEqual(job_id, 24776)
821 d654aae1 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances_name_rename)
822 d654aae1 Michael Hanselmann
        self.assertItems(["inst20967"])
823 d654aae1 Michael Hanselmann
824 d654aae1 Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
825 d654aae1 Michael Hanselmann
        self.assertEqual(len(data), 3)
826 d654aae1 Michael Hanselmann
        self.assertEqual(data["new_name"], new_name)
827 d654aae1 Michael Hanselmann
        self.assertEqual(data["ip_check"], ip_check)
828 d654aae1 Michael Hanselmann
        self.assertEqual(data["name_check"], name_check)
829 d654aae1 Michael Hanselmann
830 95ab4de9 David Knowles
  def testGetJobs(self):
831 2004e673 Iustin Pop
    self.rapi.AddResponse('[ { "id": "123", "uri": "\\/2\\/jobs\\/123" },'
832 2004e673 Iustin Pop
                          '  { "id": "124", "uri": "\\/2\\/jobs\\/124" } ]')
833 95ab4de9 David Knowles
    self.assertEqual([123, 124], self.client.GetJobs())
834 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs)
835 95ab4de9 David Knowles
836 95ab4de9 David Knowles
  def testGetJobStatus(self):
837 95ab4de9 David Knowles
    self.rapi.AddResponse("{\"foo\": \"bar\"}")
838 95ab4de9 David Knowles
    self.assertEqual({"foo": "bar"}, self.client.GetJobStatus(1234))
839 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
840 95ab4de9 David Knowles
    self.assertItems(["1234"])
841 95ab4de9 David Knowles
842 d9b67f70 Michael Hanselmann
  def testWaitForJobChange(self):
843 d9b67f70 Michael Hanselmann
    fields = ["id", "summary"]
844 d9b67f70 Michael Hanselmann
    expected = {
845 d9b67f70 Michael Hanselmann
      "job_info": [123, "something"],
846 d9b67f70 Michael Hanselmann
      "log_entries": [],
847 d9b67f70 Michael Hanselmann
      }
848 d9b67f70 Michael Hanselmann
849 d9b67f70 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson(expected))
850 d9b67f70 Michael Hanselmann
    result = self.client.WaitForJobChange(123, fields, [], -1)
851 d9b67f70 Michael Hanselmann
    self.assertEqualValues(expected, result)
852 d9b67f70 Michael Hanselmann
    self.assertHandler(rlib2.R_2_jobs_id_wait)
853 d9b67f70 Michael Hanselmann
    self.assertItems(["123"])
854 d9b67f70 Michael Hanselmann
855 cf9ada49 Michael Hanselmann
  def testCancelJob(self):
856 cd577680 Michael Hanselmann
    self.rapi.AddResponse("[true, \"Job 123 will be canceled\"]")
857 cd577680 Michael Hanselmann
    self.assertEqual([True, "Job 123 will be canceled"],
858 cf9ada49 Michael Hanselmann
                     self.client.CancelJob(999, dry_run=True))
859 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
860 95ab4de9 David Knowles
    self.assertItems(["999"])
861 95ab4de9 David Knowles
    self.assertDryRun()
862 95ab4de9 David Knowles
863 95ab4de9 David Knowles
  def testGetNodes(self):
864 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
865 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
866 95ab4de9 David Knowles
    self.assertEqual(["node1", "node2"], self.client.GetNodes())
867 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
868 95ab4de9 David Knowles
869 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
870 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
871 95ab4de9 David Knowles
    self.assertEqual([{"id": "node1", "uri": "uri1"},
872 95ab4de9 David Knowles
                      {"id": "node2", "uri": "uri2"}],
873 95ab4de9 David Knowles
                     self.client.GetNodes(bulk=True))
874 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
875 95ab4de9 David Knowles
    self.assertBulk()
876 95ab4de9 David Knowles
877 591e5103 Michael Hanselmann
  def testGetNode(self):
878 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
879 591e5103 Michael Hanselmann
    self.assertEqual({}, self.client.GetNode("node-foo"))
880 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name)
881 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
882 95ab4de9 David Knowles
883 95ab4de9 David Knowles
  def testEvacuateNode(self):
884 95ab4de9 David Knowles
    self.rapi.AddResponse("9876")
885 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-1", remote_node="node-2")
886 95ab4de9 David Knowles
    self.assertEqual(9876, job_id)
887 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_evacuate)
888 95ab4de9 David Knowles
    self.assertItems(["node-1"])
889 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["node-2"])
890 95ab4de9 David Knowles
891 95ab4de9 David Knowles
    self.rapi.AddResponse("8888")
892 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True)
893 95ab4de9 David Knowles
    self.assertEqual(8888, job_id)
894 95ab4de9 David Knowles
    self.assertItems(["node-3"])
895 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
896 95ab4de9 David Knowles
    self.assertDryRun()
897 95ab4de9 David Knowles
898 95ab4de9 David Knowles
    self.assertRaises(client.GanetiApiError,
899 95ab4de9 David Knowles
                      self.client.EvacuateNode,
900 95ab4de9 David Knowles
                      "node-4", iallocator="hail", remote_node="node-5")
901 95ab4de9 David Knowles
902 95ab4de9 David Knowles
  def testMigrateNode(self):
903 95ab4de9 David Knowles
    self.rapi.AddResponse("1111")
904 95ab4de9 David Knowles
    self.assertEqual(1111, self.client.MigrateNode("node-a", dry_run=True))
905 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
906 95ab4de9 David Knowles
    self.assertItems(["node-a"])
907 1f334d96 Iustin Pop
    self.assert_("mode" not in self.rapi.GetLastHandler().queryargs)
908 1f334d96 Iustin Pop
    self.assertDryRun()
909 1f334d96 Iustin Pop
910 1f334d96 Iustin Pop
    self.rapi.AddResponse("1112")
911 1f334d96 Iustin Pop
    self.assertEqual(1112, self.client.MigrateNode("node-a", dry_run=True,
912 1f334d96 Iustin Pop
                                                   mode="live"))
913 1f334d96 Iustin Pop
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
914 1f334d96 Iustin Pop
    self.assertItems(["node-a"])
915 1f334d96 Iustin Pop
    self.assertQuery("mode", ["live"])
916 95ab4de9 David Knowles
    self.assertDryRun()
917 95ab4de9 David Knowles
918 95ab4de9 David Knowles
  def testGetNodeRole(self):
919 95ab4de9 David Knowles
    self.rapi.AddResponse("\"master\"")
920 95ab4de9 David Knowles
    self.assertEqual("master", self.client.GetNodeRole("node-a"))
921 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
922 95ab4de9 David Knowles
    self.assertItems(["node-a"])
923 95ab4de9 David Knowles
924 95ab4de9 David Knowles
  def testSetNodeRole(self):
925 95ab4de9 David Knowles
    self.rapi.AddResponse("789")
926 95ab4de9 David Knowles
    self.assertEqual(789,
927 95ab4de9 David Knowles
        self.client.SetNodeRole("node-foo", "master-candidate", force=True))
928 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
929 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
930 10f5ab6c Michael Hanselmann
    self.assertQuery("force", ["1"])
931 2a7c3583 Michael Hanselmann
    self.assertEqual("\"master-candidate\"", self.rapi.GetLastRequestData())
932 95ab4de9 David Knowles
933 95ab4de9 David Knowles
  def testGetNodeStorageUnits(self):
934 95ab4de9 David Knowles
    self.rapi.AddResponse("42")
935 95ab4de9 David Knowles
    self.assertEqual(42,
936 95ab4de9 David Knowles
        self.client.GetNodeStorageUnits("node-x", "lvm-pv", "fields"))
937 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage)
938 95ab4de9 David Knowles
    self.assertItems(["node-x"])
939 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
940 95ab4de9 David Knowles
    self.assertQuery("output_fields", ["fields"])
941 95ab4de9 David Knowles
942 95ab4de9 David Knowles
  def testModifyNodeStorageUnits(self):
943 95ab4de9 David Knowles
    self.rapi.AddResponse("14")
944 95ab4de9 David Knowles
    self.assertEqual(14,
945 95ab4de9 David Knowles
        self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda"))
946 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
947 95ab4de9 David Knowles
    self.assertItems(["node-z"])
948 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
949 95ab4de9 David Knowles
    self.assertQuery("name", ["hda"])
950 fde28316 Michael Hanselmann
    self.assertQuery("allocatable", None)
951 fde28316 Michael Hanselmann
952 fde28316 Michael Hanselmann
    for allocatable, query_allocatable in [(True, "1"), (False, "0")]:
953 fde28316 Michael Hanselmann
      self.rapi.AddResponse("7205")
954 fde28316 Michael Hanselmann
      job_id = self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda",
955 fde28316 Michael Hanselmann
                                                  allocatable=allocatable)
956 fde28316 Michael Hanselmann
      self.assertEqual(7205, job_id)
957 fde28316 Michael Hanselmann
      self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
958 fde28316 Michael Hanselmann
      self.assertItems(["node-z"])
959 fde28316 Michael Hanselmann
      self.assertQuery("storage_type", ["lvm-pv"])
960 fde28316 Michael Hanselmann
      self.assertQuery("name", ["hda"])
961 fde28316 Michael Hanselmann
      self.assertQuery("allocatable", [query_allocatable])
962 95ab4de9 David Knowles
963 752df8bb Michael Hanselmann
  def testRepairNodeStorageUnits(self):
964 752df8bb Michael Hanselmann
    self.rapi.AddResponse("99")
965 752df8bb Michael Hanselmann
    self.assertEqual(99, self.client.RepairNodeStorageUnits("node-z", "lvm-pv",
966 752df8bb Michael Hanselmann
                                                            "hda"))
967 752df8bb Michael Hanselmann
    self.assertHandler(rlib2.R_2_nodes_name_storage_repair)
968 752df8bb Michael Hanselmann
    self.assertItems(["node-z"])
969 752df8bb Michael Hanselmann
    self.assertQuery("storage_type", ["lvm-pv"])
970 752df8bb Michael Hanselmann
    self.assertQuery("name", ["hda"])
971 752df8bb Michael Hanselmann
972 95ab4de9 David Knowles
  def testGetNodeTags(self):
973 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"fry\", \"bender\"]")
974 95ab4de9 David Knowles
    self.assertEqual(["fry", "bender"], self.client.GetNodeTags("node-k"))
975 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
976 95ab4de9 David Knowles
    self.assertItems(["node-k"])
977 95ab4de9 David Knowles
978 95ab4de9 David Knowles
  def testAddNodeTags(self):
979 cab667cc David Knowles
    self.rapi.AddResponse("1234")
980 cab667cc David Knowles
    self.assertEqual(1234,
981 cab667cc David Knowles
        self.client.AddNodeTags("node-v", ["awesome"], dry_run=True))
982 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
983 95ab4de9 David Knowles
    self.assertItems(["node-v"])
984 95ab4de9 David Knowles
    self.assertDryRun()
985 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
986 95ab4de9 David Knowles
987 95ab4de9 David Knowles
  def testDeleteNodeTags(self):
988 cd577680 Michael Hanselmann
    self.rapi.AddResponse("16861")
989 cd577680 Michael Hanselmann
    self.assertEqual(16861, self.client.DeleteNodeTags("node-w", ["awesome"],
990 cd577680 Michael Hanselmann
                                                       dry_run=True))
991 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
992 95ab4de9 David Knowles
    self.assertItems(["node-w"])
993 95ab4de9 David Knowles
    self.assertDryRun()
994 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
995 95ab4de9 David Knowles
996 a268af8d Adeodato Simo
  def testGetGroups(self):
997 a268af8d Adeodato Simo
    groups = [{"name": "group1",
998 a268af8d Adeodato Simo
               "uri": "/2/groups/group1",
999 a268af8d Adeodato Simo
               },
1000 a268af8d Adeodato Simo
              {"name": "group2",
1001 a268af8d Adeodato Simo
               "uri": "/2/groups/group2",
1002 a268af8d Adeodato Simo
               },
1003 a268af8d Adeodato Simo
              ]
1004 a268af8d Adeodato Simo
    self.rapi.AddResponse(serializer.DumpJson(groups))
1005 a268af8d Adeodato Simo
    self.assertEqual(["group1", "group2"], self.client.GetGroups())
1006 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups)
1007 a268af8d Adeodato Simo
1008 a268af8d Adeodato Simo
  def testGetGroupsBulk(self):
1009 a268af8d Adeodato Simo
    groups = [{"name": "group1",
1010 a268af8d Adeodato Simo
               "uri": "/2/groups/group1",
1011 a268af8d Adeodato Simo
               "node_cnt": 2,
1012 a268af8d Adeodato Simo
               "node_list": ["gnt1.test",
1013 a268af8d Adeodato Simo
                             "gnt2.test",
1014 a268af8d Adeodato Simo
                             ],
1015 a268af8d Adeodato Simo
               },
1016 a268af8d Adeodato Simo
              {"name": "group2",
1017 a268af8d Adeodato Simo
               "uri": "/2/groups/group2",
1018 a268af8d Adeodato Simo
               "node_cnt": 1,
1019 a268af8d Adeodato Simo
               "node_list": ["gnt3.test",
1020 a268af8d Adeodato Simo
                             ],
1021 a268af8d Adeodato Simo
               },
1022 a268af8d Adeodato Simo
              ]
1023 a268af8d Adeodato Simo
    self.rapi.AddResponse(serializer.DumpJson(groups))
1024 a268af8d Adeodato Simo
1025 a268af8d Adeodato Simo
    self.assertEqual(groups, self.client.GetGroups(bulk=True))
1026 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups)
1027 a268af8d Adeodato Simo
    self.assertBulk()
1028 a268af8d Adeodato Simo
1029 a268af8d Adeodato Simo
  def testGetGroup(self):
1030 a268af8d Adeodato Simo
    group = {"ctime": None,
1031 a268af8d Adeodato Simo
             "name": "default",
1032 a268af8d Adeodato Simo
             }
1033 a268af8d Adeodato Simo
    self.rapi.AddResponse(serializer.DumpJson(group))
1034 a268af8d Adeodato Simo
    self.assertEqual({"ctime": None, "name": "default"},
1035 a268af8d Adeodato Simo
                     self.client.GetGroup("default"))
1036 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups_name)
1037 a268af8d Adeodato Simo
    self.assertItems(["default"])
1038 a268af8d Adeodato Simo
1039 a268af8d Adeodato Simo
  def testCreateGroup(self):
1040 a268af8d Adeodato Simo
    self.rapi.AddResponse("12345")
1041 a268af8d Adeodato Simo
    job_id = self.client.CreateGroup("newgroup", dry_run=True)
1042 a268af8d Adeodato Simo
    self.assertEqual(job_id, 12345)
1043 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups)
1044 a268af8d Adeodato Simo
    self.assertDryRun()
1045 a268af8d Adeodato Simo
1046 a268af8d Adeodato Simo
  def testDeleteGroup(self):
1047 a268af8d Adeodato Simo
    self.rapi.AddResponse("12346")
1048 a268af8d Adeodato Simo
    job_id = self.client.DeleteGroup("newgroup", dry_run=True)
1049 a268af8d Adeodato Simo
    self.assertEqual(job_id, 12346)
1050 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups_name)
1051 a268af8d Adeodato Simo
    self.assertDryRun()
1052 a268af8d Adeodato Simo
1053 a268af8d Adeodato Simo
  def testRenameGroup(self):
1054 a268af8d Adeodato Simo
    self.rapi.AddResponse("12347")
1055 a268af8d Adeodato Simo
    job_id = self.client.RenameGroup("oldname", "newname")
1056 a268af8d Adeodato Simo
    self.assertEqual(job_id, 12347)
1057 a268af8d Adeodato Simo
    self.assertHandler(rlib2.R_2_groups_name_rename)
1058 a268af8d Adeodato Simo
1059 7187e6ff Adeodato Simo
  def testModifyGroup(self):
1060 7187e6ff Adeodato Simo
    self.rapi.AddResponse("12348")
1061 7187e6ff Adeodato Simo
    job_id = self.client.ModifyGroup("mygroup", alloc_policy="foo")
1062 7187e6ff Adeodato Simo
    self.assertEqual(job_id, 12348)
1063 7187e6ff Adeodato Simo
    self.assertHandler(rlib2.R_2_groups_name_modify)
1064 7187e6ff Adeodato Simo
1065 4245446f Adeodato Simo
  def testAssignGroupNodes(self):
1066 4245446f Adeodato Simo
    self.rapi.AddResponse("12349")
1067 4245446f Adeodato Simo
    job_id = self.client.AssignGroupNodes("mygroup", ["node1", "node2"],
1068 4245446f Adeodato Simo
                                          force=True, dry_run=True)
1069 4245446f Adeodato Simo
    self.assertEqual(job_id, 12349)
1070 4245446f Adeodato Simo
    self.assertHandler(rlib2.R_2_groups_name_assign_nodes)
1071 4245446f Adeodato Simo
    self.assertDryRun()
1072 4245446f Adeodato Simo
    self.assertUseForce()
1073 4245446f Adeodato Simo
1074 08c11c40 Michael Hanselmann
  def testModifyInstance(self):
1075 08c11c40 Michael Hanselmann
    self.rapi.AddResponse("23681")
1076 08c11c40 Michael Hanselmann
    job_id = self.client.ModifyInstance("inst7210", os_name="linux")
1077 08c11c40 Michael Hanselmann
    self.assertEqual(job_id, 23681)
1078 08c11c40 Michael Hanselmann
    self.assertItems(["inst7210"])
1079 08c11c40 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_modify)
1080 08c11c40 Michael Hanselmann
    self.assertEqual(serializer.LoadJson(self.rapi.GetLastRequestData()),
1081 08c11c40 Michael Hanselmann
                     { "os_name": "linux", })
1082 08c11c40 Michael Hanselmann
1083 62e999a5 Michael Hanselmann
  def testModifyCluster(self):
1084 62e999a5 Michael Hanselmann
    for mnh in [None, False, True]:
1085 62e999a5 Michael Hanselmann
      self.rapi.AddResponse("14470")
1086 62e999a5 Michael Hanselmann
      self.assertEqual(14470,
1087 62e999a5 Michael Hanselmann
        self.client.ModifyCluster(maintain_node_health=mnh))
1088 62e999a5 Michael Hanselmann
      self.assertHandler(rlib2.R_2_cluster_modify)
1089 62e999a5 Michael Hanselmann
      self.assertItems([])
1090 62e999a5 Michael Hanselmann
      data = serializer.LoadJson(self.rapi.GetLastRequestData())
1091 62e999a5 Michael Hanselmann
      self.assertEqual(len(data), 1)
1092 62e999a5 Michael Hanselmann
      self.assertEqual(data["maintain_node_health"], mnh)
1093 62e999a5 Michael Hanselmann
      self.assertEqual(self.rapi.CountPending(), 0)
1094 62e999a5 Michael Hanselmann
1095 54d4c13b Michael Hanselmann
  def testRedistributeConfig(self):
1096 54d4c13b Michael Hanselmann
    self.rapi.AddResponse("3364")
1097 54d4c13b Michael Hanselmann
    job_id = self.client.RedistributeConfig()
1098 54d4c13b Michael Hanselmann
    self.assertEqual(job_id, 3364)
1099 54d4c13b Michael Hanselmann
    self.assertItems([])
1100 54d4c13b Michael Hanselmann
    self.assertHandler(rlib2.R_2_redist_config)
1101 54d4c13b Michael Hanselmann
1102 b680c8be Michael Hanselmann
  def testActivateInstanceDisks(self):
1103 b680c8be Michael Hanselmann
    self.rapi.AddResponse("23547")
1104 b680c8be Michael Hanselmann
    job_id = self.client.ActivateInstanceDisks("inst28204")
1105 b680c8be Michael Hanselmann
    self.assertEqual(job_id, 23547)
1106 b680c8be Michael Hanselmann
    self.assertItems(["inst28204"])
1107 b680c8be Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_activate_disks)
1108 b680c8be Michael Hanselmann
    self.assertFalse(self.rapi.GetLastHandler().queryargs)
1109 b680c8be Michael Hanselmann
1110 b680c8be Michael Hanselmann
  def testActivateInstanceDisksIgnoreSize(self):
1111 b680c8be Michael Hanselmann
    self.rapi.AddResponse("11044")
1112 b680c8be Michael Hanselmann
    job_id = self.client.ActivateInstanceDisks("inst28204", ignore_size=True)
1113 b680c8be Michael Hanselmann
    self.assertEqual(job_id, 11044)
1114 b680c8be Michael Hanselmann
    self.assertItems(["inst28204"])
1115 b680c8be Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_activate_disks)
1116 b680c8be Michael Hanselmann
    self.assertQuery("ignore_size", ["1"])
1117 b680c8be Michael Hanselmann
1118 b680c8be Michael Hanselmann
  def testDeactivateInstanceDisks(self):
1119 b680c8be Michael Hanselmann
    self.rapi.AddResponse("14591")
1120 b680c8be Michael Hanselmann
    job_id = self.client.DeactivateInstanceDisks("inst28234")
1121 b680c8be Michael Hanselmann
    self.assertEqual(job_id, 14591)
1122 b680c8be Michael Hanselmann
    self.assertItems(["inst28234"])
1123 b680c8be Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_deactivate_disks)
1124 b680c8be Michael Hanselmann
    self.assertFalse(self.rapi.GetLastHandler().queryargs)
1125 b680c8be Michael Hanselmann
1126 b82d4c5e Michael Hanselmann
  def testGetInstanceConsole(self):
1127 b82d4c5e Michael Hanselmann
    self.rapi.AddResponse("26876")
1128 b82d4c5e Michael Hanselmann
    job_id = self.client.GetInstanceConsole("inst21491")
1129 b82d4c5e Michael Hanselmann
    self.assertEqual(job_id, 26876)
1130 b82d4c5e Michael Hanselmann
    self.assertItems(["inst21491"])
1131 b82d4c5e Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_console)
1132 b82d4c5e Michael Hanselmann
    self.assertFalse(self.rapi.GetLastHandler().queryargs)
1133 b82d4c5e Michael Hanselmann
    self.assertFalse(self.rapi.GetLastRequestData())
1134 b82d4c5e Michael Hanselmann
1135 e23881ed Michael Hanselmann
  def testGrowInstanceDisk(self):
1136 e23881ed Michael Hanselmann
    for idx, wait_for_sync in enumerate([None, False, True]):
1137 e23881ed Michael Hanselmann
      amount = 128 + (512 * idx)
1138 e23881ed Michael Hanselmann
      self.assertEqual(self.rapi.CountPending(), 0)
1139 e23881ed Michael Hanselmann
      self.rapi.AddResponse("30783")
1140 e23881ed Michael Hanselmann
      self.assertEqual(30783,
1141 e23881ed Michael Hanselmann
        self.client.GrowInstanceDisk("eze8ch", idx, amount,
1142 e23881ed Michael Hanselmann
                                     wait_for_sync=wait_for_sync))
1143 e23881ed Michael Hanselmann
      self.assertHandler(rlib2.R_2_instances_name_disk_grow)
1144 e23881ed Michael Hanselmann
      self.assertItems(["eze8ch", str(idx)])
1145 e23881ed Michael Hanselmann
      data = serializer.LoadJson(self.rapi.GetLastRequestData())
1146 e23881ed Michael Hanselmann
      if wait_for_sync is None:
1147 e23881ed Michael Hanselmann
        self.assertEqual(len(data), 1)
1148 e23881ed Michael Hanselmann
        self.assert_("wait_for_sync" not in data)
1149 e23881ed Michael Hanselmann
      else:
1150 e23881ed Michael Hanselmann
        self.assertEqual(len(data), 2)
1151 e23881ed Michael Hanselmann
        self.assertEqual(data["wait_for_sync"], wait_for_sync)
1152 e23881ed Michael Hanselmann
      self.assertEqual(data["amount"], amount)
1153 e23881ed Michael Hanselmann
      self.assertEqual(self.rapi.CountPending(), 0)
1154 e23881ed Michael Hanselmann
1155 95ab4de9 David Knowles
1156 70b0d2a2 Michael Hanselmann
class RapiTestRunner(unittest.TextTestRunner):
1157 70b0d2a2 Michael Hanselmann
  def run(self, *args):
1158 70b0d2a2 Michael Hanselmann
    global _used_handlers
1159 70b0d2a2 Michael Hanselmann
    assert _used_handlers is None
1160 70b0d2a2 Michael Hanselmann
1161 70b0d2a2 Michael Hanselmann
    _used_handlers = set()
1162 70b0d2a2 Michael Hanselmann
    try:
1163 70b0d2a2 Michael Hanselmann
      # Run actual tests
1164 70b0d2a2 Michael Hanselmann
      result = unittest.TextTestRunner.run(self, *args)
1165 70b0d2a2 Michael Hanselmann
1166 70b0d2a2 Michael Hanselmann
      diff = (set(connector.CONNECTOR.values()) - _used_handlers -
1167 70b0d2a2 Michael Hanselmann
             _KNOWN_UNUSED)
1168 70b0d2a2 Michael Hanselmann
      if diff:
1169 70b0d2a2 Michael Hanselmann
        raise AssertionError("The following RAPI resources were not used by the"
1170 70b0d2a2 Michael Hanselmann
                             " RAPI client: %r" % utils.CommaJoin(diff))
1171 70b0d2a2 Michael Hanselmann
    finally:
1172 70b0d2a2 Michael Hanselmann
      # Reset global variable
1173 70b0d2a2 Michael Hanselmann
      _used_handlers = None
1174 70b0d2a2 Michael Hanselmann
1175 70b0d2a2 Michael Hanselmann
    return result
1176 70b0d2a2 Michael Hanselmann
1177 70b0d2a2 Michael Hanselmann
1178 95ab4de9 David Knowles
if __name__ == '__main__':
1179 70b0d2a2 Michael Hanselmann
  client.UsesRapiClient(testutils.GanetiTestProgram)(testRunner=RapiTestRunner)