From f13b1accfb1ab86a5ef30ac2b65397389add8339 Mon Sep 17 00:00:00 2001 From: Qiaowei Ren Date: Sat, 15 Aug 2015 10:54:49 +0800 Subject: [PATCH] xenapi: support the session when xenserver is slave current xenapi inspector is only support the session to master xenserver, and when xenserver is slave mode the session could not be created successfully. Change-Id: Icbcd497f0c5e50984d24f46f8db519f1eb2e0296 Closes-Bug: 1484768 --- ceilometer/compute/virt/xenapi/inspector.py | 27 +++++++++++++++++-- .../compute/virt/xenapi/test_inspector.py | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/ceilometer/compute/virt/xenapi/inspector.py b/ceilometer/compute/virt/xenapi/inspector.py index 02d69ed0..19405dd0 100644 --- a/ceilometer/compute/virt/xenapi/inspector.py +++ b/ceilometer/compute/virt/xenapi/inspector.py @@ -15,6 +15,7 @@ from oslo_config import cfg from oslo_utils import units +import six.moves.urllib.parse as urlparse try: import XenAPI as api except ImportError: @@ -48,6 +49,18 @@ class XenapiException(virt_inspector.InspectorException): pass +def swap_xapi_host(url, host_addr): + """Replace the XenServer address present in 'url' with 'host_addr'.""" + temp_url = urlparse.urlparse(url) + # The connection URL is served by XAPI and doesn't support having a + # path for the connection url after the port. And username/password + # will be pass separately. So the URL like "http://abc:abc@abc:433/abc" + # should not appear for XAPI case. + temp_netloc = temp_url.netloc.replace(temp_url.hostname, '%s' % host_addr) + replaced = temp_url._replace(netloc=temp_netloc) + return urlparse.urlunparse(replaced) + + def get_api_session(): if not api: raise ImportError(_('XenAPI not installed')) @@ -64,8 +77,18 @@ def get_api_session(): else api.Session(url)) session.login_with_password(username, password) except api.Failure as e: - msg = _("Could not connect to XenAPI: %s") % e.details[0] - raise XenapiException(msg) + if e.details[0] == 'HOST_IS_SLAVE': + master = e.details[1] + url = swap_xapi_host(url, master) + try: + session = api.Session(url) + session.login_with_password(username, password) + except api.Failure as es: + raise XenapiException(_('Could not connect slave host: %s ') % + es.details[0]) + else: + msg = _("Could not connect to XenAPI: %s") % e.details[0] + raise XenapiException(msg) return session diff --git a/ceilometer/tests/unit/compute/virt/xenapi/test_inspector.py b/ceilometer/tests/unit/compute/virt/xenapi/test_inspector.py index 1048c49d..c5d5390f 100644 --- a/ceilometer/tests/unit/compute/virt/xenapi/test_inspector.py +++ b/ceilometer/tests/unit/compute/virt/xenapi/test_inspector.py @@ -21,6 +21,33 @@ from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.compute.virt.xenapi import inspector as xenapi_inspector +class TestSwapXapiHost(base.BaseTestCase): + + def test_swapping(self): + self.assertEqual( + "http://otherserver:8765/somepath", + xenapi_inspector.swap_xapi_host( + "http://someserver:8765/somepath", 'otherserver')) + + def test_no_port(self): + self.assertEqual( + "http://otherserver/somepath", + xenapi_inspector.swap_xapi_host( + "http://someserver/somepath", 'otherserver')) + + def test_no_path(self): + self.assertEqual( + "http://otherserver", + xenapi_inspector.swap_xapi_host( + "http://someserver", 'otherserver')) + + def test_same_hostname_path(self): + self.assertEqual( + "http://other:80/some", + xenapi_inspector.swap_xapi_host( + "http://some:80/some", 'other')) + + class TestXenapiInspection(base.BaseTestCase): def setUp(self):