heat-dashboard/heat_dashboard/content/template_generator/api.py
kaz_shinohara 7732884d37 Rename API_TIMEOUT and API_PARALLEL vars
API_TIMEOUT and API_PARALLEL, both of them are for template generator
and the naming looks too generic.  This is not good because they will be
global under django.  It's better to  rename them to indicate both
parameters for heat-dashboard.

Change-Id: I1ad610fd796d158174ae9cb855bd5d8da72bc1f8
Closes-Bug: #1750930
2018-02-23 16:33:39 +09:00

280 lines
8.5 KiB
Python

# 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.
import json
from functools import wraps
from multiprocessing import pool
from django.conf import settings
from openstack_dashboard import api as dashboard_api
from heat_dashboard import api as heat_api
try:
API_TIMEOUT = settings.HEAT_TEMPLATE_GENERATOR_API_TIMEOUT
except AttributeError:
API_TIMEOUT = 60
try:
API_PARALLEL = settings.HEAT_TEMPLATE_GENERATOR_API_PARALLEL
except AttributeError:
API_PARALLEL = 2
def handle_exception(func):
@wraps(func)
def wrapped(*args, **kwargs):
ret, err = None, None
try:
ret = func(*args, **kwargs)
except Exception as error:
err = error.message
return ret if ret else [], err
return wrapped
@handle_exception
def get_networks(request):
return dashboard_api.neutron.network_list(request)
@handle_exception
def get_subnets(request):
return dashboard_api.neutron.subnet_list(request)
@handle_exception
def get_volume_ids(request):
return [{'id': vol.id,
'name': vol.name if vol.name else '(%s)' % vol.id}
for vol in dashboard_api.cinder.volume_list(request)]
@handle_exception
def get_volume_snapshots(request):
return [{'id': volsnap.id,
'name': volsnap.name if volsnap.name else '(%s)' % volsnap.id[:6]}
for volsnap in dashboard_api.cinder.volume_snapshot_list(request)]
@handle_exception
def get_volume_types(request):
return [{'id': voltype.id,
'name': voltype.name if voltype.name else '(%s)' % voltype.id[:6]}
for voltype in dashboard_api.cinder.volume_type_list(request)]
@handle_exception
def get_volume_backups(request):
return [{'id': volbackup.id,
'name': volbackup.name
if volbackup.name else '(%s)' % volbackup.id[:6]}
for volbackup in dashboard_api.cinder.volume_backup_list(request)]
@handle_exception
def get_images(request):
images = dashboard_api.glance.image_list_detailed(request)
if isinstance(images, tuple):
images = images[0]
return [{'id': img.id,
'name': img.name if img.name else '(%s)' % img.id[:6]}
for img in images]
@handle_exception
def get_floatingips(request):
return [{'id': fip.id, 'name': fip.floating_ip_address}
for fip in dashboard_api.neutron.tenant_floating_ip_list(
request, True)]
@handle_exception
def get_ports(request):
return [{'id': port.id,
'name': port.name if port.name else '(%s)' % port.id[:6]}
for port in dashboard_api.neutron.port_list(request)]
@handle_exception
def get_security_groups(request):
return [{'id': secgroup.id,
'name': secgroup.name
if secgroup.name else '(%s)' % secgroup.id[:6]}
for secgroup in dashboard_api.neutron.security_group_list(request)]
@handle_exception
def get_routers(request):
return [{'id': router.id,
'name': router.name if router.name else '(%s)' % router.id[:6]}
for router in dashboard_api.neutron.router_list(request)]
@handle_exception
def get_qos_policies(request):
return [{'id': policy.id,
'name': policy.name
if policy.name else '(%s)' % policy.id[:6]}
for policy in dashboard_api.neutron.policy_list(request)]
@handle_exception
def get_availability_zones(request):
return [{'id': az.zoneName, 'name': az.zoneName}
for az in dashboard_api.nova.availability_zone_list(request)]
@handle_exception
def get_flavors(request):
return [{'id': flavor.name, 'name': flavor.name}
for flavor in dashboard_api.nova.flavor_list(request)]
@handle_exception
def get_instances(request):
servers = dashboard_api.nova.server_list(request)
if isinstance(servers, tuple):
servers = servers[0]
return [{'id': server.id,
'name': server.name if server.name else '(%s)' % server.id[:6]}
for server in servers]
@handle_exception
def get_keypairs(request):
return [{'name': keypair.name}
for keypair in dashboard_api.nova.keypair_list(request)]
@handle_exception
def get_template_versions(request):
return [{'name': version.version, 'id': version.version}
for version in heat_api.heat.template_version_list(request)
if version.type == 'hot']
class APIThread(object):
thread_pool = pool.ThreadPool(processes=API_PARALLEL)
async_results = {}
def add_thread(self, apikey, func, args):
self.async_results[apikey] = self.thread_pool.apply_async(func, args)
def get_async_result(self, apikey):
if apikey not in self.async_results:
return [], None
try:
ret, err = self.async_results[apikey].get(
timeout=API_TIMEOUT)
except Exception as error:
ret, err = [], error.message
return ret, err
def _get_network_resources(options, all_networks):
try:
if all_networks:
options['networks'] = [
{'id': nw.id,
'name': nw.name if nw.name else '(%s)' % nw.id[: 6]}
for nw in all_networks if not getattr(nw, 'router:external')]
options['floating_networks'] = [
{'id': nw.id,
'name': nw.name if nw.name else '(%s)' % nw.id[: 6]}
for nw in all_networks if getattr(nw, 'router:external')]
else:
options['networks'] = []
options['floating_networks'] = []
except Exception:
options['networks'] = []
options['floating_networks'] = []
def _get_subnet_resources(options, all_subnets):
try:
if all_subnets and options.get('floating_networks'):
floating_network_ids = [nw.get('id')
for nw in options['floating_networks']]
options['subnets'] = [{'id': sb.id, 'name': sb.name}
for sb in all_subnets
if sb.network_id not in floating_network_ids]
options['floating_subnets'] = [
{'id': subnet.id, 'name': subnet.name}
for subnet in all_subnets
if subnet.network_id in floating_network_ids]
else:
options['subnets'] = []
options['floating_subnets'] = []
except Exception:
options['subnets'] = []
options['floating_subnets'] = []
def get_resource_options(request):
api_threads = APIThread()
api_mapping = {
'volumes': get_volume_ids,
'volume_snapshots': get_volume_snapshots,
'volume_types': get_volume_types,
'volume_backups': get_volume_backups,
'images': get_images,
'floatingips': get_floatingips,
'networks': get_networks,
'subnets': get_subnets,
'ports': get_ports,
'security_groups': get_security_groups,
'routers': get_routers,
'qos_policies': get_qos_policies,
'availability_zones': get_availability_zones,
'flavors': get_flavors,
'instances': get_instances,
'keypairs': get_keypairs,
'template_versions': get_template_versions,
}
options = {}
errors = {}
for resource, method in api_mapping.items():
api_threads.add_thread(resource, method, args=(request,))
for resource in api_mapping.keys():
ret, err = api_threads.get_async_result(resource)
options[resource] = ret
if err:
errors[resource.replace('_', ' ').capitalize()] = err
all_networks = options.pop('networks')
_get_network_resources(options, all_networks)
all_subnets = options.pop('subnets')
_get_subnet_resources(options, all_subnets)
role_names = []
for role in request.user.roles:
role_names.append(role.get('name'))
options.update({
'auth': {
'tenant_id': request.user.tenant_id,
'admin': 'admin' in role_names,
},
})
if len(errors.keys()) > 0:
options.update({'errors': errors})
return json.dumps(options)