summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVipin Balachandran <vbala@vmware.com>2014-02-28 06:53:51 +0530
committerVipin Balachandran <vbala@vmware.com>2014-03-03 16:19:51 +0530
commitd670193844a04fe75f0aa3903d6aa2476d15445e (patch)
treec333da69b717e81f5b3db3e2a9e4bb69c42cdc82
parentceb716f58e4a8bcbf04c057d4b26e990194ac562 (diff)
downloadoslo-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.py41
-rw-r--r--oslo/vmware/pbm.py66
-rw-r--r--oslo/vmware/vim.py12
-rw-r--r--oslo/vmware/vim_util.py14
-rw-r--r--tests/test_api.py2
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()