Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ bebe7a73

History | View | Annotate | Download (19.9 kB)

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

24 a47f574c Oleksiy Mishchenko
"""
25 a47f574c Oleksiy Mishchenko
26 2771835c Michael Hanselmann
import tempfile
27 4fab7cab Michael Hanselmann
import random
28 a47f574c Oleksiy Mishchenko
29 a47f574c Oleksiy Mishchenko
from ganeti import utils
30 a47f574c Oleksiy Mishchenko
from ganeti import constants
31 a47f574c Oleksiy Mishchenko
from ganeti import errors
32 2771835c Michael Hanselmann
from ganeti import cli
33 2771835c Michael Hanselmann
from ganeti import rapi
34 b82d4c5e Michael Hanselmann
from ganeti import objects
35 4fab7cab Michael Hanselmann
from ganeti import query
36 4fab7cab Michael Hanselmann
from ganeti import compat
37 4fab7cab Michael Hanselmann
from ganeti import qlang
38 2771835c Michael Hanselmann
39 b459a848 Andrea Spadaccini
import ganeti.rapi.client        # pylint: disable=W0611
40 2771835c Michael Hanselmann
import ganeti.rapi.client_utils
41 a47f574c Oleksiy Mishchenko
42 a47f574c Oleksiy Mishchenko
import qa_config
43 a47f574c Oleksiy Mishchenko
import qa_utils
44 a47f574c Oleksiy Mishchenko
import qa_error
45 a47f574c Oleksiy Mishchenko
46 3582eef6 Iustin Pop
from qa_utils import (AssertEqual, AssertIn, AssertMatch, StartLocalCommand)
47 a47f574c Oleksiy Mishchenko
48 a47f574c Oleksiy Mishchenko
49 2771835c Michael Hanselmann
_rapi_ca = None
50 2771835c Michael Hanselmann
_rapi_client = None
51 5d831182 Michael Hanselmann
_rapi_username = None
52 5d831182 Michael Hanselmann
_rapi_password = None
53 e6ce18ac René Nussbaumer
54 e6ce18ac René Nussbaumer
55 2771835c Michael Hanselmann
def Setup(username, password):
56 2771835c Michael Hanselmann
  """Configures the RAPI client.
57 725ec2f1 René Nussbaumer

58 2771835c Michael Hanselmann
  """
59 b459a848 Andrea Spadaccini
  # pylint: disable=W0603
60 3582eef6 Iustin Pop
  # due to global usage
61 2771835c Michael Hanselmann
  global _rapi_ca
62 2771835c Michael Hanselmann
  global _rapi_client
63 5d831182 Michael Hanselmann
  global _rapi_username
64 5d831182 Michael Hanselmann
  global _rapi_password
65 5d831182 Michael Hanselmann
66 5d831182 Michael Hanselmann
  _rapi_username = username
67 5d831182 Michael Hanselmann
  _rapi_password = password
68 e6ce18ac René Nussbaumer
69 2771835c Michael Hanselmann
  master = qa_config.GetMasterNode()
70 e6ce18ac René Nussbaumer
71 2771835c Michael Hanselmann
  # Load RAPI certificate from master node
72 2771835c Michael Hanselmann
  cmd = ["cat", constants.RAPI_CERT_FILE]
73 e6ce18ac René Nussbaumer
74 2771835c Michael Hanselmann
  # Write to temporary file
75 2771835c Michael Hanselmann
  _rapi_ca = tempfile.NamedTemporaryFile()
76 2771835c Michael Hanselmann
  _rapi_ca.write(qa_utils.GetCommandOutput(master["primary"],
77 2771835c Michael Hanselmann
                                           utils.ShellQuoteArgs(cmd)))
78 2771835c Michael Hanselmann
  _rapi_ca.flush()
79 e6ce18ac René Nussbaumer
80 2771835c Michael Hanselmann
  port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
81 2a7c3583 Michael Hanselmann
  cfg_curl = rapi.client.GenericCurlConfig(cafile=_rapi_ca.name,
82 2a7c3583 Michael Hanselmann
                                           proxy="")
83 e6ce18ac René Nussbaumer
84 2771835c Michael Hanselmann
  _rapi_client = rapi.client.GanetiRapiClient(master["primary"], port=port,
85 2771835c Michael Hanselmann
                                              username=username,
86 2771835c Michael Hanselmann
                                              password=password,
87 2a7c3583 Michael Hanselmann
                                              curl_config_fn=cfg_curl)
88 e6ce18ac René Nussbaumer
89 2771835c Michael Hanselmann
  print "RAPI protocol version: %s" % _rapi_client.GetVersion()
90 a47f574c Oleksiy Mishchenko
91 a47f574c Oleksiy Mishchenko
92 a47f574c Oleksiy Mishchenko
INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
93 a5b9d725 Iustin Pop
                   "admin_state",
94 a5b9d725 Iustin Pop
                   "disk_template", "disk.sizes",
95 22482387 Iustin Pop
                   "nic.ips", "nic.macs", "nic.modes", "nic.links",
96 a5b9d725 Iustin Pop
                   "beparams", "hvparams",
97 4ea3de4e Balazs Lecz
                   "oper_state", "oper_ram", "oper_vcpus", "status", "tags")
98 a47f574c Oleksiy Mishchenko
99 a47f574c Oleksiy Mishchenko
NODE_FIELDS = ("name", "dtotal", "dfree",
100 a47f574c Oleksiy Mishchenko
               "mtotal", "mnode", "mfree",
101 a47f574c Oleksiy Mishchenko
               "pinst_cnt", "sinst_cnt", "tags")
102 a47f574c Oleksiy Mishchenko
103 30131294 Adeodato Simo
GROUP_FIELDS = frozenset([
104 30131294 Adeodato Simo
  "name", "uuid",
105 90e99856 Adeodato Simo
  "alloc_policy",
106 30131294 Adeodato Simo
  "node_cnt", "node_list",
107 30131294 Adeodato Simo
  ])
108 30131294 Adeodato Simo
109 94e63ca1 Michael Hanselmann
JOB_FIELDS = frozenset([
110 94e63ca1 Michael Hanselmann
  "id", "ops", "status", "summary",
111 94e63ca1 Michael Hanselmann
  "opstatus", "opresult", "oplog",
112 94e63ca1 Michael Hanselmann
  "received_ts", "start_ts", "end_ts",
113 94e63ca1 Michael Hanselmann
  ])
114 94e63ca1 Michael Hanselmann
115 68289c75 Iustin Pop
LIST_FIELDS = ("id", "uri")
116 a47f574c Oleksiy Mishchenko
117 a47f574c Oleksiy Mishchenko
118 a47f574c Oleksiy Mishchenko
def Enabled():
119 a47f574c Oleksiy Mishchenko
  """Return whether remote API tests should be run.
120 a47f574c Oleksiy Mishchenko

121 a47f574c Oleksiy Mishchenko
  """
122 d0c8c01d Iustin Pop
  return qa_config.TestEnabled("rapi")
123 a47f574c Oleksiy Mishchenko
124 a47f574c Oleksiy Mishchenko
125 a47f574c Oleksiy Mishchenko
def _DoTests(uris):
126 b459a848 Andrea Spadaccini
  # pylint: disable=W0212
127 3582eef6 Iustin Pop
  # due to _SendRequest usage
128 94e63ca1 Michael Hanselmann
  results = []
129 a47f574c Oleksiy Mishchenko
130 94e63ca1 Michael Hanselmann
  for uri, verify, method, body in uris:
131 a47f574c Oleksiy Mishchenko
    assert uri.startswith("/")
132 a47f574c Oleksiy Mishchenko
133 c326b4ef Michael Hanselmann
    print "%s %s" % (method, uri)
134 2771835c Michael Hanselmann
    data = _rapi_client._SendRequest(method, uri, None, body)
135 a47f574c Oleksiy Mishchenko
136 a47f574c Oleksiy Mishchenko
    if verify is not None:
137 a47f574c Oleksiy Mishchenko
      if callable(verify):
138 a47f574c Oleksiy Mishchenko
        verify(data)
139 a47f574c Oleksiy Mishchenko
      else:
140 a47f574c Oleksiy Mishchenko
        AssertEqual(data, verify)
141 a47f574c Oleksiy Mishchenko
142 fd837171 Michael Hanselmann
    results.append(data)
143 94e63ca1 Michael Hanselmann
144 94e63ca1 Michael Hanselmann
  return results
145 94e63ca1 Michael Hanselmann
146 94e63ca1 Michael Hanselmann
147 94e63ca1 Michael Hanselmann
def _VerifyReturnsJob(data):
148 d0c8c01d Iustin Pop
  AssertMatch(data, r"^\d+$")
149 94e63ca1 Michael Hanselmann
150 a47f574c Oleksiy Mishchenko
151 a47f574c Oleksiy Mishchenko
def TestVersion():
152 a47f574c Oleksiy Mishchenko
  """Testing remote API version.
153 a47f574c Oleksiy Mishchenko

154 a47f574c Oleksiy Mishchenko
  """
155 a47f574c Oleksiy Mishchenko
  _DoTests([
156 d0c8c01d Iustin Pop
    ("/version", constants.RAPI_VERSION, "GET", None),
157 a47f574c Oleksiy Mishchenko
    ])
158 a47f574c Oleksiy Mishchenko
159 a47f574c Oleksiy Mishchenko
160 a47f574c Oleksiy Mishchenko
def TestEmptyCluster():
161 a47f574c Oleksiy Mishchenko
  """Testing remote API on an empty cluster.
162 a47f574c Oleksiy Mishchenko

163 a47f574c Oleksiy Mishchenko
  """
164 94e63ca1 Michael Hanselmann
  master = qa_config.GetMasterNode()
165 94e63ca1 Michael Hanselmann
  master_full = qa_utils.ResolveNodeName(master)
166 a47f574c Oleksiy Mishchenko
167 a47f574c Oleksiy Mishchenko
  def _VerifyInfo(data):
168 a47f574c Oleksiy Mishchenko
    AssertIn("name", data)
169 a47f574c Oleksiy Mishchenko
    AssertIn("master", data)
170 94e63ca1 Michael Hanselmann
    AssertEqual(data["master"], master_full)
171 a47f574c Oleksiy Mishchenko
172 a47f574c Oleksiy Mishchenko
  def _VerifyNodes(data):
173 a47f574c Oleksiy Mishchenko
    master_entry = {
174 94e63ca1 Michael Hanselmann
      "id": master_full,
175 94e63ca1 Michael Hanselmann
      "uri": "/2/nodes/%s" % master_full,
176 a47f574c Oleksiy Mishchenko
      }
177 a47f574c Oleksiy Mishchenko
    AssertIn(master_entry, data)
178 a47f574c Oleksiy Mishchenko
179 a47f574c Oleksiy Mishchenko
  def _VerifyNodesBulk(data):
180 a47f574c Oleksiy Mishchenko
    for node in data:
181 a47f574c Oleksiy Mishchenko
      for entry in NODE_FIELDS:
182 a47f574c Oleksiy Mishchenko
        AssertIn(entry, node)
183 a47f574c Oleksiy Mishchenko
184 30131294 Adeodato Simo
  def _VerifyGroups(data):
185 30131294 Adeodato Simo
    default_group = {
186 75cf411a Adeodato Simo
      "name": constants.INITIAL_NODE_GROUP_NAME,
187 75cf411a Adeodato Simo
      "uri": "/2/groups/" + constants.INITIAL_NODE_GROUP_NAME,
188 30131294 Adeodato Simo
      }
189 30131294 Adeodato Simo
    AssertIn(default_group, data)
190 30131294 Adeodato Simo
191 30131294 Adeodato Simo
  def _VerifyGroupsBulk(data):
192 30131294 Adeodato Simo
    for group in data:
193 30131294 Adeodato Simo
      for field in GROUP_FIELDS:
194 30131294 Adeodato Simo
        AssertIn(field, group)
195 30131294 Adeodato Simo
196 a47f574c Oleksiy Mishchenko
  _DoTests([
197 d0c8c01d Iustin Pop
    ("/", None, "GET", None),
198 d0c8c01d Iustin Pop
    ("/2/info", _VerifyInfo, "GET", None),
199 d0c8c01d Iustin Pop
    ("/2/tags", None, "GET", None),
200 d0c8c01d Iustin Pop
    ("/2/nodes", _VerifyNodes, "GET", None),
201 d0c8c01d Iustin Pop
    ("/2/nodes?bulk=1", _VerifyNodesBulk, "GET", None),
202 d0c8c01d Iustin Pop
    ("/2/groups", _VerifyGroups, "GET", None),
203 d0c8c01d Iustin Pop
    ("/2/groups?bulk=1", _VerifyGroupsBulk, "GET", None),
204 d0c8c01d Iustin Pop
    ("/2/instances", [], "GET", None),
205 d0c8c01d Iustin Pop
    ("/2/instances?bulk=1", [], "GET", None),
206 d0c8c01d Iustin Pop
    ("/2/os", None, "GET", None),
207 a47f574c Oleksiy Mishchenko
    ])
208 a47f574c Oleksiy Mishchenko
209 4d2bd00a Michael Hanselmann
  # Test HTTP Not Found
210 4d2bd00a Michael Hanselmann
  for method in ["GET", "PUT", "POST", "DELETE"]:
211 4d2bd00a Michael Hanselmann
    try:
212 4d2bd00a Michael Hanselmann
      _DoTests([("/99/resource/not/here/99", None, method, None)])
213 4d2bd00a Michael Hanselmann
    except rapi.client.GanetiApiError, err:
214 4d2bd00a Michael Hanselmann
      AssertEqual(err.code, 404)
215 4d2bd00a Michael Hanselmann
    else:
216 4d2bd00a Michael Hanselmann
      raise qa_error.Error("Non-existent resource didn't return HTTP 404")
217 4d2bd00a Michael Hanselmann
218 4d2bd00a Michael Hanselmann
  # Test HTTP Not Implemented
219 4d2bd00a Michael Hanselmann
  for method in ["PUT", "POST", "DELETE"]:
220 4d2bd00a Michael Hanselmann
    try:
221 4d2bd00a Michael Hanselmann
      _DoTests([("/version", None, method, None)])
222 4d2bd00a Michael Hanselmann
    except rapi.client.GanetiApiError, err:
223 4d2bd00a Michael Hanselmann
      AssertEqual(err.code, 501)
224 4d2bd00a Michael Hanselmann
    else:
225 4d2bd00a Michael Hanselmann
      raise qa_error.Error("Non-implemented method didn't fail")
226 4d2bd00a Michael Hanselmann
227 a47f574c Oleksiy Mishchenko
228 4fab7cab Michael Hanselmann
def TestRapiQuery():
229 4fab7cab Michael Hanselmann
  """Testing resource queries via remote API.
230 4fab7cab Michael Hanselmann

231 4fab7cab Michael Hanselmann
  """
232 4fab7cab Michael Hanselmann
  master_name = qa_utils.ResolveNodeName(qa_config.GetMasterNode())
233 4fab7cab Michael Hanselmann
  rnd = random.Random(7818)
234 4fab7cab Michael Hanselmann
235 4fab7cab Michael Hanselmann
  for what in constants.QR_VIA_RAPI:
236 4fab7cab Michael Hanselmann
    all_fields = query.ALL_FIELDS[what].keys()
237 4fab7cab Michael Hanselmann
    rnd.shuffle(all_fields)
238 4fab7cab Michael Hanselmann
239 4fab7cab Michael Hanselmann
    # No fields, should return everything
240 4fab7cab Michael Hanselmann
    result = _rapi_client.QueryFields(what)
241 4fab7cab Michael Hanselmann
    qresult = objects.QueryFieldsResponse.FromDict(result)
242 4fab7cab Michael Hanselmann
    AssertEqual(len(qresult.fields), len(all_fields))
243 4fab7cab Michael Hanselmann
244 4fab7cab Michael Hanselmann
    # One field
245 4fab7cab Michael Hanselmann
    result = _rapi_client.QueryFields(what, fields=["name"])
246 4fab7cab Michael Hanselmann
    qresult = objects.QueryFieldsResponse.FromDict(result)
247 4fab7cab Michael Hanselmann
    AssertEqual(len(qresult.fields), 1)
248 4fab7cab Michael Hanselmann
249 4fab7cab Michael Hanselmann
    # Specify all fields, order must be correct
250 4fab7cab Michael Hanselmann
    result = _rapi_client.QueryFields(what, fields=all_fields)
251 4fab7cab Michael Hanselmann
    qresult = objects.QueryFieldsResponse.FromDict(result)
252 4fab7cab Michael Hanselmann
    AssertEqual(len(qresult.fields), len(all_fields))
253 4fab7cab Michael Hanselmann
    AssertEqual([fdef.name for fdef in qresult.fields], all_fields)
254 4fab7cab Michael Hanselmann
255 4fab7cab Michael Hanselmann
    # Unknown field
256 4fab7cab Michael Hanselmann
    result = _rapi_client.QueryFields(what, fields=["_unknown!"])
257 4fab7cab Michael Hanselmann
    qresult = objects.QueryFieldsResponse.FromDict(result)
258 4fab7cab Michael Hanselmann
    AssertEqual(len(qresult.fields), 1)
259 4fab7cab Michael Hanselmann
    AssertEqual(qresult.fields[0].name, "_unknown!")
260 4fab7cab Michael Hanselmann
    AssertEqual(qresult.fields[0].kind, constants.QFT_UNKNOWN)
261 4fab7cab Michael Hanselmann
262 4fab7cab Michael Hanselmann
    # Try once more, this time without the client
263 4fab7cab Michael Hanselmann
    _DoTests([
264 4fab7cab Michael Hanselmann
      ("/2/query/%s/fields" % what, None, "GET", None),
265 4fab7cab Michael Hanselmann
      ("/2/query/%s/fields?fields=name,name,%s" % (what, all_fields[0]),
266 4fab7cab Michael Hanselmann
       None, "GET", None),
267 4fab7cab Michael Hanselmann
      ])
268 4fab7cab Michael Hanselmann
269 4fab7cab Michael Hanselmann
    # Try missing query argument
270 4fab7cab Michael Hanselmann
    try:
271 4fab7cab Michael Hanselmann
      _DoTests([
272 4fab7cab Michael Hanselmann
        ("/2/query/%s" % what, None, "GET", None),
273 4fab7cab Michael Hanselmann
        ])
274 4fab7cab Michael Hanselmann
    except rapi.client.GanetiApiError, err:
275 4fab7cab Michael Hanselmann
      AssertEqual(err.code, 400)
276 4fab7cab Michael Hanselmann
    else:
277 4fab7cab Michael Hanselmann
      raise qa_error.Error("Request missing 'fields' parameter didn't fail")
278 4fab7cab Michael Hanselmann
279 4fab7cab Michael Hanselmann
    def _Check(exp_fields, data):
280 4fab7cab Michael Hanselmann
      qresult = objects.QueryResponse.FromDict(data)
281 4fab7cab Michael Hanselmann
      AssertEqual([fdef.name for fdef in qresult.fields], exp_fields)
282 4fab7cab Michael Hanselmann
      if not isinstance(qresult.data, list):
283 4fab7cab Michael Hanselmann
        raise qa_error.Error("Query did not return a list")
284 4fab7cab Michael Hanselmann
285 4fab7cab Michael Hanselmann
    _DoTests([
286 4fab7cab Michael Hanselmann
      # Specify fields in query
287 4fab7cab Michael Hanselmann
      ("/2/query/%s?fields=%s" % (what, ",".join(all_fields)),
288 4fab7cab Michael Hanselmann
       compat.partial(_Check, all_fields), "GET", None),
289 4fab7cab Michael Hanselmann
290 4fab7cab Michael Hanselmann
      ("/2/query/%s?fields=name" % what,
291 4fab7cab Michael Hanselmann
       compat.partial(_Check, ["name"]), "GET", None),
292 4fab7cab Michael Hanselmann
293 4fab7cab Michael Hanselmann
      # Note the spaces
294 4fab7cab Michael Hanselmann
      ("/2/query/%s?fields=name,%%20name%%09,name%%20" % what,
295 4fab7cab Michael Hanselmann
       compat.partial(_Check, ["name"] * 3), "GET", None),
296 4fab7cab Michael Hanselmann
297 4fab7cab Michael Hanselmann
      # PUT with fields in query
298 4fab7cab Michael Hanselmann
      ("/2/query/%s?fields=name" % what,
299 4fab7cab Michael Hanselmann
       compat.partial(_Check, ["name"]), "PUT", {}),
300 4fab7cab Michael Hanselmann
301 4fab7cab Michael Hanselmann
      # Fields in body
302 4fab7cab Michael Hanselmann
      ("/2/query/%s" % what, compat.partial(_Check, all_fields), "PUT", {
303 4fab7cab Michael Hanselmann
         "fields": all_fields,
304 4fab7cab Michael Hanselmann
         }),
305 4fab7cab Michael Hanselmann
306 4fab7cab Michael Hanselmann
      ("/2/query/%s" % what, compat.partial(_Check, ["name"] * 4), "PUT", {
307 4fab7cab Michael Hanselmann
         "fields": ["name"] * 4,
308 4fab7cab Michael Hanselmann
         }),
309 4fab7cab Michael Hanselmann
      ])
310 4fab7cab Michael Hanselmann
311 4fab7cab Michael Hanselmann
    def _CheckFilter():
312 4fab7cab Michael Hanselmann
      _DoTests([
313 4fab7cab Michael Hanselmann
        # With filter
314 4fab7cab Michael Hanselmann
        ("/2/query/%s" % what, compat.partial(_Check, all_fields), "PUT", {
315 4fab7cab Michael Hanselmann
           "fields": all_fields,
316 4fab7cab Michael Hanselmann
           "filter": [qlang.OP_TRUE, "name"],
317 4fab7cab Michael Hanselmann
           }),
318 4fab7cab Michael Hanselmann
        ])
319 4fab7cab Michael Hanselmann
320 4fab7cab Michael Hanselmann
    if what == constants.QR_LOCK:
321 4fab7cab Michael Hanselmann
      # Locks can't be filtered
322 4fab7cab Michael Hanselmann
      try:
323 4fab7cab Michael Hanselmann
        _CheckFilter()
324 4fab7cab Michael Hanselmann
      except rapi.client.GanetiApiError, err:
325 4fab7cab Michael Hanselmann
        AssertEqual(err.code, 500)
326 4fab7cab Michael Hanselmann
      else:
327 4fab7cab Michael Hanselmann
        raise qa_error.Error("Filtering locks didn't fail")
328 4fab7cab Michael Hanselmann
    else:
329 4fab7cab Michael Hanselmann
      _CheckFilter()
330 4fab7cab Michael Hanselmann
331 4fab7cab Michael Hanselmann
    if what == constants.QR_NODE:
332 4fab7cab Michael Hanselmann
      # Test with filter
333 4fab7cab Michael Hanselmann
      (nodes, ) = _DoTests([("/2/query/%s" % what,
334 4fab7cab Michael Hanselmann
        compat.partial(_Check, ["name", "master"]), "PUT", {
335 4fab7cab Michael Hanselmann
        "fields": ["name", "master"],
336 4fab7cab Michael Hanselmann
        "filter": [qlang.OP_TRUE, "master"],
337 4fab7cab Michael Hanselmann
        })])
338 4fab7cab Michael Hanselmann
      qresult = objects.QueryResponse.FromDict(nodes)
339 4fab7cab Michael Hanselmann
      AssertEqual(qresult.data, [
340 4fab7cab Michael Hanselmann
        [[constants.RS_NORMAL, master_name], [constants.RS_NORMAL, True]],
341 4fab7cab Michael Hanselmann
        ])
342 4fab7cab Michael Hanselmann
343 4fab7cab Michael Hanselmann
344 a47f574c Oleksiy Mishchenko
def TestInstance(instance):
345 a47f574c Oleksiy Mishchenko
  """Testing getting instance(s) info via remote API.
346 a47f574c Oleksiy Mishchenko

347 a47f574c Oleksiy Mishchenko
  """
348 a47f574c Oleksiy Mishchenko
  def _VerifyInstance(data):
349 a47f574c Oleksiy Mishchenko
    for entry in INSTANCE_FIELDS:
350 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
351 c85d3b64 Michael Hanselmann
352 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesList(data):
353 a47f574c Oleksiy Mishchenko
    for instance in data:
354 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
355 a47f574c Oleksiy Mishchenko
        AssertIn(entry, instance)
356 c85d3b64 Michael Hanselmann
357 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesBulk(data):
358 a47f574c Oleksiy Mishchenko
    for instance_data in data:
359 a47f574c Oleksiy Mishchenko
      _VerifyInstance(instance_data)
360 a47f574c Oleksiy Mishchenko
361 a47f574c Oleksiy Mishchenko
  _DoTests([
362 d0c8c01d Iustin Pop
    ("/2/instances/%s" % instance["name"], _VerifyInstance, "GET", None),
363 d0c8c01d Iustin Pop
    ("/2/instances", _VerifyInstancesList, "GET", None),
364 d0c8c01d Iustin Pop
    ("/2/instances?bulk=1", _VerifyInstancesBulk, "GET", None),
365 94e63ca1 Michael Hanselmann
    ("/2/instances/%s/activate-disks" % instance["name"],
366 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
367 94e63ca1 Michael Hanselmann
    ("/2/instances/%s/deactivate-disks" % instance["name"],
368 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
369 a47f574c Oleksiy Mishchenko
    ])
370 a47f574c Oleksiy Mishchenko
371 71910715 Iustin Pop
  # Test OpBackupPrepare
372 ebeb600f Michael Hanselmann
  (job_id, ) = _DoTests([
373 ebeb600f Michael Hanselmann
    ("/2/instances/%s/prepare-export?mode=%s" %
374 ebeb600f Michael Hanselmann
     (instance["name"], constants.EXPORT_MODE_REMOTE),
375 ebeb600f Michael Hanselmann
     _VerifyReturnsJob, "PUT", None),
376 ebeb600f Michael Hanselmann
    ])
377 ebeb600f Michael Hanselmann
378 ebeb600f Michael Hanselmann
  result = _WaitForRapiJob(job_id)[0]
379 ebeb600f Michael Hanselmann
  AssertEqual(len(result["handshake"]), 3)
380 ebeb600f Michael Hanselmann
  AssertEqual(result["handshake"][0], constants.RIE_VERSION)
381 ebeb600f Michael Hanselmann
  AssertEqual(len(result["x509_key_name"]), 3)
382 ebeb600f Michael Hanselmann
  AssertIn("-----BEGIN CERTIFICATE-----", result["x509_ca"])
383 ebeb600f Michael Hanselmann
384 a47f574c Oleksiy Mishchenko
385 a47f574c Oleksiy Mishchenko
def TestNode(node):
386 a47f574c Oleksiy Mishchenko
  """Testing getting node(s) info via remote API.
387 a47f574c Oleksiy Mishchenko

388 a47f574c Oleksiy Mishchenko
  """
389 a47f574c Oleksiy Mishchenko
  def _VerifyNode(data):
390 a47f574c Oleksiy Mishchenko
    for entry in NODE_FIELDS:
391 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
392 c85d3b64 Michael Hanselmann
393 a47f574c Oleksiy Mishchenko
  def _VerifyNodesList(data):
394 a47f574c Oleksiy Mishchenko
    for node in data:
395 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
396 a47f574c Oleksiy Mishchenko
        AssertIn(entry, node)
397 c85d3b64 Michael Hanselmann
398 a47f574c Oleksiy Mishchenko
  def _VerifyNodesBulk(data):
399 a47f574c Oleksiy Mishchenko
    for node_data in data:
400 a47f574c Oleksiy Mishchenko
      _VerifyNode(node_data)
401 a47f574c Oleksiy Mishchenko
402 a47f574c Oleksiy Mishchenko
  _DoTests([
403 d0c8c01d Iustin Pop
    ("/2/nodes/%s" % node["primary"], _VerifyNode, "GET", None),
404 d0c8c01d Iustin Pop
    ("/2/nodes", _VerifyNodesList, "GET", None),
405 d0c8c01d Iustin Pop
    ("/2/nodes?bulk=1", _VerifyNodesBulk, "GET", None),
406 a47f574c Oleksiy Mishchenko
    ])
407 a47f574c Oleksiy Mishchenko
408 a47f574c Oleksiy Mishchenko
409 a47f574c Oleksiy Mishchenko
def TestTags(kind, name, tags):
410 a47f574c Oleksiy Mishchenko
  """Tests .../tags resources.
411 a47f574c Oleksiy Mishchenko

412 a47f574c Oleksiy Mishchenko
  """
413 a47f574c Oleksiy Mishchenko
  if kind == constants.TAG_CLUSTER:
414 a5b9d725 Iustin Pop
    uri = "/2/tags"
415 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_NODE:
416 a5b9d725 Iustin Pop
    uri = "/2/nodes/%s/tags" % name
417 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_INSTANCE:
418 a5b9d725 Iustin Pop
    uri = "/2/instances/%s/tags" % name
419 fe508a9d Michael Hanselmann
  elif kind == constants.TAG_NODEGROUP:
420 fe508a9d Michael Hanselmann
    uri = "/2/groups/%s/tags" % name
421 a47f574c Oleksiy Mishchenko
  else:
422 a47f574c Oleksiy Mishchenko
    raise errors.ProgrammerError("Unknown tag kind")
423 a47f574c Oleksiy Mishchenko
424 a47f574c Oleksiy Mishchenko
  def _VerifyTags(data):
425 94e63ca1 Michael Hanselmann
    AssertEqual(sorted(tags), sorted(data))
426 a47f574c Oleksiy Mishchenko
427 4fab7cab Michael Hanselmann
  queryargs = "&".join("tag=%s" % i for i in tags)
428 c326b4ef Michael Hanselmann
429 c326b4ef Michael Hanselmann
  # Add tags
430 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
431 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "PUT", None),
432 c326b4ef Michael Hanselmann
    ])
433 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
434 c326b4ef Michael Hanselmann
435 c326b4ef Michael Hanselmann
  # Retrieve tags
436 a47f574c Oleksiy Mishchenko
  _DoTests([
437 d0c8c01d Iustin Pop
    (uri, _VerifyTags, "GET", None),
438 a47f574c Oleksiy Mishchenko
    ])
439 8cb70e56 Michael Hanselmann
440 c326b4ef Michael Hanselmann
  # Remove tags
441 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
442 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "DELETE", None),
443 c326b4ef Michael Hanselmann
    ])
444 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
445 c326b4ef Michael Hanselmann
446 8cb70e56 Michael Hanselmann
447 8cb70e56 Michael Hanselmann
def _WaitForRapiJob(job_id):
448 8cb70e56 Michael Hanselmann
  """Waits for a job to finish.
449 8cb70e56 Michael Hanselmann

450 8cb70e56 Michael Hanselmann
  """
451 8cb70e56 Michael Hanselmann
  def _VerifyJob(data):
452 8cb70e56 Michael Hanselmann
    AssertEqual(data["id"], job_id)
453 8cb70e56 Michael Hanselmann
    for field in JOB_FIELDS:
454 8cb70e56 Michael Hanselmann
      AssertIn(field, data)
455 8cb70e56 Michael Hanselmann
456 8cb70e56 Michael Hanselmann
  _DoTests([
457 8cb70e56 Michael Hanselmann
    ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
458 8cb70e56 Michael Hanselmann
    ])
459 8cb70e56 Michael Hanselmann
460 ebeb600f Michael Hanselmann
  return rapi.client_utils.PollJob(_rapi_client, job_id,
461 ebeb600f Michael Hanselmann
                                   cli.StdioJobPollReportCb())
462 8cb70e56 Michael Hanselmann
463 8cb70e56 Michael Hanselmann
464 4b10fb65 Adeodato Simo
def TestRapiNodeGroups():
465 4b10fb65 Adeodato Simo
  """Test several node group operations using RAPI.
466 4b10fb65 Adeodato Simo

467 4b10fb65 Adeodato Simo
  """
468 4b10fb65 Adeodato Simo
  groups = qa_config.get("groups", {})
469 4b10fb65 Adeodato Simo
  group1, group2, group3 = groups.get("inexistent-groups",
470 4b10fb65 Adeodato Simo
                                      ["group1", "group2", "group3"])[:3]
471 4b10fb65 Adeodato Simo
472 4b10fb65 Adeodato Simo
  # Create a group with no attributes
473 4b10fb65 Adeodato Simo
  body = {
474 4b10fb65 Adeodato Simo
    "name": group1,
475 4b10fb65 Adeodato Simo
    }
476 4b10fb65 Adeodato Simo
477 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
478 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
479 4b10fb65 Adeodato Simo
    ])
480 4b10fb65 Adeodato Simo
481 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
482 4b10fb65 Adeodato Simo
483 4b10fb65 Adeodato Simo
  # Create a group specifying alloc_policy
484 4b10fb65 Adeodato Simo
  body = {
485 4b10fb65 Adeodato Simo
    "name": group2,
486 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
487 4b10fb65 Adeodato Simo
    }
488 4b10fb65 Adeodato Simo
489 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
490 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
491 4b10fb65 Adeodato Simo
    ])
492 4b10fb65 Adeodato Simo
493 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
494 4b10fb65 Adeodato Simo
495 4b10fb65 Adeodato Simo
  # Modify alloc_policy
496 4b10fb65 Adeodato Simo
  body = {
497 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
498 4b10fb65 Adeodato Simo
    }
499 4b10fb65 Adeodato Simo
500 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
501 4b10fb65 Adeodato Simo
    ("/2/groups/%s/modify" % group1, _VerifyReturnsJob, "PUT", body),
502 4b10fb65 Adeodato Simo
    ])
503 4b10fb65 Adeodato Simo
504 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
505 4b10fb65 Adeodato Simo
506 4b10fb65 Adeodato Simo
  # Rename a group
507 4b10fb65 Adeodato Simo
  body = {
508 4b10fb65 Adeodato Simo
    "new_name": group3,
509 4b10fb65 Adeodato Simo
    }
510 4b10fb65 Adeodato Simo
511 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
512 4b10fb65 Adeodato Simo
    ("/2/groups/%s/rename" % group2, _VerifyReturnsJob, "PUT", body),
513 4b10fb65 Adeodato Simo
    ])
514 4b10fb65 Adeodato Simo
515 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
516 4b10fb65 Adeodato Simo
517 4b10fb65 Adeodato Simo
  # Delete groups
518 4b10fb65 Adeodato Simo
  for group in [group1, group3]:
519 4b10fb65 Adeodato Simo
    (job_id, ) = _DoTests([
520 4b10fb65 Adeodato Simo
      ("/2/groups/%s" % group, _VerifyReturnsJob, "DELETE", None),
521 4b10fb65 Adeodato Simo
      ])
522 4b10fb65 Adeodato Simo
523 4b10fb65 Adeodato Simo
    _WaitForRapiJob(job_id)
524 4b10fb65 Adeodato Simo
525 4b10fb65 Adeodato Simo
526 924e95f9 Michael Hanselmann
def TestRapiInstanceAdd(node, use_client):
527 8cb70e56 Michael Hanselmann
  """Test adding a new instance via RAPI"""
528 8cb70e56 Michael Hanselmann
  instance = qa_config.AcquireInstance()
529 8cb70e56 Michael Hanselmann
  try:
530 924e95f9 Michael Hanselmann
    disk_sizes = [utils.ParseUnit(size) for size in qa_config.get("disk")]
531 713a79e7 Michael Hanselmann
    disks = [{"size": size} for size in disk_sizes]
532 713a79e7 Michael Hanselmann
    nics = [{}]
533 924e95f9 Michael Hanselmann
534 713a79e7 Michael Hanselmann
    beparams = {
535 8ccbbe4b Guido Trotter
      constants.BE_MAXMEM: utils.ParseUnit(qa_config.get(constants.BE_MAXMEM)),
536 8ccbbe4b Guido Trotter
      constants.BE_MINMEM: utils.ParseUnit(qa_config.get(constants.BE_MINMEM)),
537 713a79e7 Michael Hanselmann
      }
538 924e95f9 Michael Hanselmann
539 713a79e7 Michael Hanselmann
    if use_client:
540 924e95f9 Michael Hanselmann
      job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
541 924e95f9 Michael Hanselmann
                                           instance["name"],
542 924e95f9 Michael Hanselmann
                                           constants.DT_PLAIN,
543 924e95f9 Michael Hanselmann
                                           disks, nics,
544 924e95f9 Michael Hanselmann
                                           os=qa_config.get("os"),
545 924e95f9 Michael Hanselmann
                                           pnode=node["primary"],
546 924e95f9 Michael Hanselmann
                                           beparams=beparams)
547 924e95f9 Michael Hanselmann
    else:
548 924e95f9 Michael Hanselmann
      body = {
549 713a79e7 Michael Hanselmann
        "__version__": 1,
550 713a79e7 Michael Hanselmann
        "mode": constants.INSTANCE_CREATE,
551 924e95f9 Michael Hanselmann
        "name": instance["name"],
552 713a79e7 Michael Hanselmann
        "os_type": qa_config.get("os"),
553 924e95f9 Michael Hanselmann
        "disk_template": constants.DT_PLAIN,
554 924e95f9 Michael Hanselmann
        "pnode": node["primary"],
555 713a79e7 Michael Hanselmann
        "beparams": beparams,
556 713a79e7 Michael Hanselmann
        "disks": disks,
557 713a79e7 Michael Hanselmann
        "nics": nics,
558 924e95f9 Michael Hanselmann
        }
559 924e95f9 Michael Hanselmann
560 924e95f9 Michael Hanselmann
      (job_id, ) = _DoTests([
561 924e95f9 Michael Hanselmann
        ("/2/instances", _VerifyReturnsJob, "POST", body),
562 924e95f9 Michael Hanselmann
        ])
563 8cb70e56 Michael Hanselmann
564 8cb70e56 Michael Hanselmann
    _WaitForRapiJob(job_id)
565 8cb70e56 Michael Hanselmann
566 8cb70e56 Michael Hanselmann
    return instance
567 8cb70e56 Michael Hanselmann
  except:
568 8cb70e56 Michael Hanselmann
    qa_config.ReleaseInstance(instance)
569 8cb70e56 Michael Hanselmann
    raise
570 8cb70e56 Michael Hanselmann
571 8cb70e56 Michael Hanselmann
572 924e95f9 Michael Hanselmann
def TestRapiInstanceRemove(instance, use_client):
573 8cb70e56 Michael Hanselmann
  """Test removing instance via RAPI"""
574 924e95f9 Michael Hanselmann
  if use_client:
575 924e95f9 Michael Hanselmann
    job_id = _rapi_client.DeleteInstance(instance["name"])
576 924e95f9 Michael Hanselmann
  else:
577 924e95f9 Michael Hanselmann
    (job_id, ) = _DoTests([
578 924e95f9 Michael Hanselmann
      ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
579 924e95f9 Michael Hanselmann
      ])
580 8cb70e56 Michael Hanselmann
581 8cb70e56 Michael Hanselmann
  _WaitForRapiJob(job_id)
582 8cb70e56 Michael Hanselmann
583 8cb70e56 Michael Hanselmann
  qa_config.ReleaseInstance(instance)
584 5d831182 Michael Hanselmann
585 5d831182 Michael Hanselmann
586 938bde86 Michael Hanselmann
def TestRapiInstanceMigrate(instance):
587 938bde86 Michael Hanselmann
  """Test migrating instance via RAPI"""
588 938bde86 Michael Hanselmann
  # Move to secondary node
589 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
590 938bde86 Michael Hanselmann
  # And back to previous primary
591 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
592 c0a146a1 Michael Hanselmann
593 c0a146a1 Michael Hanselmann
594 c0a146a1 Michael Hanselmann
def TestRapiInstanceFailover(instance):
595 c0a146a1 Michael Hanselmann
  """Test failing over instance via RAPI"""
596 c0a146a1 Michael Hanselmann
  # Move to secondary node
597 c0a146a1 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
598 c0a146a1 Michael Hanselmann
  # And back to previous primary
599 c0a146a1 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
600 a7418448 Michael Hanselmann
601 a7418448 Michael Hanselmann
602 a7418448 Michael Hanselmann
def TestRapiInstanceShutdown(instance):
603 a7418448 Michael Hanselmann
  """Test stopping an instance via RAPI"""
604 a7418448 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ShutdownInstance(instance["name"]))
605 a7418448 Michael Hanselmann
606 a7418448 Michael Hanselmann
607 a7418448 Michael Hanselmann
def TestRapiInstanceStartup(instance):
608 a7418448 Michael Hanselmann
  """Test starting an instance via RAPI"""
609 a7418448 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.StartupInstance(instance["name"]))
610 938bde86 Michael Hanselmann
611 938bde86 Michael Hanselmann
612 4c1a464b Iustin Pop
def TestRapiInstanceRenameAndBack(rename_source, rename_target):
613 4c1a464b Iustin Pop
  """Test renaming instance via RAPI
614 4c1a464b Iustin Pop

615 4c1a464b Iustin Pop
  This must leave the instance with the original name (in the
616 4c1a464b Iustin Pop
  non-failure case).
617 4c1a464b Iustin Pop

618 4c1a464b Iustin Pop
  """
619 e5c2accd Guido Trotter
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
620 4c1a464b Iustin Pop
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_target, rename_source))
621 7fb50870 Michael Hanselmann
622 7fb50870 Michael Hanselmann
623 0220d2cf Guido Trotter
def TestRapiInstanceReinstall(instance):
624 0220d2cf Guido Trotter
  """Test reinstalling an instance via RAPI"""
625 0e265161 Guido Trotter
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"]))
626 0220d2cf Guido Trotter
627 0220d2cf Guido Trotter
628 539d65ba Michael Hanselmann
def TestRapiInstanceReplaceDisks(instance):
629 539d65ba Michael Hanselmann
  """Test replacing instance disks via RAPI"""
630 539d65ba Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ReplaceInstanceDisks(instance["name"],
631 539d65ba Michael Hanselmann
    mode=constants.REPLACE_DISK_AUTO, disks=[]))
632 539d65ba Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ReplaceInstanceDisks(instance["name"],
633 539d65ba Michael Hanselmann
    mode=constants.REPLACE_DISK_SEC, disks="0"))
634 539d65ba Michael Hanselmann
635 539d65ba Michael Hanselmann
636 3b7158ef Michael Hanselmann
def TestRapiInstanceModify(instance):
637 3b7158ef Michael Hanselmann
  """Test modifying instance via RAPI"""
638 3b7158ef Michael Hanselmann
  def _ModifyInstance(**kwargs):
639 3b7158ef Michael Hanselmann
    _WaitForRapiJob(_rapi_client.ModifyInstance(instance["name"], **kwargs))
640 3b7158ef Michael Hanselmann
641 3b7158ef Michael Hanselmann
  _ModifyInstance(hvparams={
642 3b7158ef Michael Hanselmann
    constants.HV_KERNEL_ARGS: "single",
643 3b7158ef Michael Hanselmann
    })
644 3b7158ef Michael Hanselmann
645 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
646 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: 3,
647 3b7158ef Michael Hanselmann
    })
648 3b7158ef Michael Hanselmann
649 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
650 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: constants.VALUE_DEFAULT,
651 3b7158ef Michael Hanselmann
    })
652 3b7158ef Michael Hanselmann
653 3b7158ef Michael Hanselmann
  _ModifyInstance(hvparams={
654 3b7158ef Michael Hanselmann
    constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
655 3b7158ef Michael Hanselmann
    })
656 3b7158ef Michael Hanselmann
657 3b7158ef Michael Hanselmann
658 b82d4c5e Michael Hanselmann
def TestRapiInstanceConsole(instance):
659 b82d4c5e Michael Hanselmann
  """Test getting instance console information via RAPI"""
660 b82d4c5e Michael Hanselmann
  result = _rapi_client.GetInstanceConsole(instance["name"])
661 b82d4c5e Michael Hanselmann
  console = objects.InstanceConsole.FromDict(result)
662 b82d4c5e Michael Hanselmann
  AssertEqual(console.Validate(), True)
663 b82d4c5e Michael Hanselmann
  AssertEqual(console.instance, qa_utils.ResolveInstanceName(instance["name"]))
664 b82d4c5e Michael Hanselmann
665 b82d4c5e Michael Hanselmann
666 b82d4c5e Michael Hanselmann
def TestRapiStoppedInstanceConsole(instance):
667 b82d4c5e Michael Hanselmann
  """Test getting stopped instance's console information via RAPI"""
668 b82d4c5e Michael Hanselmann
  try:
669 b82d4c5e Michael Hanselmann
    _rapi_client.GetInstanceConsole(instance["name"])
670 b82d4c5e Michael Hanselmann
  except rapi.client.GanetiApiError, err:
671 b82d4c5e Michael Hanselmann
    AssertEqual(err.code, 503)
672 b82d4c5e Michael Hanselmann
  else:
673 b82d4c5e Michael Hanselmann
    raise qa_error.Error("Getting console for stopped instance didn't"
674 b82d4c5e Michael Hanselmann
                         " return HTTP 503")
675 b82d4c5e Michael Hanselmann
676 b82d4c5e Michael Hanselmann
677 2932dc44 Michael Hanselmann
def GetOperatingSystems():
678 2932dc44 Michael Hanselmann
  """Retrieves a list of all available operating systems.
679 2932dc44 Michael Hanselmann

680 2932dc44 Michael Hanselmann
  """
681 2932dc44 Michael Hanselmann
  return _rapi_client.GetOperatingSystems()
682 2932dc44 Michael Hanselmann
683 2932dc44 Michael Hanselmann
684 638a7266 Iustin Pop
def TestInterClusterInstanceMove(src_instance, dest_instance,
685 638a7266 Iustin Pop
                                 pnode, snode, tnode):
686 5d831182 Michael Hanselmann
  """Test tools/move-instance"""
687 5d831182 Michael Hanselmann
  master = qa_config.GetMasterNode()
688 5d831182 Michael Hanselmann
689 5d831182 Michael Hanselmann
  rapi_pw_file = tempfile.NamedTemporaryFile()
690 5d831182 Michael Hanselmann
  rapi_pw_file.write(_rapi_password)
691 5d831182 Michael Hanselmann
  rapi_pw_file.flush()
692 5d831182 Michael Hanselmann
693 5d831182 Michael Hanselmann
  # TODO: Run some instance tests before moving back
694 677e16eb Iustin Pop
695 638a7266 Iustin Pop
  if snode is None:
696 638a7266 Iustin Pop
    # instance is not redundant, but we still need to pass a node
697 638a7266 Iustin Pop
    # (which will be ignored)
698 638a7266 Iustin Pop
    fsec = tnode
699 638a7266 Iustin Pop
  else:
700 638a7266 Iustin Pop
    fsec = snode
701 638a7266 Iustin Pop
  # note: pnode:snode are the *current* nodes, so we move it first to
702 638a7266 Iustin Pop
  # tnode:pnode, then back to pnode:snode
703 677e16eb Iustin Pop
  for si, di, pn, sn in [(src_instance["name"], dest_instance["name"],
704 638a7266 Iustin Pop
                          tnode["primary"], pnode["primary"]),
705 677e16eb Iustin Pop
                         (dest_instance["name"], src_instance["name"],
706 638a7266 Iustin Pop
                          pnode["primary"], fsec["primary"])]:
707 5d831182 Michael Hanselmann
    cmd = [
708 5d831182 Michael Hanselmann
      "../tools/move-instance",
709 5d831182 Michael Hanselmann
      "--verbose",
710 5d831182 Michael Hanselmann
      "--src-ca-file=%s" % _rapi_ca.name,
711 5d831182 Michael Hanselmann
      "--src-username=%s" % _rapi_username,
712 5d831182 Michael Hanselmann
      "--src-password-file=%s" % rapi_pw_file.name,
713 677e16eb Iustin Pop
      "--dest-instance-name=%s" % di,
714 677e16eb Iustin Pop
      "--dest-primary-node=%s" % pn,
715 677e16eb Iustin Pop
      "--dest-secondary-node=%s" % sn,
716 a889c536 Michael Hanselmann
      "--net=0:mac=%s" % constants.VALUE_GENERATE,
717 5d831182 Michael Hanselmann
      master["primary"],
718 5d831182 Michael Hanselmann
      master["primary"],
719 677e16eb Iustin Pop
      si,
720 5d831182 Michael Hanselmann
      ]
721 5d831182 Michael Hanselmann
722 5d831182 Michael Hanselmann
    AssertEqual(StartLocalCommand(cmd).wait(), 0)