Merge "Move the NovaInventory class to utils/openstack/nova.py"

This commit is contained in:
Jenkins
2017-06-20 07:19:44 +00:00
committed by Gerrit Code Review
6 changed files with 178 additions and 231 deletions

View File

@@ -26,7 +26,6 @@ from blazar.db import utils as db_utils
from blazar.manager import exceptions as manager_ex
from blazar.plugins import base
from blazar.plugins import oshosts as plugin
from blazar.plugins.oshosts import nova_inventory
from blazar.utils.openstack import nova
from blazar.utils import trusts
@@ -243,7 +242,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
raise manager_ex.InvalidHost(host=host_values)
with trusts.create_ctx_from_trust(trust_id):
inventory = nova_inventory.NovaInventory()
inventory = nova.NovaInventory()
servers = inventory.get_servers_per_host(host_ref)
if servers:
raise manager_ex.HostHavingServers(host=host_ref,
@@ -326,7 +325,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
with trusts.create_ctx_from_trust(host['trust_id']):
# TODO(sbauza):
# - Check if no leases having this host scheduled
inventory = nova_inventory.NovaInventory()
inventory = nova.NovaInventory()
servers = inventory.get_servers_per_host(
host['hypervisor_hostname'])
if servers:

View File

@@ -1,84 +0,0 @@
# Copyright (c) 2013 Bull.
#
# 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 novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from blazar.manager import exceptions as manager_exceptions
from blazar.utils.openstack import nova
class NovaInventory(nova.NovaClientWrapper):
def __init__(self):
super(NovaInventory, self).__init__(
username=cfg.CONF.os_admin_username,
password=cfg.CONF.os_admin_password,
user_domain_name=cfg.CONF.os_admin_user_domain_name,
project_name=cfg.CONF.os_admin_project_name,
project_domain_name=cfg.CONF.os_admin_user_domain_name)
def get_host_details(self, host):
"""Get Nova capabilities of a single host
:param host: UUID or name of nova-compute host
:return: Dict of capabilities or raise HostNotFound
"""
try:
hypervisor = self.nova.hypervisors.get(host)
except nova_exceptions.NotFound:
try:
hypervisors_list = self.nova.hypervisors.search(host)
except nova_exceptions.NotFound:
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise manager_exceptions.MultipleHostsFound(host)
else:
hypervisor_id = hypervisors_list[0].id
# NOTE(sbauza): No need to catch the exception as we're sure
# that the hypervisor exists
hypervisor = self.nova.hypervisors.get(hypervisor_id)
try:
return {'id': hypervisor.id,
'hypervisor_hostname': hypervisor.hypervisor_hostname,
'service_name': hypervisor.service['host'],
'vcpus': hypervisor.vcpus,
'cpu_info': hypervisor.cpu_info,
'hypervisor_type': hypervisor.hypervisor_type,
'hypervisor_version': hypervisor.hypervisor_version,
'memory_mb': hypervisor.memory_mb,
'local_gb': hypervisor.local_gb}
except AttributeError:
raise manager_exceptions.InvalidHost(host=host)
def get_servers_per_host(self, host):
"""List all servers of a nova-compute host
:param host: Name (not UUID) of nova-compute host
:return: Dict of servers or None
"""
try:
hypervisors_list = self.nova.hypervisors.search(host, servers=True)
except nova_exceptions.NotFound:
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise manager_exceptions.MultipleHostsFound(host)
else:
try:
return hypervisors_list[0].servers
except AttributeError:
# NOTE(sbauza): nova.hypervisors.search(servers=True) returns
# a list of hosts without 'servers' attribute if no servers
# are running on that host
return None

View File

@@ -1,139 +0,0 @@
# Copyright (c) 2013 Bull.
#
# 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 novaclient import exceptions as nova_exceptions
from novaclient.v2 import hypervisors
from blazar import context
from blazar.manager import exceptions as manager_exceptions
from blazar.plugins.oshosts import nova_inventory
from blazar import tests
from blazar.utils.openstack import base
class FakeNovaHypervisors(object):
class FakeHost(object):
id = 1
hypervisor_hostname = 'fake_name'
vcpus = 1
cpu_info = 'fake_cpu'
hypervisor_type = 'fake_type'
hypervisor_version = 1000000
memory_mb = 8192
local_gb = 10
servers = ['server1', 'server2']
service = {'host': 'fake_name'}
@classmethod
def get(cls, host):
try:
host = int(host)
except ValueError:
raise nova_exceptions.NotFound(404)
if host == cls.FakeHost.id:
return cls.FakeHost
else:
raise nova_exceptions.NotFound(404)
@classmethod
def search(cls, host, servers=False):
if host == 'multiple':
return [cls.FakeHost, cls.FakeHost]
if host == cls.FakeHost.service['host']:
return [cls.FakeHost]
else:
raise nova_exceptions.NotFound(404)
@classmethod
def expected(cls):
return {'id': cls.FakeHost.id,
'hypervisor_hostname': cls.FakeHost.hypervisor_hostname,
'service_name': cls.FakeHost.service['host'],
'vcpus': cls.FakeHost.vcpus,
'cpu_info': cls.FakeHost.cpu_info,
'hypervisor_type': cls.FakeHost.hypervisor_type,
'hypervisor_version': cls.FakeHost.hypervisor_version,
'memory_mb': cls.FakeHost.memory_mb,
'local_gb': cls.FakeHost.local_gb}
class NovaInventoryTestCase(tests.TestCase):
def setUp(self):
super(NovaInventoryTestCase, self).setUp()
self.context = context
self.patch(self.context, 'BlazarContext')
self.nova_inventory = nova_inventory
self.patch(base, 'url_for').return_value = 'http://foo.bar'
self.inventory = self.nova_inventory.NovaInventory()
self.hypervisors_get = self.patch(hypervisors.HypervisorManager, 'get')
self.hypervisors_get.side_effect = FakeNovaHypervisors.get
self.hypervisors_search = self.patch(hypervisors.HypervisorManager,
'search')
self.hypervisors_search.side_effect = FakeNovaHypervisors.search
def test_get_host_details_with_host_id(self):
host = self.inventory.get_host_details('1')
expected = FakeNovaHypervisors.expected()
self.assertEqual(expected, host)
def test_get_host_details_with_host_name(self):
host = self.inventory.get_host_details('fake_name')
expected = FakeNovaHypervisors.expected()
self.assertEqual(expected, host)
def test_get_host_details_with_host_name_having_multiple_results(self):
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_host_details, 'multiple')
def test_get_host_details_with_host_id_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, '2')
def test_get_host_details_with_host_name_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, 'wrong_name')
def test_get_host_details_with_invalid_host(self):
invalid_host = FakeNovaHypervisors.FakeHost
del invalid_host.vcpus
self.hypervisors_get.return_value = invalid_host
self.assertRaises(manager_exceptions.InvalidHost,
self.inventory.get_host_details, '1')
def test_get_servers_per_host(self):
servers = self.inventory.get_servers_per_host('fake_name')
self.assertEqual(FakeNovaHypervisors.FakeHost.servers, servers)
def test_get_servers_per_host_with_host_id(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, '1')
def test_get_servers_per_host_with_host_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, 'wrong_name')
def test_get_servers_per_host_having_multiple_results(self):
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_servers_per_host, 'multiple')
def test_get_servers_per_host_with_host_having_no_servers(self):
host_with_zero_servers = FakeNovaHypervisors.FakeHost
# NOTE(sbauza): We need to simulate a host having zero servers
del host_with_zero_servers.servers
servers = self.inventory.get_servers_per_host('fake_name')
self.assertIsNone(servers)

View File

@@ -27,7 +27,6 @@ from blazar.manager import exceptions as manager_exceptions
from blazar.manager import service
from blazar.plugins import oshosts as plugin
from blazar.plugins.oshosts import host_plugin
from blazar.plugins.oshosts import nova_inventory
from blazar import tests
from blazar.utils.openstack import base
from blazar.utils.openstack import nova
@@ -52,7 +51,6 @@ class PhysicalHostPlugingSetupOnlyTestCase(tests.TestCase):
self.host_plugin = host_plugin
self.fake_phys_plugin = self.host_plugin.PhysicalHostPlugin()
self.nova = nova
self.nova_inventory = nova_inventory
self.rp_create = self.patch(self.nova.ReservationPool, 'create')
self.db_api = db_api
self.db_host_extra_capability_get_all_per_host = (
@@ -134,18 +132,17 @@ class PhysicalHostPluginTestCase(tests.TestCase):
self.db_api, 'host_extra_capability_update')
self.nova = nova
self.nova_inventory = nova_inventory
self.rp_create = self.patch(self.nova.ReservationPool, 'create')
self.patch(self.nova.ReservationPool, 'get_aggregate_from_name_or_id')
self.add_compute_host = self.patch(self.nova.ReservationPool,
'add_computehost')
self.remove_compute_host = self.patch(self.nova.ReservationPool,
'remove_computehost')
self.get_host_details = self.patch(self.nova_inventory.NovaInventory,
self.get_host_details = self.patch(self.nova.NovaInventory,
'get_host_details')
self.get_host_details.return_value = self.fake_host
self.get_servers_per_host = self.patch(
self.nova_inventory.NovaInventory, 'get_servers_per_host')
self.nova.NovaInventory, 'get_servers_per_host')
self.get_servers_per_host.return_value = None
self.get_extra_capabilities = self.patch(
self.fake_phys_plugin, '_get_extra_capabilities')

View File

@@ -18,6 +18,7 @@ from keystoneauth1 import session
from keystoneauth1 import token_endpoint
from novaclient import client as nova_client
from novaclient import exceptions as nova_exceptions
from novaclient.v2 import hypervisors
from oslo_config import cfg
from blazar import context
@@ -405,3 +406,119 @@ class ReservationPoolTestCase(tests.TestCase):
check = self.nova.aggregates.set_metadata
check.assert_called_once_with(self.fake_aggregate.id,
{'projectY': None})
class FakeNovaHypervisors(object):
class FakeHost(object):
id = 1
hypervisor_hostname = 'fake_name'
vcpus = 1
cpu_info = 'fake_cpu'
hypervisor_type = 'fake_type'
hypervisor_version = 1000000
memory_mb = 8192
local_gb = 10
servers = ['server1', 'server2']
service = {'host': 'fake_name'}
@classmethod
def get(cls, host):
try:
host = int(host)
except ValueError:
raise nova_exceptions.NotFound(404)
if host == cls.FakeHost.id:
return cls.FakeHost
else:
raise nova_exceptions.NotFound(404)
@classmethod
def search(cls, host, servers=False):
if host == 'multiple':
return [cls.FakeHost, cls.FakeHost]
if host == cls.FakeHost.service['host']:
return [cls.FakeHost]
else:
raise nova_exceptions.NotFound(404)
@classmethod
def expected(cls):
return {'id': cls.FakeHost.id,
'hypervisor_hostname': cls.FakeHost.hypervisor_hostname,
'service_name': cls.FakeHost.service['host'],
'vcpus': cls.FakeHost.vcpus,
'cpu_info': cls.FakeHost.cpu_info,
'hypervisor_type': cls.FakeHost.hypervisor_type,
'hypervisor_version': cls.FakeHost.hypervisor_version,
'memory_mb': cls.FakeHost.memory_mb,
'local_gb': cls.FakeHost.local_gb}
class NovaInventoryTestCase(tests.TestCase):
def setUp(self):
super(NovaInventoryTestCase, self).setUp()
self.context = context
self.patch(self.context, 'BlazarContext')
self.nova = nova
self.patch(base, 'url_for').return_value = 'http://foo.bar'
self.inventory = self.nova.NovaInventory()
self.hypervisors_get = self.patch(hypervisors.HypervisorManager, 'get')
self.hypervisors_get.side_effect = FakeNovaHypervisors.get
self.hypervisors_search = self.patch(hypervisors.HypervisorManager,
'search')
self.hypervisors_search.side_effect = FakeNovaHypervisors.search
def test_get_host_details_with_host_id(self):
host = self.inventory.get_host_details('1')
expected = FakeNovaHypervisors.expected()
self.assertEqual(expected, host)
def test_get_host_details_with_host_name(self):
host = self.inventory.get_host_details('fake_name')
expected = FakeNovaHypervisors.expected()
self.assertEqual(expected, host)
def test_get_host_details_with_host_name_having_multiple_results(self):
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_host_details, 'multiple')
def test_get_host_details_with_host_id_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, '2')
def test_get_host_details_with_host_name_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, 'wrong_name')
def test_get_host_details_with_invalid_host(self):
invalid_host = FakeNovaHypervisors.FakeHost
del invalid_host.vcpus
self.hypervisors_get.return_value = invalid_host
self.assertRaises(manager_exceptions.InvalidHost,
self.inventory.get_host_details, '1')
def test_get_servers_per_host(self):
servers = self.inventory.get_servers_per_host('fake_name')
self.assertEqual(FakeNovaHypervisors.FakeHost.servers, servers)
def test_get_servers_per_host_with_host_id(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, '1')
def test_get_servers_per_host_with_host_not_found(self):
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, 'wrong_name')
def test_get_servers_per_host_having_multiple_results(self):
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_servers_per_host, 'multiple')
def test_get_servers_per_host_with_host_having_no_servers(self):
host_with_zero_servers = FakeNovaHypervisors.FakeHost
# NOTE(sbauza): We need to simulate a host having zero servers
del host_with_zero_servers.servers
servers = self.inventory.get_servers_per_host('fake_name')
self.assertEqual(None, servers)

View File

@@ -421,3 +421,60 @@ class ReservationPool(NovaClientWrapper):
metadata = {project_id: None}
return self.nova.aggregates.set_metadata(agg.id, metadata)
class NovaInventory(NovaClientWrapper):
def get_host_details(self, host):
"""Get Nova capabilities of a single host
:param host: UUID or name of nova-compute host
:return: Dict of capabilities or raise HostNotFound
"""
try:
hypervisor = self.nova.hypervisors.get(host)
except nova_exception.NotFound:
try:
hypervisors_list = self.nova.hypervisors.search(host)
except nova_exception.NotFound:
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise manager_exceptions.MultipleHostsFound(host)
else:
hypervisor_id = hypervisors_list[0].id
# NOTE(sbauza): No need to catch the exception as we're sure
# that the hypervisor exists
hypervisor = self.nova.hypervisors.get(hypervisor_id)
try:
return {'id': hypervisor.id,
'hypervisor_hostname': hypervisor.hypervisor_hostname,
'service_name': hypervisor.service['host'],
'vcpus': hypervisor.vcpus,
'cpu_info': hypervisor.cpu_info,
'hypervisor_type': hypervisor.hypervisor_type,
'hypervisor_version': hypervisor.hypervisor_version,
'memory_mb': hypervisor.memory_mb,
'local_gb': hypervisor.local_gb}
except AttributeError:
raise manager_exceptions.InvalidHost(host=host)
def get_servers_per_host(self, host):
"""List all servers of a nova-compute host
:param host: Name (not UUID) of nova-compute host
:return: Dict of servers or None
"""
try:
hypervisors_list = self.nova.hypervisors.search(host, servers=True)
except nova_exception.NotFound:
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise manager_exceptions.MultipleHostsFound(host)
else:
try:
return hypervisors_list[0].servers
except AttributeError:
# NOTE(sbauza): nova.hypervisors.search(servers=True) returns
# a list of hosts without 'servers' attribute if no servers
# are running on that host
return None