osops-coda/coda/views.py

575 lines
16 KiB
Python

# Copyright [2015] Hewlett-Packard Development Company, L.P.
#
# 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.
"""
The Coda views.
Not much else to say right now.
"""
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import render
# from django.conf import settings
from horizon import views
import json
from openstack_dashboard.dashboards.coda.coda import cinder
from openstack_dashboard.dashboards.coda.coda import coda
from openstack_dashboard.dashboards.coda.coda import glance
from openstack_dashboard.dashboards.coda.coda import keystone
from openstack_dashboard.dashboards.coda.coda import neutron
from openstack_dashboard.dashboards.coda.coda import nova
DISPATCH_MAP = {
'instances': nova.list_instances,
'floating_ips': neutron.list_floating_ips,
'security_groups': neutron.list_security_groups,
'networks': neutron.list_networks,
'subnets': neutron.list_subnets,
'routers': neutron.list_routers,
'volumes': cinder.list_volumes,
'snapshots': cinder.list_snapshots,
'backups': cinder.list_backups,
'images': glance.list_images
}
class IndexView(views.APIView):
"""Class based definition of the index view."""
template_name = 'coda/coda/index.html'
def get_data(self, request, context, *args, **kwargs):
"""No context needed."""
return context
def results(request):
"""The results view."""
project_id = request.POST['project_id']
update_cache = request.POST.get('update_cache', 'False')
auth_token = coda.get_auth_token()
if auth_token == 'error':
msg = "Coda User failed to authenticate with the Identity Service."
context = {
'project_id': project_id,
'error_message': msg
}
return render(request, 'coda/coda/error.html', context)
project_exists, project_info = keystone.project_exists(
auth_token,
project_id)
if project_exists:
users = keystone.get_project_users(auth_token, project_id)
regions = coda.get_coda_regions()
context = {
'project_id': project_id,
'project_info': project_info,
'users': users,
'regions': regions,
'update_cache': update_cache,
}
return render(request, 'coda/coda/results.html', context)
else:
context = {
'project_id': project_id
}
return render(request, 'coda/coda/no_project.html', context)
def instances(request):
"""The instances view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST.get('update_cache', 'True')
instances_dict = get_project_resource(
region,
project_id,
'instances',
update_cache)
# todo (nathan) fix this later broken during port from hp pub cloud
# images_key = region + '_coda_images'
# coda_images = cache.get(images_key)
coda_images = None
if coda_images is not None:
image_list = []
if 'public' in coda_images:
image_list.extend(coda_images['public'])
if project_id in coda_images:
image_list.extend(coda_images[project_id])
coda.fill_image_info(instances_dict, image_list)
else:
coda.fill_image_info(instances_dict, None)
return HttpResponse(json.dumps(instances_dict))
def floating_ips(request):
"""The floating ips view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
floating_ips_dict = get_project_resource(
region,
project_id,
'floating_ips',
update_cache)
return HttpResponse(json.dumps(floating_ips_dict))
def security_groups(request):
"""The security groups view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
security_groups_dict = get_project_resource(
region,
project_id,
'security_groups',
update_cache)
return HttpResponse(json.dumps(security_groups_dict))
def networks(request):
"""The networks view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
networks_dict = get_project_resource(
region,
project_id,
'networks',
update_cache)
return HttpResponse(json.dumps(networks_dict))
def subnets(request):
"""The subnets view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
subnets_dict = get_project_resource(
region,
project_id,
'subnets',
update_cache)
return HttpResponse(json.dumps(subnets_dict))
def routers(request):
"""The routers view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
routers_dict = get_project_resource(
region,
project_id,
'routers',
update_cache)
return HttpResponse(json.dumps(routers_dict))
def volumes(request):
"""The volumes view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
volumes_dict = get_project_resource(
region,
project_id,
'volumes',
update_cache)
snapshots_dict = get_project_resource(
region,
project_id,
'snapshots',
update_cache)
backups_dict = get_project_resource(
region,
project_id,
'backups',
update_cache)
volumes_dict = coda.fill_volume_info(
volumes_dict,
snapshots_dict,
backups_dict)
return HttpResponse(json.dumps(volumes_dict))
def images(request):
"""The images view."""
project_id = request.POST['project_id']
region = request.POST['region']
update_cache = request.POST['update_cache']
images_dict = None
images_key = region + '_' + project_id + '_images'
project_images = cache.get(images_key)
if update_cache == 'True':
images_dict = get_all_images(region, True)
elif project_images is None:
images_dict = get_all_images(region, False)
if images_dict is not None:
if project_id in images_dict:
project_images = images_dict[project_id]
else:
project_images = {}
cache.set(images_key, project_images, 600)
return HttpResponse(json.dumps(project_images))
def get_all_images(region, reload_cache=False):
"""Utility method, might belong elsewhere."""
images_key = region + '_coda_images'
coda_images = cache.get(images_key)
if reload_cache is True or coda_images is None or len(coda_images) == 0:
auth_token = coda.get_auth_token()
images_dict = glance.list_all_images(auth_token, region)
coda_images = images_dict
cache.set(images_key, coda_images, 3600)
return coda_images
def confirm_delete(request):
"""The confirm delete view."""
project_id = request.POST['project_id']
auth_token = coda.get_auth_token()
project_exists, project_info = keystone.project_exists(
auth_token,
project_id)
users = keystone.get_project_users(auth_token, project_id)
regions = coda.get_coda_regions()
context = {
'project_id': project_id,
'project_info': project_info,
'users': users,
'regions': regions,
}
return render(request, 'coda/coda/confirm_delete.html', context)
def delete_resources(request):
"""The deleting resources view."""
project_id = request.POST['project_id']
os_tenant_id = request.POST['os_tenant_id']
os_username = request.POST['os_username']
os_password = request.POST['os_password']
user_token = keystone.user_authenticate(
os_tenant_id,
os_username,
os_password)
project_exists, project_info = keystone.project_exists(
user_token,
project_id)
users = keystone.get_project_users(user_token, project_id)
regions = coda.get_coda_regions()
context = {
'project_id': project_id,
'project_info': project_info,
'users': users,
'regions': regions,
'user_token': user_token
}
return render(request, 'coda/coda/delete/results.html', context)
def delete_instances(request):
"""The deleting instances view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
instance_dict = remove_project_resource(region, project_id, 'instances')
if instance_dict is not None:
for user_id, instance_list in instance_dict.iteritems():
for instance in instance_list:
result[instance['id']] = nova.delete_instance(
user_token,
region,
project_id,
instance['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_floating_ips(request):
"""The deleting floating ips view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
floating_ips_dict = remove_project_resource(
region,
project_id,
'floating_ips')
if floating_ips_dict is not None:
for floating_ip in floating_ips_dict:
result[floating_ip['id']] = neutron.delete_floating_ip(
user_token,
region,
project_id,
floating_ip['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_security_groups(request):
"""The deleting security groups view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
security_groups_dict = remove_project_resource(
region,
project_id,
'security_groups')
if security_groups_dict is not None:
for sec_group in security_groups_dict:
result[sec_group['id']] = neutron.delete_security_group(
user_token,
region,
project_id,
sec_group['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_networks(request):
"""The deleting networks view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
networks_dict = remove_project_resource(region, project_id, 'networks')
remove_project_resource(region, project_id, 'subnets')
if networks_dict is not None:
for network in networks_dict:
result[network['id']] = neutron.delete_network(
user_token,
region,
project_id,
network['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_routers(request):
"""The deleting routers view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
routers_dict = remove_project_resource(region, project_id, 'routers')
if routers_dict is not None:
for router in routers_dict:
result[router['id']] = neutron.delete_router(
user_token,
region,
project_id,
router['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_volumes(request):
"""The deleting volumes view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
volumes_dict = remove_project_resource(region, project_id, 'volumes')
if volumes_dict is not None:
for volume in volumes_dict:
result[volume['id']] = cinder.delete_volume(
user_token,
region,
project_id,
volume['id'])
else:
result = 'ERROR'
return HttpResponse(json.dumps(result))
def delete_snapshots(request):
"""The deleting snapshots view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
snapshots_dict = remove_project_resource(region, project_id, 'snapshots')
if snapshots_dict is not None:
for snapshot in snapshots_dict:
result[snapshot['id']] = cinder.delete_snapshot(
user_token,
region,
project_id,
snapshot['id'])
return HttpResponse(json.dumps(result))
def delete_backups(request):
"""The deleting backups view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
backups_dict = remove_project_resource(region, project_id, 'backups')
if backups_dict is not None:
for backup in backups_dict:
result[backup['id']] = cinder.delete_backup(
user_token,
region,
project_id,
backup['id'])
return HttpResponse(json.dumps(result))
def delete_images(request):
"""The deleting images view."""
result = {}
project_id = request.POST['project_id']
user_token = request.POST['user_token']
region = request.POST['region']
images_key = region + '_' + project_id + '_images'
tenant_images = cache.get(images_key)
error_images = []
if tenant_images is not None:
# todo (nathan) improve this
# remove the tenant image cached
# cache.delete(images_key)
# scrubber_images = get_all_images(region)
# scrubber_images.pop(tenant_id, None)
# cache.set('scrubber_images', scrubber_images, 3600)
for image in tenant_images:
result[image['id']] = glance.delete_image(
user_token,
region,
image['id'])
if result[image['id']] != 'Image Deleted':
error_images.append(image)
else:
# todo (nathan) log that there were no images to delete
result = {}
# related to above, this is hackish, but it works for now
if len(error_images) > 0:
cache.set(images_key, error_images, 600)
else:
cache.set(images_key, {}, 600)
return HttpResponse(json.dumps(result))
def get_project_resource(region, project_id, resource, update_cache='True'):
"""Utility method to get resource map from cache."""
resource_map = 'ERROR'
resource_key = region + '_' + project_id + '_' + resource
if resource in DISPATCH_MAP:
if update_cache == 'True':
coda_token = coda.get_auth_token()
resource_map = DISPATCH_MAP[resource](
coda_token,
region,
project_id)
else:
resource_map = cache.get(resource_key)
if resource_map is None:
coda_token = coda.get_auth_token()
resource_map = DISPATCH_MAP[resource](
coda_token,
region,
project_id)
cache.set(resource_key, resource_map, 600)
return resource_map
def remove_project_resource(region, tenant_id, resource):
"""Utility method to remove resource map from cache."""
resource_key = region + '_' + tenant_id + '_' + resource
resource_map = cache.get(resource_key)
if resource_map is not None:
cache.delete(resource_key)
return resource_map