diff options
author | Vipin Balachandran <vbala@vmware.com> | 2014-02-28 06:53:51 +0530 |
---|---|---|
committer | Vipin Balachandran <vbala@vmware.com> | 2014-03-03 16:19:51 +0530 |
commit | d670193844a04fe75f0aa3903d6aa2476d15445e (patch) | |
tree | c333da69b717e81f5b3db3e2a9e4bb69c42cdc82 | |
parent | ceb716f58e4a8bcbf04c057d4b26e990194ac562 (diff) | |
download | oslo-vmware-d670193844a04fe75f0aa3903d6aa2476d15445e.tar.gz |
Add PBM client for policy based placement
This change defines a SOAP based client to invoke VMware PBM APIs.
It also make necessary changes in VMwareAPISession to expose the
PBM client to the drivers.
Change-Id: Ic715cf8795e178ce8d99d492501935658ad9b2a7
-rw-r--r-- | oslo/vmware/api.py | 41 | ||||
-rw-r--r-- | oslo/vmware/pbm.py | 66 | ||||
-rw-r--r-- | oslo/vmware/vim.py | 12 | ||||
-rw-r--r-- | oslo/vmware/vim_util.py | 14 | ||||
-rw-r--r-- | tests/test_api.py | 2 |
5 files changed, 118 insertions, 17 deletions
diff --git a/oslo/vmware/api.py b/oslo/vmware/api.py index 634da82..feac811 100644 --- a/oslo/vmware/api.py +++ b/oslo/vmware/api.py @@ -28,6 +28,7 @@ import six from oslo.vmware.common import loopingcall from oslo.vmware import exceptions from oslo.vmware.openstack.common.gettextutils import _ +from oslo.vmware import pbm from oslo.vmware import vim from oslo.vmware import vim_util @@ -132,7 +133,7 @@ class VMwareAPISession(object): def __init__(self, host, server_username, server_password, api_retry_count, task_poll_interval, scheme='https', - create_session=True, wsdl_loc=None): + 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] @@ -145,8 +146,8 @@ class VMwareAPISession(object): :param scheme: protocol-- http or https :param _create_session: whether to setup a connection at the time of instance creation - :param wsdl_loc: WSDL file location for invoking SOAP calls on server - using suds + :param wsdl_loc: VIM API WSDL file location + :param pbm_wsdl_loc: PBM service WSDL file location :raises: VimException, VimFaultException, VimAttributeException, VimSessionOverLoadException """ @@ -156,10 +157,12 @@ class VMwareAPISession(object): self._api_retry_count = api_retry_count self._task_poll_interval = task_poll_interval self._scheme = scheme - self._wsdl_loc = wsdl_loc + self._vim_wsdl_loc = wsdl_loc + self._pbm_wsdl_loc = pbm_wsdl_loc self._session_id = None self._session_username = None self._vim = None + self._pbm = None if create_session: self._create_session() @@ -168,9 +171,22 @@ class VMwareAPISession(object): if not self._vim: self._vim = vim.Vim(protocol=self._scheme, host=self._host, - wsdl_loc=self._wsdl_loc) + wsdl_loc=self._vim_wsdl_loc) return self._vim + @property + def pbm(self): + if not self._pbm and self._pbm_wsdl_loc: + self._pbm = pbm.PBMClient(self._pbm_wsdl_loc, + protocol=self._scheme, + host=self._host) + if self._session_id: + # To handle the case where pbm property is accessed after + # session creation. If pbm property is accessed before session + # creation, we set the cookie in _create_session. + self._pbm.set_cookie(self._get_session_cookie()) + return self._pbm + @RetryDecorator(exceptions=(exceptions.VimConnectionException,)) def _create_session(self): """Establish session with the server.""" @@ -209,6 +225,10 @@ class VMwareAPISession(object): prev_session_id, exc_info=True) + # Set PBM client cookie. + if self._pbm: + self._pbm.set_cookie(self._get_session_cookie()) + def __del__(self): """Log out and terminate the current session.""" if self._session_id: @@ -452,3 +472,14 @@ class VMwareAPISession(object): lease, exc_info=True) return "Unknown" + + def _get_session_cookie(self): + """Get the cookie corresponding to the current session. + + :returns: cookie corresponding to the current session + """ + cookies = self.vim.client.options.transport.cookiejar + for c in cookies: + if c.name.lower() == 'vmware_soap_session': + return c.value + return None diff --git a/oslo/vmware/pbm.py b/oslo/vmware/pbm.py new file mode 100644 index 0000000..004c881 --- /dev/null +++ b/oslo/vmware/pbm.py @@ -0,0 +1,66 @@ +# Copyright (c) 2014 VMware, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +VMware PBM client. + +PBM is used for policy based placement in VMware datastores. +Refer http://goo.gl/GR2o6U for more details. +""" + +import suds +import suds.sax.element as element + +from oslo.vmware import vim +from oslo.vmware import vim_util + + +SERVICE_INSTANCE = 'ServiceInstance' +SERVICE_TYPE = 'PbmServiceInstance' + + +class PBMClient(vim.Vim): + """SOAP based PBM client.""" + + def __init__(self, pbm_wsdl_loc, protocol='https', host='localhost'): + """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] + """ + self._url = vim_util.get_soap_url(protocol, host, 'pbm') + self._pbm_client = suds.client.Client(pbm_wsdl_loc, location=self._url) + self._pbm_service_content = None + + def set_cookie(self, cookie): + """Set the authenticated VIM session's cookie in the SOAP client. + + :param cookie: cookie to set + """ + elem = element.Element('vcSessionCookie').setText(cookie) + self._pbm_client.set_options(soapheaders=elem) + + @property + def client(self): + return self._pbm_client + + @property + def service_content(self): + if not self._pbm_service_content: + si_moref = vim_util.get_moref(SERVICE_INSTANCE, SERVICE_TYPE) + self._pbm_service_content = ( + self._pbm_client.service.PbmRetrieveServiceContent(si_moref)) + return self._pbm_service_content diff --git a/oslo/vmware/vim.py b/oslo/vmware/vim.py index d37c1db..8c553a4 100644 --- a/oslo/vmware/vim.py +++ b/oslo/vmware/vim.py @@ -79,7 +79,7 @@ class Vim(object): """ if not wsdl_loc: wsdl_loc = Vim._get_wsdl_loc(protocol, host) - soap_url = Vim._get_soap_url(protocol, host) + soap_url = vim_util.get_soap_url(protocol, host) self._client = suds.client.Client(wsdl_loc, location=soap_url, plugins=[VimMessagePlugin()]) @@ -95,16 +95,6 @@ class Vim(object): """ return '%s://%s/sdk/vimService.wsdl' % (protocol, host) - @staticmethod - def _get_soap_url(protocol, host): - """Get ESX/VC server's SOAP service URL. - - :param protocol: http or https - :param host: server IP address[:port] or host name[:port] - :returns: URL of ESX/VC server's SOAP service - """ - return '%s://%s/sdk' % (protocol, host) - @property def service_content(self): return self._service_content diff --git a/oslo/vmware/vim_util.py b/oslo/vmware/vim_util.py index c9b022b..c7194c5 100644 --- a/oslo/vmware/vim_util.py +++ b/oslo/vmware/vim_util.py @@ -17,6 +17,7 @@ The VMware API utility module. """ +import netaddr import suds @@ -365,3 +366,16 @@ def get_object_property(vim, moref, property_name): if prop: prop_val = prop[0].val return prop_val + + +def get_soap_url(protocol, host, 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 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) diff --git a/tests/test_api.py b/tests/test_api.py index 4182b3f..af182ee 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -119,7 +119,7 @@ class VMwareAPISessionTest(base.TestCase): api_session.vim self.VimMock.assert_called_with(protocol=api_session._scheme, host=VMwareAPISessionTest.SERVER_IP, - wsdl_loc=api_session._wsdl_loc) + wsdl_loc=api_session._vim_wsdl_loc) def test_create_session(self): session = mock.Mock() |