Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ fe508a9d

History | View | Annotate | Download (18.8 kB)

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

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

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

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

153 a47f574c Oleksiy Mishchenko
  """
154 a47f574c Oleksiy Mishchenko
  _DoTests([
155 94e63ca1 Michael Hanselmann
    ("/version", constants.RAPI_VERSION, 'GET', None),
156 a47f574c Oleksiy Mishchenko
    ])
157 a47f574c Oleksiy Mishchenko
158 a47f574c Oleksiy Mishchenko
159 a47f574c Oleksiy Mishchenko
def TestEmptyCluster():
160 a47f574c Oleksiy Mishchenko
  """Testing remote API on an empty cluster.
161 a47f574c Oleksiy Mishchenko

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

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

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

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

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

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

466 4b10fb65 Adeodato Simo
  """
467 4b10fb65 Adeodato Simo
  groups = qa_config.get("groups", {})
468 4b10fb65 Adeodato Simo
  group1, group2, group3 = groups.get("inexistent-groups",
469 4b10fb65 Adeodato Simo
                                      ["group1", "group2", "group3"])[:3]
470 4b10fb65 Adeodato Simo
471 4b10fb65 Adeodato Simo
  # Create a group with no attributes
472 4b10fb65 Adeodato Simo
  body = {
473 4b10fb65 Adeodato Simo
    "name": group1,
474 4b10fb65 Adeodato Simo
    }
475 4b10fb65 Adeodato Simo
476 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
477 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
478 4b10fb65 Adeodato Simo
    ])
479 4b10fb65 Adeodato Simo
480 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
481 4b10fb65 Adeodato Simo
482 4b10fb65 Adeodato Simo
  # Create a group specifying alloc_policy
483 4b10fb65 Adeodato Simo
  body = {
484 4b10fb65 Adeodato Simo
    "name": group2,
485 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
486 4b10fb65 Adeodato Simo
    }
487 4b10fb65 Adeodato Simo
488 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
489 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
490 4b10fb65 Adeodato Simo
    ])
491 4b10fb65 Adeodato Simo
492 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
493 4b10fb65 Adeodato Simo
494 4b10fb65 Adeodato Simo
  # Modify alloc_policy
495 4b10fb65 Adeodato Simo
  body = {
496 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
497 4b10fb65 Adeodato Simo
    }
498 4b10fb65 Adeodato Simo
499 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
500 4b10fb65 Adeodato Simo
    ("/2/groups/%s/modify" % group1, _VerifyReturnsJob, "PUT", body),
501 4b10fb65 Adeodato Simo
    ])
502 4b10fb65 Adeodato Simo
503 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
504 4b10fb65 Adeodato Simo
505 4b10fb65 Adeodato Simo
  # Rename a group
506 4b10fb65 Adeodato Simo
  body = {
507 4b10fb65 Adeodato Simo
    "new_name": group3,
508 4b10fb65 Adeodato Simo
    }
509 4b10fb65 Adeodato Simo
510 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
511 4b10fb65 Adeodato Simo
    ("/2/groups/%s/rename" % group2, _VerifyReturnsJob, "PUT", body),
512 4b10fb65 Adeodato Simo
    ])
513 4b10fb65 Adeodato Simo
514 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
515 4b10fb65 Adeodato Simo
516 4b10fb65 Adeodato Simo
  # Delete groups
517 4b10fb65 Adeodato Simo
  for group in [group1, group3]:
518 4b10fb65 Adeodato Simo
    (job_id, ) = _DoTests([
519 4b10fb65 Adeodato Simo
      ("/2/groups/%s" % group, _VerifyReturnsJob, "DELETE", None),
520 4b10fb65 Adeodato Simo
      ])
521 4b10fb65 Adeodato Simo
522 4b10fb65 Adeodato Simo
    _WaitForRapiJob(job_id)
523 4b10fb65 Adeodato Simo
524 4b10fb65 Adeodato Simo
525 924e95f9 Michael Hanselmann
def TestRapiInstanceAdd(node, use_client):
526 8cb70e56 Michael Hanselmann
  """Test adding a new instance via RAPI"""
527 8cb70e56 Michael Hanselmann
  instance = qa_config.AcquireInstance()
528 8cb70e56 Michael Hanselmann
  try:
529 924e95f9 Michael Hanselmann
    memory = utils.ParseUnit(qa_config.get("mem"))
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 713a79e7 Michael Hanselmann
      constants.BE_MEMORY: memory,
536 713a79e7 Michael Hanselmann
      }
537 924e95f9 Michael Hanselmann
538 713a79e7 Michael Hanselmann
    if use_client:
539 924e95f9 Michael Hanselmann
      job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
540 924e95f9 Michael Hanselmann
                                           instance["name"],
541 924e95f9 Michael Hanselmann
                                           constants.DT_PLAIN,
542 924e95f9 Michael Hanselmann
                                           disks, nics,
543 924e95f9 Michael Hanselmann
                                           os=qa_config.get("os"),
544 924e95f9 Michael Hanselmann
                                           pnode=node["primary"],
545 924e95f9 Michael Hanselmann
                                           beparams=beparams)
546 924e95f9 Michael Hanselmann
    else:
547 924e95f9 Michael Hanselmann
      body = {
548 713a79e7 Michael Hanselmann
        "__version__": 1,
549 713a79e7 Michael Hanselmann
        "mode": constants.INSTANCE_CREATE,
550 924e95f9 Michael Hanselmann
        "name": instance["name"],
551 713a79e7 Michael Hanselmann
        "os_type": qa_config.get("os"),
552 924e95f9 Michael Hanselmann
        "disk_template": constants.DT_PLAIN,
553 924e95f9 Michael Hanselmann
        "pnode": node["primary"],
554 713a79e7 Michael Hanselmann
        "beparams": beparams,
555 713a79e7 Michael Hanselmann
        "disks": disks,
556 713a79e7 Michael Hanselmann
        "nics": nics,
557 924e95f9 Michael Hanselmann
        }
558 924e95f9 Michael Hanselmann
559 924e95f9 Michael Hanselmann
      (job_id, ) = _DoTests([
560 924e95f9 Michael Hanselmann
        ("/2/instances", _VerifyReturnsJob, "POST", body),
561 924e95f9 Michael Hanselmann
        ])
562 8cb70e56 Michael Hanselmann
563 8cb70e56 Michael Hanselmann
    _WaitForRapiJob(job_id)
564 8cb70e56 Michael Hanselmann
565 8cb70e56 Michael Hanselmann
    return instance
566 8cb70e56 Michael Hanselmann
  except:
567 8cb70e56 Michael Hanselmann
    qa_config.ReleaseInstance(instance)
568 8cb70e56 Michael Hanselmann
    raise
569 8cb70e56 Michael Hanselmann
570 8cb70e56 Michael Hanselmann
571 924e95f9 Michael Hanselmann
def TestRapiInstanceRemove(instance, use_client):
572 8cb70e56 Michael Hanselmann
  """Test removing instance via RAPI"""
573 924e95f9 Michael Hanselmann
  if use_client:
574 924e95f9 Michael Hanselmann
    job_id = _rapi_client.DeleteInstance(instance["name"])
575 924e95f9 Michael Hanselmann
  else:
576 924e95f9 Michael Hanselmann
    (job_id, ) = _DoTests([
577 924e95f9 Michael Hanselmann
      ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
578 924e95f9 Michael Hanselmann
      ])
579 8cb70e56 Michael Hanselmann
580 8cb70e56 Michael Hanselmann
  _WaitForRapiJob(job_id)
581 8cb70e56 Michael Hanselmann
582 8cb70e56 Michael Hanselmann
  qa_config.ReleaseInstance(instance)
583 5d831182 Michael Hanselmann
584 5d831182 Michael Hanselmann
585 938bde86 Michael Hanselmann
def TestRapiInstanceMigrate(instance):
586 938bde86 Michael Hanselmann
  """Test migrating instance via RAPI"""
587 938bde86 Michael Hanselmann
  # Move to secondary node
588 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
589 938bde86 Michael Hanselmann
  # And back to previous primary
590 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
591 938bde86 Michael Hanselmann
592 938bde86 Michael Hanselmann
593 e5c2accd Guido Trotter
def TestRapiInstanceRename(rename_source, rename_target):
594 7fb50870 Michael Hanselmann
  """Test renaming instance via RAPI"""
595 e5c2accd Guido Trotter
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
596 7fb50870 Michael Hanselmann
597 7fb50870 Michael Hanselmann
598 0220d2cf Guido Trotter
def TestRapiInstanceReinstall(instance):
599 0220d2cf Guido Trotter
  """Test reinstalling an instance via RAPI"""
600 0e265161 Guido Trotter
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"]))
601 0220d2cf Guido Trotter
602 0220d2cf Guido Trotter
603 3b7158ef Michael Hanselmann
def TestRapiInstanceModify(instance):
604 3b7158ef Michael Hanselmann
  """Test modifying instance via RAPI"""
605 3b7158ef Michael Hanselmann
  def _ModifyInstance(**kwargs):
606 3b7158ef Michael Hanselmann
    _WaitForRapiJob(_rapi_client.ModifyInstance(instance["name"], **kwargs))
607 3b7158ef Michael Hanselmann
608 3b7158ef Michael Hanselmann
  _ModifyInstance(hvparams={
609 3b7158ef Michael Hanselmann
    constants.HV_KERNEL_ARGS: "single",
610 3b7158ef Michael Hanselmann
    })
611 3b7158ef Michael Hanselmann
612 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
613 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: 3,
614 3b7158ef Michael Hanselmann
    })
615 3b7158ef Michael Hanselmann
616 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
617 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: constants.VALUE_DEFAULT,
618 3b7158ef Michael Hanselmann
    })
619 3b7158ef Michael Hanselmann
620 3b7158ef Michael Hanselmann
  _ModifyInstance(hvparams={
621 3b7158ef Michael Hanselmann
    constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
622 3b7158ef Michael Hanselmann
    })
623 3b7158ef Michael Hanselmann
624 3b7158ef Michael Hanselmann
625 b82d4c5e Michael Hanselmann
def TestRapiInstanceConsole(instance):
626 b82d4c5e Michael Hanselmann
  """Test getting instance console information via RAPI"""
627 b82d4c5e Michael Hanselmann
  result = _rapi_client.GetInstanceConsole(instance["name"])
628 b82d4c5e Michael Hanselmann
  console = objects.InstanceConsole.FromDict(result)
629 b82d4c5e Michael Hanselmann
  AssertEqual(console.Validate(), True)
630 b82d4c5e Michael Hanselmann
  AssertEqual(console.instance, qa_utils.ResolveInstanceName(instance["name"]))
631 b82d4c5e Michael Hanselmann
632 b82d4c5e Michael Hanselmann
633 b82d4c5e Michael Hanselmann
def TestRapiStoppedInstanceConsole(instance):
634 b82d4c5e Michael Hanselmann
  """Test getting stopped instance's console information via RAPI"""
635 b82d4c5e Michael Hanselmann
  try:
636 b82d4c5e Michael Hanselmann
    _rapi_client.GetInstanceConsole(instance["name"])
637 b82d4c5e Michael Hanselmann
  except rapi.client.GanetiApiError, err:
638 b82d4c5e Michael Hanselmann
    AssertEqual(err.code, 503)
639 b82d4c5e Michael Hanselmann
  else:
640 b82d4c5e Michael Hanselmann
    raise qa_error.Error("Getting console for stopped instance didn't"
641 b82d4c5e Michael Hanselmann
                         " return HTTP 503")
642 b82d4c5e Michael Hanselmann
643 b82d4c5e Michael Hanselmann
644 2932dc44 Michael Hanselmann
def GetOperatingSystems():
645 2932dc44 Michael Hanselmann
  """Retrieves a list of all available operating systems.
646 2932dc44 Michael Hanselmann

647 2932dc44 Michael Hanselmann
  """
648 2932dc44 Michael Hanselmann
  return _rapi_client.GetOperatingSystems()
649 2932dc44 Michael Hanselmann
650 2932dc44 Michael Hanselmann
651 638a7266 Iustin Pop
def TestInterClusterInstanceMove(src_instance, dest_instance,
652 638a7266 Iustin Pop
                                 pnode, snode, tnode):
653 5d831182 Michael Hanselmann
  """Test tools/move-instance"""
654 5d831182 Michael Hanselmann
  master = qa_config.GetMasterNode()
655 5d831182 Michael Hanselmann
656 5d831182 Michael Hanselmann
  rapi_pw_file = tempfile.NamedTemporaryFile()
657 5d831182 Michael Hanselmann
  rapi_pw_file.write(_rapi_password)
658 5d831182 Michael Hanselmann
  rapi_pw_file.flush()
659 5d831182 Michael Hanselmann
660 5d831182 Michael Hanselmann
  # TODO: Run some instance tests before moving back
661 677e16eb Iustin Pop
662 638a7266 Iustin Pop
  if snode is None:
663 638a7266 Iustin Pop
    # instance is not redundant, but we still need to pass a node
664 638a7266 Iustin Pop
    # (which will be ignored)
665 638a7266 Iustin Pop
    fsec = tnode
666 638a7266 Iustin Pop
  else:
667 638a7266 Iustin Pop
    fsec = snode
668 638a7266 Iustin Pop
  # note: pnode:snode are the *current* nodes, so we move it first to
669 638a7266 Iustin Pop
  # tnode:pnode, then back to pnode:snode
670 677e16eb Iustin Pop
  for si, di, pn, sn in [(src_instance["name"], dest_instance["name"],
671 638a7266 Iustin Pop
                          tnode["primary"], pnode["primary"]),
672 677e16eb Iustin Pop
                         (dest_instance["name"], src_instance["name"],
673 638a7266 Iustin Pop
                          pnode["primary"], fsec["primary"])]:
674 5d831182 Michael Hanselmann
    cmd = [
675 5d831182 Michael Hanselmann
      "../tools/move-instance",
676 5d831182 Michael Hanselmann
      "--verbose",
677 5d831182 Michael Hanselmann
      "--src-ca-file=%s" % _rapi_ca.name,
678 5d831182 Michael Hanselmann
      "--src-username=%s" % _rapi_username,
679 5d831182 Michael Hanselmann
      "--src-password-file=%s" % rapi_pw_file.name,
680 677e16eb Iustin Pop
      "--dest-instance-name=%s" % di,
681 677e16eb Iustin Pop
      "--dest-primary-node=%s" % pn,
682 677e16eb Iustin Pop
      "--dest-secondary-node=%s" % sn,
683 a889c536 Michael Hanselmann
      "--net=0:mac=%s" % constants.VALUE_GENERATE,
684 5d831182 Michael Hanselmann
      master["primary"],
685 5d831182 Michael Hanselmann
      master["primary"],
686 677e16eb Iustin Pop
      si,
687 5d831182 Michael Hanselmann
      ]
688 5d831182 Michael Hanselmann
689 5d831182 Michael Hanselmann
    AssertEqual(StartLocalCommand(cmd).wait(), 0)