Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ d3737aca

History | View | Annotate | Download (24.3 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 dcd85eef Michael Hanselmann
  cmd = ["cat", qa_utils.MakeNodePath(master, 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 aecba21e 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 301adaae Michael Hanselmann
  if qa_config.UseVirtualCluster():
92 301adaae Michael Hanselmann
    # TODO: Implement full support for RAPI on virtual clusters
93 301adaae Michael Hanselmann
    print qa_utils.FormatWarning("RAPI tests are not yet supported on"
94 301adaae Michael Hanselmann
                                 " virtual clusters and will be disabled")
95 e6ce18ac René Nussbaumer
96 301adaae Michael Hanselmann
    assert _rapi_client is None
97 301adaae Michael Hanselmann
  else:
98 301adaae Michael Hanselmann
    _rapi_client = rapi.client.GanetiRapiClient(master.primary, port=port,
99 301adaae Michael Hanselmann
                                                username=username,
100 301adaae Michael Hanselmann
                                                password=password,
101 301adaae Michael Hanselmann
                                                curl_config_fn=cfg_curl)
102 301adaae Michael Hanselmann
103 301adaae Michael Hanselmann
    print "RAPI protocol version: %s" % _rapi_client.GetVersion()
104 a47f574c Oleksiy Mishchenko
105 a47f574c Oleksiy Mishchenko
106 a47f574c Oleksiy Mishchenko
INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
107 a5b9d725 Iustin Pop
                   "admin_state",
108 0e514de1 Bernardo Dal Seno
                   "disk_template", "disk.sizes", "disk.spindles",
109 22482387 Iustin Pop
                   "nic.ips", "nic.macs", "nic.modes", "nic.links",
110 a5b9d725 Iustin Pop
                   "beparams", "hvparams",
111 4ea3de4e Balazs Lecz
                   "oper_state", "oper_ram", "oper_vcpus", "status", "tags")
112 a47f574c Oleksiy Mishchenko
113 06fb92cf Bernardo Dal Seno
NODE_FIELDS = ("name", "dtotal", "dfree", "sptotal", "spfree",
114 a47f574c Oleksiy Mishchenko
               "mtotal", "mnode", "mfree",
115 a47f574c Oleksiy Mishchenko
               "pinst_cnt", "sinst_cnt", "tags")
116 a47f574c Oleksiy Mishchenko
117 b8028dcf Michael Hanselmann
GROUP_FIELDS = compat.UniqueFrozenset([
118 30131294 Adeodato Simo
  "name", "uuid",
119 90e99856 Adeodato Simo
  "alloc_policy",
120 30131294 Adeodato Simo
  "node_cnt", "node_list",
121 30131294 Adeodato Simo
  ])
122 30131294 Adeodato Simo
123 b8028dcf Michael Hanselmann
JOB_FIELDS = compat.UniqueFrozenset([
124 94e63ca1 Michael Hanselmann
  "id", "ops", "status", "summary",
125 94e63ca1 Michael Hanselmann
  "opstatus", "opresult", "oplog",
126 94e63ca1 Michael Hanselmann
  "received_ts", "start_ts", "end_ts",
127 94e63ca1 Michael Hanselmann
  ])
128 94e63ca1 Michael Hanselmann
129 68289c75 Iustin Pop
LIST_FIELDS = ("id", "uri")
130 a47f574c Oleksiy Mishchenko
131 a47f574c Oleksiy Mishchenko
132 a47f574c Oleksiy Mishchenko
def Enabled():
133 a47f574c Oleksiy Mishchenko
  """Return whether remote API tests should be run.
134 a47f574c Oleksiy Mishchenko

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

171 a47f574c Oleksiy Mishchenko
  """
172 a47f574c Oleksiy Mishchenko
  _DoTests([
173 d0c8c01d Iustin Pop
    ("/version", constants.RAPI_VERSION, "GET", None),
174 a47f574c Oleksiy Mishchenko
    ])
175 a47f574c Oleksiy Mishchenko
176 a47f574c Oleksiy Mishchenko
177 a47f574c Oleksiy Mishchenko
def TestEmptyCluster():
178 a47f574c Oleksiy Mishchenko
  """Testing remote API on an empty cluster.
179 a47f574c Oleksiy Mishchenko

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

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

387 a47f574c Oleksiy Mishchenko
  """
388 a47f574c Oleksiy Mishchenko
  def _VerifyInstance(data):
389 a47f574c Oleksiy Mishchenko
    for entry in INSTANCE_FIELDS:
390 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
391 c85d3b64 Michael Hanselmann
392 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesList(data):
393 a47f574c Oleksiy Mishchenko
    for instance in data:
394 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
395 a47f574c Oleksiy Mishchenko
        AssertIn(entry, instance)
396 c85d3b64 Michael Hanselmann
397 a47f574c Oleksiy Mishchenko
  def _VerifyInstancesBulk(data):
398 a47f574c Oleksiy Mishchenko
    for instance_data in data:
399 a47f574c Oleksiy Mishchenko
      _VerifyInstance(instance_data)
400 a47f574c Oleksiy Mishchenko
401 a47f574c Oleksiy Mishchenko
  _DoTests([
402 b5f33afa Michael Hanselmann
    ("/2/instances/%s" % instance.name, _VerifyInstance, "GET", None),
403 d0c8c01d Iustin Pop
    ("/2/instances", _VerifyInstancesList, "GET", None),
404 d0c8c01d Iustin Pop
    ("/2/instances?bulk=1", _VerifyInstancesBulk, "GET", None),
405 b5f33afa Michael Hanselmann
    ("/2/instances/%s/activate-disks" % instance.name,
406 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
407 b5f33afa Michael Hanselmann
    ("/2/instances/%s/deactivate-disks" % instance.name,
408 d0c8c01d Iustin Pop
     _VerifyReturnsJob, "PUT", None),
409 a47f574c Oleksiy Mishchenko
    ])
410 a47f574c Oleksiy Mishchenko
411 71910715 Iustin Pop
  # Test OpBackupPrepare
412 ebeb600f Michael Hanselmann
  (job_id, ) = _DoTests([
413 ebeb600f Michael Hanselmann
    ("/2/instances/%s/prepare-export?mode=%s" %
414 b5f33afa Michael Hanselmann
     (instance.name, constants.EXPORT_MODE_REMOTE),
415 ebeb600f Michael Hanselmann
     _VerifyReturnsJob, "PUT", None),
416 ebeb600f Michael Hanselmann
    ])
417 ebeb600f Michael Hanselmann
418 ebeb600f Michael Hanselmann
  result = _WaitForRapiJob(job_id)[0]
419 ebeb600f Michael Hanselmann
  AssertEqual(len(result["handshake"]), 3)
420 ebeb600f Michael Hanselmann
  AssertEqual(result["handshake"][0], constants.RIE_VERSION)
421 ebeb600f Michael Hanselmann
  AssertEqual(len(result["x509_key_name"]), 3)
422 ebeb600f Michael Hanselmann
  AssertIn("-----BEGIN CERTIFICATE-----", result["x509_ca"])
423 ebeb600f Michael Hanselmann
424 a47f574c Oleksiy Mishchenko
425 a47f574c Oleksiy Mishchenko
def TestNode(node):
426 a47f574c Oleksiy Mishchenko
  """Testing getting node(s) info via remote API.
427 a47f574c Oleksiy Mishchenko

428 a47f574c Oleksiy Mishchenko
  """
429 a47f574c Oleksiy Mishchenko
  def _VerifyNode(data):
430 a47f574c Oleksiy Mishchenko
    for entry in NODE_FIELDS:
431 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
432 c85d3b64 Michael Hanselmann
433 a47f574c Oleksiy Mishchenko
  def _VerifyNodesList(data):
434 a47f574c Oleksiy Mishchenko
    for node in data:
435 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
436 a47f574c Oleksiy Mishchenko
        AssertIn(entry, node)
437 c85d3b64 Michael Hanselmann
438 a47f574c Oleksiy Mishchenko
  def _VerifyNodesBulk(data):
439 a47f574c Oleksiy Mishchenko
    for node_data in data:
440 a47f574c Oleksiy Mishchenko
      _VerifyNode(node_data)
441 a47f574c Oleksiy Mishchenko
442 a47f574c Oleksiy Mishchenko
  _DoTests([
443 aecba21e Michael Hanselmann
    ("/2/nodes/%s" % node.primary, _VerifyNode, "GET", None),
444 d0c8c01d Iustin Pop
    ("/2/nodes", _VerifyNodesList, "GET", None),
445 d0c8c01d Iustin Pop
    ("/2/nodes?bulk=1", _VerifyNodesBulk, "GET", None),
446 a47f574c Oleksiy Mishchenko
    ])
447 a47f574c Oleksiy Mishchenko
448 a47f574c Oleksiy Mishchenko
449 c1513c7f Michael Hanselmann
def _FilterTags(seq):
450 c1513c7f Michael Hanselmann
  """Removes unwanted tags from a sequence.
451 c1513c7f Michael Hanselmann

452 c1513c7f Michael Hanselmann
  """
453 c1513c7f Michael Hanselmann
  ignore_re = qa_config.get("ignore-tags-re", None)
454 c1513c7f Michael Hanselmann
455 c1513c7f Michael Hanselmann
  if ignore_re:
456 c1513c7f Michael Hanselmann
    return itertools.ifilterfalse(re.compile(ignore_re).match, seq)
457 c1513c7f Michael Hanselmann
  else:
458 c1513c7f Michael Hanselmann
    return seq
459 c1513c7f Michael Hanselmann
460 c1513c7f Michael Hanselmann
461 a47f574c Oleksiy Mishchenko
def TestTags(kind, name, tags):
462 a47f574c Oleksiy Mishchenko
  """Tests .../tags resources.
463 a47f574c Oleksiy Mishchenko

464 a47f574c Oleksiy Mishchenko
  """
465 a47f574c Oleksiy Mishchenko
  if kind == constants.TAG_CLUSTER:
466 a5b9d725 Iustin Pop
    uri = "/2/tags"
467 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_NODE:
468 a5b9d725 Iustin Pop
    uri = "/2/nodes/%s/tags" % name
469 a47f574c Oleksiy Mishchenko
  elif kind == constants.TAG_INSTANCE:
470 a5b9d725 Iustin Pop
    uri = "/2/instances/%s/tags" % name
471 fe508a9d Michael Hanselmann
  elif kind == constants.TAG_NODEGROUP:
472 fe508a9d Michael Hanselmann
    uri = "/2/groups/%s/tags" % name
473 a47f574c Oleksiy Mishchenko
  else:
474 a47f574c Oleksiy Mishchenko
    raise errors.ProgrammerError("Unknown tag kind")
475 a47f574c Oleksiy Mishchenko
476 a47f574c Oleksiy Mishchenko
  def _VerifyTags(data):
477 c1513c7f Michael Hanselmann
    AssertEqual(sorted(tags), sorted(_FilterTags(data)))
478 a47f574c Oleksiy Mishchenko
479 4fab7cab Michael Hanselmann
  queryargs = "&".join("tag=%s" % i for i in tags)
480 c326b4ef Michael Hanselmann
481 c326b4ef Michael Hanselmann
  # Add tags
482 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
483 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "PUT", None),
484 c326b4ef Michael Hanselmann
    ])
485 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
486 c326b4ef Michael Hanselmann
487 c326b4ef Michael Hanselmann
  # Retrieve tags
488 a47f574c Oleksiy Mishchenko
  _DoTests([
489 d0c8c01d Iustin Pop
    (uri, _VerifyTags, "GET", None),
490 a47f574c Oleksiy Mishchenko
    ])
491 8cb70e56 Michael Hanselmann
492 c326b4ef Michael Hanselmann
  # Remove tags
493 c326b4ef Michael Hanselmann
  (job_id, ) = _DoTests([
494 4fab7cab Michael Hanselmann
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "DELETE", None),
495 c326b4ef Michael Hanselmann
    ])
496 c326b4ef Michael Hanselmann
  _WaitForRapiJob(job_id)
497 c326b4ef Michael Hanselmann
498 8cb70e56 Michael Hanselmann
499 8cb70e56 Michael Hanselmann
def _WaitForRapiJob(job_id):
500 8cb70e56 Michael Hanselmann
  """Waits for a job to finish.
501 8cb70e56 Michael Hanselmann

502 8cb70e56 Michael Hanselmann
  """
503 8cb70e56 Michael Hanselmann
  def _VerifyJob(data):
504 8cb70e56 Michael Hanselmann
    AssertEqual(data["id"], job_id)
505 8cb70e56 Michael Hanselmann
    for field in JOB_FIELDS:
506 8cb70e56 Michael Hanselmann
      AssertIn(field, data)
507 8cb70e56 Michael Hanselmann
508 8cb70e56 Michael Hanselmann
  _DoTests([
509 8cb70e56 Michael Hanselmann
    ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
510 8cb70e56 Michael Hanselmann
    ])
511 8cb70e56 Michael Hanselmann
512 ebeb600f Michael Hanselmann
  return rapi.client_utils.PollJob(_rapi_client, job_id,
513 ebeb600f Michael Hanselmann
                                   cli.StdioJobPollReportCb())
514 8cb70e56 Michael Hanselmann
515 8cb70e56 Michael Hanselmann
516 4b10fb65 Adeodato Simo
def TestRapiNodeGroups():
517 4b10fb65 Adeodato Simo
  """Test several node group operations using RAPI.
518 4b10fb65 Adeodato Simo

519 4b10fb65 Adeodato Simo
  """
520 b4d2d2cb Michael Hanselmann
  (group1, group2, group3) = qa_utils.GetNonexistentGroups(3)
521 4b10fb65 Adeodato Simo
522 4b10fb65 Adeodato Simo
  # Create a group with no attributes
523 4b10fb65 Adeodato Simo
  body = {
524 4b10fb65 Adeodato Simo
    "name": group1,
525 4b10fb65 Adeodato Simo
    }
526 4b10fb65 Adeodato Simo
527 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
528 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
529 4b10fb65 Adeodato Simo
    ])
530 4b10fb65 Adeodato Simo
531 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
532 4b10fb65 Adeodato Simo
533 4b10fb65 Adeodato Simo
  # Create a group specifying alloc_policy
534 4b10fb65 Adeodato Simo
  body = {
535 4b10fb65 Adeodato Simo
    "name": group2,
536 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
537 4b10fb65 Adeodato Simo
    }
538 4b10fb65 Adeodato Simo
539 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
540 4b10fb65 Adeodato Simo
    ("/2/groups", _VerifyReturnsJob, "POST", body),
541 4b10fb65 Adeodato Simo
    ])
542 4b10fb65 Adeodato Simo
543 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
544 4b10fb65 Adeodato Simo
545 4b10fb65 Adeodato Simo
  # Modify alloc_policy
546 4b10fb65 Adeodato Simo
  body = {
547 4b10fb65 Adeodato Simo
    "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
548 4b10fb65 Adeodato Simo
    }
549 4b10fb65 Adeodato Simo
550 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
551 4b10fb65 Adeodato Simo
    ("/2/groups/%s/modify" % group1, _VerifyReturnsJob, "PUT", body),
552 4b10fb65 Adeodato Simo
    ])
553 4b10fb65 Adeodato Simo
554 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
555 4b10fb65 Adeodato Simo
556 4b10fb65 Adeodato Simo
  # Rename a group
557 4b10fb65 Adeodato Simo
  body = {
558 4b10fb65 Adeodato Simo
    "new_name": group3,
559 4b10fb65 Adeodato Simo
    }
560 4b10fb65 Adeodato Simo
561 4b10fb65 Adeodato Simo
  (job_id, ) = _DoTests([
562 4b10fb65 Adeodato Simo
    ("/2/groups/%s/rename" % group2, _VerifyReturnsJob, "PUT", body),
563 4b10fb65 Adeodato Simo
    ])
564 4b10fb65 Adeodato Simo
565 4b10fb65 Adeodato Simo
  _WaitForRapiJob(job_id)
566 4b10fb65 Adeodato Simo
567 4b10fb65 Adeodato Simo
  # Delete groups
568 4b10fb65 Adeodato Simo
  for group in [group1, group3]:
569 4b10fb65 Adeodato Simo
    (job_id, ) = _DoTests([
570 4b10fb65 Adeodato Simo
      ("/2/groups/%s" % group, _VerifyReturnsJob, "DELETE", None),
571 4b10fb65 Adeodato Simo
      ])
572 4b10fb65 Adeodato Simo
573 4b10fb65 Adeodato Simo
    _WaitForRapiJob(job_id)
574 4b10fb65 Adeodato Simo
575 4b10fb65 Adeodato Simo
576 924e95f9 Michael Hanselmann
def TestRapiInstanceAdd(node, use_client):
577 8cb70e56 Michael Hanselmann
  """Test adding a new instance via RAPI"""
578 bab4f56a Helga Velroyen
  if not qa_config.IsTemplateSupported(constants.DT_PLAIN):
579 bab4f56a Helga Velroyen
    return
580 8cb70e56 Michael Hanselmann
  instance = qa_config.AcquireInstance()
581 02a5fe0e Michael Hanselmann
  instance.SetDiskTemplate(constants.DT_PLAIN)
582 8cb70e56 Michael Hanselmann
  try:
583 090128b6 Christos Stavrakakis
    disks = [{"size": utils.ParseUnit(d.get("size")),
584 090128b6 Christos Stavrakakis
              "name": str(d.get("name"))}
585 090128b6 Christos Stavrakakis
             for d in qa_config.GetDiskOptions()]
586 0afce24e Michael Hanselmann
    nic0_mac = instance.GetNicMacAddr(0, constants.VALUE_GENERATE)
587 f346a7d9 Michael Hanselmann
    nics = [{
588 f346a7d9 Michael Hanselmann
      constants.INIC_MAC: nic0_mac,
589 f346a7d9 Michael Hanselmann
      }]
590 924e95f9 Michael Hanselmann
591 713a79e7 Michael Hanselmann
    beparams = {
592 8ccbbe4b Guido Trotter
      constants.BE_MAXMEM: utils.ParseUnit(qa_config.get(constants.BE_MAXMEM)),
593 8ccbbe4b Guido Trotter
      constants.BE_MINMEM: utils.ParseUnit(qa_config.get(constants.BE_MINMEM)),
594 713a79e7 Michael Hanselmann
      }
595 924e95f9 Michael Hanselmann
596 713a79e7 Michael Hanselmann
    if use_client:
597 924e95f9 Michael Hanselmann
      job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
598 b5f33afa Michael Hanselmann
                                           instance.name,
599 924e95f9 Michael Hanselmann
                                           constants.DT_PLAIN,
600 924e95f9 Michael Hanselmann
                                           disks, nics,
601 924e95f9 Michael Hanselmann
                                           os=qa_config.get("os"),
602 aecba21e Michael Hanselmann
                                           pnode=node.primary,
603 924e95f9 Michael Hanselmann
                                           beparams=beparams)
604 924e95f9 Michael Hanselmann
    else:
605 924e95f9 Michael Hanselmann
      body = {
606 713a79e7 Michael Hanselmann
        "__version__": 1,
607 713a79e7 Michael Hanselmann
        "mode": constants.INSTANCE_CREATE,
608 b5f33afa Michael Hanselmann
        "name": instance.name,
609 713a79e7 Michael Hanselmann
        "os_type": qa_config.get("os"),
610 924e95f9 Michael Hanselmann
        "disk_template": constants.DT_PLAIN,
611 aecba21e Michael Hanselmann
        "pnode": node.primary,
612 713a79e7 Michael Hanselmann
        "beparams": beparams,
613 713a79e7 Michael Hanselmann
        "disks": disks,
614 713a79e7 Michael Hanselmann
        "nics": nics,
615 924e95f9 Michael Hanselmann
        }
616 924e95f9 Michael Hanselmann
617 924e95f9 Michael Hanselmann
      (job_id, ) = _DoTests([
618 924e95f9 Michael Hanselmann
        ("/2/instances", _VerifyReturnsJob, "POST", body),
619 924e95f9 Michael Hanselmann
        ])
620 8cb70e56 Michael Hanselmann
621 8cb70e56 Michael Hanselmann
    _WaitForRapiJob(job_id)
622 8cb70e56 Michael Hanselmann
623 8cb70e56 Michael Hanselmann
    return instance
624 8cb70e56 Michael Hanselmann
  except:
625 6f88e076 Michael Hanselmann
    instance.Release()
626 8cb70e56 Michael Hanselmann
    raise
627 8cb70e56 Michael Hanselmann
628 8cb70e56 Michael Hanselmann
629 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
630 924e95f9 Michael Hanselmann
def TestRapiInstanceRemove(instance, use_client):
631 8cb70e56 Michael Hanselmann
  """Test removing instance via RAPI"""
632 bab4f56a Helga Velroyen
  # FIXME: this does not work if LVM is not enabled. Find out if this is a bug
633 bab4f56a Helga Velroyen
  # in RAPI or in the test
634 bab4f56a Helga Velroyen
  if not qa_config.IsStorageTypeSupported(constants.ST_LVM_VG):
635 bab4f56a Helga Velroyen
    return
636 bab4f56a Helga Velroyen
637 924e95f9 Michael Hanselmann
  if use_client:
638 b5f33afa Michael Hanselmann
    job_id = _rapi_client.DeleteInstance(instance.name)
639 924e95f9 Michael Hanselmann
  else:
640 924e95f9 Michael Hanselmann
    (job_id, ) = _DoTests([
641 b5f33afa Michael Hanselmann
      ("/2/instances/%s" % instance.name, _VerifyReturnsJob, "DELETE", None),
642 924e95f9 Michael Hanselmann
      ])
643 8cb70e56 Michael Hanselmann
644 8cb70e56 Michael Hanselmann
  _WaitForRapiJob(job_id)
645 8cb70e56 Michael Hanselmann
646 5d831182 Michael Hanselmann
647 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
648 938bde86 Michael Hanselmann
def TestRapiInstanceMigrate(instance):
649 938bde86 Michael Hanselmann
  """Test migrating instance via RAPI"""
650 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
651 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
652 5de31440 Bernardo Dal Seno
                              " test")
653 5de31440 Bernardo Dal Seno
    return
654 938bde86 Michael Hanselmann
  # Move to secondary node
655 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance.name))
656 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
657 938bde86 Michael Hanselmann
  # And back to previous primary
658 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance.name))
659 c0a146a1 Michael Hanselmann
660 c0a146a1 Michael Hanselmann
661 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
662 c0a146a1 Michael Hanselmann
def TestRapiInstanceFailover(instance):
663 c0a146a1 Michael Hanselmann
  """Test failing over instance via RAPI"""
664 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
665 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
666 5de31440 Bernardo Dal Seno
                              " test")
667 5de31440 Bernardo Dal Seno
    return
668 c0a146a1 Michael Hanselmann
  # Move to secondary node
669 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance.name))
670 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
671 c0a146a1 Michael Hanselmann
  # And back to previous primary
672 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance.name))
673 a7418448 Michael Hanselmann
674 a7418448 Michael Hanselmann
675 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
676 a7418448 Michael Hanselmann
def TestRapiInstanceShutdown(instance):
677 a7418448 Michael Hanselmann
  """Test stopping an instance via RAPI"""
678 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ShutdownInstance(instance.name))
679 a7418448 Michael Hanselmann
680 a7418448 Michael Hanselmann
681 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
682 a7418448 Michael Hanselmann
def TestRapiInstanceStartup(instance):
683 a7418448 Michael Hanselmann
  """Test starting an instance via RAPI"""
684 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.StartupInstance(instance.name))
685 938bde86 Michael Hanselmann
686 938bde86 Michael Hanselmann
687 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
688 4c1a464b Iustin Pop
def TestRapiInstanceRenameAndBack(rename_source, rename_target):
689 4c1a464b Iustin Pop
  """Test renaming instance via RAPI
690 4c1a464b Iustin Pop

691 4c1a464b Iustin Pop
  This must leave the instance with the original name (in the
692 4c1a464b Iustin Pop
  non-failure case).
693 4c1a464b Iustin Pop

694 4c1a464b Iustin Pop
  """
695 e5c2accd Guido Trotter
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
696 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_source, False)
697 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
698 4c1a464b Iustin Pop
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_target, rename_source))
699 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(rename_target, False)
700 7fb50870 Michael Hanselmann
701 7fb50870 Michael Hanselmann
702 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
703 0220d2cf Guido Trotter
def TestRapiInstanceReinstall(instance):
704 0220d2cf Guido Trotter
  """Test reinstalling an instance via RAPI"""
705 ad658827 Bernardo Dal Seno
  if instance.disk_template == constants.DT_DISKLESS:
706 ad658827 Bernardo Dal Seno
    print qa_utils.FormatInfo("Test not supported for diskless instances")
707 ad658827 Bernardo Dal Seno
    return
708 ad658827 Bernardo Dal Seno
709 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance.name))
710 51131cad Michael Hanselmann
  # By default, the instance is started again
711 51131cad Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
712 51131cad Michael Hanselmann
713 51131cad Michael Hanselmann
  # Reinstall again without starting
714 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ReinstallInstance(instance.name,
715 51131cad Michael Hanselmann
                                                 no_startup=True))
716 0220d2cf Guido Trotter
717 0220d2cf Guido Trotter
718 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
719 539d65ba Michael Hanselmann
def TestRapiInstanceReplaceDisks(instance):
720 539d65ba Michael Hanselmann
  """Test replacing instance disks via RAPI"""
721 5de31440 Bernardo Dal Seno
  if not IsDiskReplacingSupported(instance):
722 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support disk replacing,"
723 5de31440 Bernardo Dal Seno
                              " skipping test")
724 5de31440 Bernardo Dal Seno
    return
725 5ae4945a Iustin Pop
  fn = _rapi_client.ReplaceInstanceDisks
726 b5f33afa Michael Hanselmann
  _WaitForRapiJob(fn(instance.name,
727 5ae4945a Iustin Pop
                     mode=constants.REPLACE_DISK_AUTO, disks=[]))
728 b5f33afa Michael Hanselmann
  _WaitForRapiJob(fn(instance.name,
729 5ae4945a Iustin Pop
                     mode=constants.REPLACE_DISK_SEC, disks="0"))
730 539d65ba Michael Hanselmann
731 539d65ba Michael Hanselmann
732 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
733 3b7158ef Michael Hanselmann
def TestRapiInstanceModify(instance):
734 3b7158ef Michael Hanselmann
  """Test modifying instance via RAPI"""
735 a8dbf746 Michael Hanselmann
  default_hv = qa_config.GetDefaultHypervisor()
736 a8dbf746 Michael Hanselmann
737 3b7158ef Michael Hanselmann
  def _ModifyInstance(**kwargs):
738 b5f33afa Michael Hanselmann
    _WaitForRapiJob(_rapi_client.ModifyInstance(instance.name, **kwargs))
739 3b7158ef Michael Hanselmann
740 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
741 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: 3,
742 3b7158ef Michael Hanselmann
    })
743 3b7158ef Michael Hanselmann
744 3b7158ef Michael Hanselmann
  _ModifyInstance(beparams={
745 3b7158ef Michael Hanselmann
    constants.BE_VCPUS: constants.VALUE_DEFAULT,
746 3b7158ef Michael Hanselmann
    })
747 3b7158ef Michael Hanselmann
748 a8dbf746 Michael Hanselmann
  if default_hv == constants.HT_XEN_PVM:
749 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
750 a8dbf746 Michael Hanselmann
      constants.HV_KERNEL_ARGS: "single",
751 a8dbf746 Michael Hanselmann
      })
752 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
753 a8dbf746 Michael Hanselmann
      constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
754 a8dbf746 Michael Hanselmann
      })
755 a8dbf746 Michael Hanselmann
  elif default_hv == constants.HT_XEN_HVM:
756 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
757 a8dbf746 Michael Hanselmann
      constants.HV_BOOT_ORDER: "acn",
758 a8dbf746 Michael Hanselmann
      })
759 a8dbf746 Michael Hanselmann
    _ModifyInstance(hvparams={
760 a8dbf746 Michael Hanselmann
      constants.HV_BOOT_ORDER: constants.VALUE_DEFAULT,
761 a8dbf746 Michael Hanselmann
      })
762 3b7158ef Michael Hanselmann
763 3b7158ef Michael Hanselmann
764 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
765 b82d4c5e Michael Hanselmann
def TestRapiInstanceConsole(instance):
766 b82d4c5e Michael Hanselmann
  """Test getting instance console information via RAPI"""
767 b5f33afa Michael Hanselmann
  result = _rapi_client.GetInstanceConsole(instance.name)
768 b82d4c5e Michael Hanselmann
  console = objects.InstanceConsole.FromDict(result)
769 b82d4c5e Michael Hanselmann
  AssertEqual(console.Validate(), True)
770 b5f33afa Michael Hanselmann
  AssertEqual(console.instance, qa_utils.ResolveInstanceName(instance.name))
771 b82d4c5e Michael Hanselmann
772 b82d4c5e Michael Hanselmann
773 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
774 b82d4c5e Michael Hanselmann
def TestRapiStoppedInstanceConsole(instance):
775 b82d4c5e Michael Hanselmann
  """Test getting stopped instance's console information via RAPI"""
776 b82d4c5e Michael Hanselmann
  try:
777 b5f33afa Michael Hanselmann
    _rapi_client.GetInstanceConsole(instance.name)
778 b82d4c5e Michael Hanselmann
  except rapi.client.GanetiApiError, err:
779 b82d4c5e Michael Hanselmann
    AssertEqual(err.code, 503)
780 b82d4c5e Michael Hanselmann
  else:
781 b82d4c5e Michael Hanselmann
    raise qa_error.Error("Getting console for stopped instance didn't"
782 b82d4c5e Michael Hanselmann
                         " return HTTP 503")
783 b82d4c5e Michael Hanselmann
784 b82d4c5e Michael Hanselmann
785 2932dc44 Michael Hanselmann
def GetOperatingSystems():
786 2932dc44 Michael Hanselmann
  """Retrieves a list of all available operating systems.
787 2932dc44 Michael Hanselmann

788 2932dc44 Michael Hanselmann
  """
789 2932dc44 Michael Hanselmann
  return _rapi_client.GetOperatingSystems()
790 2932dc44 Michael Hanselmann
791 2932dc44 Michael Hanselmann
792 638a7266 Iustin Pop
def TestInterClusterInstanceMove(src_instance, dest_instance,
793 c99200a3 Bernardo Dal Seno
                                 inodes, tnode):
794 5d831182 Michael Hanselmann
  """Test tools/move-instance"""
795 5d831182 Michael Hanselmann
  master = qa_config.GetMasterNode()
796 5d831182 Michael Hanselmann
797 5d831182 Michael Hanselmann
  rapi_pw_file = tempfile.NamedTemporaryFile()
798 5d831182 Michael Hanselmann
  rapi_pw_file.write(_rapi_password)
799 5d831182 Michael Hanselmann
  rapi_pw_file.flush()
800 5d831182 Michael Hanselmann
801 02a5fe0e Michael Hanselmann
  dest_instance.SetDiskTemplate(src_instance.disk_template)
802 906a0346 Bernardo Dal Seno
803 5d831182 Michael Hanselmann
  # TODO: Run some instance tests before moving back
804 677e16eb Iustin Pop
805 c99200a3 Bernardo Dal Seno
  if len(inodes) > 1:
806 c99200a3 Bernardo Dal Seno
    # No disk template currently requires more than 1 secondary node. If this
807 c99200a3 Bernardo Dal Seno
    # changes, either this test must be skipped or the script must be updated.
808 c99200a3 Bernardo Dal Seno
    assert len(inodes) == 2
809 c99200a3 Bernardo Dal Seno
    snode = inodes[1]
810 c99200a3 Bernardo Dal Seno
  else:
811 638a7266 Iustin Pop
    # instance is not redundant, but we still need to pass a node
812 638a7266 Iustin Pop
    # (which will be ignored)
813 c99200a3 Bernardo Dal Seno
    snode = tnode
814 c99200a3 Bernardo Dal Seno
  pnode = inodes[0]
815 638a7266 Iustin Pop
  # note: pnode:snode are the *current* nodes, so we move it first to
816 638a7266 Iustin Pop
  # tnode:pnode, then back to pnode:snode
817 b5f33afa Michael Hanselmann
  for si, di, pn, sn in [(src_instance.name, dest_instance.name,
818 aecba21e Michael Hanselmann
                          tnode.primary, pnode.primary),
819 b5f33afa Michael Hanselmann
                         (dest_instance.name, src_instance.name,
820 aecba21e Michael Hanselmann
                          pnode.primary, snode.primary)]:
821 5d831182 Michael Hanselmann
    cmd = [
822 5d831182 Michael Hanselmann
      "../tools/move-instance",
823 5d831182 Michael Hanselmann
      "--verbose",
824 5d831182 Michael Hanselmann
      "--src-ca-file=%s" % _rapi_ca.name,
825 5d831182 Michael Hanselmann
      "--src-username=%s" % _rapi_username,
826 5d831182 Michael Hanselmann
      "--src-password-file=%s" % rapi_pw_file.name,
827 677e16eb Iustin Pop
      "--dest-instance-name=%s" % di,
828 677e16eb Iustin Pop
      "--dest-primary-node=%s" % pn,
829 677e16eb Iustin Pop
      "--dest-secondary-node=%s" % sn,
830 a889c536 Michael Hanselmann
      "--net=0:mac=%s" % constants.VALUE_GENERATE,
831 aecba21e Michael Hanselmann
      master.primary,
832 aecba21e Michael Hanselmann
      master.primary,
833 677e16eb Iustin Pop
      si,
834 5d831182 Michael Hanselmann
      ]
835 5d831182 Michael Hanselmann
836 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(di, False)
837 5d831182 Michael Hanselmann
    AssertEqual(StartLocalCommand(cmd).wait(), 0)
838 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(si, False)
839 5fa0375e Michael Hanselmann
    qa_utils.RunInstanceCheck(di, True)