| # This library can be used in two different contexts: |
| # 1) From the VTN synchronizer |
| # 2) From the handcrafted VTN API endpoint |
| # |
| # If (1) then the modelaccessor module can provide us with models from the API |
| # or django as appropriate. If (2) then we must use django, until we can |
| # reconcile what to do about handcrafted API endpoints |
| |
| import __main__ as main_program |
| |
| if "synchronizer" in main_program.__file__: |
| from synchronizers.new_base.modelaccessor import * |
| in_synchronizer = True |
| else: |
| from core.models import * |
| in_synchronizer = False |
| |
| VTN_SERVCOMP_KINDS=["PRIVATE","VSG"] |
| |
| class VTNNetwork(object): |
| def __init__(self, xos_network=None): |
| self.xos_network = xos_network |
| |
| def get_controller_network(self): |
| for cn in self.xos_network.controllernetworks.all(): |
| # TODO: find the right one |
| return cn |
| return None |
| |
| def get_cn_field(self, fieldname): |
| cn=self.get_controller_network() |
| if not cn: |
| return None |
| return getattr(cn, fieldname) |
| |
| @property |
| def id(self): |
| return self.get_cn_field("net_id") |
| |
| @property |
| def name(self): |
| return self.xos_network.name |
| |
| @property |
| def subnet(self): |
| return self.get_cn_field("subnet") |
| |
| @property |
| def gateway(self): |
| return self.get_cn_field("gateway") |
| |
| @property |
| def segmentation_id(self): |
| return self.get_cn_field("segmentation_id") |
| |
| @property |
| def type(self): |
| return self.xos_network.template.vtn_kind |
| |
| @property |
| def providerNetworks(self): |
| slice = self.xos_network.owner |
| service = slice.service |
| if not service: |
| return [] |
| |
| nets=[] |
| for tenant in service.subscribed_tenants.all(): |
| if tenant.provider_service: |
| bidirectional = tenant.connect_method!="private-unidirectional" |
| for net in tenant.provider_service.get_composable_networks(): |
| if not net.controllernetworks.exists(): |
| continue |
| |
| cn = net.controllernetworks.all()[0] |
| |
| if not cn.net_id: |
| continue |
| |
| nets.append({"id": cn.net_id, |
| "name": net.name, |
| "bidirectional": bidirectional}) |
| return nets |
| |
| @property |
| def subscriberNetworks(self): |
| slice = self.xos_network.owner |
| service = slice.service |
| if not service: |
| return [] |
| |
| nets=[] |
| for tenant in service.provided_tenants.all(): |
| if tenant.subscriber_service: |
| bidirectional = tenant.connect_method!="private-unidirectional" |
| for net in tenant.subscriber_service.get_composable_networks(): |
| if not net.controllernetworks.exists(): |
| continue |
| |
| cn = net.controllernetworks.all()[0] |
| |
| if not cn.net_id: |
| continue |
| |
| nets.append({"id": cn.net_id, |
| "name": net.name, |
| "bidirectional": bidirectional}) |
| return nets |
| |
| @property |
| def ownerSliceName(self): |
| if self.xos_network.owner: |
| return self.xos_network.owner.name |
| return None |
| |
| @property |
| def ownerServiceName(self): |
| if self.xos_network.owner and self.xos_network.owner.service: |
| return self.xos_network.owner.service.name |
| return None |
| |
| def to_dict(self): |
| return {"id": self.id, |
| "name": self.name, |
| "subnet": self.subnet, |
| "gateway": self.gateway, |
| "segmentation_id": self.segmentation_id, |
| "type": self.type, |
| "providerNetworks": self.providerNetworks, |
| "subscriberNetworks": self.subscriberNetworks, |
| "ownerSliceName": self.ownerSliceName, |
| "ownerServiceName": self.ownerServiceName} |
| |
| def __eq__(self, other): |
| return self.to_dict() == other.to_dict() |
| |
| class VTNPort(object): |
| def __init__(self, xos_port=None): |
| self.xos_port = xos_port |
| |
| def get_controller_network(self): |
| for cn in self.xos_port.network.controllernetworks.all(): |
| # TODO: find the right one |
| return cn |
| return None |
| |
| def get_vsg_tenants(self): |
| # If the VSG service isn't onboarded, then return an empty list. |
| if (in_synchronizer): |
| if not model_accessor.has_model_class("VSGTenant"): |
| print "VSGTenant model does not exist. Returning no tenants" |
| return [] |
| VSGTenant = model_accessor.get_model_class("VSGTenant") # suppress undefined local variable error |
| else: |
| try: |
| from services.vsg.models import VSGTenant |
| except ImportError: |
| # TODO: Set up logging for this library... |
| print "Failed to import VSG, returning no tenants" |
| return [] |
| |
| vsg_tenants=[] |
| for tenant in VSGTenant.objects.all(): |
| if tenant.instance.id == self.xos_port.instance.id: |
| vsg_tenants.append(tenant) |
| return vsg_tenants |
| |
| @property |
| def vlan_id(self): |
| if not self.xos_port.instance: |
| return None |
| |
| # Only some kinds of networks can have s-tags associated with them. |
| # Currently, only VSG access networks qualify. |
| if not self.xos_port.network.template.vtn_kind in ["VSG",]: |
| return None |
| |
| if (in_synchronizer): |
| tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(self.xos_port.instance), |
| object_id=self.xos_port.instance.id, |
| name="s_tag") |
| else: |
| tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag") |
| |
| if not tags: |
| return None |
| |
| return tags[0].value |
| |
| @property |
| def floating_address_pairs(self): |
| # Floating_address_pairs is the set of WAN addresses that should be |
| # applied to this port. |
| |
| address_pairs = [] |
| |
| # only look apply the VSG addresses if the Network is of the VSG vtn_kind |
| if self.xos_port.network.template.vtn_kind in ["VSG", ]: |
| for vsg in self.get_vsg_tenants(): |
| if vsg.wan_container_ip and vsg.wan_container_mac: |
| address_pairs.append({"ip_address": vsg.wan_container_ip, |
| "mac_address": vsg.wan_container_mac}) |
| |
| if vsg.wan_vm_ip and vsg.wan_vm_mac: |
| address_pairs.append({"ip_address": vsg.wan_vm_ip, |
| "mac_address": vsg.wan_vm_mac}) |
| |
| return address_pairs |
| |
| @property |
| def id(self): |
| return self.xos_port.port_id |
| |
| @property |
| def name(self): |
| return "port-%s" % self.xos_port.id |
| |
| @property |
| def network_id(self): |
| cn = self.get_controller_network() |
| if not cn: |
| return None |
| return cn.net_id |
| |
| @property |
| def network_name(self): |
| return self.xos_port.network.name |
| |
| @property |
| def mac_address(self): |
| return self.xos_port.mac |
| |
| @property |
| def ip_address(self): |
| return self.xos_port.ip |
| |
| def to_dict(self): |
| return {"id": self.id, |
| "name": self.name, |
| "network_id": self.network_id, |
| "mac_address": self.mac_address, |
| "ip_address": self.ip_address, |
| "floating_address_pairs": self.floating_address_pairs, |
| "vlan_id": self.vlan_id} |
| |
| def __eq__(self, other): |
| return self.to_dict() == other.to_dict() |
| |