VMware: Split out VMwareAPISession

The VMwareAPISession object is not only used by the driver, but in
practically all modules of vmwareapi. It reduces a bit the scope of
the driver module itself.

Partial-Bug: #1962771

Change-Id: I4094b6031872bd3b5c871b9a82c7e01280a3352d
This commit is contained in:
Fabian Wiesel 2022-03-05 09:29:11 +00:00 committed by Kiran Pawar
parent 1ff89a09d4
commit 03fd208c56
9 changed files with 168 additions and 110 deletions

@ -36,7 +36,7 @@ def fake_vim_prop(arg):
return fake.get_fake_vim_object(arg)
def fake_is_vim_object(arg, module):
def fake_is_vim_object(module):
"""Stubs out the VMwareAPISession's is_vim_object method."""
return isinstance(module, fake.FakeVim)
@ -74,9 +74,10 @@ def set_stubs(test):
fake.fake_upload_image)
test.stub_out('nova.virt.vmwareapi.images.fetch_image',
fake.fake_fetch_image)
test.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession.vim',
test.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.vim',
fake_vim_prop)
test.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession._is_vim_object',
test.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.'
'_is_vim_object',
fake_is_vim_object)
test.stub_out('nova.network.neutron.API.update_instance_vnic_index',
lambda *args, **kwargs: None)

@ -61,6 +61,7 @@ from nova.virt.vmwareapi import ds_util
from nova.virt.vmwareapi import error_util
from nova.virt.vmwareapi import imagecache
from nova.virt.vmwareapi import images
from nova.virt.vmwareapi import session
from nova.virt.vmwareapi import vif
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util
@ -109,20 +110,11 @@ DEFAULT_FLAVOR_OBJS = [
]
def _fake_create_session(inst):
session = vmwareapi_fake.DataObject()
session.key = 'fake_key'
session.userName = 'fake_username'
session._pbm_wsdl_loc = None
session._pbm = None
inst._session = session
class VMwareDriverStartupTestCase(test.NoDBTestCase):
def _start_driver_with_flags(self, expected_exception_type, startup_flags):
self.flags(**startup_flags)
with mock.patch(
'nova.virt.vmwareapi.driver.VMwareAPISession.__init__'):
'nova.virt.vmwareapi.session.VMwareAPISession.__init__'):
e = self.assertRaises(Exception, driver.VMwareVCDriver, None) # noqa
self.assertIs(type(e), expected_exception_type)
@ -154,36 +146,6 @@ class VMwareDriverStartupTestCase(test.NoDBTestCase):
group='vmware'))
class VMwareSessionTestCase(test.NoDBTestCase):
@mock.patch.object(driver.VMwareAPISession, '_is_vim_object',
return_value=False)
def test_call_method(self, mock_is_vim):
with test.nested(
mock.patch.object(driver.VMwareAPISession, '_create_session',
_fake_create_session),
mock.patch.object(driver.VMwareAPISession, 'invoke_api'),
) as (fake_create, fake_invoke):
session = driver.VMwareAPISession()
session._vim = mock.Mock()
module = mock.Mock()
session._call_method(module, 'fira')
fake_invoke.assert_called_once_with(module, 'fira', session._vim)
@mock.patch.object(driver.VMwareAPISession, '_is_vim_object',
return_value=True)
def test_call_method_vim(self, mock_is_vim):
with test.nested(
mock.patch.object(driver.VMwareAPISession, '_create_session',
_fake_create_session),
mock.patch.object(driver.VMwareAPISession, 'invoke_api'),
) as (fake_create, fake_invoke):
session = driver.VMwareAPISession()
module = mock.Mock()
session._call_method(module, 'fira')
fake_invoke.assert_called_once_with(module, 'fira')
class VMwareAPIVMTestCase(test.NoDBTestCase,
test_diagnostics.DiagnosticsComparisonMixin):
"""Unit tests for Vmware API connection calls."""
@ -337,7 +299,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
_fake_check_session)
with mock.patch.object(greenthread, 'sleep'):
self.conn = driver.VMwareAPISession()
self.conn = session.VMwareAPISession()
self.assertEqual(2, self.attempts)
def _get_flavor_by_name(self, type):

@ -22,8 +22,8 @@ from oslo_vmware import vim_util
from nova import test
from nova.tests.unit.virt.vmwareapi import fake
from nova.tests.unit.virt.vmwareapi import stubs
from nova.virt.vmwareapi import driver
from nova.virt.vmwareapi import network_util
from nova.virt.vmwareapi import session
ResultSet = collections.namedtuple('ResultSet', ['objects'])
@ -36,12 +36,12 @@ class GetNetworkWithTheNameTestCase(test.NoDBTestCase):
def setUp(self):
super(GetNetworkWithTheNameTestCase, self).setUp()
fake.reset()
self.stub_out('nova.virt.vmwareapi.driver.VMwareAPISession.vim',
self.stub_out('nova.virt.vmwareapi.session.VMwareAPISession.vim',
stubs.fake_vim_prop)
self.stub_out('nova.virt.vmwareapi.driver.'
self.stub_out('nova.virt.vmwareapi.session.'
'VMwareAPISession.is_vim_object',
stubs.fake_is_vim_object)
self._session = driver.VMwareAPISession()
self._session = session.VMwareAPISession()
def _build_cluster_networks(self, networks):
"""Returns a set of results for a cluster network lookup.

@ -0,0 +1,70 @@
# Copyright (c) 2022 SAP SE
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
# Copyright 2011 OpenStack Foundation
#
# 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.
"""
Test suite for VMwareAPI Session
"""
import mock
from nova import test
from nova.tests.unit.virt.vmwareapi import fake as vmwareapi_fake
from nova.virt.vmwareapi import session
def _fake_create_session(inst):
_session = vmwareapi_fake.DataObject()
_session.key = 'fake_key'
_session.userName = 'fake_username'
_session._pbm_wsdl_loc = None
_session._pbm = None
inst._session = _session
class VMwareSessionTestCase(test.NoDBTestCase):
@mock.patch.object(session.VMwareAPISession, '_is_vim_object',
return_value=False)
def test_call_method(self, mock_is_vim):
with test.nested(
mock.patch.object(session.VMwareAPISession,
'_create_session',
_fake_create_session),
mock.patch.object(session.VMwareAPISession,
'invoke_api'),
) as (fake_create, fake_invoke):
_session = session.VMwareAPISession()
_session._vim = mock.Mock()
module = mock.Mock()
_session._call_method(module, 'fira')
fake_invoke.assert_called_once_with(module, 'fira', _session._vim)
@mock.patch.object(session.VMwareAPISession, '_is_vim_object',
return_value=True)
def test_call_method_vim(self, mock_is_vim):
with test.nested(
mock.patch.object(session.VMwareAPISession,
'_create_session',
_fake_create_session),
mock.patch.object(session.VMwareAPISession,
'invoke_api'),
) as (fake_create, fake_invoke):
_session = session.VMwareAPISession()
module = mock.Mock()
_session._call_method(module, 'fira')
fake_invoke.assert_called_once_with(module, 'fira')

@ -32,7 +32,7 @@ from nova.tests.unit import fake_instance
from nova.tests.unit.virt.vmwareapi import fake
from nova.tests.unit.virt.vmwareapi import stubs
from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import driver
from nova.virt.vmwareapi import session as vmware_session
from nova.virt.vmwareapi import vm_util
@ -1037,7 +1037,7 @@ class VMwareVMUtilTestCase(test.NoDBTestCase):
found[0] = True
mock_log_warn.side_effect = fake_log_warn
session = driver.VMwareAPISession()
session = vmware_session.VMwareAPISession()
config_spec = vm_util.get_vm_create_spec(
session.vim.client.factory,
@ -2049,19 +2049,21 @@ class VMwareVMUtilTestCase(test.NoDBTestCase):
session._wait_for_task.assert_called_once_with(task)
@mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop)
@mock.patch.object(vmware_session.VMwareAPISession, 'vim',
stubs.fake_vim_prop)
class VMwareVMUtilGetHostRefTestCase(test.NoDBTestCase):
# N.B. Mocking on the class only mocks test_*(), but we need
# VMwareAPISession.vim to be mocked in both setUp and tests. Not mocking in
# setUp causes object initialisation to fail. Not mocking in tests results
# in vim calls not using FakeVim.
@mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop)
# session.VMwareAPISession.vim to be mocked in both setUp and tests.
# Not mocking in setUp causes object initialisation to fail. Not
# mocking in tests results in vim calls not using FakeVim.
@mock.patch.object(vmware_session.VMwareAPISession, 'vim',
stubs.fake_vim_prop)
def setUp(self):
super(VMwareVMUtilGetHostRefTestCase, self).setUp()
fake.reset()
vm_util.vm_refs_cache_reset()
self.session = driver.VMwareAPISession()
self.session = vmware_session.VMwareAPISession()
# Create a fake VirtualMachine running on a known host
self.host_ref = list(fake._db_content['HostSystem'].keys())[0]

@ -37,9 +37,9 @@ from nova.tests.unit.virt.vmwareapi import stubs
from nova import version
from nova.virt import hardware
from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import driver
from nova.virt.vmwareapi import ds_util
from nova.virt.vmwareapi import images
from nova.virt.vmwareapi import session
from nova.virt.vmwareapi import vif
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util
@ -65,7 +65,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
self.flags(my_ip='',
flat_injected=True)
self._context = context.RequestContext('fake_user', 'fake_project')
self._session = driver.VMwareAPISession()
self._session = session.VMwareAPISession()
self._virtapi = mock.Mock()
self._image_id = uuids.image

@ -27,7 +27,7 @@ from nova.tests.unit import fake_instance
from nova.tests.unit.virt.vmwareapi import fake as vmwareapi_fake
from nova.tests.unit.virt.vmwareapi import stubs
from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import driver
from nova.virt.vmwareapi import session
from nova.virt.vmwareapi import vm_util
from nova.virt.vmwareapi import volumeops
@ -40,7 +40,7 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
super(VMwareVolumeOpsTestCase, self).setUp()
vmwareapi_fake.reset()
stubs.set_stubs(self)
self._session = driver.VMwareAPISession()
self._session = session.VMwareAPISession()
self._context = context.RequestContext('fake_user', 'fake_project')
self._volumeops = volumeops.VMwareVolumeOps(self._session)

@ -27,10 +27,8 @@ from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import units
from oslo_utils import versionutils as v_utils
from oslo_vmware import api
from oslo_vmware import exceptions as vexc
from oslo_vmware import pbm
from oslo_vmware import vim
from oslo_vmware import vim_util
from nova.compute import power_state
@ -47,6 +45,7 @@ from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import ds_util
from nova.virt.vmwareapi import error_util
from nova.virt.vmwareapi import host
from nova.virt.vmwareapi import session
from nova.virt.vmwareapi import vim_util as nova_vim_util
from nova.virt.vmwareapi import vm_util
from nova.virt.vmwareapi import vmops
@ -113,7 +112,7 @@ class VMwareVCDriver(driver.ComputeDriver):
_("Invalid Regular Expression %s")
% CONF.vmware.datastore_regex)
self._session = VMwareAPISession(scheme=scheme)
self._session = session.VMwareAPISession(scheme=scheme)
self._check_min_version()
@ -716,50 +715,3 @@ class VMwareVCDriver(driver.ComputeDriver):
def detach_interface(self, context, instance, vif):
"""Detach an interface from the instance."""
self._vmops.detach_interface(context, instance, vif)
class VMwareAPISession(api.VMwareAPISession):
"""Sets up a session with the VC/ESX host and handles all
the calls made to the host.
"""
def __init__(self, host_ip=CONF.vmware.host_ip,
host_port=CONF.vmware.host_port,
username=CONF.vmware.host_username,
password=CONF.vmware.host_password,
retry_count=CONF.vmware.api_retry_count,
scheme="https",
cacert=CONF.vmware.ca_file,
insecure=CONF.vmware.insecure,
pool_size=CONF.vmware.connection_pool_size):
super(VMwareAPISession, self).__init__(
host=host_ip,
port=host_port,
server_username=username,
server_password=password,
api_retry_count=retry_count,
task_poll_interval=CONF.vmware.task_poll_interval,
scheme=scheme,
create_session=True,
cacert=cacert,
insecure=insecure,
pool_size=pool_size)
def _is_vim_object(self, module):
"""Check if the module is a VIM Object instance."""
return isinstance(module, vim.Vim)
def _call_method(self, module, method, *args, **kwargs):
"""Calls a method within the module specified with
args provided.
"""
if not self._is_vim_object(module):
return self.invoke_api(module, method, self.vim, *args, **kwargs)
else:
return self.invoke_api(module, method, *args, **kwargs)
def _wait_for_task(self, task_ref):
"""Return a Deferred that will give the result of the given task.
The task is polled until it completes.
"""
return self.wait_for_task(task_ref)

@ -0,0 +1,71 @@
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2012 VMware, Inc.
# Copyright (c) 2011 Citrix Systems, Inc.
# Copyright 2011 OpenStack Foundation
#
# 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.
from oslo_vmware import api
from oslo_vmware import vim
import nova.conf
CONF = nova.conf.CONF
class VMwareAPISession(api.VMwareAPISession):
"""Sets up a session with the VC/ESX host and handles all
the calls made to the host.
"""
def __init__(self, host_ip=CONF.vmware.host_ip,
host_port=CONF.vmware.host_port,
username=CONF.vmware.host_username,
password=CONF.vmware.host_password,
retry_count=CONF.vmware.api_retry_count,
scheme="https",
cacert=CONF.vmware.ca_file,
insecure=CONF.vmware.insecure,
pool_size=CONF.vmware.connection_pool_size):
super(VMwareAPISession, self).__init__(
host=host_ip,
port=host_port,
server_username=username,
server_password=password,
api_retry_count=retry_count,
task_poll_interval=CONF.vmware.task_poll_interval,
scheme=scheme,
create_session=True,
cacert=cacert,
insecure=insecure,
pool_size=pool_size)
@staticmethod
def _is_vim_object(module):
"""Check if the module is a VIM Object instance."""
return isinstance(module, vim.Vim)
def _call_method(self, module, method, *args, **kwargs):
"""Calls a method within the module specified with
args provided.
"""
if not self._is_vim_object(module):
return self.invoke_api(module, method, self.vim, *args, **kwargs)
else:
return self.invoke_api(module, method, *args, **kwargs)
def _wait_for_task(self, task_ref):
"""Return a Deferred that will give the result of the given task.
The task is polled until it completes.
"""
return self.wait_for_task(task_ref)