added deployment information back into session-deployed.xml

This commit is contained in:
Blake J. Harnden 2018-08-21 14:26:59 -07:00
parent 991abb1895
commit 4649563664
4 changed files with 165 additions and 7 deletions

View file

@ -38,7 +38,8 @@ from core.mobility import MobilityManager
from core.netns import nodes
from core.sdt import Sdt
from core.service import CoreServices
from core.xml import corexml
from core.xml import corexml, corexmldeployment
from core.xml.xmlsession import save_session_xml
class Session(object):
@ -381,7 +382,10 @@ class Session(object):
xml_file_version = self.options.get_config("xmlfilever")
if xml_file_version in ("1.0",):
xml_file_name = os.path.join(self.session_dir, "session-deployed.xml")
corexml.CoreXmlWriter(self).write(xml_file_name)
xml_writer = corexml.CoreXmlWriter(self)
corexmldeployment.CoreXmlDeployment(self, xml_writer.scenario)
xml_writer.write(xml_file_name)
save_session_xml(self, xml_file_name + ".old", xml_file_version)
def get_environment(self, state=True):
"""

View file

@ -387,13 +387,13 @@ class NetworkElement(NodeElement):
class CoreXmlWriter(object):
def __init__(self, session):
self.session = session
self.scenario = None
self.scenario = etree.Element("scenario")
self.networks = None
self.devices = None
self.write_session()
def write(self, file_name):
def write_session(self):
# generate xml content
self.scenario = etree.Element("scenario", name=file_name)
links = self.write_nodes()
self.write_links(links)
self.write_mobility_configs()
@ -405,6 +405,9 @@ class CoreXmlWriter(object):
self.write_session_metadata()
self.write_default_services()
def write(self, file_name):
self.scenario.set("name", file_name)
# write out generated xml
xml_tree = etree.ElementTree(self.scenario)
xml_tree.write(file_name, xml_declaration=True, pretty_print=True, encoding="UTF-8")

View file

@ -0,0 +1,151 @@
import os
import socket
from lxml import etree
from core import constants
from core import logger
from core.coreobj import PyCoreNode
from core.enumerations import NodeTypes
from core.misc import utils, nodeutils, ipaddress
def add_type(parent_element, name):
type_element = etree.SubElement(parent_element, "type")
type_element.text = name
def add_address(host_element, address_type, address, interface_name=None):
address_element = etree.SubElement(host_element, "address", type=address_type)
address_element.text = address
if interface_name is not None:
address_element.set("iface", interface_name)
def add_mapping(parent_element, maptype, mapref):
etree.SubElement(parent_element, "mapping", type=maptype, ref=mapref)
def add_emane_interface(host_element, netif, platform_name="p1", transport_name="t1"):
nem_id = netif.net.nemidmap[netif]
host_id = host_element.get("id")
# platform data
platform_id = "%s/%s" % (host_id, platform_name)
platform_element = etree.SubElement(host_element, "emanePlatform", id=platform_id, name=platform_name)
# transport data
transport_id = "%s/%s" % (host_id, transport_name)
transport_element = etree.SubElement(host_element, "transport", id=transport_id, name=transport_name)
# nem data
nem_name = "nem%s" % nem_id
nem_element_id = "%s/%s" % (host_id, nem_name)
nem_element = etree.SubElement(platform_element, "nem", id=nem_element_id, name=nem_name)
nem_id_element = etree.SubElement(nem_element, "parameter", name="nemid")
nem_id_element.text = str(nem_id)
add_mapping(transport_element, "nem", nem_element_id)
def get_address_type(address):
addr, slash, prefixlen = address.partition("/")
if ipaddress.is_ipv4_address(addr):
address_type = "IPv4"
elif ipaddress.is_ipv6_address(addr):
address_type = "IPv6"
else:
raise NotImplementedError
return address_type
def get_ipv4_addresses(hostname):
if hostname == "localhost":
addresses = []
args = [constants.IP_BIN, "-o", "-f", "inet", "addr", "show"]
output = utils.check_cmd(args)
for line in output.split(os.linesep):
split = line.split()
if not split:
continue
interface_name = split[1]
address = split[3]
if not address.startswith("127."):
addresses.append((interface_name, address))
return addresses
else:
# TODO: handle other hosts
raise NotImplementedError
class CoreXmlDeployment(object):
def __init__(self, session, scenario):
self.session = session
self.scenario = scenario
self.root = etree.SubElement(scenario, "container", id="TestBed", name="TestBed")
self.add_deployment()
def find_device(self, name):
device = self.scenario.find("devices/device[@name='%s']" % name)
logger.info("specific found scenario device: %s", device)
return device
def find_interface(self, device, name):
interface = self.scenario.find("devices/device[@name='%s']/interfaces/interface[@name='%s']" % (
device.name, name))
logger.info("specific found scenario interface: %s", interface)
return interface
def add_deployment(self):
physical_host = self.add_physical_host(socket.gethostname())
# TODO: handle other servers
# servers = self.session.broker.getservernames()
# servers.remove("localhost")
for node in self.session.objects.itervalues():
if isinstance(node, PyCoreNode):
self.add_virtual_host(physical_host, node)
def add_physical_host(self, name):
# add host
host_id = "%s/%s" % (self.root.get("id"), name)
host_element = etree.SubElement(self.root, "testHost", id=host_id, name=name)
# add type element
add_type(host_element, "physical")
# add ipv4 addresses
for interface_name, address in get_ipv4_addresses("localhost"):
add_address(host_element, "IPv4", address, interface_name)
return host_element
def add_virtual_host(self, physical_host, node):
assert isinstance(node, PyCoreNode)
# create virtual host element
host_id = "%s/%s" % (physical_host.get("id"), node.name)
host_element = etree.SubElement(physical_host, "testHost", id=host_id, name=node.name)
# TODO: need to inject mapping into device element?
self.find_device(node.name)
# device = self.find_device(self.root.base_element, obj.name)
# if device is None:
# logger.warn("corresponding XML device not found for %s", obj.name)
# return
# add_mapping(device, "testHost", host_id)
# add host type
add_type(host_element, "virtual")
for netif in node.netifs():
for address in netif.addrlist:
address_type = get_address_type(address)
add_address(host_element, address_type, address, netif.name)
if nodeutils.is_node(netif.net, NodeTypes.EMANE):
add_emane_interface(host_element, netif)
# TODO: need to inject mapping in interface?
# interface = self.find_interface(device, netif.name)
# add_mapping(interface, "nem", nem.getAttribute("id"))

View file

@ -7,7 +7,6 @@ import os.path
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.xml import corexml
from core.xml.xmlparser import core_document_parser
from core.xml.xmlwriter import core_document_writer
@ -33,4 +32,5 @@ def save_session_xml(session, filename, version):
"""
Export a session to the EmulationScript XML format.
"""
corexml.CoreXmlWriter(session).write(filename)
doc = core_document_writer(session, version)
doc.writexml(filename)