Commit 31a33a47 by Szabolcs Gelencser

Implement snapshot cleanup of UpdateSharedTempates view

parent 7f83651c
...@@ -45,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters ...@@ -45,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import DetailView, View, DeleteView, FormView from django.views.generic import DetailView, View, DeleteView, FormView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from keystoneauth1.identity import v3 from keystoneauth1.identity import v3
from vm.models.instance import TemplateGroupMember, TemplateUserMember from vm.models.instance import TemplateGroupMember, TemplateUserMember, InstanceTemplate
from openstack_auth.utils import fix_auth_url_version from openstack_auth.utils import fix_auth_url_version
from vm.models import Instance from vm.models import Instance
...@@ -419,6 +419,7 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -419,6 +419,7 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
from openstack_api import keystone from openstack_api import keystone
return keystone.group_list(request=self.request, user=self.request.user) return keystone.group_list(request=self.request, user=self.request.user)
# TODO: extract this to openstack_api
def __get_glance_admin_client(self, project_id): def __get_glance_admin_client(self, project_id):
from keystoneauth1 import session from keystoneauth1 import session
from glanceclient import Client from glanceclient import Client
...@@ -433,6 +434,7 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -433,6 +434,7 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
return Client('2', session=session) return Client('2', session=session)
# TODO: extract this to openstack_api
def __get_keystone_admin_client(self): def __get_keystone_admin_client(self):
from keystoneauth1 import session from keystoneauth1 import session
from keystoneclient.v3 import client from keystoneclient.v3 import client
...@@ -601,6 +603,86 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -601,6 +603,86 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
return redirect("%s#access" % self.template.get_absolute_url()) return redirect("%s#access" % self.template.get_absolute_url())
class UpdateSharedTemplates(View):
# TODO: extract these to openstack_api
def __get_glance_admin_client(self):
from keystoneauth1 import session
from glanceclient import Client
auth = v3.Password(
auth_url=fix_auth_url_version(settings.OPENSTACK_KEYSTONE_URL),
user_id=settings.OPENSTACK_CIRCLE_USERID,
password=settings.OPENSTACK_CIRCLE_PASSWORD,
project_id=self.project_id,
)
session = session.Session(auth=auth, verify=False)
return Client('2', session=session)
# TODO: extract this to openstack_api
def __get_keystone_admin_client(self):
from keystoneauth1 import session
from keystoneclient.v3 import client
auth = v3.Password(
auth_url=fix_auth_url_version(settings.OPENSTACK_KEYSTONE_URL),
user_id=settings.OPENSTACK_CIRCLE_USERID,
password=settings.OPENSTACK_CIRCLE_PASSWORD,
)
sess = session.Session(auth=auth, verify=False)
return client.Client(session=sess, interface=settings.OPENSTACK_INTERFACE)
def __get_templates_of_snapshots(self):
images = openstack_api.glance.image_list_detailed(self.request)[0] # TODO: why nested lists?
snapshot_ids = [
i.id for i in images if hasattr(i, 'image_location') and i.image_location == 'snapshot'
]
return InstanceTemplate.objects.filter(image_id__in=snapshot_ids)
def __list_users_of_group(self, group_id):
keystone = self.__get_keystone_admin_client()
return keystone.users.list(group=group_id)
def __is_member_of_groups(self, template):
for group in template.groups.all():
group_members = self.__list_users_of_group(group.group_id)
for group_member in group_members:
if group_member.default_project_id == self.project_id:
return True
return False
def __cleanup_snapshot(self, template):
try:
template.users.get(project_id=self.project_id)
return # member is assigned as user
except TemplateUserMember.DoesNotExist:
pass
if not self.__is_member_of_groups(template):
self.glance.image_members.delete(template.image_id, self.project_id)
def __cleanup_snapshots(self):
templates_of_existing_snaps = self.__get_templates_of_snapshots()
for t in templates_of_existing_snaps:
self.__cleanup_snapshot(t)
def __update_shared_templates(self):
self.__cleanup_snapshots()
def post(self, request):
if not hasattr(request.POST, 'secret') or \
not hasattr(request.POST, 'project_id'):
return HttpResponse(status=400)
secret = request.POST['secret']
if secret != settings.SESSIONHOOK_SHARED_SECRET:
return HttpResponse(status=401)
self.project_id = request.POST['project_id']
self.glance = self.__get_glance_admin_client()
self.__update_shared_templates()
class GraphMixin(object): class GraphMixin(object):
graph_time_options = [ graph_time_options = [
{'time': "1h", 'name': _("1 hour")}, {'time': "1h", 'name': _("1 hour")},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment