several bug fixes
[plstackapi.git] / planetstack / openstack / observer.py
1 import time
2 import traceback
3 from datetime import datetime
4 from core.models import *
5 from django.db.models import F, Q
6 from openstack.manager import OpenStackManager
7
8
9 class OpenStackObserver:
10     
11     def __init__(self):
12         self.manager = OpenStackManager()
13
14     def run(self):
15         if not self.manager.enabled or not self.manager.has_openstack:
16             return
17         while True:
18             try:
19                 #self.sync_roles()
20                 self.sync_tenants()
21                 self.sync_users()
22                 #self.sync_user_tenant_roles()
23                 self.sync_slivers()
24                 time.sleep(7)
25             except:
26                 traceback.print_exc() 
27
28     def sync_roles(self):
29         """
30         save all role that don't already exist in keystone. Remove keystone roles that
31         don't exist in planetstack
32         """
33         # sync all roles that don't already in keystone  
34         keystone_roles = self.manager.driver.shell.keystone.roles.findall()
35         keystone_role_names = [kr.name for kr in keystone_roles]
36         pending_roles = Role.objects.all()
37         pending_role_names = [r.role_type for r in pending_roles] 
38         for role in pending_roles:
39             if role.role_type not in keystone_role_names:
40                 self.manager.save_role(role)
41
42
43         # delete keystone roles that don't exist in planetstack 
44         for keystone_role in keystone_roles:
45             if keystone_role.name == 'admin':
46                 continue
47             if keystone_role.name not in pending_role_names:
48                 pass
49                 #self.manager.driver.delete_role({id: keystone_role.id})
50
51     def sync_tenants(self):
52         """
53         Save all sites and sliceswhere enacted < updated or enacted == None. 
54         Remove sites and slices that no don't exist in openstack db if they 
55         have an enacted time (enacted != None).
56         """ 
57         # get all sites that need to be synced (enacted < updated or enacted is None)
58         pending_sites = Site.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
59         for site in pending_sites:
60             self.manager.save_site(site)
61             site.save()
62             site.enacted = datetime.now()
63             site.save(update_fields=['enacted'])
64
65         # get all slices that need to be synced (enacted < updated or enacted is None)
66         pending_slices = Slice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
67         for slice in pending_slices:
68             self.manager.init_caller(slice.creator, slice.creator.site.login_base)
69             self.manager.save_slice(slice)
70             slice.save()
71             slice.enacted = datetime.now()
72             slice.save(update_fields=['enacted'])
73
74         # get all sites that where enacted != null. We can assume these sites
75         # have previously been synced and need to be checed for deletion.
76         sites = Site.objects.filter(enacted__isnull=False)
77         site_dict = {}
78         for site in sites:
79             site_dict[site.login_base] = site
80
81         # get all slices that where enacted != null. We can assume these slices
82         # have previously been synced and need to be checed for deletion.
83         slices = Slice.objects.filter(enacted__isnull=False)
84         slice_dict = {}
85         for slice in slices:
86             slice_dict[slice.name] = slice
87
88         # delete keystone tenants that don't have a site record
89         tenants = self.manager.driver.shell.keystone.tenants.findall()
90         for tenant in tenants:
91             if tenant.name == 'admin': 
92                 continue
93             if tenant.name not in site_dict and tenant.name not in slice_dict:
94                 #print "delete " + tenant.name
95                 pass
96                 #self.manager.driver.delete_tenant(tenant.id)
97
98
99     def sync_users(self):
100         """
101         save all users where enacted < updated or enacted == None. Remove users that
102         no don't exist in openstack db if they have an enacted time (enacted != None).
103         """ 
104         # get all users that need to be synced (enacted < updated or enacted is None)
105         pending_users = User.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
106         for user in pending_users:
107             self.manager.save_user(user)
108             user.save()
109             user.enacted = datetime.now()
110             user.save(update_fields=['enacted'])
111
112         # get all users that where enacted != null. We can assume these users
113         # have previously been synced and need to be checed for deletion.
114         users = User.objects.filter(enacted__isnull=False)
115         user_dict = {}
116         for user in users:
117             user_dict[user.kuser_id] = user
118
119         # delete keystone users that don't have a user record
120         users = self.manager.driver.shell.keystone.users.findall()
121         for user in users:
122             if user.name == 'admin':
123                 continue
124             if user.id not in user_dict:
125                 pass
126                 #self.manager.driver.delete_user(user.id)
127         
128         
129     def sync_slivers(self):
130         """
131         save all slivers where enacted < updated or enacted == None. Remove slivers that
132         no don't exist in openstack db if they have an enacted time (enacted != None).
133         """
134         # get all users that need to be synced (enacted < updated or enacted is None)
135         pending_slivers = Sliver.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
136         for sliver in pending_slivers:
137             if not sliver.instance_id and sliver.creator:  
138                 # update manager context
139                 self.manager.init_caller(sliver.creator, sliver.slice.name)
140                 self.manager.save_sliver(sliver)
141                 sliver.save()
142                 sliver.enacted = datetime.now()
143                 sliver.save(update_fields=['enacted'])
144
145         # get all slivers that where enacted != null. We can assume these users
146         # have previously been synced and need to be checed for deletion.
147         slivers = Sliver.objects.filter(enacted__isnull=False)
148         sliver_dict = {}
149         for sliver in slivers:
150             sliver_dict[sliver.instance_id] = sliver
151
152         # delete sliver that don't have a sliver record
153         ctx = self.manager.driver.shell.nova_db.ctx 
154         instances = self.manager.driver.shell.nova_db.instance_get_all(ctx)
155         for instance in instances:
156             if instance.id not in sliver_dict:
157                 # lookup tenant and update context  
158                 #tenant = self.manager.driver.shell.keystone.tenants.findall(id=instance.tenant_id) 
159                 #self.manager.init_admin(tenant=tenant.name)  
160                 #self.manager.driver.destroy_instance(instance.id)
161                 pass