blob: e1c15bb77f86879f71e3085f8d6d254cdd16e229 [file] [log] [blame]
Scott Baker08a4df32017-03-15 14:13:59 -07001# This library can be used in two different contexts:
2# 1) From the VTN synchronizer
3# 2) From the handcrafted VTN API endpoint
4#
5# If (1) then the modelaccessor module can provide us with models from the API
6# or django as appropriate. If (2) then we must use django, until we can
7# reconcile what to do about handcrafted API endpoints
8
9import __main__ as main_program
10
11if "synchronizer" in main_program.__file__:
12 from synchronizers.new_base.modelaccessor import *
13 in_synchronizer = True
14else:
15 from core.models import *
16 in_synchronizer = False
Scott Baker23429032016-09-06 12:02:39 -070017
18VTN_SERVCOMP_KINDS=["PRIVATE","VSG"]
19
20class VTNNetwork(object):
21 def __init__(self, xos_network=None):
22 self.xos_network = xos_network
23
24 def get_controller_network(self):
25 for cn in self.xos_network.controllernetworks.all():
26 # TODO: find the right one
27 return cn
28 return None
29
30 def get_cn_field(self, fieldname):
31 cn=self.get_controller_network()
32 if not cn:
33 return None
34 return getattr(cn, fieldname)
35
36 @property
37 def id(self):
38 return self.get_cn_field("net_id")
39
40 @property
41 def name(self):
42 return self.xos_network.name
43
44 @property
45 def subnet(self):
46 return self.get_cn_field("subnet")
47
48 @property
49 def gateway(self):
50 return self.get_cn_field("gateway")
51
52 @property
53 def segmentation_id(self):
54 return self.get_cn_field("segmentation_id")
55
56 @property
57 def type(self):
58 return self.xos_network.template.vtn_kind
59
60 @property
61 def providerNetworks(self):
62 slice = self.xos_network.owner
63 service = slice.service
64 if not service:
65 return []
66
67 nets=[]
68 for tenant in service.subscribed_tenants.all():
69 if tenant.provider_service:
70 bidirectional = tenant.connect_method!="private-unidirectional"
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000071 for net in tenant.provider_service.get_composable_networks():
72 if not net.controllernetworks.exists():
73 continue
Scott Baker23429032016-09-06 12:02:39 -070074
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000075 cn = net.controllernetworks.all()[0]
Scott Baker43da8a12017-01-18 08:28:49 -080076
77 if not cn.net_id:
78 continue
79
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000080 nets.append({"id": cn.net_id,
81 "name": net.name,
82 "bidirectional": bidirectional})
Scott Baker23429032016-09-06 12:02:39 -070083 return nets
84
85 @property
86 def subscriberNetworks(self):
87 slice = self.xos_network.owner
88 service = slice.service
89 if not service:
90 return []
91
92 nets=[]
93 for tenant in service.provided_tenants.all():
94 if tenant.subscriber_service:
95 bidirectional = tenant.connect_method!="private-unidirectional"
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000096 for net in tenant.subscriber_service.get_composable_networks():
97 if not net.controllernetworks.exists():
98 continue
Scott Baker23429032016-09-06 12:02:39 -070099
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +0000100 cn = net.controllernetworks.all()[0]
Scott Baker43da8a12017-01-18 08:28:49 -0800101
102 if not cn.net_id:
103 continue
104
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +0000105 nets.append({"id": cn.net_id,
106 "name": net.name,
107 "bidirectional": bidirectional})
Scott Baker23429032016-09-06 12:02:39 -0700108 return nets
109
110 @property
111 def ownerSliceName(self):
112 if self.xos_network.owner:
113 return self.xos_network.owner.name
114 return None
115
116 @property
117 def ownerServiceName(self):
118 if self.xos_network.owner and self.xos_network.owner.service:
119 return self.xos_network.owner.service.name
120 return None
121
Scott Bakerb3a80de2016-09-06 16:51:27 -0700122 def to_dict(self):
123 return {"id": self.id,
124 "name": self.name,
125 "subnet": self.subnet,
126 "gateway": self.gateway,
127 "segmentation_id": self.segmentation_id,
128 "type": self.type,
129 "providerNetworks": self.providerNetworks,
130 "subscriberNetworks": self.subscriberNetworks,
131 "ownerSliceName": self.ownerSliceName,
132 "ownerServiceName": self.ownerServiceName}
133
134 def __eq__(self, other):
135 return self.to_dict() == other.to_dict()
136
Scott Baker23429032016-09-06 12:02:39 -0700137class VTNPort(object):
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800138 def __init__(self, xos_port=None):
139 self.xos_port = xos_port
140
141 def get_controller_network(self):
142 for cn in self.xos_port.network.controllernetworks.all():
143 # TODO: find the right one
144 return cn
145 return None
146
147 def get_vsg_tenants(self):
Scott Baker3af34482017-02-21 08:48:23 -0800148 # If the VSG service isn't onboarded, then return an empty list.
Scott Baker08a4df32017-03-15 14:13:59 -0700149 if (in_synchronizer):
150 if not model_accessor.has_model_class("VSGTenant"):
151 print "VSGTenant model does not exist. Returning no tenants"
152 return []
153 VSGTenant = model_accessor.get_model_class("VSGTenant") # suppress undefined local variable error
154 else:
155 try:
156 from services.vsg.models import VSGTenant
157 except ImportError:
158 # TODO: Set up logging for this library...
159 print "Failed to import VSG, returning no tenants"
160 return []
161
162 vsg_tenants=[]
163 for tenant in VSGTenant.objects.all():
164 if tenant.instance.id == self.xos_port.instance.id:
165 vsg_tenants.append(tenant)
166 return vsg_tenants
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800167
168 @property
169 def vlan_id(self):
170 if not self.xos_port.instance:
171 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700172
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800173 # Only some kinds of networks can have s-tags associated with them.
174 # Currently, only VSG access networks qualify.
175 if not self.xos_port.network.template.vtn_kind in ["VSG",]:
176 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700177
178 if (in_synchronizer):
179 tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(self.xos_port.instance),
180 object_id=self.xos_port.instance.id,
181 name="s_tag")
182 else:
183 tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag")
184
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800185 if not tags:
186 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700187
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800188 return tags[0].value
189
190 @property
191 def floating_address_pairs(self):
192 # Floating_address_pairs is the set of WAN addresses that should be
193 # applied to this port.
194
195 address_pairs = []
196
197 # only look apply the VSG addresses if the Network is of the VSG vtn_kind
198 if self.xos_port.network.template.vtn_kind in ["VSG", ]:
199 for vsg in self.get_vsg_tenants():
200 if vsg.wan_container_ip and vsg.wan_container_mac:
201 address_pairs.append({"ip_address": vsg.wan_container_ip,
202 "mac_address": vsg.wan_container_mac})
203
204 if vsg.wan_vm_ip and vsg.wan_vm_mac:
205 address_pairs.append({"ip_address": vsg.wan_vm_ip,
206 "mac_address": vsg.wan_vm_mac})
207
208 return address_pairs
209
210 @property
211 def id(self):
212 return self.xos_port.port_id
213
214 @property
215 def name(self):
216 return "port-%s" % self.xos_port.id
217
218 @property
219 def network_id(self):
220 cn = self.get_controller_network()
221 if not cn:
222 return None
223 return cn.net_id
224
225 @property
226 def network_name(self):
227 return self.xos_port.network.name
228
229 @property
230 def mac_address(self):
231 return self.xos_port.mac
232
233 @property
234 def ip_address(self):
Scott Baker23429032016-09-06 12:02:39 -0700235 return self.xos_port.ip
236
Scott Bakerb3a80de2016-09-06 16:51:27 -0700237 def to_dict(self):
238 return {"id": self.id,
239 "name": self.name,
240 "network_id": self.network_id,
241 "mac_address": self.mac_address,
242 "ip_address": self.ip_address,
243 "floating_address_pairs": self.floating_address_pairs,
244 "vlan_id": self.vlan_id}
245
246 def __eq__(self, other):
247 return self.to_dict() == other.to_dict()
248