blob: e1c15bb77f86879f71e3085f8d6d254cdd16e229 [file] [log] [blame]
# 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()