blob: 0da4809b340bae70524043c99c3bdc39af6f6c1b [file] [log] [blame]
Scott Baker1b241612015-04-14 17:19:16 -07001from django.db import models
Scott Baker27fab492016-02-13 14:38:43 -08002from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port, AddressPool
Scott Baker1b241612015-04-14 17:19:16 -07003from core.models.plcorebase import StrippedCharField
4import os
Scott Baker1027cd62015-07-08 19:01:56 -07005from django.db import models, transaction
Scott Baker1b241612015-04-14 17:19:16 -07006from django.forms.models import model_to_dict
7from django.db.models import Q
8from operator import itemgetter, attrgetter, methodcaller
Scott Baker87891952016-02-02 16:56:18 -08009from core.models import Tag
10from core.models.service import LeastLoadedNodeScheduler
Scott Baker6b3c9b32016-04-13 11:25:52 -070011from services.vrouter.models import VRouterService, VRouterTenant
Scott Baker697fb0b2015-04-20 09:16:17 -070012import traceback
Scott Bakerd921e1c2015-04-20 14:24:29 -070013from xos.exceptions import *
Scott Baker27fab492016-02-13 14:38:43 -080014from xos.config import Config
Scott Baker1b241612015-04-14 17:19:16 -070015
Scott Baker1b241612015-04-14 17:19:16 -070016class ConfigurationError(Exception):
17 pass
18
Scott Baker361c86c2015-07-06 14:38:02 -070019VOLT_KIND = "vOLT"
20VCPE_KIND = "vCPE"
21VBNG_KIND = "vBNG"
Scott Bakerf08823d2015-07-06 16:50:30 -070022CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
23
Scott Baker27fab492016-02-13 14:38:43 -080024CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
25
Scott Bakerf08823d2015-07-06 16:50:30 -070026# -------------------------------------------
27# CordSubscriberRoot
28# -------------------------------------------
29
30class CordSubscriberRoot(Subscriber):
Scott Bakercd349182015-07-06 17:21:21 -070031 class Meta:
32 proxy = True
33
Scott Bakerf08823d2015-07-06 16:50:30 -070034 KIND = CORD_SUBSCRIBER_KIND
35
Scott Baker95e38ae2016-03-01 20:14:35 -080036 status_choices = (("enabled", "Enabled"),
37 ("suspended", "Suspended"),
38 ("delinquent", "Delinquent"),
39 ("copyrightviolation", "Copyright Violation"))
40
41 # 'simple_attributes' will be expanded into properties and setters that
42 # store the attribute using self.set_attribute / self.get_attribute.
43
44 simple_attributes = ( ("firewall_enable", False),
45 ("firewall_rules", "accept all anywhere anywhere"),
46 ("url_filter_enable", False),
47 ("url_filter_rules", "allow all"),
48 ("url_filter_level", "PG"),
49 ("cdn_enable", False),
50 ("users", []),
51 ("is_demo_user", False),
52
Matteod86563d2016-03-02 09:33:20 -080053 ("uplink_speed", 1000000000), # 1 gigabit, a reasonable default?
54 ("downlink_speed", 1000000000),
Scott Baker95e38ae2016-03-01 20:14:35 -080055 ("enable_uverse", True) )
56
57 default_attributes = {"status": "enabled"}
Scott Bakerf08823d2015-07-06 16:50:30 -070058
Scott Baker7c7b6312015-07-07 12:15:03 -070059 sync_attributes = ("firewall_enable",
60 "firewall_rules",
61 "url_filter_enable",
62 "url_filter_rules",
Scott Bakere059cf72016-03-01 20:44:40 -080063 "cdn_enable",
64 "uplink_speed",
65 "downlink_speed",
66 "enable_uverse",
67 "status")
Scott Baker7c7b6312015-07-07 12:15:03 -070068
Scott Bakerf08823d2015-07-06 16:50:30 -070069 def __init__(self, *args, **kwargs):
70 super(CordSubscriberRoot, self).__init__(*args, **kwargs)
71 self.cached_volt = None
Scott Baker7c7b6312015-07-07 12:15:03 -070072 self._initial_url_filter_enable = self.url_filter_enable
Scott Bakerf08823d2015-07-06 16:50:30 -070073
74 @property
75 def volt(self):
76 volt = self.get_newest_subscribed_tenant(VOLTTenant)
77 if not volt:
78 return None
79
80 # always return the same object when possible
81 if (self.cached_volt) and (self.cached_volt.id == volt.id):
Scott Bakerdb66fd32015-07-07 17:59:44 -070082 return self.cached_volt
Scott Bakerf08823d2015-07-06 16:50:30 -070083
Scott Bakercd349182015-07-06 17:21:21 -070084 #volt.caller = self.creator
Scott Bakerf08823d2015-07-06 16:50:30 -070085 self.cached_volt = volt
86 return volt
87
88 @property
Scott Baker95e38ae2016-03-01 20:14:35 -080089 def status(self):
90 return self.get_attribute("status", self.default_attributes["status"])
Scott Bakerf08823d2015-07-06 16:50:30 -070091
Scott Baker95e38ae2016-03-01 20:14:35 -080092 @status.setter
93 def status(self, value):
94 if not value in [x[0] for x in self.status_choices]:
95 raise Exception("invalid status %s" % value)
96 self.set_attribute("status", value)
Scott Bakerf08823d2015-07-06 16:50:30 -070097
98 def find_user(self, uid):
99 uid = int(uid)
100 for user in self.users:
101 if user["id"] == uid:
102 return user
103 return None
104
105 def update_user(self, uid, **kwargs):
106 # kwargs may be "level" or "mac"
107 # Setting one of these to None will cause None to be stored in the db
108 uid = int(uid)
109 users = self.users
110 for user in users:
111 if user["id"] == uid:
112 for arg in kwargs.keys():
113 user[arg] = kwargs[arg]
114 self.users = users
115 return user
116 raise ValueError("User %d not found" % uid)
117
118 def create_user(self, **kwargs):
119 if "name" not in kwargs:
120 raise XOSMissingField("The name field is required")
121
122 for user in self.users:
123 if kwargs["name"] == user["name"]:
124 raise XOSDuplicateKey("User %s already exists" % kwargs["name"])
125
126 uids = [x["id"] for x in self.users]
127 if uids:
128 uid = max(uids)+1
129 else:
130 uid = 0
131 newuser = kwargs.copy()
132 newuser["id"] = uid
133
134 users = self.users
135 users.append(newuser)
136 self.users = users
137
138 return newuser
139
140 def delete_user(self, uid):
141 uid = int(uid)
142 users = self.users
143 for user in users:
144 if user["id"]==uid:
145 users.remove(user)
146 self.users = users
147 return
148
149 raise ValueError("Users %d not found" % uid)
150
151 @property
152 def services(self):
153 return {"cdn": self.cdn_enable,
154 "url_filter": self.url_filter_enable,
155 "firewall": self.firewall_enable}
156
157 @services.setter
158 def services(self, value):
159 pass
Scott Baker361c86c2015-07-06 14:38:02 -0700160
Scott Baker7c7b6312015-07-07 12:15:03 -0700161 def save(self, *args, **kwargs):
Scott Bakerdc880f32016-03-31 14:45:31 -0700162 self.validate_unique_service_specific_id(none_okay=True)
Scott Bakereaee05e2015-07-24 18:56:57 -0700163 if (not hasattr(self, 'caller') or not self.caller.is_admin):
164 if (self.has_field_changed("service_specific_id")):
165 raise XOSPermissionDenied("You do not have permission to change service_specific_id")
Scott Baker7c7b6312015-07-07 12:15:03 -0700166 super(CordSubscriberRoot, self).save(*args, **kwargs)
167 if (self.volt) and (self.volt.vcpe): # and (self._initial_url_filter_enabled != self.url_filter_enable):
168 # 1) trigger manage_bbs_account to run
169 # 2) trigger vcpe observer to wake up
170 self.volt.vcpe.save()
171
Scott Baker95e38ae2016-03-01 20:14:35 -0800172CordSubscriberRoot.setup_simple_attributes()
Scott Bakerdb66fd32015-07-07 17:59:44 -0700173
Scott Baker39b0d892015-04-15 20:59:15 -0700174# -------------------------------------------
175# VOLT
176# -------------------------------------------
177
178class VOLTService(Service):
Scott Baker361c86c2015-07-06 14:38:02 -0700179 KIND = VOLT_KIND
Scott Baker39b0d892015-04-15 20:59:15 -0700180
Scott Baker1b241612015-04-14 17:19:16 -0700181 class Meta:
Scott Baker39b0d892015-04-15 20:59:15 -0700182 app_label = "cord"
183 verbose_name = "vOLT Service"
184 proxy = True
185
186class VOLTTenant(Tenant):
187 class Meta:
188 proxy = True
189
Scott Baker361c86c2015-07-06 14:38:02 -0700190 KIND = VOLT_KIND
Scott Baker39b0d892015-04-15 20:59:15 -0700191
Scott Baker89a338c2015-11-09 20:25:21 -0800192 default_attributes = {"vlan_id": None, "s_tag": None, "c_tag": None}
Scott Baker557aada2015-04-20 09:48:34 -0700193 def __init__(self, *args, **kwargs):
194 volt_services = VOLTService.get_service_objects().all()
195 if volt_services:
196 self._meta.get_field("provider_service").default = volt_services[0].id
197 super(VOLTTenant, self).__init__(*args, **kwargs)
Scott Baker361c86c2015-07-06 14:38:02 -0700198 self.cached_vcpe = None
Scott Baker5e76f802015-06-24 12:54:24 -0700199
Scott Baker39b0d892015-04-15 20:59:15 -0700200 @property
Scott Baker89a338c2015-11-09 20:25:21 -0800201 def s_tag(self):
202 return self.get_attribute("s_tag", self.default_attributes["s_tag"])
203
204 @s_tag.setter
205 def s_tag(self, value):
206 self.set_attribute("s_tag", value)
207
208 @property
209 def c_tag(self):
210 return self.get_attribute("c_tag", self.default_attributes["c_tag"])
211
212 @c_tag.setter
213 def c_tag(self, value):
214 self.set_attribute("c_tag", value)
215
216 # for now, vlan_id is a synonym for c_tag
217
218 @property
Scott Bakere744c7b2015-04-20 11:50:09 -0700219 def vlan_id(self):
Scott Baker89a338c2015-11-09 20:25:21 -0800220 return self.c_tag
Scott Bakere744c7b2015-04-20 11:50:09 -0700221
222 @vlan_id.setter
223 def vlan_id(self, value):
Scott Baker89a338c2015-11-09 20:25:21 -0800224 self.c_tag = value
Scott Bakere744c7b2015-04-20 11:50:09 -0700225
226 @property
Scott Baker39b0d892015-04-15 20:59:15 -0700227 def vcpe(self):
Scott Baker664bbe52016-02-11 11:08:42 -0800228 vcpe = self.get_newest_subscribed_tenant(VSGTenant)
Scott Baker361c86c2015-07-06 14:38:02 -0700229 if not vcpe:
230 return None
231
232 # always return the same object when possible
233 if (self.cached_vcpe) and (self.cached_vcpe.id == vcpe.id):
Scott Baker697fb0b2015-04-20 09:16:17 -0700234 return self.cached_vcpe
Scott Baker361c86c2015-07-06 14:38:02 -0700235
Scott Baker9c8a2c72015-05-05 17:49:46 -0700236 vcpe.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700237 self.cached_vcpe = vcpe
238 return vcpe
Scott Baker39b0d892015-04-15 20:59:15 -0700239
240 @vcpe.setter
241 def vcpe(self, value):
Scott Bakercd349182015-07-06 17:21:21 -0700242 raise XOSConfigurationError("vOLT.vCPE cannot be set this way -- create a new vCPE object and set its subscriber_tenant instead")
243
244 @property
245 def subscriber(self):
246 if not self.subscriber_root:
247 return None
248 subs = CordSubscriberRoot.objects.filter(id=self.subscriber_root.id)
249 if not subs:
250 return None
251 return subs[0]
Scott Baker39b0d892015-04-15 20:59:15 -0700252
Scott Baker9c8a2c72015-05-05 17:49:46 -0700253 @property
254 def creator(self):
255 if getattr(self, "cached_creator", None):
256 return self.cached_creator
257 creator_id=self.get_attribute("creator_id")
258 if not creator_id:
259 return None
260 users=User.objects.filter(id=creator_id)
261 if not users:
262 return None
263 user=users[0]
264 self.cached_creator = users[0]
265 return user
266
267 @creator.setter
268 def creator(self, value):
269 if value:
270 value = value.id
271 if (value != self.get_attribute("creator_id", None)):
272 self.cached_creator=None
273 self.set_attribute("creator_id", value)
274
Scott Baker39b0d892015-04-15 20:59:15 -0700275 def manage_vcpe(self):
276 # Each VOLT object owns exactly one VCPE object
277
278 if self.deleted:
279 return
280
281 if self.vcpe is None:
Scott Baker4698b922016-02-11 12:07:10 -0800282 vsgServices = VSGService.get_service_objects().all()
283 if not vsgServices:
284 raise XOSConfigurationError("No VSG Services available")
Scott Baker39b0d892015-04-15 20:59:15 -0700285
Scott Baker4698b922016-02-11 12:07:10 -0800286 vcpe = VSGTenant(provider_service = vsgServices[0],
Scott Baker39b0d892015-04-15 20:59:15 -0700287 subscriber_tenant = self)
Scott Baker9c8a2c72015-05-05 17:49:46 -0700288 vcpe.caller = self.creator
Scott Baker39b0d892015-04-15 20:59:15 -0700289 vcpe.save()
290
Scott Baker7c7b6312015-07-07 12:15:03 -0700291 def manage_subscriber(self):
292 if (self.subscriber_root is None):
293 # The vOLT is not connected to a Subscriber, so either find an
294 # existing subscriber with the same SSID, or autogenerate a new
295 # subscriber.
296 #
297 # TODO: This probably goes away when we rethink the ONOS-to-XOS
298 # vOLT API.
299
300 subs = CordSubscriberRoot.get_tenant_objects().filter(service_specific_id = self.service_specific_id)
301 if subs:
302 sub = subs[0]
303 else:
304 sub = CordSubscriberRoot(service_specific_id = self.service_specific_id,
305 name = "autogenerated-for-vOLT-%s" % self.id)
306 sub.save()
307 self.subscriber_root = sub
308 self.save()
309
Scott Baker39b0d892015-04-15 20:59:15 -0700310 def cleanup_vcpe(self):
311 if self.vcpe:
Scott Baker361c86c2015-07-06 14:38:02 -0700312 # print "XXX cleanup vcpe", self.vcpe
Scott Baker39b0d892015-04-15 20:59:15 -0700313 self.vcpe.delete()
Scott Baker39b0d892015-04-15 20:59:15 -0700314
Scott Baker5e76f802015-06-24 12:54:24 -0700315 def cleanup_orphans(self):
Scott Baker361c86c2015-07-06 14:38:02 -0700316 # ensure vOLT only has one vCPE
317 cur_vcpe = self.vcpe
Scott Baker664bbe52016-02-11 11:08:42 -0800318 for vcpe in list(self.get_subscribed_tenants(VSGTenant)):
Scott Baker361c86c2015-07-06 14:38:02 -0700319 if (not cur_vcpe) or (vcpe.id != cur_vcpe.id):
320 # print "XXX clean up orphaned vcpe", vcpe
321 vcpe.delete()
Scott Baker5e76f802015-06-24 12:54:24 -0700322
Scott Baker39b0d892015-04-15 20:59:15 -0700323 def save(self, *args, **kwargs):
Scott Baker95fa7f02016-03-30 09:39:59 -0700324 # VOLTTenant probably doesn't need a SSID anymore; that will be handled
325 # by CORDSubscriberRoot...
326 # self.validate_unique_service_specific_id()
Scott Bakerd921e1c2015-04-20 14:24:29 -0700327
Scott Baker7c7b6312015-07-07 12:15:03 -0700328 if (self.subscriber_root is not None):
329 subs = self.subscriber_root.get_subscribed_tenants(VOLTTenant)
330 if (subs) and (self not in subs):
331 raise XOSDuplicateKey("Subscriber should only be linked to one vOLT")
332
Scott Baker9c8a2c72015-05-05 17:49:46 -0700333 if not self.creator:
334 if not getattr(self, "caller", None):
335 # caller must be set when creating a vCPE since it creates a slice
336 raise XOSProgrammingError("VOLTTenant's self.caller was not set")
337 self.creator = self.caller
338 if not self.creator:
339 raise XOSProgrammingError("VOLTTenant's self.creator was not set")
340
Scott Baker39b0d892015-04-15 20:59:15 -0700341 super(VOLTTenant, self).save(*args, **kwargs)
Scott Baker1027cd62015-07-08 19:01:56 -0700342 model_policy_volt(self.pk)
343 #self.manage_vcpe()
344 #self.manage_subscriber()
345 #self.cleanup_orphans()
Scott Baker39b0d892015-04-15 20:59:15 -0700346
347 def delete(self, *args, **kwargs):
348 self.cleanup_vcpe()
349 super(VOLTTenant, self).delete(*args, **kwargs)
350
Scott Baker1027cd62015-07-08 19:01:56 -0700351def model_policy_volt(pk):
352 # TODO: this should be made in to a real model_policy
353 with transaction.atomic():
354 volt = VOLTTenant.objects.select_for_update().filter(pk=pk)
355 if not volt:
356 return
357 volt = volt[0]
358 volt.manage_vcpe()
359 volt.manage_subscriber()
360 volt.cleanup_orphans()
361
Scott Baker39b0d892015-04-15 20:59:15 -0700362# -------------------------------------------
363# VCPE
364# -------------------------------------------
365
Scott Baker4698b922016-02-11 12:07:10 -0800366class VSGService(Service):
Scott Baker361c86c2015-07-06 14:38:02 -0700367 KIND = VCPE_KIND
Scott Baker39b0d892015-04-15 20:59:15 -0700368
Scott Baker9dec42e2016-03-10 20:12:15 -0800369 URL_FILTER_KIND_CHOICES = ( (None, "None"), ("safebrowsing", "Safe Browsing"), ("answerx", "AnswerX") )
Scott Baker73f8f2b2016-03-10 19:23:10 -0800370
Scott Bakera0886fb2015-07-15 18:08:06 -0700371 simple_attributes = ( ("bbs_api_hostname", None),
372 ("bbs_api_port", None),
Scott Baker3d2493b2015-07-15 17:42:43 -0700373 ("bbs_server", None),
Scott Baker4d3cc752016-02-18 06:43:02 -0800374 ("backend_network_label", "hpc_client"),
375 ("wan_container_gateway_ip", ""),
376 ("wan_container_gateway_mac", ""),
Scott Bakerda3122a2016-02-23 14:58:49 -0800377 ("wan_container_netbits", "24"),
Scott Baker6526f552016-03-04 11:29:02 -0800378 ("dns_servers", "8.8.8.8"),
Scott Baker73f8f2b2016-03-10 19:23:10 -0800379 ("url_filter_kind", None),
Scott Baker6526f552016-03-04 11:29:02 -0800380 ("node_label", None) )
Scott Baker7ba272e2015-07-13 14:30:25 -0700381
382 def __init__(self, *args, **kwargs):
Scott Baker4698b922016-02-11 12:07:10 -0800383 super(VSGService, self).__init__(*args, **kwargs)
Scott Baker7ba272e2015-07-13 14:30:25 -0700384
Scott Baker39b0d892015-04-15 20:59:15 -0700385 class Meta:
386 app_label = "cord"
Scott Baker060f7352016-02-11 16:56:34 -0800387 verbose_name = "vSG Service"
Scott Baker39b0d892015-04-15 20:59:15 -0700388 proxy = True
Scott Baker1b241612015-04-14 17:19:16 -0700389
Scott Baker5c8abf82015-05-20 20:45:11 -0700390 def allocate_bbs_account(self):
Scott Baker664bbe52016-02-11 11:08:42 -0800391 vcpes = VSGTenant.get_tenant_objects().all()
Scott Baker5c8abf82015-05-20 20:45:11 -0700392 bbs_accounts = [vcpe.bbs_account for vcpe in vcpes]
393
394 # There's a bit of a race here; some other user could be trying to
395 # allocate a bbs_account at the same time we are.
396
Scott Bakerf4f61ca2015-06-09 12:03:56 -0700397 for i in range(2,21):
Scott Baker5c8abf82015-05-20 20:45:11 -0700398 account_name = "bbs%02d@onlab.us" % i
399 if (account_name not in bbs_accounts):
400 return account_name
401
402 raise XOSConfigurationError("We've run out of available broadbandshield accounts. Delete some vcpe and try again.")
403
Scott Baker3d2493b2015-07-15 17:42:43 -0700404 @property
405 def bbs_slice(self):
406 bbs_slice_id=self.get_attribute("bbs_slice_id")
407 if not bbs_slice_id:
408 return None
409 bbs_slices=Slice.objects.filter(id=bbs_slice_id)
410 if not bbs_slices:
411 return None
412 return bbs_slices[0]
413
414 @bbs_slice.setter
415 def bbs_slice(self, value):
416 if value:
417 value = value.id
418 self.set_attribute("bbs_slice_id", value)
419
Scott Baker4698b922016-02-11 12:07:10 -0800420VSGService.setup_simple_attributes()
Scott Baker7ba272e2015-07-13 14:30:25 -0700421
Scott Baker87891952016-02-02 16:56:18 -0800422#class STagBlock(PlCoreBase):
423# instance = models.ForeignKey(Instance, related_name="s_tags")
424# s_tag = models.CharField(null=false, blank=false, unique=true, max_length=10)
425# #c_tags = models.TextField(null=true, blank=true)
426#
427# def __unicode__(self): return u'%s' % (self.s_tag)
Scott Baker7ba272e2015-07-13 14:30:25 -0700428
Scott Baker664bbe52016-02-11 11:08:42 -0800429class VSGTenant(TenantWithContainer):
Scott Baker1b241612015-04-14 17:19:16 -0700430 class Meta:
431 proxy = True
432
Scott Baker361c86c2015-07-06 14:38:02 -0700433 KIND = VCPE_KIND
Scott Baker39b0d892015-04-15 20:59:15 -0700434
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700435 sync_attributes = ("nat_ip", "nat_mac",
436 "lan_ip", "lan_mac",
Scott Baker27fab492016-02-13 14:38:43 -0800437 "wan_ip", "wan_mac",
438 "wan_container_ip", "wan_container_mac",
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700439 "private_ip", "private_mac",
440 "hpc_client_ip", "hpc_client_mac")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700441
Tony Mack3de59e32015-08-19 11:58:18 -0400442 default_attributes = {"instance_id": None,
Scott Bakerf7f7e572015-11-02 20:55:07 -0800443 "container_id": None,
Scott Baker5c8abf82015-05-20 20:45:11 -0700444 "users": [],
Scott Bakerd40a42d2015-06-09 12:22:29 -0700445 "bbs_account": None,
Scott Baker27fab492016-02-13 14:38:43 -0800446 "last_ansible_hash": None,
447 "wan_container_ip": None}
Scott Baker1b241612015-04-14 17:19:16 -0700448
Scott Baker697fb0b2015-04-20 09:16:17 -0700449 def __init__(self, *args, **kwargs):
Scott Baker664bbe52016-02-11 11:08:42 -0800450 super(VSGTenant, self).__init__(*args, **kwargs)
Scott Baker697fb0b2015-04-20 09:16:17 -0700451 self.cached_vbng=None
Scott Bakerb7a16e22016-04-13 09:12:45 -0700452 self.cached_vrouter=None
Scott Baker9c8a2c72015-05-05 17:49:46 -0700453
454 @property
Scott Baker697fb0b2015-04-20 09:16:17 -0700455 def vbng(self):
Scott Baker361c86c2015-07-06 14:38:02 -0700456 vbng = self.get_newest_subscribed_tenant(VBNGTenant)
457 if not vbng:
458 return None
459
460 # always return the same object when possible
461 if (self.cached_vbng) and (self.cached_vbng.id == vbng.id):
Scott Baker697fb0b2015-04-20 09:16:17 -0700462 return self.cached_vbng
Scott Baker361c86c2015-07-06 14:38:02 -0700463
Scott Baker9c8a2c72015-05-05 17:49:46 -0700464 vbng.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700465 self.cached_vbng = vbng
466 return vbng
467
468 @vbng.setter
469 def vbng(self, value):
Scott Baker361c86c2015-07-06 14:38:02 -0700470 raise XOSConfigurationError("vCPE.vBNG cannot be set this way -- create a new vBNG object and set it's subscriber_tenant instead")
Scott Baker1b241612015-04-14 17:19:16 -0700471
Scott Bakercd349182015-07-06 17:21:21 -0700472 @property
Scott Bakerb7a16e22016-04-13 09:12:45 -0700473 def vrouter(self):
474 vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
475 if not vrouter:
476 return None
477
478 # always return the same object when possible
479 if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
480 return self.cached_vrouter
481
482 vrouter.caller = self.creator
483 self.cached_vrouter = vrouter
484 return vrouter
485
486 @vrouter.setter
487 def vrouter(self, value):
488 raise XOSConfigurationError("vCPE.vRouter cannot be set this way -- create a new vRuter object and set its subscriber_tenant instead")
489
490 @property
Scott Bakercd349182015-07-06 17:21:21 -0700491 def volt(self):
492 if not self.subscriber_tenant:
493 return None
494 volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
495 if not volts:
496 return None
497 return volts[0]
498
Scott Bakerf08823d2015-07-06 16:50:30 -0700499 @property
500 def bbs_account(self):
501 return self.get_attribute("bbs_account", self.default_attributes["bbs_account"])
502
503 @bbs_account.setter
504 def bbs_account(self, value):
505 return self.set_attribute("bbs_account", value)
506
507 @property
508 def last_ansible_hash(self):
509 return self.get_attribute("last_ansible_hash", self.default_attributes["last_ansible_hash"])
510
511 @last_ansible_hash.setter
512 def last_ansible_hash(self, value):
513 return self.set_attribute("last_ansible_hash", value)
514
515 @property
516 def ssh_command(self):
Tony Mack3de59e32015-08-19 11:58:18 -0400517 if self.instance:
518 return self.instance.get_ssh_command()
Scott Bakerf08823d2015-07-06 16:50:30 -0700519 else:
Tony Mack3de59e32015-08-19 11:58:18 -0400520 return "no-instance"
Scott Bakerf08823d2015-07-06 16:50:30 -0700521
522 @ssh_command.setter
523 def ssh_command(self, value):
524 pass
525
Scott Baker706bf972015-05-20 08:19:25 -0700526 @property
527 def addresses(self):
Scott Bakerf7f7e572015-11-02 20:55:07 -0800528 if self.instance:
529 ports = self.instance.ports.all()
530 elif self.container:
531 ports = self.container.ports.all()
532 else:
Scott Baker706bf972015-05-20 08:19:25 -0700533 return {}
534
535 addresses = {}
Scott Bakerf7f7e572015-11-02 20:55:07 -0800536 for ns in ports:
Scott Baker706bf972015-05-20 08:19:25 -0700537 if "lan" in ns.network.name.lower():
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700538 addresses["lan"] = (ns.ip, ns.mac)
Scott Baker706bf972015-05-20 08:19:25 -0700539 elif "wan" in ns.network.name.lower():
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700540 addresses["wan"] = (ns.ip, ns.mac)
Scott Baker706bf972015-05-20 08:19:25 -0700541 elif "private" in ns.network.name.lower():
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700542 addresses["private"] = (ns.ip, ns.mac)
Scott Baker706bf972015-05-20 08:19:25 -0700543 elif "nat" in ns.network.name.lower():
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700544 addresses["nat"] = (ns.ip, ns.mac)
Scott Baker710ad052015-06-04 10:26:44 -0700545 elif "hpc_client" in ns.network.name.lower():
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700546 addresses["hpc_client"] = (ns.ip, ns.mac)
Scott Baker706bf972015-05-20 08:19:25 -0700547 return addresses
548
Scott Baker27fab492016-02-13 14:38:43 -0800549 # ------------------------------------------------------------------------
550 # The following IP addresses all come from the VM
551 # Note: They might not be useful for the VTN-vSG
552
Scott Bakera6a7e032015-05-20 08:25:29 -0700553 @property
554 def nat_ip(self):
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700555 return self.addresses.get("nat", (None,None) )[0]
556
557 @property
558 def nat_mac(self):
559 return self.addresses.get("nat", (None,None) )[1]
Scott Bakera6a7e032015-05-20 08:25:29 -0700560
561 @property
562 def lan_ip(self):
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700563 return self.addresses.get("lan", (None, None) )[0]
564
565 @property
566 def lan_mac(self):
567 return self.addresses.get("lan", (None, None) )[1]
Scott Bakera6a7e032015-05-20 08:25:29 -0700568
569 @property
570 def wan_ip(self):
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700571 return self.addresses.get("wan", (None, None) )[0]
Scott Bakera6a7e032015-05-20 08:25:29 -0700572
573 @property
Scott Baker3f4fe402015-06-05 12:08:34 -0700574 def wan_mac(self):
Andy Baviera75c1192015-09-09 18:06:30 -0400575 return self.addresses.get("wan", (None, None) )[1]
Scott Baker3f4fe402015-06-05 12:08:34 -0700576
Scott Baker27fab492016-02-13 14:38:43 -0800577 # end of VM IP address stubs
578 # ------------------------------------------------------------------------
579
580 @property
581 def wan_container_ip(self):
Scott Bakerc8ab0252016-04-13 15:00:13 -0700582 if self.vrouter:
583 return self.vrouter.public_ip
Scott Baker27fab492016-02-13 14:38:43 -0800584 else:
Scott Bakerc8ab0252016-04-13 15:00:13 -0700585 if (CORD_USE_VTN):
586 # Should this be an error?
587 return None
588 else:
589 # When not using VTN, wan_container_ip is the same as wan_ip.
590 # XXX Is this broken for multiple-containers-per-VM?
591 return self.wan_ip
Scott Baker27fab492016-02-13 14:38:43 -0800592
593 @wan_container_ip.setter
594 def wan_container_ip(self, value):
Scott Bakerc8ab0252016-04-13 15:00:13 -0700595 raise Exception("wan_container_ip is not settable")
Scott Baker27fab492016-02-13 14:38:43 -0800596
Scott Baker7aa5e992016-02-18 15:18:47 -0800597 def ip_to_mac(self, ip):
598 (a, b, c, d) = ip.split('.')
599 return "02:42:%02x:%02x:%02x:%02x" % (int(a), int(b), int(c), int(d))
600
Andy Bavier0fa3dd62015-10-29 14:01:47 -0400601 # Generate the MAC for the container interface connected to WAN
602 @property
603 def wan_container_mac(self):
Scott Bakerc8ab0252016-04-13 15:00:13 -0700604 if self.vrouter:
Scott Baker09766cb2016-04-14 18:01:33 -0700605 return self.vrouter.public_mac
Scott Bakerc8ab0252016-04-13 15:00:13 -0700606 else:
607 if (CORD_USE_VTN):
608 # Should this be an error?
609 return None
610 else:
611 return self.ip_to_mac(self.wan_container_ip)
Andy Bavier0fa3dd62015-10-29 14:01:47 -0400612
Scott Baker3f4fe402015-06-05 12:08:34 -0700613 @property
Scott Bakerde3ef832016-04-14 17:19:01 -0700614 def wan_vm_ip(self):
615 tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
616 if tags:
617 tenant = VRouterTenant.objects.get(id=tags[0].value)
618 return tenant.public_ip
619 else:
620 if CORD_USE_VTN:
621 raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
622 else:
623 return ""
624
625 @property
626 def wan_vm_mac(self):
627 tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
628 if tags:
629 tenant = VRouterTenant.objects.get(id=tags[0].value)
630 return tenant.public_mac
631 else:
632 if CORD_USE_VTN:
633 raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
634 else:
635 return ""
636
637 @property
Scott Bakera6a7e032015-05-20 08:25:29 -0700638 def private_ip(self):
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700639 return self.addresses.get("private", (None, None) )[0]
640
641 @property
642 def private_mac(self):
643 return self.addresses.get("private", (None, None) )[1]
Scott Bakera6a7e032015-05-20 08:25:29 -0700644
Scott Baker710ad052015-06-04 10:26:44 -0700645 @property
646 def hpc_client_ip(self):
Scott Bakerd35a4bc2015-09-09 10:57:16 -0700647 return self.addresses.get("hpc_client", (None, None) )[0]
648
649 @property
650 def hpc_client_mac(self):
651 return self.addresses.get("hpc_client", (None, None) )[1]
Scott Baker710ad052015-06-04 10:26:44 -0700652
Scott Baker7bbdd2f2015-06-09 12:30:30 -0700653 @property
654 def is_synced(self):
655 return (self.enacted is not None) and (self.enacted >= self.updated)
656
657 @is_synced.setter
658 def is_synced(self, value):
659 pass
660
Scott Baker697fb0b2015-04-20 09:16:17 -0700661 def manage_vbng(self):
662 # Each vCPE object owns exactly one vBNG object
663
664 if self.deleted:
665 return
666
667 if self.vbng is None:
668 vbngServices = VBNGService.get_service_objects().all()
669 if not vbngServices:
Scott Bakerd921e1c2015-04-20 14:24:29 -0700670 raise XOSConfigurationError("No VBNG Services available")
Scott Baker697fb0b2015-04-20 09:16:17 -0700671
672 vbng = VBNGTenant(provider_service = vbngServices[0],
673 subscriber_tenant = self)
Scott Baker9c8a2c72015-05-05 17:49:46 -0700674 vbng.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700675 vbng.save()
676
Scott Baker697fb0b2015-04-20 09:16:17 -0700677 def cleanup_vbng(self):
678 if self.vbng:
Scott Baker361c86c2015-07-06 14:38:02 -0700679 # print "XXX cleanup vnbg", self.vbng
Scott Baker697fb0b2015-04-20 09:16:17 -0700680 self.vbng.delete()
Scott Baker697fb0b2015-04-20 09:16:17 -0700681
Scott Bakerc8ab0252016-04-13 15:00:13 -0700682 def get_vrouter_service(self):
683 vrouterServices = VRouterService.get_service_objects().all()
684 if not vrouterServices:
685 raise XOSConfigurationError("No VROUTER Services available")
686 return vrouterServices[0]
687
Scott Bakerb7a16e22016-04-13 09:12:45 -0700688 def manage_vrouter(self):
689 # Each vCPE object owns exactly one vRouterTenant object
690
691 if self.deleted:
692 return
693
694 if self.vrouter is None:
Scott Bakerc8ab0252016-04-13 15:00:13 -0700695 vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_tenant = self)
Scott Bakerb7a16e22016-04-13 09:12:45 -0700696 vrouter.caller = self.creator
697 vrouter.save()
698
699 def cleanup_vrouter(self):
700 if self.vrouter:
701 # print "XXX cleanup vrouter", self.vrouter
702 self.vrouter.delete()
703
Scott Baker5e76f802015-06-24 12:54:24 -0700704 def cleanup_orphans(self):
Scott Baker361c86c2015-07-06 14:38:02 -0700705 # ensure vCPE only has one vBNG
706 cur_vbng = self.vbng
707 for vbng in list(self.get_subscribed_tenants(VBNGTenant)):
708 if (not cur_vbng) or (vbng.id != cur_vbng.id):
709 # print "XXX clean up orphaned vbng", vbng
710 vbng.delete()
Scott Baker5e76f802015-06-24 12:54:24 -0700711
Scott Bakerb7a16e22016-04-13 09:12:45 -0700712 # ensure vCPE only has one vRouter
713 cur_vrouter = self.vrouter
714 for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
715 if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
716 # print "XXX clean up orphaned vrouter", vrouter
717 vrouter.delete()
718
Tony Mack3de59e32015-08-19 11:58:18 -0400719 if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
720 instances=Instance.objects.filter(id=self.orig_instance_id)
721 if instances:
722 # print "XXX clean up orphaned instance", instances[0]
723 instances[0].delete()
Scott Baker5e76f802015-06-24 12:54:24 -0700724
Scott Baker87891952016-02-02 16:56:18 -0800725 def get_slice(self):
726 if not self.provider_service.slices.count():
Matteo Scandoloc916b5e2016-04-07 14:38:54 -0700727 print self, "dio porco"
Scott Baker87891952016-02-02 16:56:18 -0800728 raise XOSConfigurationError("The service has no slices")
729 slice = self.provider_service.slices.all()[0]
730 return slice
731
Scott Baker6526f552016-03-04 11:29:02 -0800732 def get_vsg_service(self):
733 return VSGService.get_service_objects().get(id=self.provider_service.id)
734
Scott Baker87891952016-02-02 16:56:18 -0800735 def find_instance_for_s_tag(self, s_tag):
736 #s_tags = STagBlock.objects.find(s_s_tag)
737 #if s_tags:
738 # return s_tags[0].instance
739
740 tags = Tag.objects.filter(name="s_tag", value=s_tag)
741 if tags:
742 return tags[0].content_object
743
744 return None
745
746 def find_or_make_instance_for_s_tag(self, s_tag):
747 instance = self.find_instance_for_s_tag(self.volt.s_tag)
748 if instance:
749 return instance
750
751 flavors = Flavor.objects.filter(name="m1.small")
752 if not flavors:
753 raise XOSConfigurationError("No m1.small flavor")
754
755 slice = self.provider_service.slices.all()[0]
756
757 if slice.default_isolation == "container_vm":
758 (node, parent) = ContainerVmScheduler(slice).pick()
759 else:
Scott Baker6526f552016-03-04 11:29:02 -0800760 (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_vsg_service().node_label).pick()
Scott Baker87891952016-02-02 16:56:18 -0800761
762 instance = Instance(slice = slice,
763 node = node,
764 image = self.image,
765 creator = self.creator,
766 deployment = node.site_deployment.deployment,
767 flavor = flavors[0],
768 isolation = slice.default_isolation,
769 parent = parent)
Scott Bakerda5e8872016-02-12 16:17:04 -0800770
Scott Baker87891952016-02-02 16:56:18 -0800771 self.save_instance(instance)
772
773 return instance
774
775 def manage_container(self):
776 from core.models import Instance, Flavor
777
778 if self.deleted:
779 return
780
781 # For container or container_vm isolation, use what TenantWithCotnainer
782 # provides us
783 slice = self.get_slice()
784 if slice.default_isolation in ["container_vm", "container"]:
Scott Baker664bbe52016-02-11 11:08:42 -0800785 super(VSGTenant,self).manage_container()
Scott Baker87891952016-02-02 16:56:18 -0800786 return
787
788 if not self.volt:
789 raise XOSConfigurationError("This vCPE container has no volt")
790
Scott Baker4d3cc752016-02-18 06:43:02 -0800791 if self.instance:
792 # We're good.
793 return
794
Scott Baker87891952016-02-02 16:56:18 -0800795 instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
796 self.instance = instance
797 super(TenantWithContainer, self).save()
798
799 def cleanup_container(self):
800 if self.get_slice().default_isolation in ["container_vm", "container"]:
Scott Baker664bbe52016-02-11 11:08:42 -0800801 super(VSGTenant,self).cleanup_container()
Scott Baker87891952016-02-02 16:56:18 -0800802
803 # To-do: cleanup unused instances
804 pass
805
Scott Baker5c8abf82015-05-20 20:45:11 -0700806 def manage_bbs_account(self):
807 if self.deleted:
808 return
809
Scott Bakerdb66fd32015-07-07 17:59:44 -0700810 if self.volt and self.volt.subscriber and self.volt.subscriber.url_filter_enable:
Scott Bakere2570112015-05-20 20:57:28 -0700811 if not self.bbs_account:
Scott Baker4698b922016-02-11 12:07:10 -0800812 # make sure we use the proxied VSGService object, not the generic Service object
813 vcpe_service = VSGService.objects.get(id=self.provider_service.id)
Scott Baker7c7b6312015-07-07 12:15:03 -0700814 self.bbs_account = vcpe_service.allocate_bbs_account()
Scott Baker664bbe52016-02-11 11:08:42 -0800815 super(VSGTenant, self).save()
Scott Bakere2570112015-05-20 20:57:28 -0700816 else:
817 if self.bbs_account:
818 self.bbs_account = None
Scott Baker664bbe52016-02-11 11:08:42 -0800819 super(VSGTenant, self).save()
Scott Baker5c8abf82015-05-20 20:45:11 -0700820
Scott Baker0a17ccc2015-11-16 22:53:49 -0800821 def find_or_make_port(self, instance, network, **kwargs):
822 port = Port.objects.filter(instance=instance, network=network)
823 if port:
824 port = port[0]
825 else:
826 port = Port(instance=instance, network=network, **kwargs)
827 port.save()
828 return port
829
Scott Bakerda5e8872016-02-12 16:17:04 -0800830 def get_lan_network(self, instance):
Scott Bakerda5e8872016-02-12 16:17:04 -0800831 slice = self.provider_service.slices.all()[0]
Scott Baker27fab492016-02-13 14:38:43 -0800832 if CORD_USE_VTN:
833 # there should only be one network private network, and its template should not be the management template
834 lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
835 if len(lan_networks)>1:
836 raise XOSProgrammingError("The vSG slice should only have one non-management private network")
837 else:
838 lan_networks = [x for x in slice.networks.all() if "lan" in x.name]
Scott Bakerda5e8872016-02-12 16:17:04 -0800839 if not lan_networks:
840 raise XOSProgrammingError("No lan_network")
841 return lan_networks[0]
842
Scott Baker0a17ccc2015-11-16 22:53:49 -0800843 def save_instance(self, instance):
844 with transaction.atomic():
Andy Bavierde1707d2015-12-16 14:10:01 -0500845 instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
Scott Baker664bbe52016-02-11 11:08:42 -0800846 super(VSGTenant, self).save_instance(instance)
Scott Baker0a17ccc2015-11-16 22:53:49 -0800847
848 if instance.isolation in ["container", "container_vm"]:
Scott Bakerda5e8872016-02-12 16:17:04 -0800849 lan_network = self.get_lan_network(instance)
850 port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
Scott Baker0a17ccc2015-11-16 22:53:49 -0800851 port.set_parameter("c_tag", self.volt.c_tag)
852 port.set_parameter("s_tag", self.volt.s_tag)
853 port.set_parameter("device", "eth1")
Scott Bakerc7711632015-11-19 16:51:27 -0800854 port.set_parameter("bridge", "br-lan")
Scott Baker0a17ccc2015-11-16 22:53:49 -0800855
856 wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
857 if not wan_networks:
858 raise XOSProgrammingError("No wan_network")
859 port = self.find_or_make_port(instance, wan_networks[0])
860 port.set_parameter("next_hop", value="10.0.1.253") # FIX ME
861 port.set_parameter("device", "eth0")
862
Scott Bakerda5e8872016-02-12 16:17:04 -0800863 if instance.isolation in ["vm"]:
864 lan_network = self.get_lan_network(instance)
865 port = self.find_or_make_port(instance, lan_network)
866 port.set_parameter("c_tag", self.volt.c_tag)
867 port.set_parameter("s_tag", self.volt.s_tag)
868 port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
869 port.save()
870
Scott Baker87891952016-02-02 16:56:18 -0800871 # tag the instance with the s-tag, so we can easily find the
872 # instance later
873 if self.volt and self.volt.s_tag:
874 tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
875 if not tags:
876 tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
877 tag.save()
878
Scott Baker7aa5e992016-02-18 15:18:47 -0800879 # VTN-CORD needs a WAN address for the VM, so that the VM can
880 # be configured.
881 if CORD_USE_VTN:
Scott Bakerc8ab0252016-04-13 15:00:13 -0700882 tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
Scott Baker7aa5e992016-02-18 15:18:47 -0800883 if not tags:
Scott Bakerc8ab0252016-04-13 15:00:13 -0700884 vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service)
885 vrouter.set_attribute("tenant_for_instance_id", instance.id)
886 vrouter.save()
887 tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id)
Scott Baker7aa5e992016-02-18 15:18:47 -0800888 tag.save()
889
Scott Baker1b241612015-04-14 17:19:16 -0700890 def save(self, *args, **kwargs):
Scott Baker9c8a2c72015-05-05 17:49:46 -0700891 if not self.creator:
892 if not getattr(self, "caller", None):
893 # caller must be set when creating a vCPE since it creates a slice
Scott Baker664bbe52016-02-11 11:08:42 -0800894 raise XOSProgrammingError("VSGTenant's self.caller was not set")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700895 self.creator = self.caller
896 if not self.creator:
Scott Baker664bbe52016-02-11 11:08:42 -0800897 raise XOSProgrammingError("VSGTenant's self.creator was not set")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700898
Scott Baker664bbe52016-02-11 11:08:42 -0800899 super(VSGTenant, self).save(*args, **kwargs)
Scott Baker1027cd62015-07-08 19:01:56 -0700900 model_policy_vcpe(self.pk)
Scott Baker1b241612015-04-14 17:19:16 -0700901
902 def delete(self, *args, **kwargs):
Scott Baker697fb0b2015-04-20 09:16:17 -0700903 self.cleanup_vbng()
Scott Baker269c9aa2016-04-13 15:44:42 -0700904 self.cleanup_vrouter()
Scott Bakere458afd2015-09-09 16:36:06 -0700905 self.cleanup_container()
Scott Baker664bbe52016-02-11 11:08:42 -0800906 super(VSGTenant, self).delete(*args, **kwargs)
Scott Baker1b241612015-04-14 17:19:16 -0700907
Scott Baker1027cd62015-07-08 19:01:56 -0700908def model_policy_vcpe(pk):
909 # TODO: this should be made in to a real model_policy
910 with transaction.atomic():
Scott Baker664bbe52016-02-11 11:08:42 -0800911 vcpe = VSGTenant.objects.select_for_update().filter(pk=pk)
Scott Baker1027cd62015-07-08 19:01:56 -0700912 if not vcpe:
913 return
914 vcpe = vcpe[0]
Scott Bakere458afd2015-09-09 16:36:06 -0700915 vcpe.manage_container()
Scott Bakerb7a16e22016-04-13 09:12:45 -0700916 vcpe.manage_vrouter()
917 #vcpe.manage_vbng()
Scott Baker1027cd62015-07-08 19:01:56 -0700918 vcpe.manage_bbs_account()
919 vcpe.cleanup_orphans()
920
Scott Baker697fb0b2015-04-20 09:16:17 -0700921#----------------------------------------------------------------------------
922# vBNG
923#----------------------------------------------------------------------------
924
925class VBNGService(Service):
Scott Baker361c86c2015-07-06 14:38:02 -0700926 KIND = VBNG_KIND
Scott Baker697fb0b2015-04-20 09:16:17 -0700927
Scott Bakere337e512015-10-20 22:12:51 -0700928 simple_attributes = ( ("vbng_url", ""), ) # "http://10.0.3.136:8181/onos/virtualbng/"
Scott Baker3d7ec1a2015-07-21 18:24:21 -0700929
Scott Baker697fb0b2015-04-20 09:16:17 -0700930 class Meta:
931 app_label = "cord"
932 verbose_name = "vBNG Service"
933 proxy = True
934
Scott Baker3d7ec1a2015-07-21 18:24:21 -0700935VBNGService.setup_simple_attributes()
936
Scott Baker697fb0b2015-04-20 09:16:17 -0700937class VBNGTenant(Tenant):
938 class Meta:
939 proxy = True
940
Scott Baker361c86c2015-07-06 14:38:02 -0700941 KIND = VBNG_KIND
Scott Baker697fb0b2015-04-20 09:16:17 -0700942
Scott Baker99ff5512015-06-02 14:34:04 -0700943 default_attributes = {"routeable_subnet": "",
Scott Baker790613c2015-06-08 19:09:53 -0700944 "mapped_ip": "",
945 "mapped_mac": "",
946 "mapped_hostname": ""}
Scott Baker697fb0b2015-04-20 09:16:17 -0700947
948 @property
949 def routeable_subnet(self):
950 return self.get_attribute("routeable_subnet", self.default_attributes["routeable_subnet"])
951
952 @routeable_subnet.setter
953 def routeable_subnet(self, value):
954 self.set_attribute("routeable_subnet", value)
Scott Baker99ff5512015-06-02 14:34:04 -0700955
956 @property
957 def mapped_ip(self):
958 return self.get_attribute("mapped_ip", self.default_attributes["mapped_ip"])
959
960 @mapped_ip.setter
961 def mapped_ip(self, value):
962 self.set_attribute("mapped_ip", value)
Scott Baker790613c2015-06-08 19:09:53 -0700963
964 @property
965 def mapped_mac(self):
966 return self.get_attribute("mapped_mac", self.default_attributes["mapped_mac"])
967
968 @mapped_mac.setter
969 def mapped_mac(self, value):
970 self.set_attribute("mapped_mac", value)
971
972 @property
973 def mapped_hostname(self):
974 return self.get_attribute("mapped_hostname", self.default_attributes["mapped_hostname"])
975
976 @mapped_hostname.setter
977 def mapped_hostname(self, value):
978 self.set_attribute("mapped_hostname", value)