do not update the 'updated' timestamp when updating the 'enacted' timestamp otherwise...
[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.enacted = datetime.now()
62             site.save(update_fields=['enacted'])
63
64         # get all slices that need to be synced (enacted < updated or enacted is None)
65         pending_slices = Slice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
66         for slice in pending_slices:
67             self.manager.save_slice(slice)
68             slice.enacted = datetime.now()
69             slice.save(update_fields=['enacted'])
70
71         # get all sites that where enacted != null. We can assume these sites
72         # have previously been synced and need to be checed for deletion.
73         sites = Site.objects.filter(enacted__isnull=False)
74         site_dict = {}
75         for site in sites:
76             site_dict[site.login_base] = site
77
78         # get all slices that where enacted != null. We can assume these slices
79         # have previously been synced and need to be checed for deletion.
80         slices = Slice.objects.filter(enacted__isnull=False)
81         slice_dict = {}
82         for slice in slices:
83             slice_dict[slice.name] = slice
84
85         # delete keystone tenants that don't have a site record
86         tenants = self.manager.driver.shell.keystone.tenants.findall()
87         for tenant in tenants:
88             if tenant.name == 'admin': 
89                 continue
90             if tenant.name not in site_dict and tenant.name not in slice_dict:
91                 #print "delete " + tenant.name
92                 pass
93                 #self.manager.driver.delete_tenant(tenant.id)
94
95
96     def sync_users(self):
97         """
98         save all users where enacted < updated or enacted == None. Remove users that
99         no don't exist in openstack db if they have an enacted time (enacted != None).
100         """ 
101         # get all users that need to be synced (enacted < updated or enacted is None)
102         pending_users = User.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
103         for user in pending_users:
104             print "syncing user", user
105             self.manager.save_user(user)
106             user.enacted = datetime.now()
107             user.save(update_fields=['enacted'])
108
109         # get all users that where enacted != null. We can assume these users
110         # have previously been synced and need to be checed for deletion.
111         users = User.objects.filter(enacted__isnull=False)
112         user_dict = {}
113         for user in users:
114             user_dict[user.kuser_id] = user
115
116         # delete keystone users that don't have a user record
117         users = self.manager.driver.shell.keystone.users.findall()
118         for user in users:
119             if user.name == 'admin':
120                 continue
121             if user.id not in user_dict:
122                 pass
123                 #self.manager.driver.delete_user(user.id)
124         
125         
126     def sync_slivers(self):
127         """
128         save all slivers where enacted < updated or enacted == None. Remove slivers that
129         no don't exist in openstack db if they have an enacted time (enacted != None).
130         """
131         # get all users that need to be synced (enacted < updated or enacted is None)
132         pending_slivers = Sliver.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
133         for sliver in pending_slivers:
134             if sliver.creator:  
135                 # update manager context
136                 self.manager.init_caller(sliver.creator)
137                 self.manager.save_sliver(sliver)
138                 sliver.enacted = datetime.now()
139                 sliver.save(update_fields=['enacted'])
140
141         # get all slivers that where enacted != null. We can assume these users
142         # have previously been synced and need to be checed for deletion.
143         slivers = Sliver.objects.filter(enacted__isnull=False)
144         sliver_dict = {}
145         for sliver in slivers:
146             sliver_dict[sliver.instance_id] = sliver
147
148         # delete sliver that don't have a sliver record
149         ctx = self.manager.driver.shell.nova_db.ctx 
150         instances = self.manager.driver.shell.nova_db.instance_get_all(ctx)
151         for instance in instances:
152             if instance.id not in sliver_dict:
153                 # lookup tenant and update context  
154                 #tenant = self.manager.driver.shell.keystone.tenants.findall(id=instance.tenant_id) 
155                 #self.manager.init_admin(tenant=tenant.name)  
156                 #self.manager.driver.destroy_instance(instance.id)
157                 pass