From c59fcaf0847bcc583591ae79cfc06e63960f59d8 Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Mon, 10 Jun 2013 11:14:04 -0400 Subject: [PATCH] initial checkin of observer --- planetstack/openstack/driver.py | 4 + planetstack/openstack/manager.py | 11 ++- planetstack/openstack/observer.py | 120 ++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 planetstack/openstack/observer.py diff --git a/planetstack/openstack/driver.py b/planetstack/openstack/driver.py index a38b0a1..e9988e3 100644 --- a/planetstack/openstack/driver.py +++ b/planetstack/openstack/driver.py @@ -69,6 +69,10 @@ class OpenStackDriver: def delete_user(self, id): users = self.shell.keystone.users.findall(id=id) for user in users: + # delete users keys + keys = self.shell.nova.keypairs.findall() + for key in keys: + self.shell.nova.keypairs.delete(key) self.shell.keystone.users.delete(user) return 1 diff --git a/planetstack/openstack/manager.py b/planetstack/openstack/manager.py index 3c77952..e310883 100644 --- a/planetstack/openstack/manager.py +++ b/planetstack/openstack/manager.py @@ -54,15 +54,18 @@ class OpenStackManager: self.init_admin() @require_enabled - def init_user(self, auth, caller): + def init_caller(self, caller, tenant): + auth = {'username': caller.email, + 'password': '', + 'tenant': tenant} self.client = OpenStackClient(**auth) self.driver = OpenStackDriver(client=self.client) self.caller = caller @require_enabled - def init_admin(self): + def init_admin(self, tenant=None): # use the admin credentials - self.client = OpenStackClient() + self.client = OpenStackClient(tenant=tenant) self.driver = OpenStackDriver(client=self.client) self.caller = self.driver.admin_user self.caller.kuser_id = self.caller.id @@ -203,8 +206,8 @@ class OpenStackManager: if subnet: self.driver.delete_external_route(subnet) - + @require_enabled def get_next_subnet(self): # limit ourself to 10.0.x.x for now valid_subnet = lambda net: net.startswith('10.0') diff --git a/planetstack/openstack/observer.py b/planetstack/openstack/observer.py new file mode 100644 index 0000000..ac2d58a --- /dev/null +++ b/planetstack/openstack/observer.py @@ -0,0 +1,120 @@ +import time +from datetime import datetime +from core.models import * +from django.db.models import F, Q +from openstack.manager import OpenStackManager + + +class OpenStackObserver: + + def __init__(self): + self.manager = OpenStackManager() + + def sync_sites(self): + """ + save all sites where enacted < updated or enacted == None. Remove sites that + no don't exist in openstack db if they have an enacted time (enacted != None). + """ + # get all sites that need to be synced (enacted < updated or enacted is None) + pending_sites = Site.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) + for site in pending_sites: + self.manager.save_site(site) + site.enacted = datetime.now() + site.save() + + # get all sites that where enacted != null. We can assume these sites + # have previously been synced and need to be checed for deletion. + sites = Site.objects.filter(enacted__isnull=False) + site_dict = {} + for site in sites: + site_dict[site.login_base] = site + + # delete keystone tenants that don't have a site record + tenants = self.manager.driver.shell.keystone.tenants.findall() + for tenant in tenants: + if tenant.name not in site_dict: + self.manager.driver.delete_tenant(tenant.id) + + def sync_slices(self): + """ + save all slices where enacted < updated or enacted == None. Remove slices that + no don't exist in openstack db if they have an enacted time (enacted != None). + """ + # get all slices that need to be synced (enacted < updated or enacted is None) + pending_slices = Slice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) + for slice in pending_slices: + self.manager.save_slice(slice) + slice.enacted = datetime.now() + slice.save() + + # get all slices that where enacted != null. We can assume these slices + # have previously been synced and need to be checed for deletion. + slices = Slice.objects.filter(enacted__isnull=False) + slice_dict = {} + for slice in slices: + slice_dict[slice.name] = slice + + # delete keystone tenants that don't have a site record + tenants = self.manager.driver.shell.keystone.tenants.findall() + for tenant in tenants: + if tenant.name not in slice_dict: + self.manager.driver.delete_tenant(tenant.id) + + def sync_users(self): + """ + save all users where enacted < updated or enacted == None. Remove users that + no don't exist in openstack db if they have an enacted time (enacted != None). + """ + # get all users that need to be synced (enacted < updated or enacted is None) + pending_users = User.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) + for user in pending_users: + self.manager.save_user(user) + user.enacted = datetime.now() + user.save() + + # get all users that where enacted != null. We can assume these users + # have previously been synced and need to be checed for deletion. + users = User.objects.filter(enacted__isnull=False) + user_dict = {} + for user in users: + user_dict[user.kuser_id] = user + + # delete keystone users that don't have a user record + user = self.manager.driver.shell.keystone.users.findall() + for user in users: + if user.id not in user_dict: + self.manager.driver.delete_user(user.id) + + + + def sync_slivers(self): + """ + save all slivers where enacted < updated or enacted == None. Remove slivers that + no don't exist in openstack db if they have an enacted time (enacted != None). + """ + # get all users that need to be synced (enacted < updated or enacted is None) + pending_slivers = Sliver.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) + for sliver in pending_slivers: + if sliver.creator: + # update manager context + self.manager.init_caller(sliver.creator) + self.manager.save_sliver(sliver) + sliver.enacted = datetime.now() + sliver.save() + + # get all slivers that where enacted != null. We can assume these users + # have previously been synced and need to be checed for deletion. + slivers = Sliver.objects.filter(enacted__isnull=False) + sliver_dict = {} + for sliver in slivers: + sliver_dict[sliver.instance_id] = sliver + + # delete sliver that don't have a sliver record + ctx = self.manager.driver.shell.nova_db.ctx + instances = self.manager.driver.shell.nova_db.instance_get_all(ctx) + for instance in instances: + if instance.id not in sliver_dict: + # lookup tenant and update context + tenant = self.manager.driver.shell.keystone.tenants.findall(id=instance.tenant_id) + self.manager.init_admin(tenant=tenant.name) + self.manager.driver.destroy_instance(instance.id) -- 2.43.0