Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 1 | from core.models import * |
| 2 | from services.vtn.models import VTNService |
| 3 | |
| 4 | VTN_SERVCOMP_KINDS=["PRIVATE","VSG"] |
| 5 | |
| 6 | class VTNNetwork(object): |
| 7 | def __init__(self, xos_network=None): |
| 8 | self.xos_network = xos_network |
| 9 | |
| 10 | def get_controller_network(self): |
| 11 | for cn in self.xos_network.controllernetworks.all(): |
| 12 | # TODO: find the right one |
| 13 | return cn |
| 14 | return None |
| 15 | |
| 16 | def get_cn_field(self, fieldname): |
| 17 | cn=self.get_controller_network() |
| 18 | if not cn: |
| 19 | return None |
| 20 | return getattr(cn, fieldname) |
| 21 | |
| 22 | @property |
| 23 | def id(self): |
| 24 | return self.get_cn_field("net_id") |
| 25 | |
| 26 | @property |
| 27 | def name(self): |
| 28 | return self.xos_network.name |
| 29 | |
| 30 | @property |
| 31 | def subnet(self): |
| 32 | return self.get_cn_field("subnet") |
| 33 | |
| 34 | @property |
| 35 | def gateway(self): |
| 36 | return self.get_cn_field("gateway") |
| 37 | |
| 38 | @property |
| 39 | def segmentation_id(self): |
| 40 | return self.get_cn_field("segmentation_id") |
| 41 | |
| 42 | @property |
| 43 | def type(self): |
| 44 | return self.xos_network.template.vtn_kind |
| 45 | |
| 46 | @property |
| 47 | def providerNetworks(self): |
| 48 | slice = self.xos_network.owner |
| 49 | service = slice.service |
| 50 | if not service: |
| 51 | return [] |
| 52 | |
| 53 | nets=[] |
| 54 | for tenant in service.subscribed_tenants.all(): |
| 55 | if tenant.provider_service: |
| 56 | bidirectional = tenant.connect_method!="private-unidirectional" |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 57 | for net in tenant.provider_service.get_composable_networks(): |
| 58 | if not net.controllernetworks.exists(): |
| 59 | continue |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 60 | |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 61 | cn = net.controllernetworks.all()[0] |
Scott Baker | 43da8a1 | 2017-01-18 08:28:49 -0800 | [diff] [blame] | 62 | |
| 63 | if not cn.net_id: |
| 64 | continue |
| 65 | |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 66 | nets.append({"id": cn.net_id, |
| 67 | "name": net.name, |
| 68 | "bidirectional": bidirectional}) |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 69 | return nets |
| 70 | |
| 71 | @property |
| 72 | def subscriberNetworks(self): |
| 73 | slice = self.xos_network.owner |
| 74 | service = slice.service |
| 75 | if not service: |
| 76 | return [] |
| 77 | |
| 78 | nets=[] |
| 79 | for tenant in service.provided_tenants.all(): |
| 80 | if tenant.subscriber_service: |
| 81 | bidirectional = tenant.connect_method!="private-unidirectional" |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 82 | for net in tenant.subscriber_service.get_composable_networks(): |
| 83 | if not net.controllernetworks.exists(): |
| 84 | continue |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 85 | |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 86 | cn = net.controllernetworks.all()[0] |
Scott Baker | 43da8a1 | 2017-01-18 08:28:49 -0800 | [diff] [blame] | 87 | |
| 88 | if not cn.net_id: |
| 89 | continue |
| 90 | |
Srikanth Vavilapalli | 9c1c66f | 2016-12-03 23:52:16 +0000 | [diff] [blame] | 91 | nets.append({"id": cn.net_id, |
| 92 | "name": net.name, |
| 93 | "bidirectional": bidirectional}) |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 94 | return nets |
| 95 | |
| 96 | @property |
| 97 | def ownerSliceName(self): |
| 98 | if self.xos_network.owner: |
| 99 | return self.xos_network.owner.name |
| 100 | return None |
| 101 | |
| 102 | @property |
| 103 | def ownerServiceName(self): |
| 104 | if self.xos_network.owner and self.xos_network.owner.service: |
| 105 | return self.xos_network.owner.service.name |
| 106 | return None |
| 107 | |
Scott Baker | b3a80de | 2016-09-06 16:51:27 -0700 | [diff] [blame] | 108 | def to_dict(self): |
| 109 | return {"id": self.id, |
| 110 | "name": self.name, |
| 111 | "subnet": self.subnet, |
| 112 | "gateway": self.gateway, |
| 113 | "segmentation_id": self.segmentation_id, |
| 114 | "type": self.type, |
| 115 | "providerNetworks": self.providerNetworks, |
| 116 | "subscriberNetworks": self.subscriberNetworks, |
| 117 | "ownerSliceName": self.ownerSliceName, |
| 118 | "ownerServiceName": self.ownerServiceName} |
| 119 | |
| 120 | def __eq__(self, other): |
| 121 | return self.to_dict() == other.to_dict() |
| 122 | |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 123 | class VTNPort(object): |
Scott Baker | b8bd7fc | 2017-01-24 17:09:13 -0800 | [diff] [blame] | 124 | def __init__(self, xos_port=None): |
| 125 | self.xos_port = xos_port |
| 126 | |
| 127 | def get_controller_network(self): |
| 128 | for cn in self.xos_port.network.controllernetworks.all(): |
| 129 | # TODO: find the right one |
| 130 | return cn |
| 131 | return None |
| 132 | |
| 133 | def get_vsg_tenants(self): |
Scott Baker | 3af3448 | 2017-02-21 08:48:23 -0800 | [diff] [blame] | 134 | # If the VSG service isn't onboarded, then return an empty list. |
| 135 | try: |
| 136 | from services.vsg.models import VSGTenant |
| 137 | vsg_tenants=[] |
| 138 | for tenant in VSGTenant.get_tenant_objects().all(): |
| 139 | if tenant.instance == self.xos_port.instance: |
| 140 | vsg_tenants.append(tenant) |
| 141 | return vsg_tenants |
| 142 | except ImportError: |
| 143 | # TODO: Set up logging for this library... |
| 144 | print "Failed to import VSG, returning no tenants" |
| 145 | return [] |
Scott Baker | b8bd7fc | 2017-01-24 17:09:13 -0800 | [diff] [blame] | 146 | |
| 147 | @property |
| 148 | def vlan_id(self): |
| 149 | if not self.xos_port.instance: |
| 150 | return None |
| 151 | # Only some kinds of networks can have s-tags associated with them. |
| 152 | # Currently, only VSG access networks qualify. |
| 153 | if not self.xos_port.network.template.vtn_kind in ["VSG",]: |
| 154 | return None |
| 155 | tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag") |
| 156 | if not tags: |
| 157 | return None |
| 158 | return tags[0].value |
| 159 | |
| 160 | @property |
| 161 | def floating_address_pairs(self): |
| 162 | # Floating_address_pairs is the set of WAN addresses that should be |
| 163 | # applied to this port. |
| 164 | |
| 165 | address_pairs = [] |
| 166 | |
| 167 | # only look apply the VSG addresses if the Network is of the VSG vtn_kind |
| 168 | if self.xos_port.network.template.vtn_kind in ["VSG", ]: |
| 169 | for vsg in self.get_vsg_tenants(): |
| 170 | if vsg.wan_container_ip and vsg.wan_container_mac: |
| 171 | address_pairs.append({"ip_address": vsg.wan_container_ip, |
| 172 | "mac_address": vsg.wan_container_mac}) |
| 173 | |
| 174 | if vsg.wan_vm_ip and vsg.wan_vm_mac: |
| 175 | address_pairs.append({"ip_address": vsg.wan_vm_ip, |
| 176 | "mac_address": vsg.wan_vm_mac}) |
| 177 | |
| 178 | return address_pairs |
| 179 | |
| 180 | @property |
| 181 | def id(self): |
| 182 | return self.xos_port.port_id |
| 183 | |
| 184 | @property |
| 185 | def name(self): |
| 186 | return "port-%s" % self.xos_port.id |
| 187 | |
| 188 | @property |
| 189 | def network_id(self): |
| 190 | cn = self.get_controller_network() |
| 191 | if not cn: |
| 192 | return None |
| 193 | return cn.net_id |
| 194 | |
| 195 | @property |
| 196 | def network_name(self): |
| 197 | return self.xos_port.network.name |
| 198 | |
| 199 | @property |
| 200 | def mac_address(self): |
| 201 | return self.xos_port.mac |
| 202 | |
| 203 | @property |
| 204 | def ip_address(self): |
Scott Baker | 2342903 | 2016-09-06 12:02:39 -0700 | [diff] [blame] | 205 | return self.xos_port.ip |
| 206 | |
Scott Baker | b3a80de | 2016-09-06 16:51:27 -0700 | [diff] [blame] | 207 | def to_dict(self): |
| 208 | return {"id": self.id, |
| 209 | "name": self.name, |
| 210 | "network_id": self.network_id, |
| 211 | "mac_address": self.mac_address, |
| 212 | "ip_address": self.ip_address, |
| 213 | "floating_address_pairs": self.floating_address_pairs, |
| 214 | "vlan_id": self.vlan_id} |
| 215 | |
| 216 | def __eq__(self, other): |
| 217 | return self.to_dict() == other.to_dict() |
| 218 | |