Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ 2ef21e6e

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

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

415 a47f574c Oleksiy Mishchenko
  """
416 a47f574c Oleksiy Mishchenko
  def _VerifyNode(data):
417 a47f574c Oleksiy Mishchenko
    for entry in NODE_FIELDS:
418 a47f574c Oleksiy Mishchenko
      AssertIn(entry, data)
419 c85d3b64 Michael Hanselmann
420 a47f574c Oleksiy Mishchenko
  def _VerifyNodesList(data):
421 a47f574c Oleksiy Mishchenko
    for node in data:
422 c85d3b64 Michael Hanselmann
      for entry in LIST_FIELDS:
423 a47f574c Oleksiy Mishchenko
        AssertIn(entry, node)
424 c85d3b64 Michael Hanselmann
425 a47f574c Oleksiy Mishchenko
  def _VerifyNodesBulk(data):
426 a47f574c Oleksiy Mishchenko
    for node_data in data:
427 a47f574c Oleksiy Mishchenko
      _VerifyNode(node_data)
428 a47f574c Oleksiy Mishchenko
429 a47f574c Oleksiy Mishchenko
  _DoTests([
430 aecba21e Michael Hanselmann
    ("/2/nodes/%s" % node.primary, _VerifyNode, "GET", None),
431 d0c8c01d Iustin Pop
    ("/2/nodes", _VerifyNodesList, "GET", None),
432 d0c8c01d Iustin Pop
    ("/2/nodes?bulk=1", _VerifyNodesBulk, "GET", None),
433 a47f574c Oleksiy Mishchenko
    ])
434 a47f574c Oleksiy Mishchenko
435 a47f574c Oleksiy Mishchenko
436 c1513c7f Michael Hanselmann
def _FilterTags(seq):
437 c1513c7f Michael Hanselmann
  """Removes unwanted tags from a sequence.
438 c1513c7f Michael Hanselmann

439 c1513c7f Michael Hanselmann
  """
440 c1513c7f Michael Hanselmann
  ignore_re = qa_config.get("ignore-tags-re", None)
441 c1513c7f Michael Hanselmann
442 c1513c7f Michael Hanselmann
  if ignore_re:
443 c1513c7f Michael Hanselmann
    return itertools.ifilterfalse(re.compile(ignore_re).match, seq)
444 c1513c7f Michael Hanselmann
  else:
445 c1513c7f Michael Hanselmann
    return seq
446 c1513c7f Michael Hanselmann
447 c1513c7f Michael Hanselmann
448 a47f574c Oleksiy Mishchenko
def TestTags(kind, name, tags):
449 a47f574c Oleksiy Mishchenko
  """Tests .../tags resources.
450 a47f574c Oleksiy Mishchenko

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

489 8cb70e56 Michael Hanselmann
  """
490 8cb70e56 Michael Hanselmann
  def _VerifyJob(data):
491 8cb70e56 Michael Hanselmann
    AssertEqual(data["id"], job_id)
492 8cb70e56 Michael Hanselmann
    for field in JOB_FIELDS:
493 8cb70e56 Michael Hanselmann
      AssertIn(field, data)
494 8cb70e56 Michael Hanselmann
495 8cb70e56 Michael Hanselmann
  _DoTests([
496 8cb70e56 Michael Hanselmann
    ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
497 8cb70e56 Michael Hanselmann
    ])
498 8cb70e56 Michael Hanselmann
499 ebeb600f Michael Hanselmann
  return rapi.client_utils.PollJob(_rapi_client, job_id,
500 ebeb600f Michael Hanselmann
                                   cli.StdioJobPollReportCb())
501 8cb70e56 Michael Hanselmann
502 8cb70e56 Michael Hanselmann
503 4b10fb65 Adeodato Simo
def TestRapiNodeGroups():
504 4b10fb65 Adeodato Simo
  """Test several node group operations using RAPI.
505 4b10fb65 Adeodato Simo

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

670 4c1a464b Iustin Pop
  This must leave the instance with the original name (in the
671 4c1a464b Iustin Pop
  non-failure case).
672 4c1a464b Iustin Pop

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

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