blob: 77991831d282f4fecd6312c95e22e892fd61e858 [file] [log] [blame]
Omar Abdelkader401e1cb2017-06-21 15:52:54 -07001from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, NetworkParameter, NetworkParameterType, AddressPool, Port
Pingping Linf3e24a92016-09-19 21:35:16 +00002from core.models.plcorebase import StrippedCharField
3import os
4from django.db import models, transaction
5from django.forms.models import model_to_dict
6from django.db.models import Q
7from operator import itemgetter, attrgetter, methodcaller
8from core.models import Tag
9from core.models.service import LeastLoadedNodeScheduler
10import traceback
11from xos.exceptions import *
12from core.models import SlicePrivilege, SitePrivilege
13from sets import Set
14from xos.config import Config
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070015from models_decl import *
Pingping Linf3e24a92016-09-19 21:35:16 +000016
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070017class VPGWCService (VPGWCService_decl):
Pingping Linf3e24a92016-09-19 21:35:16 +000018 class Meta:
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070019 proxy = True
Pingping Linf3e24a92016-09-19 21:35:16 +000020
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070021class VPGWCTenant (VPGWCTenant_decl):
Pingping Linf3e24a92016-09-19 21:35:16 +000022 class Meta:
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070023 proxy = True
Pingping Linf3e24a92016-09-19 21:35:16 +000024
Pingping Linf3e24a92016-09-19 21:35:16 +000025 def __init__(self, *args, **kwargs):
Pingping Linc537fd92017-01-17 20:52:09 -080026 pgwc_services = VPGWCService.get_service_objects().all()
Pingping Linf3e24a92016-09-19 21:35:16 +000027 # When the tenant is created the default service in the form is set
28 # to be the first created HelloWorldServiceComplete
Pingping Linc537fd92017-01-17 20:52:09 -080029 if pgwc_services:
Pingping Linf3e24a92016-09-19 21:35:16 +000030 self._meta.get_field(
Pingping Linc537fd92017-01-17 20:52:09 -080031 "provider_service").default = pgwc_services[0].id
32 super(VPGWCTenant, self).__init__(*args, **kwargs)
Pingping Linf3e24a92016-09-19 21:35:16 +000033
34 def can_update(self, user):
35 #Allow creation of this model instances for non-admin users also
36 return True
37
38 def save(self, *args, **kwargs):
Pingping Linc537fd92017-01-17 20:52:09 -080039 '''
Pingping Linf3e24a92016-09-19 21:35:16 +000040 if not self.creator:
41 if not getattr(self, "caller", None):
42 # caller must be set when creating a monitoring channel since it creates a slice
43 raise XOSProgrammingError("ServiceComponents's self.caller was not set")
44 self.creator = self.caller
45 if not self.creator:
46 raise XOSProgrammingError("ServiceComponents's self.creator was not set")
Pingping Linc537fd92017-01-17 20:52:09 -080047 '''
48 super(VPGWCTenant, self).save(*args, **kwargs)
Pingping Linf3e24a92016-09-19 21:35:16 +000049 # This call needs to happen so that an instance is created for this
50 # tenant is created in the slice. One instance is created per tenant.
51 model_policy_mcord_servicecomponent(self.pk)
JianHao052a7052017-02-08 05:59:11 +000052# def save_instance(self, instance):
53# with transaction.atomic():
54# super(VPGWCTenant, self).save_instance(instance)
55# if instance.isolation in ["vm"]:
56# for ntype in vpgwc_net_types:
57# lan_network = self.get_lan_network(instance, ntype)
58# port = self.find_or_make_port(instance,lan_network)
59# if (ntype == "s5s8"):
60# port.set_parameter("s_tag", self.s5s8_pgw_tag)
61# port.set_parameter("neutron_port_name", "stag-%s" % self.s5s8_pgw_tag)
62# port.save()
63# else:
Omar Abdelkader401e1cb2017-06-21 15:52:54 -070064# return True
JianHao052a7052017-02-08 05:59:11 +000065
Pingping Linf3e24a92016-09-19 21:35:16 +000066 def save_instance(self, instance):
67 with transaction.atomic():
Pingping Linc537fd92017-01-17 20:52:09 -080068 super(VPGWCTenant, self).save_instance(instance)
JianHao39d5a8b2017-02-19 18:23:47 +080069 #if instance.isolation in ["vm"]:
70 # if self.image_name == 'pgwu':
71 # lan_network = self.get_lan_network(instance, "wan_network")
72 # port = self.find_or_make_port(instance,lan_network)
73 # port.set_parameter("neutron_port_ip", "102.0.0.8")
74 # port.save()
Pingping Linf3e24a92016-09-19 21:35:16 +000075
76 def delete(self, *args, **kwargs):
77 # Delete the instance that was created for this tenant
78 self.cleanup_container()
Pingping Linc537fd92017-01-17 20:52:09 -080079 super(VPGWCTenant, self).delete(*args, **kwargs)
Pingping Linf3e24a92016-09-19 21:35:16 +000080
81 def find_or_make_port(self, instance, network, **kwargs):
82 port = Port.objects.filter(instance=instance, network=network)
83 if port:
84 port = port[0]
85 print "port already exist", port[0]
86 else:
87 port = Port(instance=instance, network=network, **kwargs)
JianHao39d5a8b2017-02-19 18:23:47 +080088 print "NETWORK", network, "MAKE_PORT", port
Pingping Linf3e24a92016-09-19 21:35:16 +000089 port.save()
90 return port
91
92 def get_lan_network(self, instance, ntype):
93 slice = self.provider_service.slices.all()[0]
94 lan_networks = [x for x in slice.networks.all() if ntype in x.name]
95 if not lan_networks:
Pingping Linb8b186e2017-01-19 11:33:45 -080096 raise XOSProgrammingError("No lan_network")
Pingping Linf3e24a92016-09-19 21:35:16 +000097 return lan_networks[0]
98
99 def manage_container(self):
100 from core.models import Instance, Flavor
Pingping Linf3e24a92016-09-19 21:35:16 +0000101 if self.deleted:
102 return
Pingping Linf3e24a92016-09-19 21:35:16 +0000103 # For container or container_vm isolation, use what TenantWithCotnainer
104 # provides us
105 slice = self.get_slice()
106 if slice.default_isolation in ["container_vm", "container"]:
Pingping Linc537fd92017-01-17 20:52:09 -0800107 super(VPGWCTenant,self).manage_container()
Pingping Linf3e24a92016-09-19 21:35:16 +0000108 return
Pingping Linf3e24a92016-09-19 21:35:16 +0000109 if not self.s5s8_pgw_tag:
Pingping Linb8b186e2017-01-19 11:33:45 -0800110 raise XOSConfigurationError("S5S8_PGW_TAG is missed")
Pingping Linf3e24a92016-09-19 21:35:16 +0000111 if self.instance:
112 # We're good.
113 return
Pingping Linf3e24a92016-09-19 21:35:16 +0000114 instance = self.make_instance()
115 self.instance = instance
116 super(TenantWithContainer, self).save()
117
118 def get_slice(self):
119 if not self.provider_service.slices.count():
120 raise XOSConfigurationError("The service has no slices")
121 slice = self.provider_service.slices.all()[0]
122 return slice
123
124 def make_instance(self):
JianHao39d5a8b2017-02-19 18:23:47 +0800125 slice = self.provider_service.slices.all()[0]
Pingping Linf3e24a92016-09-19 21:35:16 +0000126 flavors = Flavor.objects.filter(name=slice.default_flavor)
127# flavors = Flavor.objects.filter(name="m1.xlarge")
128 if not flavors:
129 raise XOSConfigurationError("No default flavor")
130 default_flavor = slice.default_flavor
131 slice = self.provider_service.slices.all()[0]
132 if slice.default_isolation == "container_vm":
133 (node, parent) = ContainerVmScheduler(slice).pick()
134 else:
135 (node, parent) = LeastLoadedNodeScheduler(slice).pick()
136 instance = Instance(slice = slice,
137 node = node,
138 image = self.image,
139 creator = self.creator,
140 deployment = node.site_deployment.deployment,
141 flavor = flavors[0],
142 isolation = slice.default_isolation,
143 parent = parent)
144 self.save_instance(instance)
145 return instance
146
147 def ip_to_mac(self, ip):
148 (a, b, c, d) = ip.split('.')
149 return "02:42:%02x:%02x:%02x:%02x" % (int(a), int(b), int(c), int(d))
150
Saleil Bhat4f45a4f2017-02-01 17:04:22 -0800151 @property
152 def image(self):
153 img = self.image_name.strip()
154 if img.lower() != "default":
155 return Image.objects.get(name=img)
JianHao39d5a8b2017-02-19 18:23:47 +0800156 else:
Saleil Bhat4dc77d62017-02-03 13:27:38 -0800157 return super(VPGWCTenant, self).image
Saleil Bhat4f45a4f2017-02-01 17:04:22 -0800158
Pingping Linf3e24a92016-09-19 21:35:16 +0000159 @property
160 def addresses(self):
161 if (not self.id) or (not self.instance):
162 return {}
Pingping Linf3e24a92016-09-19 21:35:16 +0000163 addresses = {}
164 for ns in self.instance.ports.all():
165 if "s5s8_pgw" in ns.network.name.lower():
166 addresses["s5s8_pgw"] = (ns.ip, ns.mac)
167 return addresses
168
Pingping Linf3e24a92016-09-19 21:35:16 +0000169 @property
170 def s5s8_pgw_ip(self):
171 return self.addresses.get("s5s8_pgw", (None, None))[0]
Omar Abdelkader401e1cb2017-06-21 15:52:54 -0700172
Pingping Linf3e24a92016-09-19 21:35:16 +0000173 @property
174 def s5s8_pgw_mac(self):
175 return self.addresses.get("s5s8_pgw", (None, None))[1]
176
Pingping Linf3e24a92016-09-19 21:35:16 +0000177def model_policy_mcord_servicecomponent(pk):
178 # This section of code is atomic to prevent race conditions
179 with transaction.atomic():
180 # We find all of the tenants that are waiting to update
Pingping Linc537fd92017-01-17 20:52:09 -0800181 tenant = VPGWCTenant.objects.select_for_update().filter(pk=pk)
182 if not tenant:
Pingping Linf3e24a92016-09-19 21:35:16 +0000183 return
184 # Since this code is atomic it is safe to always use the first tenant
Pingping Linc537fd92017-01-17 20:52:09 -0800185 tenant = tenant[0]
186 tenant.manage_container()