Files
nova/nova/api/openstack/compute/availability_zone.py
T
ghanshyam b33aabee07 Use plain routes list for os-availability-zone endpoint instead of stevedore
This patch adds os-availability-zone related routes
by a plain list, instead of using stevedore. After all the Nova
API endpoints moves to the plain routes list, the usage of stevedore
for API loading will be removed from Nova.

Partial-implement-blueprint api-no-more-extensions-pike

Change-Id: I19ad0d6a3fce2342097d8a61ee4f60adf0e14aa3
2017-05-01 22:02:45 +03:00

137 lines
5.6 KiB
Python

# Copyright 2012 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 nova.api.openstack.compute.schemas import availability_zone as schema
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova import availability_zones
from nova import compute
import nova.conf
from nova.policies import availability_zone as az_policies
from nova import servicegroup
CONF = nova.conf.CONF
ATTRIBUTE_NAME = "availability_zone"
class AvailabilityZoneController(wsgi.Controller):
"""The Availability Zone API controller for the OpenStack API."""
def __init__(self):
super(AvailabilityZoneController, self).__init__()
self.servicegroup_api = servicegroup.API()
self.host_api = compute.HostAPI()
def _get_filtered_availability_zones(self, zones, is_available):
result = []
for zone in zones:
# Hide internal_service_availability_zone
if zone == CONF.internal_service_availability_zone:
continue
result.append({'zoneName': zone,
'zoneState': {'available': is_available},
"hosts": None})
return result
def _describe_availability_zones(self, context, **kwargs):
ctxt = context.elevated()
available_zones, not_available_zones = \
availability_zones.get_availability_zones(ctxt)
filtered_available_zones = \
self._get_filtered_availability_zones(available_zones, True)
filtered_not_available_zones = \
self._get_filtered_availability_zones(not_available_zones, False)
return {'availabilityZoneInfo': filtered_available_zones +
filtered_not_available_zones}
def _describe_availability_zones_verbose(self, context, **kwargs):
ctxt = context.elevated()
available_zones, not_available_zones = \
availability_zones.get_availability_zones(ctxt)
# Available services
enabled_services = self.host_api.service_get_all(
context, {'disabled': False}, set_zones=True, all_cells=True)
zone_hosts = {}
host_services = {}
api_services = ('nova-osapi_compute', 'nova-ec2', 'nova-metadata')
for service in enabled_services:
if service.binary in api_services:
# Skip API services in the listing since they are not
# maintained in the same way as other services
continue
zone_hosts.setdefault(service['availability_zone'], [])
if service['host'] not in zone_hosts[service['availability_zone']]:
zone_hosts[service['availability_zone']].append(
service['host'])
host_services.setdefault(service['availability_zone'] +
service['host'], [])
host_services[service['availability_zone'] + service['host']].\
append(service)
result = []
for zone in available_zones:
hosts = {}
for host in zone_hosts.get(zone, []):
hosts[host] = {}
for service in host_services[zone + host]:
alive = self.servicegroup_api.service_is_up(service)
hosts[host][service['binary']] = {'available': alive,
'active': True != service['disabled'],
'updated_at': service['updated_at']}
result.append({'zoneName': zone,
'zoneState': {'available': True},
"hosts": hosts})
for zone in not_available_zones:
result.append({'zoneName': zone,
'zoneState': {'available': False},
"hosts": None})
return {'availabilityZoneInfo': result}
@extensions.expected_errors(())
def index(self, req):
"""Returns a summary list of availability zone."""
context = req.environ['nova.context']
context.can(az_policies.POLICY_ROOT % 'list')
return self._describe_availability_zones(context)
@extensions.expected_errors(())
def detail(self, req):
"""Returns a detailed list of availability zone."""
context = req.environ['nova.context']
context.can(az_policies.POLICY_ROOT % 'detail')
return self._describe_availability_zones_verbose(context)
# NOTE(gmann): This function is not supposed to use 'body_deprecated_param'
# parameter as this is placed to handle scheduler_hint extension for V2.1.
def server_create(server_dict, create_kwargs, body_deprecated_param):
# NOTE(alex_xu): For v2.1 compat mode, we strip the spaces when create
# availability_zone. But we don't strip at here for backward-compatible
# with some users already created availability_zone with
# leading/trailing spaces with legacy v2 API.
create_kwargs['availability_zone'] = server_dict.get(ATTRIBUTE_NAME)
def get_server_create_schema(version):
if version == "2.0":
return schema.server_create_v20
return schema.server_create