Statistics
| Branch: | Tag: | Revision:

root / qa / qa_rapi.py @ b780c231

History | View | Annotate | Download (23.5 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 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 090128b6 Christos Stavrakakis
    disks = [{"size": utils.ParseUnit(d.get("size")),
569 090128b6 Christos Stavrakakis
              "name": str(d.get("name"))}
570 090128b6 Christos Stavrakakis
             for d in qa_config.GetDiskOptions()]
571 0afce24e Michael Hanselmann
    nic0_mac = instance.GetNicMacAddr(0, constants.VALUE_GENERATE)
572 f346a7d9 Michael Hanselmann
    nics = [{
573 f346a7d9 Michael Hanselmann
      constants.INIC_MAC: nic0_mac,
574 f346a7d9 Michael Hanselmann
      }]
575 924e95f9 Michael Hanselmann
576 713a79e7 Michael Hanselmann
    beparams = {
577 8ccbbe4b Guido Trotter
      constants.BE_MAXMEM: utils.ParseUnit(qa_config.get(constants.BE_MAXMEM)),
578 8ccbbe4b Guido Trotter
      constants.BE_MINMEM: utils.ParseUnit(qa_config.get(constants.BE_MINMEM)),
579 713a79e7 Michael Hanselmann
      }
580 924e95f9 Michael Hanselmann
581 713a79e7 Michael Hanselmann
    if use_client:
582 924e95f9 Michael Hanselmann
      job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
583 b5f33afa Michael Hanselmann
                                           instance.name,
584 924e95f9 Michael Hanselmann
                                           constants.DT_PLAIN,
585 924e95f9 Michael Hanselmann
                                           disks, nics,
586 924e95f9 Michael Hanselmann
                                           os=qa_config.get("os"),
587 aecba21e Michael Hanselmann
                                           pnode=node.primary,
588 924e95f9 Michael Hanselmann
                                           beparams=beparams)
589 924e95f9 Michael Hanselmann
    else:
590 924e95f9 Michael Hanselmann
      body = {
591 713a79e7 Michael Hanselmann
        "__version__": 1,
592 713a79e7 Michael Hanselmann
        "mode": constants.INSTANCE_CREATE,
593 b5f33afa Michael Hanselmann
        "name": instance.name,
594 713a79e7 Michael Hanselmann
        "os_type": qa_config.get("os"),
595 924e95f9 Michael Hanselmann
        "disk_template": constants.DT_PLAIN,
596 aecba21e Michael Hanselmann
        "pnode": node.primary,
597 713a79e7 Michael Hanselmann
        "beparams": beparams,
598 713a79e7 Michael Hanselmann
        "disks": disks,
599 713a79e7 Michael Hanselmann
        "nics": nics,
600 924e95f9 Michael Hanselmann
        }
601 924e95f9 Michael Hanselmann
602 924e95f9 Michael Hanselmann
      (job_id, ) = _DoTests([
603 924e95f9 Michael Hanselmann
        ("/2/instances", _VerifyReturnsJob, "POST", body),
604 924e95f9 Michael Hanselmann
        ])
605 8cb70e56 Michael Hanselmann
606 8cb70e56 Michael Hanselmann
    _WaitForRapiJob(job_id)
607 8cb70e56 Michael Hanselmann
608 8cb70e56 Michael Hanselmann
    return instance
609 8cb70e56 Michael Hanselmann
  except:
610 6f88e076 Michael Hanselmann
    instance.Release()
611 8cb70e56 Michael Hanselmann
    raise
612 8cb70e56 Michael Hanselmann
613 8cb70e56 Michael Hanselmann
614 5fa0375e Michael Hanselmann
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
615 924e95f9 Michael Hanselmann
def TestRapiInstanceRemove(instance, use_client):
616 8cb70e56 Michael Hanselmann
  """Test removing instance via RAPI"""
617 924e95f9 Michael Hanselmann
  if use_client:
618 b5f33afa Michael Hanselmann
    job_id = _rapi_client.DeleteInstance(instance.name)
619 924e95f9 Michael Hanselmann
  else:
620 924e95f9 Michael Hanselmann
    (job_id, ) = _DoTests([
621 b5f33afa Michael Hanselmann
      ("/2/instances/%s" % instance.name, _VerifyReturnsJob, "DELETE", None),
622 924e95f9 Michael Hanselmann
      ])
623 8cb70e56 Michael Hanselmann
624 8cb70e56 Michael Hanselmann
  _WaitForRapiJob(job_id)
625 8cb70e56 Michael Hanselmann
626 5d831182 Michael Hanselmann
627 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
628 938bde86 Michael Hanselmann
def TestRapiInstanceMigrate(instance):
629 938bde86 Michael Hanselmann
  """Test migrating instance via RAPI"""
630 5de31440 Bernardo Dal Seno
  if not IsMigrationSupported(instance):
631 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support migration, skipping"
632 5de31440 Bernardo Dal Seno
                              " test")
633 5de31440 Bernardo Dal Seno
    return
634 938bde86 Michael Hanselmann
  # Move to secondary node
635 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance.name))
636 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
637 938bde86 Michael Hanselmann
  # And back to previous primary
638 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance.name))
639 c0a146a1 Michael Hanselmann
640 c0a146a1 Michael Hanselmann
641 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
642 c0a146a1 Michael Hanselmann
def TestRapiInstanceFailover(instance):
643 c0a146a1 Michael Hanselmann
  """Test failing over instance via RAPI"""
644 5de31440 Bernardo Dal Seno
  if not IsFailoverSupported(instance):
645 5de31440 Bernardo Dal Seno
    print qa_utils.FormatInfo("Instance doesn't support failover, skipping"
646 5de31440 Bernardo Dal Seno
                              " test")
647 5de31440 Bernardo Dal Seno
    return
648 c0a146a1 Michael Hanselmann
  # Move to secondary node
649 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance.name))
650 5fa0375e Michael Hanselmann
  qa_utils.RunInstanceCheck(instance, True)
651 c0a146a1 Michael Hanselmann
  # And back to previous primary
652 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance.name))
653 a7418448 Michael Hanselmann
654 a7418448 Michael Hanselmann
655 5fa0375e Michael Hanselmann
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
656 a7418448 Michael Hanselmann
def TestRapiInstanceShutdown(instance):
657 a7418448 Michael Hanselmann
  """Test stopping an instance via RAPI"""
658 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.ShutdownInstance(instance.name))
659 a7418448 Michael Hanselmann
660 a7418448 Michael Hanselmann
661 5fa0375e Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
662 a7418448 Michael Hanselmann
def TestRapiInstanceStartup(instance):
663 a7418448 Michael Hanselmann
  """Test starting an instance via RAPI"""
664 b5f33afa Michael Hanselmann
  _WaitForRapiJob(_rapi_client.StartupInstance(instance.name))
665 938bde86 Michael Hanselmann
666 938bde86 Michael Hanselmann
667 51131cad Michael Hanselmann
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
668 4c1a464b Iustin Pop
def TestRapiInstanceRenameAndBack(rename_source, rename_target):
669 4c1a464b Iustin Pop
  """Test renaming instance via RAPI
670 4c1a464b Iustin Pop

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

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

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