Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ 6a654276

History | View | Annotate | Download (23.1 kB)

1 a47f574c Oleksiy Mishchenko
#
2 fd7b69c0 Michael Hanselmann
#
3 a47f574c Oleksiy Mishchenko
4 906a0346 Bernardo Dal Seno
# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 c1513c7f Michael Hanselmann
import re
29 c1513c7f Michael Hanselmann
import itertools
30 a47f574c Oleksiy Mishchenko
31 a47f574c Oleksiy Mishchenko
from ganeti import utils
32 a47f574c Oleksiy Mishchenko
from ganeti import constants
33 a47f574c Oleksiy Mishchenko
from ganeti import errors
34 2771835c Michael Hanselmann
from ganeti import cli
35 2771835c Michael Hanselmann
from ganeti import rapi
36 b82d4c5e Michael Hanselmann
from ganeti import objects
37 4fab7cab Michael Hanselmann
from ganeti import query
38 4fab7cab Michael Hanselmann
from ganeti import compat
39 4fab7cab Michael Hanselmann
from ganeti import qlang
40 304d9f02 Michael Hanselmann
from ganeti import pathutils
41 2771835c Michael Hanselmann
42 b459a848 Andrea Spadaccini
import ganeti.rapi.client        # pylint: disable=W0611
43 2771835c Michael Hanselmann
import ganeti.rapi.client_utils
44 a47f574c Oleksiy Mishchenko
45 a47f574c Oleksiy Mishchenko
import qa_config
46 a47f574c Oleksiy Mishchenko
import qa_utils
47 a47f574c Oleksiy Mishchenko
import qa_error
48 a47f574c Oleksiy Mishchenko
49 5de31440 Bernardo Dal Seno
from qa_instance import IsFailoverSupported
50 5de31440 Bernardo Dal Seno
from qa_instance import IsMigrationSupported
51 5de31440 Bernardo Dal Seno
from qa_instance import IsDiskReplacingSupported
52 3582eef6 Iustin Pop
from qa_utils import (AssertEqual, AssertIn, AssertMatch, StartLocalCommand)
53 5fa0375e Michael Hanselmann
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG
54 a47f574c Oleksiy Mishchenko
55 a47f574c Oleksiy Mishchenko
56 2771835c Michael Hanselmann
_rapi_ca = None
57 2771835c Michael Hanselmann
_rapi_client = None
58 5d831182 Michael Hanselmann
_rapi_username = None
59 5d831182 Michael Hanselmann
_rapi_password = None
60 e6ce18ac René Nussbaumer
61 e6ce18ac René Nussbaumer
62 2771835c Michael Hanselmann
def Setup(username, password):
63 2771835c Michael Hanselmann
  """Configures the RAPI client.
64 725ec2f1 René Nussbaumer

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

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

162 a47f574c Oleksiy Mishchenko
  """
163 a47f574c Oleksiy Mishchenko
  _DoTests([
164 d0c8c01d Iustin Pop
    ("/version", constants.RAPI_VERSION, "GET", None),
165 a47f574c Oleksiy Mishchenko
    ])
166 a47f574c Oleksiy Mishchenko
167 a47f574c Oleksiy Mishchenko
168 a47f574c Oleksiy Mishchenko
def TestEmptyCluster():
169 a47f574c Oleksiy Mishchenko
  """Testing remote API on an empty cluster.
170 a47f574c Oleksiy Mishchenko

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

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

365 a47f574c Oleksiy Mishchenko
  """
366 a47f574c Oleksiy Mishchenko
  def _VerifyInstance(data):
367 a47f574c Oleksiy Mishchenko
    for entry in INSTANCE_FIELDS:
368 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
369 c85d3b64 Michael Hanselmann
370 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesList(data):
371 a47f574c Oleksiy Mishchenko
    for instance in data:
372 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
373 a47f574c Oleksiy Mishchenko
        AssertIn(entry, instance)
374 c85d3b64 Michael Hanselmann
375 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesBulk(data):
376 a47f574c Oleksiy Mishchenko
    for instance_data in data:
377 a47f574c Oleksiy Mishchenko
      _VerifyInstance(instance_data)
378 a47f574c Oleksiy Mishchenko
379 a47f574c Oleksiy Mishchenko
  _DoTests([
380 d0c8c01d Iustin Pop
    ("/2/instances/%s" % instance["name"], _VerifyInstance, "GET", None),
381 d0c8c01d Iustin Pop
    ("/2/instances", _VerifyInstancesList, "GET", None),
382 d0c8c01d Iustin Pop
    ("/2/instances?bulk=1", _VerifyInstancesBulk, "GET", None),
383 94e63ca1 Michael Hanselmann
    ("/2/instances/%s/activate-disks" % instance["name"],
384 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
385 94e63ca1 Michael Hanselmann
    ("/2/instances/%s/deactivate-disks" % instance["name"],
386 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
387 a47f574c Oleksiy Mishchenko
    ])
388 a47f574c Oleksiy Mishchenko
389 71910715 Iustin Pop
  # Test OpBackupPrepare
390 ebeb600f Michael Hanselmann
  (job_id, ) = _DoTests([
391 ebeb600f Michael Hanselmann
    ("/2/instances/%s/prepare-export?mode=%s" %
392 ebeb600f Michael Hanselmann
     (instance["name"], constants.EXPORT_MODE_REMOTE),
393 ebeb600f Michael Hanselmann
     _VerifyReturnsJob, "PUT", None),
394 ebeb600f Michael Hanselmann
    ])
395 ebeb600f Michael Hanselmann
396 ebeb600f Michael Hanselmann
  result = _WaitForRapiJob(job_id)[0]
397 ebeb600f Michael Hanselmann
  AssertEqual(len(result["handshake"]), 3)
398 ebeb600f Michael Hanselmann
  AssertEqual(result["handshake"][0], constants.RIE_VERSION)
399 ebeb600f Michael Hanselmann
  AssertEqual(len(result["x509_key_name"]), 3)
400 ebeb600f Michael Hanselmann
  AssertIn("-----BEGIN CERTIFICATE-----", result["x509_ca"])
401 ebeb600f Michael Hanselmann
402 a47f574c Oleksiy Mishchenko
403 a47f574c Oleksiy Mishchenko
def TestNode(node):
404 a47f574c Oleksiy Mishchenko
  """Testing getting node(s) info via remote API.
405 a47f574c Oleksiy Mishchenko

406 a47f574c Oleksiy Mishchenko
  """
407 a47f574c Oleksiy Mishchenko
  def _VerifyNode(data):
408 a47f574c Oleksiy Mishchenko
    for entry in NODE_FIELDS:
409 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
410 c85d3b64 Michael Hanselmann
411 a47f574c Oleksiy Mishchenko
  def _VerifyNodesList(data):
412 a47f574c Oleksiy Mishchenko
    for node in data:
413 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
414 a47f574c Oleksiy Mishchenko
        AssertIn(entry, node)
415 c85d3b64 Michael Hanselmann
416 a47f574c Oleksiy Mishchenko
  def _VerifyNodesBulk(data):
417 a47f574c Oleksiy Mishchenko
    for node_data in data:
418 a47f574c Oleksiy Mishchenko
      _VerifyNode(node_data)
419 a47f574c Oleksiy Mishchenko
420 a47f574c Oleksiy Mishchenko
  _DoTests([
421 d0c8c01d Iustin Pop
    ("/2/nodes/%s" % node["primary"], _VerifyNode, "GET", None),
422 d0c8c01d Iustin Pop
    ("/2/nodes", _VerifyNodesList, "GET", None),
423 d0c8c01d Iustin Pop
    ("/2/nodes?bulk=1", _VerifyNodesBulk, "GET", None),
424 a47f574c Oleksiy Mishchenko
    ])
425 a47f574c Oleksiy Mishchenko
426 a47f574c Oleksiy Mishchenko
427 c1513c7f Michael Hanselmann
def _FilterTags(seq):
428 c1513c7f Michael Hanselmann
  """Removes unwanted tags from a sequence.
429 c1513c7f Michael Hanselmann

430 c1513c7f Michael Hanselmann
  """
431 c1513c7f Michael Hanselmann
  ignore_re = qa_config.get("ignore-tags-re", None)
432 c1513c7f Michael Hanselmann
433 c1513c7f Michael Hanselmann
  if ignore_re:
434 c1513c7f Michael Hanselmann
    return itertools.ifilterfalse(re.compile(ignore_re).match, seq)
435 c1513c7f Michael Hanselmann
  else:
436 c1513c7f Michael Hanselmann
    return seq
437 c1513c7f Michael Hanselmann
438 c1513c7f Michael Hanselmann
439 a47f574c Oleksiy Mishchenko
def TestTags(kind, name, tags):
440 a47f574c Oleksiy Mishchenko
  """Tests .../tags resources.
441 a47f574c Oleksiy Mishchenko

442 a47f574c Oleksiy Mishchenko
  """
443 a47f574c Oleksiy Mishchenko
  if kind == constants.TAG_CLUSTER:
444 a5b9d725 Iustin Pop
    uri = "/2/tags"
445 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_NODE:
446 a5b9d725 Iustin Pop
    uri = "/2/nodes/%s/tags" % name
447 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_INSTANCE:
448 a5b9d725 Iustin Pop
    uri = "/2/instances/%s/tags" % name
449 fe508a9d Michael Hanselmann
  elif kind == constants.TAG_NODEGROUP:
450 fe508a9d Michael Hanselmann
    uri = "/2/groups/%s/tags" % name
451 a47f574c Oleksiy Mishchenko
  else:
452 a47f574c Oleksiy Mishchenko
    raise errors.ProgrammerError("Unknown tag kind")
453 a47f574c Oleksiy Mishchenko
454 a47f574c Oleksiy Mishchenko
  def _VerifyTags(data):
455 c1513c7f Michael Hanselmann
    AssertEqual(sorted(tags), sorted(_FilterTags(data)))
456 a47f574c Oleksiy Mishchenko
457 4fab7cab Michael Hanselmann
  queryargs = "&".join("tag=%s" % i for i in tags)
458 c326b4ef Michael Hanselmann
459 c326b4ef Michael Hanselmann
  # Add tags
460 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
461 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "PUT", None),
462 c326b4ef Michael Hanselmann
    ])
463 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
464 c326b4ef Michael Hanselmann
465 c326b4ef Michael Hanselmann
  # Retrieve tags
466 a47f574c Oleksiy Mishchenko
  _DoTests([
467 d0c8c01d Iustin Pop
    (uri, _VerifyTags, "GET", None),
468 a47f574c Oleksiy Mishchenko
    ])
469 8cb70e56 Michael Hanselmann
470 c326b4ef Michael Hanselmann
  # Remove tags
471 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
472 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "DELETE", None),
473 c326b4ef Michael Hanselmann
    ])
474 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
475 c326b4ef Michael Hanselmann
476 8cb70e56 Michael Hanselmann
477 8cb70e56 Michael Hanselmann
def _WaitForRapiJob(job_id):
478 8cb70e56 Michael Hanselmann
  """Waits for a job to finish.
479 8cb70e56 Michael Hanselmann

480 8cb70e56 Michael Hanselmann
  """
481 8cb70e56 Michael Hanselmann
  def _VerifyJob(data):
482 8cb70e56 Michael Hanselmann
    AssertEqual(data["id"], job_id)
483 8cb70e56 Michael Hanselmann
    for field in JOB_FIELDS:
484 8cb70e56 Michael Hanselmann
      AssertIn(field, data)
485 8cb70e56 Michael Hanselmann
486 8cb70e56 Michael Hanselmann
  _DoTests([
487 8cb70e56 Michael Hanselmann
    ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
488 8cb70e56 Michael Hanselmann
    ])
489 8cb70e56 Michael Hanselmann
490 ebeb600f Michael Hanselmann
  return rapi.client_utils.PollJob(_rapi_client, job_id,
491 ebeb600f Michael Hanselmann
                                   cli.StdioJobPollReportCb())
492 8cb70e56 Michael Hanselmann
493 8cb70e56 Michael Hanselmann
494 4b10fb65 Adeodato Simo
def TestRapiNodeGroups():
495 4b10fb65 Adeodato Simo
  """Test several node group operations using RAPI.
496 4b10fb65 Adeodato Simo

497 4b10fb65 Adeodato Simo
  """
498 b4d2d2cb Michael Hanselmann
  (group1, group2, group3) = qa_utils.GetNonexistentGroups(3)
499 4b10fb65 Adeodato Simo
500 4b10fb65 Adeodato Simo
  # Create a group with no attributes
501 4b10fb65 Adeodato Simo
  body = {
502 4b10fb65 Adeodato Simo
    "name": group1,
503 4b10fb65 Adeodato Simo
    }
504 4b10fb65 Adeodato Simo
505 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
506 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
507 4b10fb65 Adeodato Simo
    ])
508 4b10fb65 Adeodato Simo
509 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
510 4b10fb65 Adeodato Simo
511 4b10fb65 Adeodato Simo
  # Create a group specifying alloc_policy
512 4b10fb65 Adeodato Simo
  body = {
513 4b10fb65 Adeodato Simo
    "name": group2,
514 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
515 4b10fb65 Adeodato Simo
    }
516 4b10fb65 Adeodato Simo
517 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
518 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
519 4b10fb65 Adeodato Simo
    ])
520 4b10fb65 Adeodato Simo
521 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
522 4b10fb65 Adeodato Simo
523 4b10fb65 Adeodato Simo
  # Modify alloc_policy
524 4b10fb65 Adeodato Simo
  body = {
525 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
526 4b10fb65 Adeodato Simo
    }
527 4b10fb65 Adeodato Simo
528 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
529 4b10fb65 Adeodato Simo
    ("/2/groups/%s/modify" % group1, _VerifyReturnsJob, "PUT", body),
530 4b10fb65 Adeodato Simo
    ])
531 4b10fb65 Adeodato Simo
532 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
533 4b10fb65 Adeodato Simo
534 4b10fb65 Adeodato Simo
  # Rename a group
535 4b10fb65 Adeodato Simo
  body = {
536 4b10fb65 Adeodato Simo
    "new_name": group3,
537 4b10fb65 Adeodato Simo
    }
538 4b10fb65 Adeodato Simo
539 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
540 4b10fb65 Adeodato Simo
    ("/2/groups/%s/rename" % group2, _VerifyReturnsJob, "PUT", body),
541 4b10fb65 Adeodato Simo
    ])
542 4b10fb65 Adeodato Simo
543 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
544 4b10fb65 Adeodato Simo
545 4b10fb65 Adeodato Simo
  # Delete groups
546 4b10fb65 Adeodato Simo
  for group in [group1, group3]:
547 4b10fb65 Adeodato Simo
    (job_id, ) = _DoTests([
548 4b10fb65 Adeodato Simo
      ("/2/groups/%s" % group, _VerifyReturnsJob, "DELETE", None),
549 4b10fb65 Adeodato Simo
      ])
550 4b10fb65 Adeodato Simo
551 4b10fb65 Adeodato Simo
    _WaitForRapiJob(job_id)
552 4b10fb65 Adeodato Simo
553 4b10fb65 Adeodato Simo
554 924e95f9 Michael Hanselmann
def TestRapiInstanceAdd(node, use_client):
555 8cb70e56 Michael Hanselmann
  """Test adding a new instance via RAPI"""
556 8cb70e56 Michael Hanselmann
  instance = qa_config.AcquireInstance()
557 906a0346 Bernardo Dal Seno
  qa_config.SetInstanceTemplate(instance, constants.DT_PLAIN)
558 8cb70e56 Michael Hanselmann
  try:
559 924e95f9 Michael Hanselmann
    disk_sizes = [utils.ParseUnit(size) for size in qa_config.get("disk")]
560 713a79e7 Michael Hanselmann
    disks = [{"size": size} for size in disk_sizes]
561 f346a7d9 Michael Hanselmann
    nic0_mac = qa_config.GetInstanceNicMac(instance,
562 f346a7d9 Michael Hanselmann
                                           default=constants.VALUE_GENERATE)
563 f346a7d9 Michael Hanselmann
    nics = [{
564 f346a7d9 Michael Hanselmann
      constants.INIC_MAC: nic0_mac,
565 f346a7d9 Michael Hanselmann
      }]
566 924e95f9 Michael Hanselmann
567 713a79e7 Michael Hanselmann
    beparams = {
568 8ccbbe4b Guido Trotter
      constants.BE_MAXMEM: utils.ParseUnit(qa_config.get(constants.BE_MAXMEM)),
569 8ccbbe4b Guido Trotter
      constants.BE_MINMEM: utils.ParseUnit(qa_config.get(constants.BE_MINMEM)),
570 713a79e7 Michael Hanselmann
      }
571 924e95f9 Michael Hanselmann
572 713a79e7 Michael Hanselmann
    if use_client:
573 924e95f9 Michael Hanselmann
      job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
574 924e95f9 Michael Hanselmann
                                           instance["name"],
575 924e95f9 Michael Hanselmann
                                           constants.DT_PLAIN,
576 924e95f9 Michael Hanselmann
                                           disks, nics,
577 924e95f9 Michael Hanselmann
                                           os=qa_config.get("os"),
578 924e95f9 Michael Hanselmann
                                           pnode=node["primary"],
579 924e95f9 Michael Hanselmann
                                           beparams=beparams)
580 924e95f9 Michael Hanselmann
    else:
581 924e95f9 Michael Hanselmann
      body = {
582 713a79e7 Michael Hanselmann
        "__version__": 1,
583 713a79e7 Michael Hanselmann
        "mode": constants.INSTANCE_CREATE,
584 924e95f9 Michael Hanselmann
        "name": instance["name"],
585 713a79e7 Michael Hanselmann
        "os_type": qa_config.get("os"),
586 924e95f9 Michael Hanselmann
        "disk_template": constants.DT_PLAIN,
587 924e95f9 Michael Hanselmann
        "pnode": node["primary"],
588 713a79e7 Michael Hanselmann
        "beparams": beparams,
589 713a79e7 Michael Hanselmann
        "disks": disks,
590 713a79e7 Michael Hanselmann
        "nics": nics,
591 924e95f9 Michael Hanselmann
        }
592 924e95f9 Michael Hanselmann
593 924e95f9 Michael Hanselmann
      (job_id, ) = _DoTests([
594 924e95f9 Michael Hanselmann
        ("/2/instances", _VerifyReturnsJob, "POST", body),
595 924e95f9 Michael Hanselmann
        ])
596 8cb70e56 Michael Hanselmann
597 8cb70e56 Michael Hanselmann
    _WaitForRapiJob(job_id)
598 8cb70e56 Michael Hanselmann
599 8cb70e56 Michael Hanselmann
    return instance
600 8cb70e56 Michael Hanselmann
  except:
601 8cb70e56 Michael Hanselmann
    qa_config.ReleaseInstance(instance)
602 8cb70e56 Michael Hanselmann
    raise
603 8cb70e56 Michael Hanselmann
604 8cb70e56 Michael Hanselmann
605 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
606 924e95f9 Michael Hanselmann
def TestRapiInstanceRemove(instance, use_client):
607 8cb70e56 Michael Hanselmann
  """Test removing instance via RAPI"""
608 924e95f9 Michael Hanselmann
  if use_client:
609 924e95f9 Michael Hanselmann
    job_id = _rapi_client.DeleteInstance(instance["name"])
610 924e95f9 Michael Hanselmann
  else:
611 924e95f9 Michael Hanselmann
    (job_id, ) = _DoTests([
612 924e95f9 Michael Hanselmann
      ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
613 924e95f9 Michael Hanselmann
      ])
614 8cb70e56 Michael Hanselmann
615 8cb70e56 Michael Hanselmann
  _WaitForRapiJob(job_id)
616 8cb70e56 Michael Hanselmann
617 5d831182 Michael Hanselmann
618 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
619 938bde86 Michael Hanselmann
def TestRapiInstanceMigrate(instance):
620 938bde86 Michael Hanselmann
  """Test migrating instance via RAPI"""
621 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
622 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
623 5de31440 Bernardo Dal Seno
                              " test")
624 5de31440 Bernardo Dal Seno
    return
625 938bde86 Michael Hanselmann
  # Move to secondary node
626 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
627 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
628 938bde86 Michael Hanselmann
  # And back to previous primary
629 938bde86 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
630 c0a146a1 Michael Hanselmann
631 c0a146a1 Michael Hanselmann
632 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
633 c0a146a1 Michael Hanselmann
def TestRapiInstanceFailover(instance):
634 c0a146a1 Michael Hanselmann
  """Test failing over instance via RAPI"""
635 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
636 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
637 5de31440 Bernardo Dal Seno
                              " test")
638 5de31440 Bernardo Dal Seno
    return
639 c0a146a1 Michael Hanselmann
  # Move to secondary node
640 c0a146a1 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
641 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
642 c0a146a1 Michael Hanselmann
  # And back to previous primary
643 c0a146a1 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
644 a7418448 Michael Hanselmann
645 a7418448 Michael Hanselmann
646 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
647 a7418448 Michael Hanselmann
def TestRapiInstanceShutdown(instance):
648 a7418448 Michael Hanselmann
  """Test stopping an instance via RAPI"""
649 a7418448 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ShutdownInstance(instance["name"]))
650 a7418448 Michael Hanselmann
651 a7418448 Michael Hanselmann
652 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
653 a7418448 Michael Hanselmann
def TestRapiInstanceStartup(instance):
654 a7418448 Michael Hanselmann
  """Test starting an instance via RAPI"""
655 a7418448 Michael Hanselmann
  _WaitForRapiJob(_rapi_client.StartupInstance(instance["name"]))
656 938bde86 Michael Hanselmann
657 938bde86 Michael Hanselmann
658 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
659 4c1a464b Iustin Pop
def TestRapiInstanceRenameAndBack(rename_source, rename_target):
660 4c1a464b Iustin Pop
  """Test renaming instance via RAPI
661 4c1a464b Iustin Pop

662 4c1a464b Iustin Pop
  This must leave the instance with the original name (in the
663 4c1a464b Iustin Pop
  non-failure case).
664 4c1a464b Iustin Pop

665 4c1a464b Iustin Pop
  """
666 e5c2accd Guido Trotter
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
667 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
668 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
669 4c1a464b Iustin Pop
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_target, rename_source))
670 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
671 7fb50870 Michael Hanselmann
672 7fb50870 Michael Hanselmann
673 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
674 0220d2cf Guido Trotter
def TestRapiInstanceReinstall(instance):
675 0220d2cf Guido Trotter
  """Test reinstalling an instance via RAPI"""
676 0e265161 Guido Trotter
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"]))
677 51131cad Michael Hanselmann
  # By default, the instance is started again
678 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
679 51131cad Michael Hanselmann
680 51131cad Michael Hanselmann
  # Reinstall again without starting
681 51131cad Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"],
682 51131cad Michael Hanselmann
                                                 no_startup=True))
683 0220d2cf Guido Trotter
684 0220d2cf Guido Trotter
685 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
686 539d65ba Michael Hanselmann
def TestRapiInstanceReplaceDisks(instance):
687 539d65ba Michael Hanselmann
  """Test replacing instance disks via RAPI"""
688 5de31440 Bernardo Dal Seno
  if not IsDiskReplacingSupported(instance):
689 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disk replacing,"
690 5de31440 Bernardo Dal Seno
                              " skipping test")
691 5de31440 Bernardo Dal Seno
    return
692 5ae4945a Iustin Pop
  fn = _rapi_client.ReplaceInstanceDisks
693 5ae4945a Iustin Pop
  _WaitForRapiJob(fn(instance["name"],
694 5ae4945a Iustin Pop
                     mode=constants.REPLACE_DISK_AUTO, disks=[]))
695 5ae4945a Iustin Pop
  _WaitForRapiJob(fn(instance["name"],
696 5ae4945a Iustin Pop
                     mode=constants.REPLACE_DISK_SEC, disks="0"))
697 539d65ba Michael Hanselmann
698 539d65ba Michael Hanselmann
699 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
700 3b7158ef Michael Hanselmann
def TestRapiInstanceModify(instance):
701 3b7158ef Michael Hanselmann
  """Test modifying instance via RAPI"""
702 a8dbf746 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
703 a8dbf746 Michael Hanselmann
704 3b7158ef Michael Hanselmann
  def _ModifyInstance(**kwargs):
705 3b7158ef Michael Hanselmann
    _WaitForRapiJob(_rapi_client.ModifyInstance(instance["name"], **kwargs))
706 3b7158ef Michael Hanselmann
707 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
708 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: 3,
709 3b7158ef Michael Hanselmann
    })
710 3b7158ef Michael Hanselmann
711 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
712 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: constants.VALUE_DEFAULT,
713 3b7158ef Michael Hanselmann
    })
714 3b7158ef Michael Hanselmann
715 a8dbf746 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
716 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
717 a8dbf746 Michael Hanselmann
      constants.HV_KERNEL_ARGS: "single",
718 a8dbf746 Michael Hanselmann
      })
719 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
720 a8dbf746 Michael Hanselmann
      constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
721 a8dbf746 Michael Hanselmann
      })
722 a8dbf746 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
723 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
724 a8dbf746 Michael Hanselmann
      constants.HV_BOOT_ORDER: "acn",
725 a8dbf746 Michael Hanselmann
      })
726 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
727 a8dbf746 Michael Hanselmann
      constants.HV_BOOT_ORDER: constants.VALUE_DEFAULT,
728 a8dbf746 Michael Hanselmann
      })
729 3b7158ef Michael Hanselmann
730 3b7158ef Michael Hanselmann
731 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
732 b82d4c5e Michael Hanselmann
def TestRapiInstanceConsole(instance):
733 b82d4c5e Michael Hanselmann
  """Test getting instance console information via RAPI"""
734 b82d4c5e Michael Hanselmann
  result = _rapi_client.GetInstanceConsole(instance["name"])
735 b82d4c5e Michael Hanselmann
  console = objects.InstanceConsole.FromDict(result)
736 b82d4c5e Michael Hanselmann
  AssertEqual(console.Validate(), True)
737 b82d4c5e Michael Hanselmann
  AssertEqual(console.instance, qa_utils.ResolveInstanceName(instance["name"]))
738 b82d4c5e Michael Hanselmann
739 b82d4c5e Michael Hanselmann
740 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
741 b82d4c5e Michael Hanselmann
def TestRapiStoppedInstanceConsole(instance):
742 b82d4c5e Michael Hanselmann
  """Test getting stopped instance's console information via RAPI"""
743 b82d4c5e Michael Hanselmann
  try:
744 b82d4c5e Michael Hanselmann
    _rapi_client.GetInstanceConsole(instance["name"])
745 b82d4c5e Michael Hanselmann
  except rapi.client.GanetiApiError, err:
746 b82d4c5e Michael Hanselmann
    AssertEqual(err.code, 503)
747 b82d4c5e Michael Hanselmann
  else:
748 b82d4c5e Michael Hanselmann
    raise qa_error.Error("Getting console for stopped instance didn't"
749 b82d4c5e Michael Hanselmann
                         " return HTTP 503")
750 b82d4c5e Michael Hanselmann
751 b82d4c5e Michael Hanselmann
752 2932dc44 Michael Hanselmann
def GetOperatingSystems():
753 2932dc44 Michael Hanselmann
  """Retrieves a list of all available operating systems.
754 2932dc44 Michael Hanselmann

755 2932dc44 Michael Hanselmann
  """
756 2932dc44 Michael Hanselmann
  return _rapi_client.GetOperatingSystems()
757 2932dc44 Michael Hanselmann
758 2932dc44 Michael Hanselmann
759 638a7266 Iustin Pop
def TestInterClusterInstanceMove(src_instance, dest_instance,
760 c99200a3 Bernardo Dal Seno
                                 inodes, tnode):
761 5d831182 Michael Hanselmann
  """Test tools/move-instance"""
762 5d831182 Michael Hanselmann
  master = qa_config.GetMasterNode()
763 5d831182 Michael Hanselmann
764 5d831182 Michael Hanselmann
  rapi_pw_file = tempfile.NamedTemporaryFile()
765 5d831182 Michael Hanselmann
  rapi_pw_file.write(_rapi_password)
766 5d831182 Michael Hanselmann
  rapi_pw_file.flush()
767 5d831182 Michael Hanselmann
768 906a0346 Bernardo Dal Seno
  qa_config.SetInstanceTemplate(dest_instance,
769 906a0346 Bernardo Dal Seno
                                qa_config.GetInstanceTemplate(src_instance))
770 906a0346 Bernardo Dal Seno
771 5d831182 Michael Hanselmann
  # TODO: Run some instance tests before moving back
772 677e16eb Iustin Pop
773 c99200a3 Bernardo Dal Seno
  if len(inodes) > 1:
774 c99200a3 Bernardo Dal Seno
    # No disk template currently requires more than 1 secondary node. If this
775 c99200a3 Bernardo Dal Seno
    # changes, either this test must be skipped or the script must be updated.
776 c99200a3 Bernardo Dal Seno
    assert len(inodes) == 2
777 c99200a3 Bernardo Dal Seno
    snode = inodes[1]
778 c99200a3 Bernardo Dal Seno
  else:
779 638a7266 Iustin Pop
    # instance is not redundant, but we still need to pass a node
780 638a7266 Iustin Pop
    # (which will be ignored)
781 c99200a3 Bernardo Dal Seno
    snode = tnode
782 c99200a3 Bernardo Dal Seno
  pnode = inodes[0]
783 638a7266 Iustin Pop
  # note: pnode:snode are the *current* nodes, so we move it first to
784 638a7266 Iustin Pop
  # tnode:pnode, then back to pnode:snode
785 677e16eb Iustin Pop
  for si, di, pn, sn in [(src_instance["name"], dest_instance["name"],
786 638a7266 Iustin Pop
                          tnode["primary"], pnode["primary"]),
787 677e16eb Iustin Pop
                         (dest_instance["name"], src_instance["name"],
788 c99200a3 Bernardo Dal Seno
                          pnode["primary"], snode["primary"])]:
789 5d831182 Michael Hanselmann
    cmd = [
790 5d831182 Michael Hanselmann
      "../tools/move-instance",
791 5d831182 Michael Hanselmann
      "--verbose",
792 5d831182 Michael Hanselmann
      "--src-ca-file=%s" % _rapi_ca.name,
793 5d831182 Michael Hanselmann
      "--src-username=%s" % _rapi_username,
794 5d831182 Michael Hanselmann
      "--src-password-file=%s" % rapi_pw_file.name,
795 677e16eb Iustin Pop
      "--dest-instance-name=%s" % di,
796 677e16eb Iustin Pop
      "--dest-primary-node=%s" % pn,
797 677e16eb Iustin Pop
      "--dest-secondary-node=%s" % sn,
798 a889c536 Michael Hanselmann
      "--net=0:mac=%s" % constants.VALUE_GENERATE,
799 5d831182 Michael Hanselmann
      master["primary"],
800 5d831182 Michael Hanselmann
      master["primary"],
801 677e16eb Iustin Pop
      si,
802 5d831182 Michael Hanselmann
      ]
803 5d831182 Michael Hanselmann
804 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(di, False)
805 5d831182 Michael Hanselmann
    AssertEqual(StartLocalCommand(cmd).wait(), 0)
806 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(si, False)
807 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(di, True)