From 2771835cd1d9c80b2b3f1f376e699ac609313845 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Mon, 10 May 2010 17:26:32 +0200 Subject: [PATCH] RAPI QA: Use RAPI client Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- qa/ganeti-qa.py | 5 ++- qa/qa_rapi.py | 111 ++++++++++++++---------------------------------- 2 files changed, 35 insertions(+), 81 deletions(-) diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py index 64026c606..b3c7d91e5 100755 --- a/qa/ganeti-qa.py +++ b/qa/ganeti-qa.py @@ -281,10 +281,13 @@ def main(): rapi_user = "ganeti-qa" rapi_secret = utils.GenerateSecret() - qa_rapi.OpenerFactory.SetCredentials(rapi_user, rapi_secret) RunEnvTests() SetupCluster(rapi_user, rapi_secret) + + # Load RAPI certificate + qa_rapi.Setup(rapi_user, rapi_secret) + RunClusterTests() RunOsTests() diff --git a/qa/qa_rapi.py b/qa/qa_rapi.py index cefed6614..639f62a92 100644 --- a/qa/qa_rapi.py +++ b/qa/qa_rapi.py @@ -22,12 +22,17 @@ """ -import urllib2 +import tempfile from ganeti import utils from ganeti import constants from ganeti import errors from ganeti import serializer +from ganeti import cli +from ganeti import rapi + +import ganeti.rapi.client +import ganeti.rapi.client_utils import qa_config import qa_utils @@ -37,58 +42,38 @@ from qa_utils import (AssertEqual, AssertNotEqual, AssertIn, AssertMatch, StartSSH) -class OpenerFactory: - """A factory singleton to construct urllib opener chain. - - This is needed because qa_config is not initialized yet at module load time - - """ - _opener = None - _rapi_user = None - _rapi_secret = None - - @classmethod - def SetCredentials(cls, rapi_user, rapi_secret): - """Set the credentials for authorized access. - - """ - cls._rapi_user = rapi_user - cls._rapi_secret = rapi_secret +_rapi_ca = None +_rapi_client = None - @classmethod - def Opener(cls): - """Construct the opener if not yet done. - """ - if not cls._opener: - if not cls._rapi_user or not cls._rapi_secret: - raise errors.ProgrammerError("SetCredentials was never called.") +def Setup(username, password): + """Configures the RAPI client. - # Create opener which doesn't try to look for proxies and does auth - master = qa_config.GetMasterNode() - host = master["primary"] - port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT) - passman = urllib2.HTTPPasswordMgrWithDefaultRealm() - passman.add_password(None, 'https://%s:%s' % (host, port), - cls._rapi_user, - cls._rapi_secret) - authhandler = urllib2.HTTPBasicAuthHandler(passman) - cls._opener = urllib2.build_opener(urllib2.ProxyHandler({}), authhandler) + """ + global _rapi_ca + global _rapi_client - return cls._opener + master = qa_config.GetMasterNode() + # Load RAPI certificate from master node + cmd = ["cat", constants.RAPI_CERT_FILE] -class RapiRequest(urllib2.Request): - """This class supports other methods beside GET/POST. + # Write to temporary file + _rapi_ca = tempfile.NamedTemporaryFile() + _rapi_ca.write(qa_utils.GetCommandOutput(master["primary"], + utils.ShellQuoteArgs(cmd))) + _rapi_ca.flush() - """ + port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT) + cfg_ssl = rapi.client.CertAuthorityVerify(cafile=_rapi_ca.name) - def __init__(self, method, url, headers, data): - urllib2.Request.__init__(self, url, data=data, headers=headers) - self._method = method + _rapi_client = rapi.client.GanetiRapiClient(master["primary"], port=port, + username=username, + password=password, + config_ssl_verification=cfg_ssl, + ignore_proxy=True) - def get_method(self): - return self._method + print "RAPI protocol version: %s" % _rapi_client.GetVersion() INSTANCE_FIELDS = ("name", "os", "pnode", "snodes", @@ -119,43 +104,12 @@ def Enabled(): def _DoTests(uris): - master = qa_config.GetMasterNode() - host = master["primary"] - port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT) results = [] for uri, verify, method, body in uris: assert uri.startswith("/") - url = "https://%s:%s%s" % (host, port, uri) - - headers = {} - - if body: - data = serializer.DumpJson(body, indent=False) - headers["Content-Type"] = "application/json" - else: - data = None - - if headers or data: - details = [] - if headers: - details.append("headers=%s" % - serializer.DumpJson(headers, indent=False).rstrip()) - if data: - details.append("data=%s" % data.rstrip()) - info = "(%s)" % (", ".join(details), ) - else: - info = "" - - print "Testing %s %s %s..." % (method, url, info) - - req = RapiRequest(method, url, headers, data) - response = OpenerFactory.Opener().open(req) - - AssertEqual(response.info()["Content-type"], "application/json") - - data = serializer.LoadJson(response.read()) + data = _rapi_client._SendRequest(method, uri, None, body) if verify is not None: if callable(verify): @@ -305,10 +259,7 @@ def _WaitForRapiJob(job_id): ("/2/jobs/%s" % job_id, _VerifyJob, "GET", None), ]) - # FIXME: Use "gnt-job watch" until RAPI supports waiting for job - cmd = ["gnt-job", "watch", str(job_id)] - AssertEqual(StartSSH(master["primary"], - utils.ShellQuoteArgs(cmd)).wait(), 0) + rapi.client_utils.PollJob(_rapi_client, job_id, cli.StdioJobPollReportCb()) def TestRapiInstanceAdd(node): -- GitLab