67eae1069d
move to oslo.db and some other oslo libraries Change-Id: I57e4f01bd46339cdfe3ed2e4748eb1e923cea584
214 lines
7.1 KiB
Python
214 lines
7.1 KiB
Python
# Copyright 2014
|
|
# The Cloudscaling Group, Inc.
|
|
#
|
|
# 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_config import cfg
|
|
from oslo_log import log as logging
|
|
|
|
from ec2api.api import clients
|
|
from ec2api.api import common
|
|
from ec2api import exception
|
|
from ec2api import utils
|
|
|
|
|
|
availability_zone_opts = [
|
|
cfg.StrOpt('internal_service_availability_zone',
|
|
default='internal',
|
|
help='The availability_zone to show internal services under'),
|
|
cfg.StrOpt('my_ip',
|
|
default=utils._get_my_ip(),
|
|
help='IP address of this host'),
|
|
cfg.StrOpt('ec2_host',
|
|
default='$my_ip',
|
|
help='The IP address of the EC2 API server'),
|
|
cfg.IntOpt('ec2_port',
|
|
default=8788,
|
|
help='The port of the EC2 API server'),
|
|
cfg.StrOpt('ec2_scheme',
|
|
default='http',
|
|
help='The protocol to use when connecting to the EC2 API '
|
|
'server (http, https)'),
|
|
cfg.StrOpt('ec2_path',
|
|
default='/',
|
|
help='The path prefix used to call the ec2 API server'),
|
|
cfg.ListOpt('region_list',
|
|
default=[],
|
|
help='List of region=fqdn pairs separated by commas'),
|
|
]
|
|
|
|
CONF = cfg.CONF
|
|
CONF.register_opts(availability_zone_opts)
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
"""Availability zones, regions, account attributes related API implementation
|
|
"""
|
|
|
|
|
|
Validator = common.Validator
|
|
|
|
|
|
def get_account_attribute_engine():
|
|
if CONF.full_vpc_support:
|
|
return AccountAttributeEngineNeutron()
|
|
else:
|
|
return AccountAttributeEngineNova()
|
|
|
|
|
|
class AvailabilityZoneDescriber(common.UniversalDescriber):
|
|
|
|
KIND = 'az'
|
|
FILTER_MAP = {'state': 'zoneState',
|
|
'zone-name': 'zoneName'}
|
|
|
|
def format(self, item=None, os_item=None):
|
|
return _format_availability_zone(os_item)
|
|
|
|
def get_db_items(self):
|
|
return []
|
|
|
|
def get_os_items(self):
|
|
nova = clients.nova(self.context)
|
|
zones = nova.availability_zones.list(detailed=False)
|
|
for zone in zones:
|
|
if zone.zoneName == CONF.internal_service_availability_zone:
|
|
zones.remove(zone)
|
|
return zones
|
|
|
|
def get_name(self, os_item):
|
|
return os_item.zoneName
|
|
|
|
def get_id(self, os_item):
|
|
return ''
|
|
|
|
def auto_update_db(self, item, os_item):
|
|
pass
|
|
|
|
|
|
def describe_availability_zones(context, zone_name=None, filter=None):
|
|
# NOTE(Alex): Openstack extension, AWS-incompability
|
|
# Checking for 'verbose' in zone_name.
|
|
if zone_name and 'verbose' in zone_name:
|
|
return _describe_verbose(context)
|
|
|
|
formatted_availability_zones = AvailabilityZoneDescriber().describe(
|
|
context, names=zone_name, filter=filter)
|
|
return {'availabilityZoneInfo': formatted_availability_zones}
|
|
|
|
|
|
def describe_regions(context, region_name=None, filter=None):
|
|
# TODO(andrey-mp): collect regions from keystone catalog
|
|
if CONF.region_list:
|
|
regions = []
|
|
for region in CONF.region_list:
|
|
name, _sep, host = region.partition('=')
|
|
if not host:
|
|
host = CONF.ec2_host
|
|
endpoint = '%s://%s:%s%s' % (CONF.ec2_scheme,
|
|
host,
|
|
CONF.ec2_port,
|
|
CONF.ec2_path)
|
|
regions.append({'regionName': name,
|
|
'regionEndpoint': endpoint})
|
|
else:
|
|
regions = [{'regionName': 'nova',
|
|
'regionEndpoint': '%s://%s:%s%s' % (CONF.ec2_scheme,
|
|
CONF.ec2_host,
|
|
CONF.ec2_port,
|
|
CONF.ec2_path)}]
|
|
return {'regionInfo': regions}
|
|
|
|
|
|
def describe_account_attributes(context, attribute_name=None):
|
|
def get_max_instances():
|
|
nova = clients.nova(context)
|
|
quotas = nova.quotas.get(context.project_id, context.user_id)
|
|
return quotas.instances
|
|
|
|
attribute_getters = {
|
|
'supported-platforms': (
|
|
account_attribute_engine.get_supported_platforms),
|
|
'default-vpc': account_attribute_engine.get_default_vpc,
|
|
'max-instances': get_max_instances,
|
|
}
|
|
|
|
formatted_attributes = []
|
|
for attribute in (attribute_name or attribute_getters):
|
|
if attribute not in attribute_getters:
|
|
raise exception.InvalidParameter(name=attribute)
|
|
formatted_attributes.append(
|
|
_format_account_attribute(attribute,
|
|
attribute_getters[attribute]()))
|
|
return {'accountAttributeSet': formatted_attributes}
|
|
|
|
|
|
def _format_availability_zone(zone):
|
|
return {'zoneName': zone.zoneName,
|
|
'zoneState': ('available'
|
|
if zone.zoneState.get('available')
|
|
else 'unavailable')
|
|
}
|
|
|
|
|
|
def _format_account_attribute(attribute, value):
|
|
if not isinstance(value, list):
|
|
value = [value]
|
|
return {'attributeName': attribute,
|
|
'attributeValueSet': [{'attributeValue': val} for val in value]}
|
|
|
|
|
|
# NOTE(Alex): Openstack extension, AWS-incompability
|
|
# The whole function and its result is incompatible with AWS.
|
|
|
|
def _describe_verbose(context):
|
|
nova = clients.nova(context)
|
|
availability_zones = nova.availability_zones.list()
|
|
|
|
formatted_availability_zones = []
|
|
for availability_zone in availability_zones:
|
|
formatted_availability_zones.append(
|
|
_format_availability_zone(availability_zone))
|
|
for host, services in availability_zone.hosts.items():
|
|
formatted_availability_zones.append(
|
|
{'zoneName': '|- %s' % host,
|
|
'zoneState': ''})
|
|
for service, values in services.items():
|
|
active = ":-)" if values['active'] else "XXX"
|
|
enabled = 'enabled' if values['available'] else 'disabled'
|
|
formatted_availability_zones.append(
|
|
{'zoneName': '| |- %s' % service,
|
|
'zoneState': ('%s %s %s' % (enabled, active,
|
|
values['updated_at']))})
|
|
|
|
return {'availabilityZoneInfo': formatted_availability_zones}
|
|
|
|
|
|
class AccountAttributeEngineNeutron(object):
|
|
|
|
def get_supported_platforms(self):
|
|
return ['EC2', 'VPC']
|
|
|
|
def get_default_vpc(self):
|
|
return 'none'
|
|
|
|
|
|
class AccountAttributeEngineNova(object):
|
|
|
|
def get_supported_platforms(self):
|
|
return ['EC2']
|
|
|
|
def get_default_vpc(self):
|
|
return 'none'
|
|
|
|
|
|
account_attribute_engine = get_account_attribute_engine()
|