From a76bd253fb4fa54c72d3440f2345642b209b5f41 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 1 May 2014 10:05:41 -0400 Subject: [PATCH] Support for IPv6 and Non-standard ports IPv6 urls are formatted with '[' and ']' around the host and the port actually shows up after the trailing ']' as well. So we need to allow for better support for both ipv6 and non standard urls when dealing with both SOAP and WSDL urls. Examples: https://[fd2e:1201:1d9f:0:8886:78e0:38cd:cb03]/sdk https://[::1]:9443/sdk/ Closes-Bug: #1287292 Change-Id: I84ab38087ea77a30f6082d8c3fae0341e3371a78 --- oslo/vmware/api.py | 15 +++++++++----- oslo/vmware/image_transfer.py | 3 +++ oslo/vmware/pbm.py | 8 ++++--- oslo/vmware/rw_handles.py | 39 +++++++++++++++++++++-------------- oslo/vmware/vim.py | 28 ++++++++++++++++++------- oslo/vmware/vim_util.py | 26 +++++++++++++++++++---- tests/test_api.py | 3 +++ tests/test_image_transfer.py | 12 +++++++++++ tests/test_rw_handles.py | 27 ++++++++++++++---------- tests/test_vim.py | 21 +++++++++++++++++++ tests/test_vim_util.py | 15 ++++++++++++++ 11 files changed, 150 insertions(+), 47 deletions(-) diff --git a/oslo/vmware/api.py b/oslo/vmware/api.py index a4d3180..2384724 100644 --- a/oslo/vmware/api.py +++ b/oslo/vmware/api.py @@ -125,18 +125,20 @@ class VMwareAPISession(object): """Setup a session with the server and handles all calls made to it. Example: - api_session = VMwareAPISession('10.1.2.3', 'administrator', 'password', - 10, 0.1, create_session=False) + api_session = VMwareAPISession('10.1.2.3', 443, 'administrator', + 'password', 10, 0.1, + create_session=False) result = api_session.invoke_api(vim_util, 'get_objects', api_session.vim, 'HostSystem', 100) """ - def __init__(self, host, server_username, server_password, + def __init__(self, host, port, server_username, server_password, api_retry_count, task_poll_interval, scheme='https', create_session=True, wsdl_loc=None, pbm_wsdl_loc=None): """Initializes the API session with given parameters. - :param host: ESX/VC server IP address[:port] or host name[:port] + :param host: ESX/VC server IP address or host name + :param port: port for connection :param server_username: username of ESX/VC server admin user :param server_password: password for param server_username :param api_retry_count: number of times an API must be retried upon @@ -152,6 +154,7 @@ class VMwareAPISession(object): VimSessionOverLoadException """ self._host = host + self._port = port self._server_username = server_username self._server_password = server_password self._api_retry_count = api_retry_count @@ -171,6 +174,7 @@ class VMwareAPISession(object): if not self._vim: self._vim = vim.Vim(protocol=self._scheme, host=self._host, + port=self._port, wsdl_loc=self._vim_wsdl_loc) return self._vim @@ -179,7 +183,8 @@ class VMwareAPISession(object): if not self._pbm and self._pbm_wsdl_loc: self._pbm = pbm.PBMClient(self._pbm_wsdl_loc, protocol=self._scheme, - host=self._host) + host=self._host, + port=self._port) if self._session_id: # To handle the case where pbm property is accessed after # session creation. If pbm property is accessed before session diff --git a/oslo/vmware/image_transfer.py b/oslo/vmware/image_transfer.py index 6fe9342..a1c869b 100644 --- a/oslo/vmware/image_transfer.py +++ b/oslo/vmware/image_transfer.py @@ -416,6 +416,7 @@ def download_flat_image(context, timeout_secs, image_service, image_id, read_handle = rw_handles.ImageReadHandle(read_iter) file_size = int(kwargs.get('image_size')) write_handle = rw_handles.FileWriteHandle(kwargs.get('host'), + kwargs.get('port'), kwargs.get('data_center_name'), kwargs.get('datastore_name'), kwargs.get('cookies'), @@ -448,6 +449,7 @@ def download_stream_optimized_data(context, timeout_secs, read_handle, file_size = int(kwargs.get('image_size')) write_handle = rw_handles.VmdkWriteHandle(kwargs.get('session'), kwargs.get('host'), + kwargs.get('port'), kwargs.get('resource_pool'), kwargs.get('vm_folder'), kwargs.get('vm_import_spec'), @@ -511,6 +513,7 @@ def upload_image(context, timeout_secs, image_service, image_id, owner_id, file_size = kwargs.get('vmdk_size') read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'), kwargs.get('host'), + kwargs.get('port'), kwargs.get('vm'), kwargs.get('vmdk_file_path'), file_size) diff --git a/oslo/vmware/pbm.py b/oslo/vmware/pbm.py index 42f88cf..8df81d8 100644 --- a/oslo/vmware/pbm.py +++ b/oslo/vmware/pbm.py @@ -37,14 +37,16 @@ LOG = logging.getLogger(__name__) class PBMClient(vim.Vim): """SOAP based PBM client.""" - def __init__(self, pbm_wsdl_loc, protocol='https', host='localhost'): + def __init__(self, pbm_wsdl_loc, protocol='https', host='localhost', + port=443): """Constructs a PBM client object. :param pbm_wsdl_loc: PBM WSDL file location :param protocol: http or https - :param host: server IP address[:port] or host name[:port] + :param host: server IP address or host name + :param port: port for connection """ - self._url = vim_util.get_soap_url(protocol, host, 'pbm') + self._url = vim_util.get_soap_url(protocol, host, port, 'pbm') self._pbm_client = suds.client.Client(pbm_wsdl_loc, location=self._url) self._pbm_service_content = None diff --git a/oslo/vmware/rw_handles.py b/oslo/vmware/rw_handles.py index 36ff372..cf4feec 100644 --- a/oslo/vmware/rw_handles.py +++ b/oslo/vmware/rw_handles.py @@ -102,13 +102,13 @@ class FileHandle(object): except Exception: return False - def _get_soap_url(self, scheme, host): + def _get_soap_url(self, scheme, host, port): """Returns the IPv4/v6 compatible SOAP URL for the given host.""" if self._is_valid_ipv6(host): - return '%s://[%s]' % (scheme, host) - return '%s://%s' % (scheme, host) + return '%s://[%s]:%d' % (scheme, host, port) + return '%s://%s:%d' % (scheme, host, port) - def _fix_esx_url(self, url, host): + def _fix_esx_url(self, url, host, port): """Fix netloc in the case of an ESX host. In the case of an ESX host, the netloc is set to '*' in the URL @@ -118,21 +118,25 @@ class FileHandle(object): urlp = urlparse.urlparse(url) if urlp.netloc == '*': scheme, netloc, path, params, query, fragment = urlp + if netaddr.valid_ipv6(host): + netloc = '[%s]:%d' % (host, port) + else: + netloc = "%s:%d" % (host, port) url = urlparse.urlunparse((scheme, - host, + netloc, path, params, query, fragment)) return url - def _find_vmdk_url(self, lease_info, host): + def _find_vmdk_url(self, lease_info, host, port): """Find the URL corresponding to a VMDK file in lease info.""" LOG.debug("Finding VMDK URL from lease info.") url = None for deviceUrl in lease_info.deviceUrl: if deviceUrl.disk: - url = self._fix_esx_url(deviceUrl.url, host) + url = self._fix_esx_url(deviceUrl.url, host, port) break if not url: excep_msg = _("Could not retrieve VMDK URL from lease info.") @@ -145,11 +149,12 @@ class FileHandle(object): class FileWriteHandle(FileHandle): """Write handle for a file in VMware server.""" - def __init__(self, host, data_center_name, datastore_name, cookies, + def __init__(self, host, port, data_center_name, datastore_name, cookies, file_path, file_size, scheme='https'): """Initializes the write handle with given parameters. - :param host: ESX/VC server IP address[:port] or host name[:port] + :param host: ESX/VC server IP address or host name + :param port: port for connection :param data_center_name: name of the data center in the case of a VC server :param datastore_name: name of the datastore where the file is stored @@ -159,7 +164,7 @@ class FileWriteHandle(FileHandle): :param scheme: protocol-- http or https :raises: VimConnectionException, ValueError """ - soap_url = self._get_soap_url(scheme, host) + soap_url = self._get_soap_url(scheme, host, port) param_list = {'dcPath': data_center_name, 'dsName': datastore_name} self._url = '%s/folder/%s' % (soap_url, file_path) self._url = self._url + '?' + urllib.urlencode(param_list) @@ -248,12 +253,13 @@ class VmdkWriteHandle(FileHandle): virtual disk contents. """ - def __init__(self, session, host, rp_ref, vm_folder_ref, import_spec, + def __init__(self, session, host, port, rp_ref, vm_folder_ref, import_spec, vmdk_size): """Initializes the VMDK write handle with input parameters. :param session: valid API session to ESX/VC server - :param host: ESX/VC server IP address[:port] or host name[:port] + :param host: ESX/VC server IP address or host name + :param port: port for connection :param rp_ref: resource pool into which the backing VM is imported :param vm_folder_ref: VM folder in ESX/VC inventory to use as parent of backing VM @@ -281,7 +287,7 @@ class VmdkWriteHandle(FileHandle): 'info') # Find VMDK URL where data is to be written - self._url = self._find_vmdk_url(lease_info, host) + self._url = self._find_vmdk_url(lease_info, host, port) self._vm_ref = lease_info.entity # Create HTTP connection to write to VMDK URL @@ -449,7 +455,7 @@ class VmdkWriteHandle(FileHandle): class VmdkReadHandle(FileHandle): """VMDK read handle based on HttpNfcLease.""" - def __init__(self, session, host, vm_ref, vmdk_path, vmdk_size): + def __init__(self, session, host, port, vm_ref, vmdk_path, vmdk_size): """Initializes the VMDK read handle with the given parameters. During the read (export) operation, the VMDK file is converted to a @@ -457,7 +463,8 @@ class VmdkReadHandle(FileHandle): file read may be smaller than the actual VMDK size. :param session: valid api session to ESX/VC server - :param host: ESX/VC server IP address[:port] or host name[:port] + :param host: ESX/VC server IP address or host name + :param port: port for connection :param vm_ref: managed object reference of the backing VM whose VMDK is to be exported :param vmdk_path: path of the VMDK file to be exported @@ -480,7 +487,7 @@ class VmdkReadHandle(FileHandle): 'info') # find URL of the VMDK file to be read and open connection - self._url = self._find_vmdk_url(lease_info, host) + self._url = self._find_vmdk_url(lease_info, host, port) self._conn = self._create_connection(session, self._url) FileHandle.__init__(self, self._conn) diff --git a/oslo/vmware/vim.py b/oslo/vmware/vim.py index 952e0e9..6eb8909 100644 --- a/oslo/vmware/vim.py +++ b/oslo/vmware/vim.py @@ -68,32 +68,44 @@ class VimMessagePlugin(suds.plugin.MessagePlugin): class Vim(object): """VIM API Client.""" - def __init__(self, protocol='https', host='localhost', wsdl_loc=None): + def __init__(self, protocol='https', host='localhost', port=None, + wsdl_loc=None): """Create communication interfaces for initiating SOAP transactions. :param protocol: http or https - :param host: server IP address[:port] or host name[:port] + :param host: server IP address or host name + :param port: port for connection :param wsdl_loc: WSDL file location :raises: VimException, VimFaultException, VimAttributeException, VimSessionOverLoadException, VimConnectionException """ if not wsdl_loc: - wsdl_loc = Vim._get_wsdl_loc(protocol, host) - soap_url = vim_util.get_soap_url(protocol, host) + wsdl_loc = Vim._get_wsdl_loc(protocol, host, port) + self._wsdl_loc = wsdl_loc + self._soap_url = vim_util.get_soap_url(protocol, host, port) self._client = suds.client.Client(wsdl_loc, - location=soap_url, + location=self._soap_url, plugins=[VimMessagePlugin()]) self._service_content = self.RetrieveServiceContent('ServiceInstance') @staticmethod - def _get_wsdl_loc(protocol, host): + def _get_wsdl_loc(protocol, host, port): """Get the default WSDL file location hosted at the server. :param protocol: http or https - :param host: server IP address[:port] or host name[:port] + :param host: server IP address or host name + :param port: port for connection :returns: default WSDL file location hosted at the server """ - return '%s://%s/sdk/vimService.wsdl' % (protocol, host) + return vim_util.get_wsdl_url(protocol, host, port) + + @property + def wsdl_url(self): + return self._wsdl_loc + + @property + def soap_url(self): + return self._soap_url @property def service_content(self): diff --git a/oslo/vmware/vim_util.py b/oslo/vmware/vim_util.py index c7194c5..bbd725f 100644 --- a/oslo/vmware/vim_util.py +++ b/oslo/vmware/vim_util.py @@ -368,14 +368,32 @@ def get_object_property(vim, moref, property_name): return prop_val -def get_soap_url(protocol, host, path='sdk'): +def get_wsdl_url(protocol, host, port=None): + """Get the default WSDL file location hosted at the server. + + :param protocol: http or https + :param host: server IP address or host name + :param port: port for connection + :returns: default WSDL file location hosted at the server + """ + return get_soap_url(protocol, host, port) + "/vimService.wsdl" + + +def get_soap_url(protocol, host, port=None, path='sdk'): """Return ESX/VC server's SOAP service URL. :param protocol: https or http - :param host: server IP address[:port] or host name[:port] + :param host: server IP address or host name + :param port: port for connection :param path: path part of the SOAP URL :returns: SOAP service URL """ if netaddr.valid_ipv6(host): - return '%s://[%s]/%s' % (protocol, host, path) - return '%s://%s/%s' % (protocol, host, path) + if port is None: + return '%s://[%s]/%s' % (protocol, host, path) + else: + return '%s://[%s]:%d/%s' % (protocol, host, port, path) + if port is None: + return '%s://%s/%s' % (protocol, host, path) + else: + return '%s://%s:%d/%s' % (protocol, host, port, path) diff --git a/tests/test_api.py b/tests/test_api.py index 1591b0f..d6e6f71 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -96,6 +96,7 @@ class VMwareAPISessionTest(base.TestCase): """Tests for VMwareAPISession.""" SERVER_IP = '10.1.2.3' + PORT = 443 USERNAME = 'admin' PASSWORD = 'password' @@ -109,6 +110,7 @@ class VMwareAPISessionTest(base.TestCase): def _create_api_session(self, _create_session, retry_count=10, task_poll_interval=1): return api.VMwareAPISession(VMwareAPISessionTest.SERVER_IP, + VMwareAPISessionTest.PORT, VMwareAPISessionTest.USERNAME, VMwareAPISessionTest.PASSWORD, retry_count, @@ -121,6 +123,7 @@ class VMwareAPISessionTest(base.TestCase): api_session.vim self.VimMock.assert_called_with(protocol=api_session._scheme, host=VMwareAPISessionTest.SERVER_IP, + port=VMwareAPISessionTest.PORT, wsdl_loc=api_session._vim_wsdl_loc) @mock.patch.object(pbm, 'PBMClient') diff --git a/tests/test_image_transfer.py b/tests/test_image_transfer.py index d76f9bf..1965cd9 100644 --- a/tests/test_image_transfer.py +++ b/tests/test_image_transfer.py @@ -307,6 +307,7 @@ class ImageTransferUtilityTest(base.TestCase): timeout_secs = 10 image_size = 1000 host = '127.0.0.1' + port = 443 dc_path = 'dc1' ds_name = 'ds1' file_path = '/fake_path' @@ -321,6 +322,7 @@ class ImageTransferUtilityTest(base.TestCase): image_id, image_size=image_size, host=host, + port=port, data_center_name=dc_path, datastore_name=ds_name, cookies=cookies, @@ -332,6 +334,7 @@ class ImageTransferUtilityTest(base.TestCase): fake_rw_handles_FileWriteHandle.assert_called_once_with( host, + port, dc_path, ds_name, cookies, @@ -356,6 +359,7 @@ class ImageTransferUtilityTest(base.TestCase): timeout_secs = 10 image_size = 1000 host = '127.0.0.1' + port = 443 resource_pool = 'rp-1' vm_folder = 'folder-1' vm_import_spec = None @@ -370,6 +374,7 @@ class ImageTransferUtilityTest(base.TestCase): read_handle, session=session, host=host, + port=port, resource_pool=resource_pool, vm_folder=vm_folder, vm_import_spec=vm_import_spec, @@ -378,6 +383,7 @@ class ImageTransferUtilityTest(base.TestCase): fake_rw_handles_VmdkWriteHandle.assert_called_once_with( session, host, + port, resource_pool, vm_folder, vm_import_spec, @@ -404,6 +410,7 @@ class ImageTransferUtilityTest(base.TestCase): timeout_secs = 10 image_size = 1000 host = '127.0.0.1' + port = 443 resource_pool = 'rp-1' vm_folder = 'folder-1' vm_import_spec = None @@ -423,6 +430,7 @@ class ImageTransferUtilityTest(base.TestCase): image_id, session=session, host=host, + port=port, resource_pool=resource_pool, vm_folder=vm_folder, vm_import_spec=vm_import_spec, @@ -438,6 +446,7 @@ class ImageTransferUtilityTest(base.TestCase): fake_ImageReadHandle, session=session, host=host, + port=port, resource_pool=resource_pool, vm_folder=vm_folder, vm_import_spec=vm_import_spec, @@ -457,6 +466,7 @@ class ImageTransferUtilityTest(base.TestCase): timeout_secs = 10 image_size = 1000 host = '127.0.0.1' + port = 443 file_path = '/fake_path' is_public = False image_name = 'fake_image' @@ -472,6 +482,7 @@ class ImageTransferUtilityTest(base.TestCase): owner_id, session=session, host=host, + port=port, vm=vm, vmdk_file_path=file_path, vmdk_size=image_size, @@ -481,6 +492,7 @@ class ImageTransferUtilityTest(base.TestCase): fake_rw_handles_VmdkReadHandle.assert_called_once_with(session, host, + port, vm, file_path, image_size) diff --git a/tests/test_rw_handles.py b/tests/test_rw_handles.py index 2941883..fb98792 100644 --- a/tests/test_rw_handles.py +++ b/tests/test_rw_handles.py @@ -43,10 +43,12 @@ class FileHandleTest(base.TestCase): lease_info = mock.Mock() lease_info.deviceUrl = [device_url_0, device_url_1] host = '10.1.2.3' - exp_url = 'https://%s/ds1/vm1.vmdk' % host + port = 443 + exp_url = 'https://%s:%d/ds1/vm1.vmdk' % (host, port) vmw_http_file = rw_handles.FileHandle(None) self.assertEqual(exp_url, vmw_http_file._find_vmdk_url(lease_info, - host)) + host, + port)) class FileWriteHandleTest(base.TestCase): @@ -66,7 +68,8 @@ class FileWriteHandleTest(base.TestCase): HTTPConnectionMock.return_value = self._conn self.vmw_http_write_file = rw_handles.FileWriteHandle( - '10.1.2.3', 'dc-0', 'ds-0', [vim_cookie], '1.vmdk', 100, 'http') + '10.1.2.3', 443, 'dc-0', 'ds-0', [vim_cookie], '1.vmdk', 100, + 'http') def test_write(self): self.vmw_http_write_file.write(None) @@ -118,6 +121,7 @@ class VmdkWriteHandleTest(base.TestCase): self.assertRaises(exceptions.VimException, lambda: rw_handles.VmdkWriteHandle(session, '10.1.2.3', + 443, 'rp-1', 'folder-1', None, @@ -125,7 +129,7 @@ class VmdkWriteHandleTest(base.TestCase): def test_write(self): session = self._create_mock_session() - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', + handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, 'rp-1', 'folder-1', None, 100) data = [1] * 10 @@ -137,7 +141,7 @@ class VmdkWriteHandleTest(base.TestCase): vmdk_size = 100 data_size = 10 session = self._create_mock_session(True, 10) - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', + handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, 'rp-1', 'folder-1', None, vmdk_size) handle.write([1] * data_size) @@ -145,7 +149,7 @@ class VmdkWriteHandleTest(base.TestCase): def test_update_progress_with_error(self): session = self._create_mock_session(True, 10) - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', + handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, 'rp-1', 'folder-1', None, 100) session.invoke_api.side_effect = exceptions.VimException(None) @@ -153,7 +157,7 @@ class VmdkWriteHandleTest(base.TestCase): def test_close(self): session = self._create_mock_session() - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', + handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, 'rp-1', 'folder-1', None, 100) @@ -215,6 +219,7 @@ class VmdkReadHandleTest(base.TestCase): self.assertRaises(exceptions.VimException, lambda: rw_handles.VmdkReadHandle(session, '10.1.2.3', + 443, 'vm-1', '[ds] disk1.vmdk', 100)) @@ -223,7 +228,7 @@ class VmdkReadHandleTest(base.TestCase): chunk_size = rw_handles.READ_CHUNKSIZE session = self._create_mock_session() self._conn.read.return_value = [1] * chunk_size - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', + handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, 'vm-1', '[ds] disk1.vmdk', chunk_size * 10) handle.read(chunk_size) @@ -235,7 +240,7 @@ class VmdkReadHandleTest(base.TestCase): vmdk_size = chunk_size * 10 session = self._create_mock_session(True, 10) self._conn.read.return_value = [1] * chunk_size - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', + handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, 'vm-1', '[ds] disk1.vmdk', vmdk_size) handle.read(chunk_size) @@ -243,7 +248,7 @@ class VmdkReadHandleTest(base.TestCase): def test_update_progress_with_error(self): session = self._create_mock_session(True, 10) - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', + handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, 'vm-1', '[ds] disk1.vmdk', 100) session.invoke_api.side_effect = exceptions.VimException(None) @@ -251,7 +256,7 @@ class VmdkReadHandleTest(base.TestCase): def test_close(self): session = self._create_mock_session() - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', + handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, 'vm-1', '[ds] disk1.vmdk', 100) diff --git a/tests/test_vim.py b/tests/test_vim.py index abdae51..28a3dcc 100644 --- a/tests/test_vim.py +++ b/tests/test_vim.py @@ -312,3 +312,24 @@ class VimTest(base.TestCase): "Faults: [ValueError('example',)]\n" "Details: {'foo': 'bar'}", string) + + def test_configure_non_default_host_port(self): + vim_obj = vim.Vim('https', 'www.test.com', 12345) + self.assertEqual('https://www.test.com:12345/sdk/vimService.wsdl', + vim_obj.wsdl_url) + self.assertEqual('https://www.test.com:12345/sdk', + vim_obj.soap_url) + + def test_configure_ipv6(self): + vim_obj = vim.Vim('https', '::1') + self.assertEqual('https://[::1]/sdk/vimService.wsdl', + vim_obj.wsdl_url) + self.assertEqual('https://[::1]/sdk', + vim_obj.soap_url) + + def test_configure_ipv6_and_non_default_host_port(self): + vim_obj = vim.Vim('https', '::1', 12345) + self.assertEqual('https://[::1]:12345/sdk/vimService.wsdl', + vim_obj.wsdl_url) + self.assertEqual('https://[::1]:12345/sdk', + vim_obj.soap_url) diff --git a/tests/test_vim_util.py b/tests/test_vim_util.py index d077d7c..17fd5ec 100644 --- a/tests/test_vim_util.py +++ b/tests/test_vim_util.py @@ -288,3 +288,18 @@ class VimUtilTest(base.TestCase): self.assertEqual(prop.val, val) get_object_properties.assert_called_once_with( vim, moref, [property_name]) + + def test_configure_without_wsdl_loc_override(self): + wsdl_url = vim_util.get_wsdl_url("https", "www.example.com") + url = vim_util.get_soap_url("https", "www.example.com") + self.assertEqual("https://www.example.com/sdk/vimService.wsdl", + wsdl_url) + self.assertEqual("https://www.example.com/sdk", url) + + def test_configure_without_wsdl_loc_override_using_ipv6(self): + # Same as above but with ipv6 based host ip + wsdl_url = vim_util.get_wsdl_url("https", "::1") + url = vim_util.get_soap_url("https", "::1") + self.assertEqual("https://[::1]/sdk/vimService.wsdl", + wsdl_url) + self.assertEqual("https://[::1]/sdk", url)