Fix tenant update
[plstackapi.git] / planetstack / observer / steps / sync_slices.py
1 import os
2 import base64
3 from netaddr import IPAddress, IPNetwork
4 from django.db.models import F, Q
5 from planetstack.config import Config
6 from observer.openstacksyncstep import OpenStackSyncStep
7 from core.models.slice import Slice
8 from util.logger import Logger, logging
9
10 logger = Logger(logfile='observer.log', level=logging.INFO)
11
12 class SyncSlices(OpenStackSyncStep):
13     provides=[Slice]
14     requested_interval=0
15
16     def fetch_pending(self):
17         return Slice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
18
19     def get_next_subnet(self):
20         # limit ourself to 10.0.x.x for now
21         valid_subnet = lambda net: net.startswith('10.0')
22         subnets = self.driver.shell.quantum.list_subnets()['subnets']
23         ints = [int(IPNetwork(subnet['cidr']).ip) for subnet in subnets \
24                 if valid_subnet(subnet['cidr'])]
25         ints.sort()
26         last_ip = IPAddress(ints[-1])
27         last_network = IPNetwork(str(last_ip) + "/24")
28         next_network = IPNetwork(str(IPAddress(last_network) + last_network.size) + "/24")
29         return next_network
30
31     def sync_record(self, slice):
32         logger.info("sync'ing slice %s" % slice.name)
33         if not slice.tenant_id:
34             nova_fields = {'tenant_name': slice.name,
35                    'description': slice.description,
36                    'enabled': slice.enabled}
37             tenant = self.driver.create_tenant(**nova_fields)
38             slice.tenant_id = tenant.id
39
40             # XXX give caller an admin role at the tenant they've created
41             self.driver.add_user_role(slice.creator.kuser_id, tenant.id, 'admin')
42
43             # refresh credentials using this tenant
44             client_driver = self.driver.client_driver(tenant=tenant.name)
45
46             # create network
47             network = client_driver.create_network(slice.name)
48             slice.network_id = network['id']
49
50             # create router
51             router = client_driver.create_router(slice.name)
52             slice.router_id = router['id']
53
54             # create subnet
55             next_subnet = self.get_next_subnet()
56             cidr = str(next_subnet.cidr)
57             ip_version = next_subnet.version
58             start = str(next_subnet[2])
59             end = str(next_subnet[-2]) 
60             subnet = client_driver.create_subnet(name=slice.name,
61                                                network_id = network['id'],
62                                                cidr_ip = cidr,
63                                                ip_version = ip_version,
64                                                start = start,
65                                                end = end)
66             slice.subnet_id = subnet['id']
67             # add subnet as interface to slice's router
68             client_driver.add_router_interface(router['id'], subnet['id'])
69             # add external route
70             client_driver.add_external_route(subnet)
71
72
73         if slice.id and slice.tenant_id:
74             self.driver.update_tenant(slice.tenant_id,
75                                       description=slice.description,
76                                       enabled=slice.enabled)   
77
78         slice.save()