blob: 82f5a0c00ec36d51722f882f59708c4d6bc0db84 [file] [log] [blame]
Matteo Scandolo0e7912c2017-08-08 13:05:24 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Scott Baker08a4df32017-03-15 14:13:59 -070017# This library can be used in two different contexts:
18# 1) From the VTN synchronizer
19# 2) From the handcrafted VTN API endpoint
20#
21# If (1) then the modelaccessor module can provide us with models from the API
22# or django as appropriate. If (2) then we must use django, until we can
23# reconcile what to do about handcrafted API endpoints
24
25import __main__ as main_program
26
27if "synchronizer" in main_program.__file__:
28 from synchronizers.new_base.modelaccessor import *
29 in_synchronizer = True
30else:
31 from core.models import *
32 in_synchronizer = False
Scott Baker23429032016-09-06 12:02:39 -070033
34VTN_SERVCOMP_KINDS=["PRIVATE","VSG"]
35
36class VTNNetwork(object):
37 def __init__(self, xos_network=None):
38 self.xos_network = xos_network
39
40 def get_controller_network(self):
41 for cn in self.xos_network.controllernetworks.all():
42 # TODO: find the right one
43 return cn
44 return None
45
46 def get_cn_field(self, fieldname):
47 cn=self.get_controller_network()
48 if not cn:
49 return None
50 return getattr(cn, fieldname)
51
52 @property
53 def id(self):
54 return self.get_cn_field("net_id")
55
56 @property
57 def name(self):
58 return self.xos_network.name
59
60 @property
61 def subnet(self):
62 return self.get_cn_field("subnet")
63
64 @property
65 def gateway(self):
66 return self.get_cn_field("gateway")
67
68 @property
69 def segmentation_id(self):
70 return self.get_cn_field("segmentation_id")
71
72 @property
73 def type(self):
74 return self.xos_network.template.vtn_kind
75
76 @property
77 def providerNetworks(self):
78 slice = self.xos_network.owner
79 service = slice.service
80 if not service:
81 return []
82
83 nets=[]
Scott Bakerd949b622017-07-18 12:10:35 -070084 for dep in service.subscribed_dependencies.all():
85 if dep.provider_service:
86 bidirectional = dep.connect_method!="private-unidirectional"
87 for net in dep.provider_service.get_composable_networks():
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000088 if not net.controllernetworks.exists():
89 continue
Scott Baker23429032016-09-06 12:02:39 -070090
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000091 cn = net.controllernetworks.all()[0]
Scott Baker43da8a12017-01-18 08:28:49 -080092
93 if not cn.net_id:
94 continue
95
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +000096 nets.append({"id": cn.net_id,
97 "name": net.name,
98 "bidirectional": bidirectional})
Scott Baker23429032016-09-06 12:02:39 -070099 return nets
100
101 @property
102 def subscriberNetworks(self):
103 slice = self.xos_network.owner
104 service = slice.service
105 if not service:
106 return []
107
108 nets=[]
Scott Bakerd949b622017-07-18 12:10:35 -0700109 for dep in service.provided_dependencies.all():
110 if dep.subscriber_service:
111 bidirectional = dep.connect_method!="private-unidirectional"
112 for net in dep.subscriber_service.get_composable_networks():
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +0000113 if not net.controllernetworks.exists():
114 continue
Scott Baker23429032016-09-06 12:02:39 -0700115
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +0000116 cn = net.controllernetworks.all()[0]
Scott Baker43da8a12017-01-18 08:28:49 -0800117
118 if not cn.net_id:
119 continue
120
Srikanth Vavilapalli9c1c66f2016-12-03 23:52:16 +0000121 nets.append({"id": cn.net_id,
122 "name": net.name,
123 "bidirectional": bidirectional})
Scott Baker23429032016-09-06 12:02:39 -0700124 return nets
125
126 @property
127 def ownerSliceName(self):
128 if self.xos_network.owner:
129 return self.xos_network.owner.name
130 return None
131
132 @property
133 def ownerServiceName(self):
134 if self.xos_network.owner and self.xos_network.owner.service:
135 return self.xos_network.owner.service.name
136 return None
137
Scott Bakerb3a80de2016-09-06 16:51:27 -0700138 def to_dict(self):
139 return {"id": self.id,
140 "name": self.name,
141 "subnet": self.subnet,
142 "gateway": self.gateway,
143 "segmentation_id": self.segmentation_id,
144 "type": self.type,
145 "providerNetworks": self.providerNetworks,
146 "subscriberNetworks": self.subscriberNetworks,
147 "ownerSliceName": self.ownerSliceName,
148 "ownerServiceName": self.ownerServiceName}
149
150 def __eq__(self, other):
151 return self.to_dict() == other.to_dict()
152
Scott Baker23429032016-09-06 12:02:39 -0700153class VTNPort(object):
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800154 def __init__(self, xos_port=None):
155 self.xos_port = xos_port
156
157 def get_controller_network(self):
158 for cn in self.xos_port.network.controllernetworks.all():
159 # TODO: find the right one
160 return cn
161 return None
162
163 def get_vsg_tenants(self):
Scott Baker3af34482017-02-21 08:48:23 -0800164 # If the VSG service isn't onboarded, then return an empty list.
Scott Baker08a4df32017-03-15 14:13:59 -0700165 if (in_synchronizer):
166 if not model_accessor.has_model_class("VSGTenant"):
167 print "VSGTenant model does not exist. Returning no tenants"
168 return []
169 VSGTenant = model_accessor.get_model_class("VSGTenant") # suppress undefined local variable error
170 else:
171 try:
172 from services.vsg.models import VSGTenant
173 except ImportError:
174 # TODO: Set up logging for this library...
175 print "Failed to import VSG, returning no tenants"
176 return []
177
178 vsg_tenants=[]
179 for tenant in VSGTenant.objects.all():
180 if tenant.instance.id == self.xos_port.instance.id:
181 vsg_tenants.append(tenant)
182 return vsg_tenants
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800183
184 @property
185 def vlan_id(self):
186 if not self.xos_port.instance:
187 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700188
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800189 # Only some kinds of networks can have s-tags associated with them.
190 # Currently, only VSG access networks qualify.
191 if not self.xos_port.network.template.vtn_kind in ["VSG",]:
192 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700193
194 if (in_synchronizer):
195 tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(self.xos_port.instance),
196 object_id=self.xos_port.instance.id,
197 name="s_tag")
198 else:
199 tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag")
200
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800201 if not tags:
202 return None
Scott Baker08a4df32017-03-15 14:13:59 -0700203
Scott Bakerb8bd7fc2017-01-24 17:09:13 -0800204 return tags[0].value
205
206 @property
207 def floating_address_pairs(self):
208 # Floating_address_pairs is the set of WAN addresses that should be
209 # applied to this port.
210
211 address_pairs = []
212
213 # only look apply the VSG addresses if the Network is of the VSG vtn_kind
214 if self.xos_port.network.template.vtn_kind in ["VSG", ]:
215 for vsg in self.get_vsg_tenants():
216 if vsg.wan_container_ip and vsg.wan_container_mac:
217 address_pairs.append({"ip_address": vsg.wan_container_ip,
218 "mac_address": vsg.wan_container_mac})
219
220 if vsg.wan_vm_ip and vsg.wan_vm_mac:
221 address_pairs.append({"ip_address": vsg.wan_vm_ip,
222 "mac_address": vsg.wan_vm_mac})
223
224 return address_pairs
225
226 @property
227 def id(self):
228 return self.xos_port.port_id
229
230 @property
231 def name(self):
232 return "port-%s" % self.xos_port.id
233
234 @property
235 def network_id(self):
236 cn = self.get_controller_network()
237 if not cn:
238 return None
239 return cn.net_id
240
241 @property
242 def network_name(self):
243 return self.xos_port.network.name
244
245 @property
246 def mac_address(self):
247 return self.xos_port.mac
248
249 @property
250 def ip_address(self):
Scott Baker23429032016-09-06 12:02:39 -0700251 return self.xos_port.ip
252
Scott Bakerb3a80de2016-09-06 16:51:27 -0700253 def to_dict(self):
254 return {"id": self.id,
255 "name": self.name,
256 "network_id": self.network_id,
257 "mac_address": self.mac_address,
258 "ip_address": self.ip_address,
259 "floating_address_pairs": self.floating_address_pairs,
260 "vlan_id": self.vlan_id}
261
262 def __eq__(self, other):
263 return self.to_dict() == other.to_dict()
264