Revision 2771835c

b/qa/ganeti-qa.py
281 281

  
282 282
  rapi_user = "ganeti-qa"
283 283
  rapi_secret = utils.GenerateSecret()
284
  qa_rapi.OpenerFactory.SetCredentials(rapi_user, rapi_secret)
285 284

  
286 285
  RunEnvTests()
287 286
  SetupCluster(rapi_user, rapi_secret)
287

  
288
  # Load RAPI certificate
289
  qa_rapi.Setup(rapi_user, rapi_secret)
290

  
288 291
  RunClusterTests()
289 292
  RunOsTests()
290 293

  
b/qa/qa_rapi.py
22 22

  
23 23
"""
24 24

  
25
import urllib2
25
import tempfile
26 26

  
27 27
from ganeti import utils
28 28
from ganeti import constants
29 29
from ganeti import errors
30 30
from ganeti import serializer
31
from ganeti import cli
32
from ganeti import rapi
33

  
34
import ganeti.rapi.client
35
import ganeti.rapi.client_utils
31 36

  
32 37
import qa_config
33 38
import qa_utils
......
37 42
                      StartSSH)
38 43

  
39 44

  
40
class OpenerFactory:
41
  """A factory singleton to construct urllib opener chain.
42

  
43
  This is needed because qa_config is not initialized yet at module load time
44

  
45
  """
46
  _opener = None
47
  _rapi_user = None
48
  _rapi_secret = None
49

  
50
  @classmethod
51
  def SetCredentials(cls, rapi_user, rapi_secret):
52
    """Set the credentials for authorized access.
53

  
54
    """
55
    cls._rapi_user = rapi_user
56
    cls._rapi_secret = rapi_secret
45
_rapi_ca = None
46
_rapi_client = None
57 47

  
58
  @classmethod
59
  def Opener(cls):
60
    """Construct the opener if not yet done.
61 48

  
62
    """
63
    if not cls._opener:
64
      if not cls._rapi_user or not cls._rapi_secret:
65
        raise errors.ProgrammerError("SetCredentials was never called.")
49
def Setup(username, password):
50
  """Configures the RAPI client.
66 51

  
67
      # Create opener which doesn't try to look for proxies and does auth
68
      master = qa_config.GetMasterNode()
69
      host = master["primary"]
70
      port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
71
      passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
72
      passman.add_password(None, 'https://%s:%s' % (host, port),
73
                           cls._rapi_user,
74
                           cls._rapi_secret)
75
      authhandler = urllib2.HTTPBasicAuthHandler(passman)
76
      cls._opener = urllib2.build_opener(urllib2.ProxyHandler({}), authhandler)
52
  """
53
  global _rapi_ca
54
  global _rapi_client
77 55

  
78
    return cls._opener
56
  master = qa_config.GetMasterNode()
79 57

  
58
  # Load RAPI certificate from master node
59
  cmd = ["cat", constants.RAPI_CERT_FILE]
80 60

  
81
class RapiRequest(urllib2.Request):
82
  """This class supports other methods beside GET/POST.
61
  # Write to temporary file
62
  _rapi_ca = tempfile.NamedTemporaryFile()
63
  _rapi_ca.write(qa_utils.GetCommandOutput(master["primary"],
64
                                           utils.ShellQuoteArgs(cmd)))
65
  _rapi_ca.flush()
83 66

  
84
  """
67
  port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
68
  cfg_ssl = rapi.client.CertAuthorityVerify(cafile=_rapi_ca.name)
85 69

  
86
  def __init__(self, method, url, headers, data):
87
    urllib2.Request.__init__(self, url, data=data, headers=headers)
88
    self._method = method
70
  _rapi_client = rapi.client.GanetiRapiClient(master["primary"], port=port,
71
                                              username=username,
72
                                              password=password,
73
                                              config_ssl_verification=cfg_ssl,
74
                                              ignore_proxy=True)
89 75

  
90
  def get_method(self):
91
    return self._method
76
  print "RAPI protocol version: %s" % _rapi_client.GetVersion()
92 77

  
93 78

  
94 79
INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
......
119 104

  
120 105

  
121 106
def _DoTests(uris):
122
  master = qa_config.GetMasterNode()
123
  host = master["primary"]
124
  port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
125 107
  results = []
126 108

  
127 109
  for uri, verify, method, body in uris:
128 110
    assert uri.startswith("/")
129 111

  
130
    url = "https://%s:%s%s" % (host, port, uri)
131

  
132
    headers = {}
133

  
134
    if body:
135
      data = serializer.DumpJson(body, indent=False)
136
      headers["Content-Type"] = "application/json"
137
    else:
138
      data = None
139

  
140
    if headers or data:
141
      details = []
142
      if headers:
143
        details.append("headers=%s" %
144
                       serializer.DumpJson(headers, indent=False).rstrip())
145
      if data:
146
        details.append("data=%s" % data.rstrip())
147
      info = "(%s)" % (", ".join(details), )
148
    else:
149
      info = ""
150

  
151
    print "Testing %s %s %s..." % (method, url, info)
152

  
153
    req = RapiRequest(method, url, headers, data)
154
    response = OpenerFactory.Opener().open(req)
155

  
156
    AssertEqual(response.info()["Content-type"], "application/json")
157

  
158
    data = serializer.LoadJson(response.read())
112
    data = _rapi_client._SendRequest(method, uri, None, body)
159 113

  
160 114
    if verify is not None:
161 115
      if callable(verify):
......
305 259
    ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
306 260
    ])
307 261

  
308
  # FIXME: Use "gnt-job watch" until RAPI supports waiting for job
309
  cmd = ["gnt-job", "watch", str(job_id)]
310
  AssertEqual(StartSSH(master["primary"],
311
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
262
  rapi.client_utils.PollJob(_rapi_client, job_id, cli.StdioJobPollReportCb())
312 263

  
313 264

  
314 265
def TestRapiInstanceAdd(node):

Also available in: Unified diff