Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.client_unittest.py @ 5823e0d2

History | View | Annotate | Download (31 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 95ab4de9 David Knowles
34 95ab4de9 David Knowles
from ganeti.rapi import connector
35 95ab4de9 David Knowles
from ganeti.rapi import rlib2
36 9279e986 Michael Hanselmann
from ganeti.rapi import client
37 95ab4de9 David Knowles
38 95ab4de9 David Knowles
import testutils
39 95ab4de9 David Knowles
40 95ab4de9 David Knowles
41 95ab4de9 David Knowles
_URI_RE = re.compile(r"https://(?P<host>.*):(?P<port>\d+)(?P<path>/.*)")
42 95ab4de9 David Knowles
43 95ab4de9 David Knowles
44 95ab4de9 David Knowles
def _GetPathFromUri(uri):
45 95ab4de9 David Knowles
  """Gets the path and query from a URI.
46 95ab4de9 David Knowles

47 95ab4de9 David Knowles
  """
48 95ab4de9 David Knowles
  match = _URI_RE.match(uri)
49 95ab4de9 David Knowles
  if match:
50 95ab4de9 David Knowles
    return match.groupdict()["path"]
51 95ab4de9 David Knowles
  else:
52 95ab4de9 David Knowles
    return None
53 95ab4de9 David Knowles
54 95ab4de9 David Knowles
55 2a7c3583 Michael Hanselmann
class FakeCurl:
56 2a7c3583 Michael Hanselmann
  def __init__(self, rapi):
57 2a7c3583 Michael Hanselmann
    self._rapi = rapi
58 2a7c3583 Michael Hanselmann
    self._opts = {}
59 2a7c3583 Michael Hanselmann
    self._info = {}
60 9279e986 Michael Hanselmann
61 2a7c3583 Michael Hanselmann
  def setopt(self, opt, value):
62 2a7c3583 Michael Hanselmann
    self._opts[opt] = value
63 95ab4de9 David Knowles
64 2a7c3583 Michael Hanselmann
  def getopt(self, opt):
65 2a7c3583 Michael Hanselmann
    return self._opts.get(opt)
66 95ab4de9 David Knowles
67 2a7c3583 Michael Hanselmann
  def unsetopt(self, opt):
68 2a7c3583 Michael Hanselmann
    self._opts.pop(opt, None)
69 95ab4de9 David Knowles
70 2a7c3583 Michael Hanselmann
  def getinfo(self, info):
71 2a7c3583 Michael Hanselmann
    return self._info[info]
72 95ab4de9 David Knowles
73 2a7c3583 Michael Hanselmann
  def perform(self):
74 2a7c3583 Michael Hanselmann
    method = self._opts[pycurl.CUSTOMREQUEST]
75 2a7c3583 Michael Hanselmann
    url = self._opts[pycurl.URL]
76 2a7c3583 Michael Hanselmann
    request_body = self._opts[pycurl.POSTFIELDS]
77 2a7c3583 Michael Hanselmann
    writefn = self._opts[pycurl.WRITEFUNCTION]
78 95ab4de9 David Knowles
79 2a7c3583 Michael Hanselmann
    path = _GetPathFromUri(url)
80 2a7c3583 Michael Hanselmann
    (code, resp_body) = self._rapi.FetchResponse(path, method, request_body)
81 95ab4de9 David Knowles
82 2a7c3583 Michael Hanselmann
    self._info[pycurl.RESPONSE_CODE] = code
83 2a7c3583 Michael Hanselmann
    if resp_body is not None:
84 2a7c3583 Michael Hanselmann
      writefn(resp_body)
85 95ab4de9 David Knowles
86 95ab4de9 David Knowles
87 95ab4de9 David Knowles
class RapiMock(object):
88 95ab4de9 David Knowles
  def __init__(self):
89 95ab4de9 David Knowles
    self._mapper = connector.Mapper()
90 95ab4de9 David Knowles
    self._responses = []
91 95ab4de9 David Knowles
    self._last_handler = None
92 2a7c3583 Michael Hanselmann
    self._last_req_data = None
93 95ab4de9 David Knowles
94 de4f53e6 Michael Hanselmann
  def AddResponse(self, response, code=200):
95 de4f53e6 Michael Hanselmann
    self._responses.insert(0, (code, response))
96 95ab4de9 David Knowles
97 48436b97 Michael Hanselmann
  def CountPending(self):
98 48436b97 Michael Hanselmann
    return len(self._responses)
99 48436b97 Michael Hanselmann
100 95ab4de9 David Knowles
  def GetLastHandler(self):
101 95ab4de9 David Knowles
    return self._last_handler
102 95ab4de9 David Knowles
103 2a7c3583 Michael Hanselmann
  def GetLastRequestData(self):
104 2a7c3583 Michael Hanselmann
    return self._last_req_data
105 2a7c3583 Michael Hanselmann
106 2a7c3583 Michael Hanselmann
  def FetchResponse(self, path, method, request_body):
107 2a7c3583 Michael Hanselmann
    self._last_req_data = request_body
108 2a7c3583 Michael Hanselmann
109 95ab4de9 David Knowles
    try:
110 95ab4de9 David Knowles
      HandlerClass, items, args = self._mapper.getController(path)
111 95ab4de9 David Knowles
      self._last_handler = HandlerClass(items, args, None)
112 95ab4de9 David Knowles
      if not hasattr(self._last_handler, method.upper()):
113 de4f53e6 Michael Hanselmann
        raise http.HttpNotImplemented(message="Method not implemented")
114 de4f53e6 Michael Hanselmann
115 95ab4de9 David Knowles
    except http.HttpException, ex:
116 95ab4de9 David Knowles
      code = ex.code
117 95ab4de9 David Knowles
      response = ex.message
118 de4f53e6 Michael Hanselmann
    else:
119 de4f53e6 Michael Hanselmann
      if not self._responses:
120 de4f53e6 Michael Hanselmann
        raise Exception("No responses")
121 95ab4de9 David Knowles
122 de4f53e6 Michael Hanselmann
      (code, response) = self._responses.pop()
123 95ab4de9 David Knowles
124 95ab4de9 David Knowles
    return code, response
125 95ab4de9 David Knowles
126 95ab4de9 David Knowles
127 2a7c3583 Michael Hanselmann
class TestConstants(unittest.TestCase):
128 2a7c3583 Michael Hanselmann
  def test(self):
129 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_PORT, constants.DEFAULT_RAPI_PORT)
130 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION)
131 2a7c3583 Michael Hanselmann
    self.assertEqual(client.HTTP_APP_JSON, http.HTTP_APP_JSON)
132 2a7c3583 Michael Hanselmann
    self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION)
133 2a7c3583 Michael Hanselmann
    self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1)
134 48436b97 Michael Hanselmann
    self.assertEqual(client._INST_NIC_PARAMS, constants.INIC_PARAMS)
135 2a7c3583 Michael Hanselmann
136 2a7c3583 Michael Hanselmann
137 95ab4de9 David Knowles
class RapiMockTest(unittest.TestCase):
138 95ab4de9 David Knowles
  def test(self):
139 95ab4de9 David Knowles
    rapi = RapiMock()
140 95ab4de9 David Knowles
    path = "/version"
141 2a7c3583 Michael Hanselmann
    self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None))
142 09127904 Michael Hanselmann
    self.assertEqual((501, "Method not implemented"),
143 2a7c3583 Michael Hanselmann
                     rapi.FetchResponse("/version", "POST", None))
144 95ab4de9 David Knowles
    rapi.AddResponse("2")
145 2a7c3583 Michael Hanselmann
    code, response = rapi.FetchResponse("/version", "GET", None)
146 95ab4de9 David Knowles
    self.assertEqual(200, code)
147 95ab4de9 David Knowles
    self.assertEqual("2", response)
148 95ab4de9 David Knowles
    self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version))
149 95ab4de9 David Knowles
150 95ab4de9 David Knowles
151 2a7c3583 Michael Hanselmann
def _FakeNoSslPycurlVersion():
152 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
153 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, None, 0)
154 2a7c3583 Michael Hanselmann
155 2a7c3583 Michael Hanselmann
156 2a7c3583 Michael Hanselmann
def _FakeFancySslPycurlVersion():
157 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
158 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, "FancySSL/1.2.3", 0)
159 2a7c3583 Michael Hanselmann
160 2a7c3583 Michael Hanselmann
161 2a7c3583 Michael Hanselmann
def _FakeOpenSslPycurlVersion():
162 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
163 2a7c3583 Michael Hanselmann
  return (2, "7.15.5", 462597, "othersystem", 668, "OpenSSL/0.9.8c", 0)
164 2a7c3583 Michael Hanselmann
165 2a7c3583 Michael Hanselmann
166 2a7c3583 Michael Hanselmann
def _FakeGnuTlsPycurlVersion():
167 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
168 2a7c3583 Michael Hanselmann
  return (3, "7.18.0", 463360, "somesystem", 1581, "GnuTLS/2.0.4", 0)
169 2a7c3583 Michael Hanselmann
170 2a7c3583 Michael Hanselmann
171 2a7c3583 Michael Hanselmann
class TestExtendedConfig(unittest.TestCase):
172 2a7c3583 Michael Hanselmann
  def testAuth(self):
173 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
174 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com",
175 2a7c3583 Michael Hanselmann
                                 username="user", password="pw",
176 2a7c3583 Michael Hanselmann
                                 curl=curl)
177 2a7c3583 Michael Hanselmann
178 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.HTTPAUTH), pycurl.HTTPAUTH_BASIC)
179 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.USERPWD), "user:pw")
180 2a7c3583 Michael Hanselmann
181 2a7c3583 Michael Hanselmann
  def testInvalidAuth(self):
182 2a7c3583 Michael Hanselmann
    # No username
183 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
184 2a7c3583 Michael Hanselmann
                      "master-a.example.com", password="pw")
185 2a7c3583 Michael Hanselmann
    # No password
186 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
187 2a7c3583 Michael Hanselmann
                      "master-b.example.com", username="user")
188 2a7c3583 Michael Hanselmann
189 2a7c3583 Michael Hanselmann
  def testCertVerifyInvalidCombinations(self):
190 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
191 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, cafile="cert1.pem")
192 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
193 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, capath="certs/")
194 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
195 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True,
196 2a7c3583 Michael Hanselmann
                      cafile="cert1.pem", capath="certs/")
197 2a7c3583 Michael Hanselmann
198 2a7c3583 Michael Hanselmann
  def testProxySignalVerifyHostname(self):
199 2a7c3583 Michael Hanselmann
    for use_gnutls in [False, True]:
200 2a7c3583 Michael Hanselmann
      if use_gnutls:
201 2a7c3583 Michael Hanselmann
        pcverfn = _FakeGnuTlsPycurlVersion
202 2a7c3583 Michael Hanselmann
      else:
203 2a7c3583 Michael Hanselmann
        pcverfn = _FakeOpenSslPycurlVersion
204 2a7c3583 Michael Hanselmann
205 2a7c3583 Michael Hanselmann
      for proxy in ["", "http://127.0.0.1:1234"]:
206 2a7c3583 Michael Hanselmann
        for use_signal in [False, True]:
207 2a7c3583 Michael Hanselmann
          for verify_hostname in [False, True]:
208 2a7c3583 Michael Hanselmann
            cfgfn = client.GenericCurlConfig(proxy=proxy, use_signal=use_signal,
209 2a7c3583 Michael Hanselmann
                                             verify_hostname=verify_hostname,
210 2a7c3583 Michael Hanselmann
                                             _pycurl_version_fn=pcverfn)
211 2a7c3583 Michael Hanselmann
212 2a7c3583 Michael Hanselmann
            curl = FakeCurl(RapiMock())
213 2a7c3583 Michael Hanselmann
            cl = client.GanetiRapiClient("master.example.com",
214 2a7c3583 Michael Hanselmann
                                         curl_config_fn=cfgfn, curl=curl)
215 2a7c3583 Michael Hanselmann
216 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.PROXY), proxy)
217 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.NOSIGNAL), not use_signal)
218 2a7c3583 Michael Hanselmann
219 2a7c3583 Michael Hanselmann
            if verify_hostname:
220 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 2)
221 2a7c3583 Michael Hanselmann
            else:
222 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 0)
223 2a7c3583 Michael Hanselmann
224 2a7c3583 Michael Hanselmann
  def testNoCertVerify(self):
225 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig()
226 2a7c3583 Michael Hanselmann
227 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
228 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
229 2a7c3583 Michael Hanselmann
                                 curl=curl)
230 2a7c3583 Michael Hanselmann
231 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.SSL_VERIFYPEER))
232 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
233 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
234 2a7c3583 Michael Hanselmann
235 2a7c3583 Michael Hanselmann
  def testCertVerifyCurlBundle(self):
236 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(use_curl_cabundle=True)
237 2a7c3583 Michael Hanselmann
238 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
239 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
240 2a7c3583 Michael Hanselmann
                                 curl=curl)
241 2a7c3583 Michael Hanselmann
242 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
243 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
244 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
245 2a7c3583 Michael Hanselmann
246 2a7c3583 Michael Hanselmann
  def testCertVerifyCafile(self):
247 2a7c3583 Michael Hanselmann
    mycert = "/tmp/some/UNUSED/cert/file.pem"
248 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(cafile=mycert)
249 2a7c3583 Michael Hanselmann
250 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
251 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
252 2a7c3583 Michael Hanselmann
                                 curl=curl)
253 2a7c3583 Michael Hanselmann
254 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
255 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAINFO), mycert)
256 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
257 2a7c3583 Michael Hanselmann
258 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
259 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
260 2a7c3583 Michael Hanselmann
    pcverfn = _FakeOpenSslPycurlVersion
261 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
262 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
263 2a7c3583 Michael Hanselmann
264 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
265 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
266 2a7c3583 Michael Hanselmann
                                 curl=curl)
267 2a7c3583 Michael Hanselmann
268 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
269 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAPATH), certdir)
270 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
271 2a7c3583 Michael Hanselmann
272 2a7c3583 Michael Hanselmann
  def testCertVerifyCapathGnuTls(self):
273 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
274 2a7c3583 Michael Hanselmann
    pcverfn = _FakeGnuTlsPycurlVersion
275 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
276 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
277 2a7c3583 Michael Hanselmann
278 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
279 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
280 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
281 2a7c3583 Michael Hanselmann
282 2a7c3583 Michael Hanselmann
  def testCertVerifyNoSsl(self):
283 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
284 2a7c3583 Michael Hanselmann
    pcverfn = _FakeNoSslPycurlVersion
285 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
286 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
287 2a7c3583 Michael Hanselmann
288 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
289 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
290 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
291 2a7c3583 Michael Hanselmann
292 2a7c3583 Michael Hanselmann
  def testCertVerifyFancySsl(self):
293 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
294 2a7c3583 Michael Hanselmann
    pcverfn = _FakeFancySslPycurlVersion
295 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
296 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
297 2a7c3583 Michael Hanselmann
298 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
299 2a7c3583 Michael Hanselmann
    self.assertRaises(NotImplementedError, client.GanetiRapiClient,
300 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
301 2a7c3583 Michael Hanselmann
302 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
303 2a7c3583 Michael Hanselmann
    for connect_timeout in [None, 1, 5, 10, 30, 60, 300]:
304 2a7c3583 Michael Hanselmann
      for timeout in [None, 1, 30, 60, 3600, 24 * 3600]:
305 2a7c3583 Michael Hanselmann
        cfgfn = client.GenericCurlConfig(connect_timeout=connect_timeout,
306 2a7c3583 Michael Hanselmann
                                         timeout=timeout)
307 2a7c3583 Michael Hanselmann
308 2a7c3583 Michael Hanselmann
        curl = FakeCurl(RapiMock())
309 2a7c3583 Michael Hanselmann
        cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
310 2a7c3583 Michael Hanselmann
                                     curl=curl)
311 2a7c3583 Michael Hanselmann
312 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.CONNECTTIMEOUT), connect_timeout)
313 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.TIMEOUT), timeout)
314 2a7c3583 Michael Hanselmann
315 2a7c3583 Michael Hanselmann
316 d9b67f70 Michael Hanselmann
class GanetiRapiClientTests(testutils.GanetiTestCase):
317 95ab4de9 David Knowles
  def setUp(self):
318 d9b67f70 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
319 d9b67f70 Michael Hanselmann
320 95ab4de9 David Knowles
    self.rapi = RapiMock()
321 2a7c3583 Michael Hanselmann
    self.curl = FakeCurl(self.rapi)
322 2a7c3583 Michael Hanselmann
    self.client = client.GanetiRapiClient("master.example.com",
323 2a7c3583 Michael Hanselmann
                                          curl=self.curl)
324 2a7c3583 Michael Hanselmann
325 2a7c3583 Michael Hanselmann
    # Signals should be disabled by default
326 2a7c3583 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.NOSIGNAL))
327 2a7c3583 Michael Hanselmann
328 2a7c3583 Michael Hanselmann
    # No auth and no proxy
329 2a7c3583 Michael Hanselmann
    self.assertFalse(self.curl.getopt(pycurl.USERPWD))
330 2a7c3583 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.PROXY) is None)
331 2a7c3583 Michael Hanselmann
332 2a7c3583 Michael Hanselmann
    # Content-type is required for requests
333 2a7c3583 Michael Hanselmann
    headers = self.curl.getopt(pycurl.HTTPHEADER)
334 2a7c3583 Michael Hanselmann
    self.assert_("Content-type: application/json" in headers)
335 95ab4de9 David Knowles
336 95ab4de9 David Knowles
  def assertHandler(self, handler_cls):
337 95ab4de9 David Knowles
    self.failUnless(isinstance(self.rapi.GetLastHandler(), handler_cls))
338 95ab4de9 David Knowles
339 95ab4de9 David Knowles
  def assertQuery(self, key, value):
340 95ab4de9 David Knowles
    self.assertEqual(value, self.rapi.GetLastHandler().queryargs.get(key, None))
341 95ab4de9 David Knowles
342 95ab4de9 David Knowles
  def assertItems(self, items):
343 95ab4de9 David Knowles
    self.assertEqual(items, self.rapi.GetLastHandler().items)
344 95ab4de9 David Knowles
345 95ab4de9 David Knowles
  def assertBulk(self):
346 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().useBulk())
347 95ab4de9 David Knowles
348 95ab4de9 David Knowles
  def assertDryRun(self):
349 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().dryRun())
350 95ab4de9 David Knowles
351 10f5ab6c Michael Hanselmann
  def testEncodeQuery(self):
352 10f5ab6c Michael Hanselmann
    query = [
353 10f5ab6c Michael Hanselmann
      ("a", None),
354 10f5ab6c Michael Hanselmann
      ("b", 1),
355 10f5ab6c Michael Hanselmann
      ("c", 2),
356 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
357 10f5ab6c Michael Hanselmann
      ("e", True),
358 10f5ab6c Michael Hanselmann
      ]
359 10f5ab6c Michael Hanselmann
360 10f5ab6c Michael Hanselmann
    expected = [
361 10f5ab6c Michael Hanselmann
      ("a", ""),
362 10f5ab6c Michael Hanselmann
      ("b", 1),
363 10f5ab6c Michael Hanselmann
      ("c", 2),
364 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
365 10f5ab6c Michael Hanselmann
      ("e", 1),
366 10f5ab6c Michael Hanselmann
      ]
367 10f5ab6c Michael Hanselmann
368 10f5ab6c Michael Hanselmann
    self.assertEqualValues(self.client._EncodeQuery(query),
369 10f5ab6c Michael Hanselmann
                           expected)
370 10f5ab6c Michael Hanselmann
371 10f5ab6c Michael Hanselmann
    # invalid types
372 10f5ab6c Michael Hanselmann
    for i in [[1, 2, 3], {"moo": "boo"}, (1, 2, 3)]:
373 10f5ab6c Michael Hanselmann
      self.assertRaises(ValueError, self.client._EncodeQuery, [("x", i)])
374 10f5ab6c Michael Hanselmann
375 8a019a03 Michael Hanselmann
  def testHttpError(self):
376 8a019a03 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
377 8a019a03 Michael Hanselmann
    try:
378 8a019a03 Michael Hanselmann
      self.client.GetJobStatus(15140)
379 8a019a03 Michael Hanselmann
    except client.GanetiApiError, err:
380 8a019a03 Michael Hanselmann
      self.assertEqual(err.code, 404)
381 8a019a03 Michael Hanselmann
    else:
382 8a019a03 Michael Hanselmann
      self.fail("Didn't raise exception")
383 8a019a03 Michael Hanselmann
384 95ab4de9 David Knowles
  def testGetVersion(self):
385 95ab4de9 David Knowles
    self.client._version = None
386 95ab4de9 David Knowles
    self.rapi.AddResponse("2")
387 95ab4de9 David Knowles
    self.assertEqual(2, self.client.GetVersion())
388 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_version)
389 95ab4de9 David Knowles
390 7eac4a4d Michael Hanselmann
  def testGetFeatures(self):
391 7eac4a4d Michael Hanselmann
    for features in [[], ["foo", "bar", "baz"]]:
392 7eac4a4d Michael Hanselmann
      self.rapi.AddResponse(serializer.DumpJson(features))
393 7eac4a4d Michael Hanselmann
      self.assertEqual(features, self.client.GetFeatures())
394 7eac4a4d Michael Hanselmann
      self.assertHandler(rlib2.R_2_features)
395 7eac4a4d Michael Hanselmann
396 48436b97 Michael Hanselmann
  def testGetFeaturesNotFound(self):
397 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
398 48436b97 Michael Hanselmann
    self.assertEqual([], self.client.GetFeatures())
399 48436b97 Michael Hanselmann
400 95ab4de9 David Knowles
  def testGetOperatingSystems(self):
401 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"beos\"]")
402 95ab4de9 David Knowles
    self.assertEqual(["beos"], self.client.GetOperatingSystems())
403 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_os)
404 95ab4de9 David Knowles
405 95ab4de9 David Knowles
  def testGetClusterTags(self):
406 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"tag\"]")
407 95ab4de9 David Knowles
    self.assertEqual(["tag"], self.client.GetClusterTags())
408 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
409 95ab4de9 David Knowles
410 95ab4de9 David Knowles
  def testAddClusterTags(self):
411 cab667cc David Knowles
    self.rapi.AddResponse("1234")
412 cab667cc David Knowles
    self.assertEqual(1234,
413 cab667cc David Knowles
        self.client.AddClusterTags(["awesome"], dry_run=True))
414 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
415 95ab4de9 David Knowles
    self.assertDryRun()
416 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
417 95ab4de9 David Knowles
418 95ab4de9 David Knowles
  def testDeleteClusterTags(self):
419 cd577680 Michael Hanselmann
    self.rapi.AddResponse("5107")
420 cd577680 Michael Hanselmann
    self.assertEqual(5107, self.client.DeleteClusterTags(["awesome"],
421 cd577680 Michael Hanselmann
                                                         dry_run=True))
422 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
423 95ab4de9 David Knowles
    self.assertDryRun()
424 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
425 95ab4de9 David Knowles
426 95ab4de9 David Knowles
  def testGetInfo(self):
427 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
428 95ab4de9 David Knowles
    self.assertEqual({}, self.client.GetInfo())
429 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_info)
430 95ab4de9 David Knowles
431 95ab4de9 David Knowles
  def testGetInstances(self):
432 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
433 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstances(bulk=True))
434 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
435 95ab4de9 David Knowles
    self.assertBulk()
436 95ab4de9 David Knowles
437 591e5103 Michael Hanselmann
  def testGetInstance(self):
438 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
439 591e5103 Michael Hanselmann
    self.assertEqual([], self.client.GetInstance("instance"))
440 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
441 95ab4de9 David Knowles
    self.assertItems(["instance"])
442 95ab4de9 David Knowles
443 591e5103 Michael Hanselmann
  def testGetInstanceInfo(self):
444 591e5103 Michael Hanselmann
    self.rapi.AddResponse("21291")
445 591e5103 Michael Hanselmann
    self.assertEqual(21291, self.client.GetInstanceInfo("inst3"))
446 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
447 591e5103 Michael Hanselmann
    self.assertItems(["inst3"])
448 591e5103 Michael Hanselmann
    self.assertQuery("static", None)
449 591e5103 Michael Hanselmann
450 591e5103 Michael Hanselmann
    self.rapi.AddResponse("3428")
451 591e5103 Michael Hanselmann
    self.assertEqual(3428, self.client.GetInstanceInfo("inst31", static=False))
452 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
453 591e5103 Michael Hanselmann
    self.assertItems(["inst31"])
454 591e5103 Michael Hanselmann
    self.assertQuery("static", ["0"])
455 591e5103 Michael Hanselmann
456 591e5103 Michael Hanselmann
    self.rapi.AddResponse("15665")
457 591e5103 Michael Hanselmann
    self.assertEqual(15665, self.client.GetInstanceInfo("inst32", static=True))
458 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
459 591e5103 Michael Hanselmann
    self.assertItems(["inst32"])
460 591e5103 Michael Hanselmann
    self.assertQuery("static", ["1"])
461 591e5103 Michael Hanselmann
462 8a47b447 Michael Hanselmann
  def testCreateInstanceOldVersion(self):
463 48436b97 Michael Hanselmann
    # No NICs
464 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
465 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
466 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [])
467 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
468 48436b97 Michael Hanselmann
469 48436b97 Michael Hanselmann
    # More than one NIC
470 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
471 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
472 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
473 48436b97 Michael Hanselmann
                      [{}, {}, {}])
474 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
475 48436b97 Michael Hanselmann
476 48436b97 Michael Hanselmann
    # Unsupported NIC fields
477 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
478 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
479 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
480 48436b97 Michael Hanselmann
                      [{"x": True, "y": False}])
481 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
482 48436b97 Michael Hanselmann
483 48436b97 Michael Hanselmann
    # Unsupported disk fields
484 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
485 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
486 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain",
487 48436b97 Michael Hanselmann
                      [{}, {"moo": "foo",}], [{}])
488 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
489 48436b97 Michael Hanselmann
490 48436b97 Michael Hanselmann
    # Unsupported fields
491 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
492 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
493 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
494 48436b97 Michael Hanselmann
                      hello_world=123)
495 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
496 48436b97 Michael Hanselmann
497 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
498 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
499 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
500 48436b97 Michael Hanselmann
                      memory=128)
501 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
502 48436b97 Michael Hanselmann
503 48436b97 Michael Hanselmann
    # Normal creation
504 48436b97 Michael Hanselmann
    testnics = [
505 48436b97 Michael Hanselmann
      [{}],
506 48436b97 Michael Hanselmann
      [{ "mac": constants.VALUE_AUTO, }],
507 48436b97 Michael Hanselmann
      [{ "ip": "192.0.2.99", "mode": constants.NIC_MODE_ROUTED, }],
508 48436b97 Michael Hanselmann
      ]
509 48436b97 Michael Hanselmann
510 48436b97 Michael Hanselmann
    testdisks = [
511 48436b97 Michael Hanselmann
      [],
512 48436b97 Michael Hanselmann
      [{ "size": 128, }],
513 48436b97 Michael Hanselmann
      [{ "size": 321, }, { "size": 4096, }],
514 48436b97 Michael Hanselmann
      ]
515 48436b97 Michael Hanselmann
516 48436b97 Michael Hanselmann
    for idx, nics in enumerate(testnics):
517 48436b97 Michael Hanselmann
      for disks in testdisks:
518 48436b97 Michael Hanselmann
        beparams = {
519 48436b97 Michael Hanselmann
          constants.BE_MEMORY: 512,
520 48436b97 Michael Hanselmann
          constants.BE_AUTO_BALANCE: False,
521 48436b97 Michael Hanselmann
          }
522 48436b97 Michael Hanselmann
        hvparams = {
523 48436b97 Michael Hanselmann
          constants.HV_MIGRATION_PORT: 9876,
524 48436b97 Michael Hanselmann
          constants.HV_VNC_TLS: True,
525 48436b97 Michael Hanselmann
          }
526 48436b97 Michael Hanselmann
527 48436b97 Michael Hanselmann
        self.rapi.AddResponse(None, code=404)
528 48436b97 Michael Hanselmann
        self.rapi.AddResponse(serializer.DumpJson(3122617 + idx))
529 48436b97 Michael Hanselmann
        job_id = self.client.CreateInstance("create", "inst1.example.com",
530 48436b97 Michael Hanselmann
                                            "plain", disks, nics,
531 48436b97 Michael Hanselmann
                                            pnode="node99", dry_run=True,
532 48436b97 Michael Hanselmann
                                            hvparams=hvparams,
533 48436b97 Michael Hanselmann
                                            beparams=beparams)
534 48436b97 Michael Hanselmann
        self.assertEqual(job_id, 3122617 + idx)
535 48436b97 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances)
536 48436b97 Michael Hanselmann
        self.assertDryRun()
537 48436b97 Michael Hanselmann
        self.assertEqual(self.rapi.CountPending(), 0)
538 48436b97 Michael Hanselmann
539 54dc4fdb Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
540 48436b97 Michael Hanselmann
        self.assertEqual(data["name"], "inst1.example.com")
541 48436b97 Michael Hanselmann
        self.assertEqual(data["disk_template"], "plain")
542 48436b97 Michael Hanselmann
        self.assertEqual(data["pnode"], "node99")
543 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_MEMORY], 512)
544 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_AUTO_BALANCE], False)
545 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_MIGRATION_PORT], 9876)
546 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_VNC_TLS], True)
547 48436b97 Michael Hanselmann
        self.assertEqual(data["disks"], [disk["size"] for disk in disks])
548 8a47b447 Michael Hanselmann
549 95ab4de9 David Knowles
  def testCreateInstance(self):
550 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
551 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("23030")
552 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("create", "inst1.example.com",
553 8a47b447 Michael Hanselmann
                                        "plain", [], [], dry_run=True)
554 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 23030)
555 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
556 95ab4de9 David Knowles
    self.assertDryRun()
557 95ab4de9 David Knowles
558 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
559 8a47b447 Michael Hanselmann
560 8a47b447 Michael Hanselmann
    for field in ["dry_run", "beparams", "hvparams", "start"]:
561 8a47b447 Michael Hanselmann
      self.assertFalse(field in data)
562 8a47b447 Michael Hanselmann
563 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst1.example.com")
564 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "plain")
565 8a47b447 Michael Hanselmann
566 8a47b447 Michael Hanselmann
  def testCreateInstance2(self):
567 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
568 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("24740")
569 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("import", "inst2.example.com",
570 8a47b447 Michael Hanselmann
                                        "drbd8", [{"size": 100,}],
571 8a47b447 Michael Hanselmann
                                        [{}, {"bridge": "br1", }],
572 8a47b447 Michael Hanselmann
                                        dry_run=False, start=True,
573 8a47b447 Michael Hanselmann
                                        pnode="node1", snode="node9",
574 8a47b447 Michael Hanselmann
                                        ip_check=False)
575 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 24740)
576 8a47b447 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances)
577 8a47b447 Michael Hanselmann
578 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
579 8a47b447 Michael Hanselmann
    self.assertEqual(data[rlib2._REQ_DATA_VERSION], 1)
580 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst2.example.com")
581 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "drbd8")
582 8a47b447 Michael Hanselmann
    self.assertEqual(data["start"], True)
583 8a47b447 Michael Hanselmann
    self.assertEqual(data["ip_check"], False)
584 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["disks"], [{"size": 100,}])
585 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["nics"], [{}, {"bridge": "br1", }])
586 8a47b447 Michael Hanselmann
587 95ab4de9 David Knowles
  def testDeleteInstance(self):
588 cab667cc David Knowles
    self.rapi.AddResponse("1234")
589 cab667cc David Knowles
    self.assertEqual(1234, self.client.DeleteInstance("instance", dry_run=True))
590 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
591 95ab4de9 David Knowles
    self.assertItems(["instance"])
592 95ab4de9 David Knowles
    self.assertDryRun()
593 95ab4de9 David Knowles
594 95ab4de9 David Knowles
  def testGetInstanceTags(self):
595 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
596 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstanceTags("fooinstance"))
597 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
598 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
599 95ab4de9 David Knowles
600 95ab4de9 David Knowles
  def testAddInstanceTags(self):
601 cab667cc David Knowles
    self.rapi.AddResponse("1234")
602 cab667cc David Knowles
    self.assertEqual(1234,
603 cab667cc David Knowles
        self.client.AddInstanceTags("fooinstance", ["awesome"], dry_run=True))
604 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
605 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
606 95ab4de9 David Knowles
    self.assertDryRun()
607 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
608 95ab4de9 David Knowles
609 95ab4de9 David Knowles
  def testDeleteInstanceTags(self):
610 cd577680 Michael Hanselmann
    self.rapi.AddResponse("25826")
611 cd577680 Michael Hanselmann
    self.assertEqual(25826, self.client.DeleteInstanceTags("foo", ["awesome"],
612 cd577680 Michael Hanselmann
                                                           dry_run=True))
613 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
614 95ab4de9 David Knowles
    self.assertItems(["foo"])
615 95ab4de9 David Knowles
    self.assertDryRun()
616 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
617 95ab4de9 David Knowles
618 95ab4de9 David Knowles
  def testRebootInstance(self):
619 cd577680 Michael Hanselmann
    self.rapi.AddResponse("6146")
620 cd577680 Michael Hanselmann
    job_id = self.client.RebootInstance("i-bar", reboot_type="hard",
621 cd577680 Michael Hanselmann
                                        ignore_secondaries=True, dry_run=True)
622 cd577680 Michael Hanselmann
    self.assertEqual(6146, job_id)
623 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reboot)
624 95ab4de9 David Knowles
    self.assertItems(["i-bar"])
625 95ab4de9 David Knowles
    self.assertDryRun()
626 95ab4de9 David Knowles
    self.assertQuery("type", ["hard"])
627 10f5ab6c Michael Hanselmann
    self.assertQuery("ignore_secondaries", ["1"])
628 95ab4de9 David Knowles
629 95ab4de9 David Knowles
  def testShutdownInstance(self):
630 cd577680 Michael Hanselmann
    self.rapi.AddResponse("1487")
631 cd577680 Michael Hanselmann
    self.assertEqual(1487, self.client.ShutdownInstance("foo-instance",
632 cd577680 Michael Hanselmann
                                                        dry_run=True))
633 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_shutdown)
634 95ab4de9 David Knowles
    self.assertItems(["foo-instance"])
635 95ab4de9 David Knowles
    self.assertDryRun()
636 95ab4de9 David Knowles
637 95ab4de9 David Knowles
  def testStartupInstance(self):
638 cd577680 Michael Hanselmann
    self.rapi.AddResponse("27149")
639 cd577680 Michael Hanselmann
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
640 cd577680 Michael Hanselmann
                                                        dry_run=True))
641 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_startup)
642 95ab4de9 David Knowles
    self.assertItems(["bar-instance"])
643 95ab4de9 David Knowles
    self.assertDryRun()
644 95ab4de9 David Knowles
645 95ab4de9 David Knowles
  def testReinstallInstance(self):
646 cd577680 Michael Hanselmann
    self.rapi.AddResponse("19119")
647 cd577680 Michael Hanselmann
    self.assertEqual(19119, self.client.ReinstallInstance("baz-instance", "DOS",
648 cd577680 Michael Hanselmann
                                                          no_startup=True))
649 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
650 95ab4de9 David Knowles
    self.assertItems(["baz-instance"])
651 95ab4de9 David Knowles
    self.assertQuery("os", ["DOS"])
652 95ab4de9 David Knowles
    self.assertQuery("nostartup", ["1"])
653 95ab4de9 David Knowles
654 95ab4de9 David Knowles
  def testReplaceInstanceDisks(self):
655 95ab4de9 David Knowles
    self.rapi.AddResponse("999")
656 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-name",
657 bfc2002f Michael Hanselmann
        disks=[0, 1], dry_run=True, iallocator="hail")
658 95ab4de9 David Knowles
    self.assertEqual(999, job_id)
659 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_replace_disks)
660 95ab4de9 David Knowles
    self.assertItems(["instance-name"])
661 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["0,1"])
662 95ab4de9 David Knowles
    self.assertQuery("mode", ["replace_auto"])
663 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
664 95ab4de9 David Knowles
    self.assertDryRun()
665 95ab4de9 David Knowles
666 95ab4de9 David Knowles
    self.rapi.AddResponse("1000")
667 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-bar",
668 bfc2002f Michael Hanselmann
        disks=[1], mode="replace_on_secondary", remote_node="foo-node",
669 95ab4de9 David Knowles
        dry_run=True)
670 95ab4de9 David Knowles
    self.assertEqual(1000, job_id)
671 95ab4de9 David Knowles
    self.assertItems(["instance-bar"])
672 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["1"])
673 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["foo-node"])
674 95ab4de9 David Knowles
    self.assertDryRun()
675 95ab4de9 David Knowles
676 bfc2002f Michael Hanselmann
    self.rapi.AddResponse("5175")
677 bfc2002f Michael Hanselmann
    self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo"))
678 bfc2002f Michael Hanselmann
    self.assertItems(["instance-moo"])
679 bfc2002f Michael Hanselmann
    self.assertQuery("disks", None)
680 bfc2002f Michael Hanselmann
681 ebeb600f Michael Hanselmann
  def testPrepareExport(self):
682 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("8326")
683 ebeb600f Michael Hanselmann
    self.assertEqual(8326, self.client.PrepareExport("inst1", "local"))
684 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_prepare_export)
685 ebeb600f Michael Hanselmann
    self.assertItems(["inst1"])
686 ebeb600f Michael Hanselmann
    self.assertQuery("mode", ["local"])
687 ebeb600f Michael Hanselmann
688 ebeb600f Michael Hanselmann
  def testExportInstance(self):
689 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("19695")
690 ebeb600f Michael Hanselmann
    job_id = self.client.ExportInstance("inst2", "local", "nodeX",
691 ebeb600f Michael Hanselmann
                                        shutdown=True)
692 ebeb600f Michael Hanselmann
    self.assertEqual(job_id, 19695)
693 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_export)
694 ebeb600f Michael Hanselmann
    self.assertItems(["inst2"])
695 ebeb600f Michael Hanselmann
696 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
697 ebeb600f Michael Hanselmann
    self.assertEqual(data["mode"], "local")
698 ebeb600f Michael Hanselmann
    self.assertEqual(data["destination"], "nodeX")
699 ebeb600f Michael Hanselmann
    self.assertEqual(data["shutdown"], True)
700 ebeb600f Michael Hanselmann
701 95ab4de9 David Knowles
  def testGetJobs(self):
702 2004e673 Iustin Pop
    self.rapi.AddResponse('[ { "id": "123", "uri": "\\/2\\/jobs\\/123" },'
703 2004e673 Iustin Pop
                          '  { "id": "124", "uri": "\\/2\\/jobs\\/124" } ]')
704 95ab4de9 David Knowles
    self.assertEqual([123, 124], self.client.GetJobs())
705 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs)
706 95ab4de9 David Knowles
707 95ab4de9 David Knowles
  def testGetJobStatus(self):
708 95ab4de9 David Knowles
    self.rapi.AddResponse("{\"foo\": \"bar\"}")
709 95ab4de9 David Knowles
    self.assertEqual({"foo": "bar"}, self.client.GetJobStatus(1234))
710 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
711 95ab4de9 David Knowles
    self.assertItems(["1234"])
712 95ab4de9 David Knowles
713 d9b67f70 Michael Hanselmann
  def testWaitForJobChange(self):
714 d9b67f70 Michael Hanselmann
    fields = ["id", "summary"]
715 d9b67f70 Michael Hanselmann
    expected = {
716 d9b67f70 Michael Hanselmann
      "job_info": [123, "something"],
717 d9b67f70 Michael Hanselmann
      "log_entries": [],
718 d9b67f70 Michael Hanselmann
      }
719 d9b67f70 Michael Hanselmann
720 d9b67f70 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson(expected))
721 d9b67f70 Michael Hanselmann
    result = self.client.WaitForJobChange(123, fields, [], -1)
722 d9b67f70 Michael Hanselmann
    self.assertEqualValues(expected, result)
723 d9b67f70 Michael Hanselmann
    self.assertHandler(rlib2.R_2_jobs_id_wait)
724 d9b67f70 Michael Hanselmann
    self.assertItems(["123"])
725 d9b67f70 Michael Hanselmann
726 cf9ada49 Michael Hanselmann
  def testCancelJob(self):
727 cd577680 Michael Hanselmann
    self.rapi.AddResponse("[true, \"Job 123 will be canceled\"]")
728 cd577680 Michael Hanselmann
    self.assertEqual([True, "Job 123 will be canceled"],
729 cf9ada49 Michael Hanselmann
                     self.client.CancelJob(999, dry_run=True))
730 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
731 95ab4de9 David Knowles
    self.assertItems(["999"])
732 95ab4de9 David Knowles
    self.assertDryRun()
733 95ab4de9 David Knowles
734 95ab4de9 David Knowles
  def testGetNodes(self):
735 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
736 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
737 95ab4de9 David Knowles
    self.assertEqual(["node1", "node2"], self.client.GetNodes())
738 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
739 95ab4de9 David Knowles
740 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
741 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
742 95ab4de9 David Knowles
    self.assertEqual([{"id": "node1", "uri": "uri1"},
743 95ab4de9 David Knowles
                      {"id": "node2", "uri": "uri2"}],
744 95ab4de9 David Knowles
                     self.client.GetNodes(bulk=True))
745 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
746 95ab4de9 David Knowles
    self.assertBulk()
747 95ab4de9 David Knowles
748 591e5103 Michael Hanselmann
  def testGetNode(self):
749 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
750 591e5103 Michael Hanselmann
    self.assertEqual({}, self.client.GetNode("node-foo"))
751 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name)
752 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
753 95ab4de9 David Knowles
754 95ab4de9 David Knowles
  def testEvacuateNode(self):
755 95ab4de9 David Knowles
    self.rapi.AddResponse("9876")
756 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-1", remote_node="node-2")
757 95ab4de9 David Knowles
    self.assertEqual(9876, job_id)
758 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_evacuate)
759 95ab4de9 David Knowles
    self.assertItems(["node-1"])
760 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["node-2"])
761 95ab4de9 David Knowles
762 95ab4de9 David Knowles
    self.rapi.AddResponse("8888")
763 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True)
764 95ab4de9 David Knowles
    self.assertEqual(8888, job_id)
765 95ab4de9 David Knowles
    self.assertItems(["node-3"])
766 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
767 95ab4de9 David Knowles
    self.assertDryRun()
768 95ab4de9 David Knowles
769 95ab4de9 David Knowles
    self.assertRaises(client.GanetiApiError,
770 95ab4de9 David Knowles
                      self.client.EvacuateNode,
771 95ab4de9 David Knowles
                      "node-4", iallocator="hail", remote_node="node-5")
772 95ab4de9 David Knowles
773 95ab4de9 David Knowles
  def testMigrateNode(self):
774 95ab4de9 David Knowles
    self.rapi.AddResponse("1111")
775 95ab4de9 David Knowles
    self.assertEqual(1111, self.client.MigrateNode("node-a", dry_run=True))
776 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
777 95ab4de9 David Knowles
    self.assertItems(["node-a"])
778 1f334d96 Iustin Pop
    self.assert_("mode" not in self.rapi.GetLastHandler().queryargs)
779 1f334d96 Iustin Pop
    self.assertDryRun()
780 1f334d96 Iustin Pop
781 1f334d96 Iustin Pop
    self.rapi.AddResponse("1112")
782 1f334d96 Iustin Pop
    self.assertEqual(1112, self.client.MigrateNode("node-a", dry_run=True,
783 1f334d96 Iustin Pop
                                                   mode="live"))
784 1f334d96 Iustin Pop
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
785 1f334d96 Iustin Pop
    self.assertItems(["node-a"])
786 1f334d96 Iustin Pop
    self.assertQuery("mode", ["live"])
787 95ab4de9 David Knowles
    self.assertDryRun()
788 95ab4de9 David Knowles
789 95ab4de9 David Knowles
  def testGetNodeRole(self):
790 95ab4de9 David Knowles
    self.rapi.AddResponse("\"master\"")
791 95ab4de9 David Knowles
    self.assertEqual("master", self.client.GetNodeRole("node-a"))
792 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
793 95ab4de9 David Knowles
    self.assertItems(["node-a"])
794 95ab4de9 David Knowles
795 95ab4de9 David Knowles
  def testSetNodeRole(self):
796 95ab4de9 David Knowles
    self.rapi.AddResponse("789")
797 95ab4de9 David Knowles
    self.assertEqual(789,
798 95ab4de9 David Knowles
        self.client.SetNodeRole("node-foo", "master-candidate", force=True))
799 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
800 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
801 10f5ab6c Michael Hanselmann
    self.assertQuery("force", ["1"])
802 2a7c3583 Michael Hanselmann
    self.assertEqual("\"master-candidate\"", self.rapi.GetLastRequestData())
803 95ab4de9 David Knowles
804 95ab4de9 David Knowles
  def testGetNodeStorageUnits(self):
805 95ab4de9 David Knowles
    self.rapi.AddResponse("42")
806 95ab4de9 David Knowles
    self.assertEqual(42,
807 95ab4de9 David Knowles
        self.client.GetNodeStorageUnits("node-x", "lvm-pv", "fields"))
808 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage)
809 95ab4de9 David Knowles
    self.assertItems(["node-x"])
810 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
811 95ab4de9 David Knowles
    self.assertQuery("output_fields", ["fields"])
812 95ab4de9 David Knowles
813 95ab4de9 David Knowles
  def testModifyNodeStorageUnits(self):
814 95ab4de9 David Knowles
    self.rapi.AddResponse("14")
815 95ab4de9 David Knowles
    self.assertEqual(14,
816 95ab4de9 David Knowles
        self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda"))
817 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
818 95ab4de9 David Knowles
    self.assertItems(["node-z"])
819 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
820 95ab4de9 David Knowles
    self.assertQuery("name", ["hda"])
821 fde28316 Michael Hanselmann
    self.assertQuery("allocatable", None)
822 fde28316 Michael Hanselmann
823 fde28316 Michael Hanselmann
    for allocatable, query_allocatable in [(True, "1"), (False, "0")]:
824 fde28316 Michael Hanselmann
      self.rapi.AddResponse("7205")
825 fde28316 Michael Hanselmann
      job_id = self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda",
826 fde28316 Michael Hanselmann
                                                  allocatable=allocatable)
827 fde28316 Michael Hanselmann
      self.assertEqual(7205, job_id)
828 fde28316 Michael Hanselmann
      self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
829 fde28316 Michael Hanselmann
      self.assertItems(["node-z"])
830 fde28316 Michael Hanselmann
      self.assertQuery("storage_type", ["lvm-pv"])
831 fde28316 Michael Hanselmann
      self.assertQuery("name", ["hda"])
832 fde28316 Michael Hanselmann
      self.assertQuery("allocatable", [query_allocatable])
833 95ab4de9 David Knowles
834 752df8bb Michael Hanselmann
  def testRepairNodeStorageUnits(self):
835 752df8bb Michael Hanselmann
    self.rapi.AddResponse("99")
836 752df8bb Michael Hanselmann
    self.assertEqual(99, self.client.RepairNodeStorageUnits("node-z", "lvm-pv",
837 752df8bb Michael Hanselmann
                                                            "hda"))
838 752df8bb Michael Hanselmann
    self.assertHandler(rlib2.R_2_nodes_name_storage_repair)
839 752df8bb Michael Hanselmann
    self.assertItems(["node-z"])
840 752df8bb Michael Hanselmann
    self.assertQuery("storage_type", ["lvm-pv"])
841 752df8bb Michael Hanselmann
    self.assertQuery("name", ["hda"])
842 752df8bb Michael Hanselmann
843 95ab4de9 David Knowles
  def testGetNodeTags(self):
844 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"fry\", \"bender\"]")
845 95ab4de9 David Knowles
    self.assertEqual(["fry", "bender"], self.client.GetNodeTags("node-k"))
846 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
847 95ab4de9 David Knowles
    self.assertItems(["node-k"])
848 95ab4de9 David Knowles
849 95ab4de9 David Knowles
  def testAddNodeTags(self):
850 cab667cc David Knowles
    self.rapi.AddResponse("1234")
851 cab667cc David Knowles
    self.assertEqual(1234,
852 cab667cc David Knowles
        self.client.AddNodeTags("node-v", ["awesome"], dry_run=True))
853 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
854 95ab4de9 David Knowles
    self.assertItems(["node-v"])
855 95ab4de9 David Knowles
    self.assertDryRun()
856 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
857 95ab4de9 David Knowles
858 95ab4de9 David Knowles
  def testDeleteNodeTags(self):
859 cd577680 Michael Hanselmann
    self.rapi.AddResponse("16861")
860 cd577680 Michael Hanselmann
    self.assertEqual(16861, self.client.DeleteNodeTags("node-w", ["awesome"],
861 cd577680 Michael Hanselmann
                                                       dry_run=True))
862 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
863 95ab4de9 David Knowles
    self.assertItems(["node-w"])
864 95ab4de9 David Knowles
    self.assertDryRun()
865 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
866 95ab4de9 David Knowles
867 95ab4de9 David Knowles
868 95ab4de9 David Knowles
if __name__ == '__main__':
869 2a7c3583 Michael Hanselmann
  client.UsesRapiClient(testutils.GanetiTestProgram)()