Handle availability zone info in compute host APIs

The create host API stores availability zone information into the
computehosts tables. The information comes from Nova's availability
zone API.

Cloud users can specify the availability zone information by following
query in the host reservation and the instance reservation.

- The host reservation
  hypervisor_properties=["==", "$availability_zone", "zone1"]

- The instance reservation
  resource_properties=["==", "$availability_zone", "zone1"]

The az_aware config is a flag to store the infomation or not.
If a cloud operator doesn't prefer to store the information, set the
flag to False.

Implements: blueprint multi-freepools
Change-Id: I26a7e635660eec54b0bef9754ef46aa5af7fe60e
This commit is contained in:
Masahito Muroi 2018-04-23 16:56:26 +09:00 committed by Hiroaki Kobayashi
parent 0c3142d2c0
commit c2ab836293
7 changed files with 124 additions and 10 deletions

View File

@ -0,0 +1,39 @@
# Copyright 2018 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.
"""add_az_in_compute
Revision ID: 35b314cd39ee
Revises: c0ae6b08b0d7
Create Date: 2018-04-23 07:40:39.750686
"""
# revision identifiers, used by Alembic.
revision = '35b314cd39ee'
down_revision = 'c0ae6b08b0d7'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('computehosts',
sa.Column('availability_zone', sa.String(length=255),
default="", nullable=False))
def downgrade():
op.drop_column('computehosts', 'availability_zone')

View File

@ -215,6 +215,7 @@ class ComputeHost(mb.BlazarBase):
memory_mb = sa.Column(sa.Integer, nullable=False)
local_gb = sa.Column(sa.Integer, nullable=False)
status = sa.Column(sa.String(13))
availability_zone = sa.Column(sa.String(255), nullable=False)
trust_id = sa.Column(sa.String(36), nullable=False)
reservable = sa.Column(sa.Boolean, nullable=False,
server_default=sa.true())

View File

@ -157,6 +157,7 @@ def _get_fake_cpu_info():
def _get_fake_host_values(id=_get_fake_random_uuid(), mem=8192, disk=10):
return {'id': id,
'availability_zone': 'az1',
'vcpus': 1,
'cpu_info': _get_fake_cpu_info(),
'hypervisor_type': 'QEMU',

View File

@ -18,8 +18,10 @@ 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 availability_zones
from novaclient.v2 import hypervisors
from oslo_config import cfg
from oslo_config import fixture
from blazar import context
from blazar.manager import exceptions as manager_exceptions
@ -411,6 +413,7 @@ class FakeNovaHypervisors(object):
class FakeHost(object):
id = 1
availability_zone = 'fake_az1'
hypervisor_hostname = 'fake_name'
vcpus = 1
cpu_info = 'fake_cpu'
@ -445,6 +448,7 @@ class FakeNovaHypervisors(object):
@classmethod
def expected(cls):
return {'id': cls.FakeHost.id,
'availability_zone': cls.FakeHost.availability_zone,
'hypervisor_hostname': cls.FakeHost.hypervisor_hostname,
'service_name': cls.FakeHost.service['host'],
'vcpus': cls.FakeHost.vcpus,
@ -455,6 +459,30 @@ class FakeNovaHypervisors(object):
'local_gb': cls.FakeHost.local_gb}
class FakeAvailabilityZones(object):
class FakeAZ1(object):
zoneName = 'fake_az1'
hosts = {
"fake_name": {
"nova-compute": {}
},
}
class FakeAZ2(object):
zoneName = 'fake_az2'
hosts = {
"fake_name": {
"nova-conductor": {},
"nova-scheduler": {}
},
}
@classmethod
def list(cls, detailed=False):
return [cls.FakeAZ1, cls.FakeAZ2]
class NovaInventoryTestCase(tests.TestCase):
def setUp(self):
super(NovaInventoryTestCase, self).setUp()
@ -469,6 +497,9 @@ class NovaInventoryTestCase(tests.TestCase):
self.hypervisors_search = self.patch(hypervisors.HypervisorManager,
'search')
self.hypervisors_search.side_effect = FakeNovaHypervisors.search
self.availability_zones = self.patch(
availability_zones.AvailabilityZoneManager, 'list')
self.availability_zones.side_effect = FakeAvailabilityZones.list
def test_get_host_details_with_host_id(self):
host = self.inventory.get_host_details('1')
@ -499,6 +530,14 @@ class NovaInventoryTestCase(tests.TestCase):
self.assertRaises(manager_exceptions.InvalidHost,
self.inventory.get_host_details, '1')
def test_get_host_details_without_az(self):
conf = fixture.Config(CONF)
conf.config(group='nova', az_aware=False)
host = self.inventory.get_host_details('fake_name')
expected = FakeNovaHypervisors.expected()
expected['availability_zone'] = ''
self.assertEqual(expected, host)
def test_get_servers_per_host(self):
servers = self.inventory.get_servers_per_host('fake_name')
self.assertEqual(FakeNovaHypervisors.FakeHost.servers, servers)

View File

@ -53,7 +53,10 @@ nova_opts = [
cfg.StrOpt('blazar_owner',
default='blazar:owner',
deprecated_group=oshosts.RESOURCE_TYPE,
help='Aggregate metadata key for knowing owner project_id')
help='Aggregate metadata key for knowing owner project_id'),
cfg.BoolOpt('az_aware',
default=True,
help='A flag to store original availability zone')
]
@ -455,8 +458,18 @@ class NovaInventory(NovaClientWrapper):
# NOTE(sbauza): No need to catch the exception as we're sure
# that the hypervisor exists
hypervisor = self.nova.hypervisors.get(hypervisor_id)
az_name = ''
if CONF.nova.az_aware:
host_name = hypervisor.hypervisor_hostname
for zone in self.nova.availability_zones.list(detailed=True):
if (host_name in zone.hosts
and 'nova-compute' in zone.hosts[host_name]):
az_name = zone.zoneName
try:
return {'id': hypervisor.id,
'availability_zone': az_name,
'hypervisor_hostname': hypervisor.hypervisor_hostname,
'service_name': hypervisor.service['host'],
'vcpus': hypervisor.vcpus,

View File

@ -91,9 +91,8 @@ REST API impact
* URL: POST /v1/leases
* Introduce the availability_zone key in physical:host and virtual:instance
resource_type.
* The availability_zone key is an optional parameter in request body.
* The hypervisor_properties in physical:host and the resource_properties
in virtual:instance support a query for availability_zone key.
Request Example:
@ -109,7 +108,14 @@ Request Example:
"disk_gb": 10,
"amount": 5,
"affinity": False,
"availability_zone", "az1"
"resource_properties": "[\"==\", \"$availability_zone\", \"az1\"]"
},
{
"resource_type": "physical:host",
"min": 3,
"max": 4,
"hypervisor_properties": "[]",
"resource_properties": "[\"==\", \"$availability_zone\", \"az1\"]"
}
],
"start": "2020-05-17 09:00"
@ -120,9 +126,6 @@ Request Example:
Response Example:
* The availability_zone is set to specified az name if an user sends a
request with the key. If not, the key is set to None.
.. sourcecode:: json
{
@ -139,7 +142,7 @@ Response Example:
"disk_gb": 10,
"amount": 5,
"affinity": False,
"availability_zone", "az1",
"resource_properties": "[\"==\", \"$availability_zone\", \"az1\"]",
"created_at": "2017-05-01 10:00:00",
"updated_at": "2017-05-01 11:00:00",
}],
@ -171,7 +174,7 @@ Other end user impact
The original az name a hypervisor belongs to is only visible through
Blazar API. Nova returns az name based on meta data of host aggregate and
Blazar sets blazar_* az name to an aggregate of host reservation. It results
users need to call Blazar Host details API if they want to know what az value
users need to call Blazar Host details API when they want to know what az value
is available in "availability_zone" key.
In most cases, only admin is allowed to configure az in Nova.
@ -193,6 +196,11 @@ information into computehost table. If hosts are used for a host reservation
Blazar can't find out the original az information while deployers upgrade
Blazar.
If deployers move a host to another availability zone by Nova API, the
deployers need to re-create the host by the Blazar host create API to
apply the new availability zone to the Blazar DB. The information is
automatically registered by Blazar only in the Blazar host create API.
Developer impact
----------------

View File

@ -0,0 +1,13 @@
---
features:
- |
Blazar handles availability zone information the compute host belongs to.
When cloud operators add a compute host resource to the Blazar's freepool,
Blazar records the availability zone into it's DB. The cloud user can
specify the availability zone information by hypervisor_properties in the
host reservation and by resource_properties in the instance reservation.
upgrade:
- |
The availability zone information is stored only when cloud operators add
a new host to Blazar's freepool. If the operators needs the infomation,
please re-add hosts already registered in Blazar.