#!/usr/bin/env python

# Copyright (2013) JDSU T&M Pte Ltd.  All rights reserved.

"""
This script calls the PI XML-API to get the card and port status of the PI hardware
and writes the result to a temporary file. The IWF reads the result and set the
IWF/traffic-hardware config parameter, which is read by the Job-manager and the UI.
"""

import os, sys, tempfile
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

import suds
import urllib2
import xml.etree.ElementTree
from xml.etree.ElementTree import Element

url = 'https://localhost:8443/instrument/externalAPI.cfc?wsdl'
user = "Administrator"
password = "<PASSWORD>"

class Card:
    def __init__(self, number, model, serial_number, mode):
        self.number = number
        self.model = model
        self.serial_number = number
        self.mode = mode
        self.ports = list()

    def add_port(self, port):
        self.ports.append(port)

class Port:
    def __init__(self, number):
        self.number = number

class PI_API(suds.client.Client):
    def __init__(self, url):
        """May throw an exception if url is invalid"""
        super(PI_API, self).__init__(url)

    def get_card_info(self, user, password):
        try:
            info = self.service.getAboutAppliance(user, password)
            #print info
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None
        root_element = xml.etree.ElementTree.XML(info)

        cards = dict()
        for card_element in root_element.getiterator("card"):
            for child in card_element.getiterator():
                if child.tag == "cardNum":
                    number = child.text
                elif child.tag == "model":
                    model = child.text
                elif child.tag == "sn":
                    serial_number = child.text
                elif child.tag == "mode":
                    mode = child.text
            cards[number] = Card(number, model, serial_number, mode)
        return cards

    def get_card_and_port_status(self, user, password):
        try:
            status = self.service.getCardAndPortStatus(user, password)
            #print status
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None
        return xml.etree.ElementTree.XML(status)

    def merge(self, cards, status):
        for port_status in status.getiterator("portStatus"):
            card_number = port_status.findtext("card")
            if card_number not in cards:
                continue

            port_number = port_status.findtext("port")
            port = Port(port_number)
            cards[card_number].add_port(port)

            for child in port_status.getiterator():
                if child.tag == "time":
                    port.status_time = child.text
                elif child.tag == "status":
                    port.status = child.text
                elif child.tag == "speed":
                    port.speed = child.text
                elif child.tag == "utilization":
                    port.utilization = child.text
                elif child.tag == "dBm":
                    port.dBm = child.text
                elif child.tag == "sfp":
                    port.sfp = child.text
                elif child.tag == "fcsErrors":
                    port.fcsErrors= child.text
                elif child.tag == "framesCount":
                    port.framesCount = child.text
                elif child.tag == "framesDropped":
                    port.framesDropped = child.text
        return cards

    def build_report(self, cards):
        root_element = Element("hardware")
        root_element.text = "\n    "
        vendor = Element("vendor")
        vendor.text = "BladeRocket"
        vendor.tail = "\n    "
        root_element.append(vendor)

        for card_number, card in cards.iteritems():
            card_element = Element("card")
            card_element.text = "\n" + (" " * 8)
            self.add_child(card_element, "number", card.number, 8)
            self.add_child(card_element, "model", card.model, 8)
            self.add_child(card_element, "serial-number", card.serial_number, 8)
            self.add_child(card_element, "mode", card.mode, 8)

            port_element = None
            for port in card.ports:
                port_element = Element("port")
                port_element.text = "\n" + (" " * 12)
                child = self.add_child(port_element, "number", port.number, 12)
                child = self.add_child(port_element, "time", port.status_time, 12)
                child = self.add_child(port_element, "status", port.status, 12)
                child = self.add_child(port_element, "speed", port.speed, 12)
                child = self.add_child(port_element, "utilization", port.utilization, 12)
                child = self.add_child(port_element, "dBm", port.dBm, 12)
                child = self.add_child(port_element, "sfp", port.sfp, 12)
                child = self.add_child(port_element, "fcsErrors", port.fcsErrors, 12)
                child = self.add_child(port_element, "framesCount", port.framesCount, 12)
                child = self.add_child(port_element, "framesDropped", port.framesDropped, 12)
                child.tail = "\n" + (" " * 8)   # correction

                port_element.tail = "\n" + (" " * 8)
                card_element.append(port_element)
            if port_element:
                port_element.tail = "\n" + (" " * 4)    # correction
            card_element.tail = "\n" + (" " * 4)
            root_element.append(card_element)
        card_element.tail = "\n"    # correction

        return xml.etree.ElementTree.tostring(root_element)

    def add_child(self, element, tag, text, indent):
        child = Element(tag)
        child.text = text
        child.tail = "\n" + (" " * indent)
        element.append(child)
        return child

    def get_report(self, user, password):
        report = self.get_napatech_card_report()
        if report:
            return report
        cards = self.get_card_info(user, password)
        if not cards:
            return None

        status = self.get_card_and_port_status(user, password)
        if status is None:
            return None

        cards = self.merge(cards, status)
        return self.build_report(cards)

    def get_napatech_card_report(self):
        """Return None if no napatech card is installed in the system."""
        try:
            status = self.service.getCardAndPortStatus(user, password)
            #print status
            if status.find("<card>Napatech-") == -1:
                return None
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None

        root_element = Element("hardware")
        root_element.text = "\n    "
        vendor = Element("vendor")
        vendor.text = "Napatech"
        vendor.tail = "\n    "
        root_element.append(vendor)

        card_element = Element("card")
        card_element.text = "\n" + (" " * 8)
        self.add_child(card_element, "number", "1", 8)

        tree = xml.etree.ElementTree.XML(status)
        port_element = None
        for port_status in tree.getiterator("portStatus"):
            card = port_status.findtext("card")
            if not card.startswith("Napatech-"):
                continue
            port_number = port_status.findtext("port")
            port = Port(port_number)
            for child in port_status.getiterator():
                if child.tag == "time":
                    port.status_time = child.text
                elif child.tag == "status":
                    port.status = child.text
                elif child.tag == "speed":
                    port.speed = child.text
                elif child.tag == "utilization":
                    port.utilization = child.text
                elif child.tag == "dBm":
                    port.dBm = child.text
                elif child.tag == "sfp":
                    port.sfp = child.text
                elif child.tag == "fcsErrors":
                    port.fcsErrors= child.text
                elif child.tag == "framesCount":
                    port.framesCount = child.text
                elif child.tag == "framesDropped":
                    port.framesDropped = child.text

            port_element = Element("port")
            port_element.text = "\n" + (" " * 12)
            child = self.add_child(port_element, "number", port.number, 12)
            child = self.add_child(port_element, "time", port.status_time, 12)
            child = self.add_child(port_element, "status", port.status, 12)
            child = self.add_child(port_element, "speed", port.speed, 12)
            child = self.add_child(port_element, "utilization", port.utilization, 12)
            child = self.add_child(port_element, "dBm", port.dBm, 12)
            child = self.add_child(port_element, "sfp", port.sfp, 12)
            child = self.add_child(port_element, "fcsErrors", port.fcsErrors, 12)
            child = self.add_child(port_element, "framesCount", port.framesCount, 12)
            child = self.add_child(port_element, "framesDropped", port.framesDropped, 12)
            child.tail = "\n" + (" " * 8)   # correction
            port_element.tail = "\n" + (" " * 8)
            card_element.append(port_element)

        if port_element:
            port_element.tail = "\n" + (" " * 4)    # correction
        card_element.tail = "\n" + (" " * 4)
        root_element.append(card_element)
        card_element.tail = "\n"    # correction

        return xml.etree.ElementTree.tostring(root_element)

if __name__ == "__main__":
    try:
        pi = PI_API(url)
        status = pi.get_report(user, password)
        if status:
            hwpath = os.path.join(tempfile.gettempdir(), "xt_hw_probe.txt")
            f = open(hwpath, "w")
            f.write(status)
            f.close()
    except urllib2.URLError as error:
        # Most likely, no PI hardware.  If hardware is present, could be because
        # the web server is done.
        print >> sys.stderr, error.args
    except IOError as error:
        print >> sys.stderr, error.args


#!/usr/bin/env python

# Copyright (2013) JDSU T&M Pte Ltd.  All rights reserved.

"""
This script calls the PI XML-API to get the card and port status of the PI hardware
and writes the result to a temporary file. The IWF reads the result and set the
IWF/traffic-hardware config parameter, which is read by the Job-manager and the UI.
"""

import os, sys, tempfile
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

import suds
import urllib2
import xml.etree.ElementTree
from xml.etree.ElementTree import Element

url = 'https://localhost:8443/instrument/externalAPI.cfc?wsdl'
user = "Administrator"
password = "<PASSWORD>"

class Card:
    def __init__(self, number, model, serial_number, mode):
        self.number = number
        self.model = model
        self.serial_number = number
        self.mode = mode
        self.ports = list()

    def add_port(self, port):
        self.ports.append(port)

class Port:
    def __init__(self, number):
        self.number = number

class PI_API(suds.client.Client):
    def __init__(self, url):
        """May throw an exception if url is invalid"""
        super(PI_API, self).__init__(url)

    def get_card_info(self, user, password):
        try:
            info = self.service.getAboutAppliance(user, password)
            #print info
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None
        root_element = xml.etree.ElementTree.XML(info)

        cards = dict()
        for card_element in root_element.getiterator("card"):
            for child in card_element.getiterator():
                if child.tag == "cardNum":
                    number = child.text
                elif child.tag == "model":
                    model = child.text
                elif child.tag == "sn":
                    serial_number = child.text
                elif child.tag == "mode":
                    mode = child.text
            cards[number] = Card(number, model, serial_number, mode)
        return cards

    def get_card_and_port_status(self, user, password):
        try:
            status = self.service.getCardAndPortStatus(user, password)
            #print status
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None
        return xml.etree.ElementTree.XML(status)

    def merge(self, cards, status):
        for port_status in status.getiterator("portStatus"):
            card_number = port_status.findtext("card")
            if card_number not in cards:
                continue

            port_number = port_status.findtext("port")
            port = Port(port_number)
            cards[card_number].add_port(port)

            for child in port_status.getiterator():
                if child.tag == "time":
                    port.status_time = child.text
                elif child.tag == "status":
                    port.status = child.text
                elif child.tag == "speed":
                    port.speed = child.text
                elif child.tag == "utilization":
                    port.utilization = child.text
                elif child.tag == "dBm":
                    port.dBm = child.text
                elif child.tag == "sfp":
                    port.sfp = child.text
                elif child.tag == "fcsErrors":
                    port.fcsErrors= child.text
                elif child.tag == "framesCount":
                    port.framesCount = child.text
                elif child.tag == "framesDropped":
                    port.framesDropped = child.text
        return cards

    def build_report(self, cards):
        root_element = Element("hardware")
        root_element.text = "\n    "
        vendor = Element("vendor")
        vendor.text = "BladeRocket"
        vendor.tail = "\n    "
        root_element.append(vendor)

        for card_number, card in cards.iteritems():
            card_element = Element("card")
            card_element.text = "\n" + (" " * 8)
            self.add_child(card_element, "number", card.number, 8)
            self.add_child(card_element, "model", card.model, 8)
            self.add_child(card_element, "serial-number", card.serial_number, 8)
            self.add_child(card_element, "mode", card.mode, 8)

            port_element = None
            for port in card.ports:
                port_element = Element("port")
                port_element.text = "\n" + (" " * 12)
                child = self.add_child(port_element, "number", port.number, 12)
                child = self.add_child(port_element, "time", port.status_time, 12)
                child = self.add_child(port_element, "status", port.status, 12)
                child = self.add_child(port_element, "speed", port.speed, 12)
                child = self.add_child(port_element, "utilization", port.utilization, 12)
                child = self.add_child(port_element, "dBm", port.dBm, 12)
                child = self.add_child(port_element, "sfp", port.sfp, 12)
                child = self.add_child(port_element, "fcsErrors", port.fcsErrors, 12)
                child = self.add_child(port_element, "framesCount", port.framesCount, 12)
                child = self.add_child(port_element, "framesDropped", port.framesDropped, 12)
                child.tail = "\n" + (" " * 8)   # correction

                port_element.tail = "\n" + (" " * 8)
                card_element.append(port_element)
            if port_element:
                port_element.tail = "\n" + (" " * 4)    # correction
            card_element.tail = "\n" + (" " * 4)
            root_element.append(card_element)
        card_element.tail = "\n"    # correction

        return xml.etree.ElementTree.tostring(root_element)

    def add_child(self, element, tag, text, indent):
        child = Element(tag)
        child.text = text
        child.tail = "\n" + (" " * indent)
        element.append(child)
        return child

    def get_report(self, user, password):
        report = self.get_napatech_card_report()
        if report:
            return report
        cards = self.get_card_info(user, password)
        if not cards:
            return None

        status = self.get_card_and_port_status(user, password)
        if status is None:
            return None

        cards = self.merge(cards, status)
        return self.build_report(cards)

    def get_napatech_card_report(self):
        """Return None if no napatech card is installed in the system."""
        try:
            status = self.service.getCardAndPortStatus(user, password)
            #print status
            if status.find("<card>Napatech-") == -1:
                return None
        except suds.WebFault as error:
            print >> sys.stderr, error.args
            return None

        root_element = Element("hardware")
        root_element.text = "\n    "
        vendor = Element("vendor")
        vendor.text = "Napatech"
        vendor.tail = "\n    "
        root_element.append(vendor)

        card_element = Element("card")
        card_element.text = "\n" + (" " * 8)
        self.add_child(card_element, "number", "1", 8)

        tree = xml.etree.ElementTree.XML(status)
        port_element = None
        for port_status in tree.getiterator("portStatus"):
            card = port_status.findtext("card")
            if not card.startswith("Napatech-"):
                continue
            port_number = port_status.findtext("port")
            port = Port(port_number)
            for child in port_status.getiterator():
                if child.tag == "time":
                    port.status_time = child.text
                elif child.tag == "status":
                    port.status = child.text
                elif child.tag == "speed":
                    port.speed = child.text
                elif child.tag == "utilization":
                    port.utilization = child.text
                elif child.tag == "dBm":
                    port.dBm = child.text
                elif child.tag == "sfp":
                    port.sfp = child.text
                elif child.tag == "fcsErrors":
                    port.fcsErrors= child.text
                elif child.tag == "framesCount":
                    port.framesCount = child.text
                elif child.tag == "framesDropped":
                    port.framesDropped = child.text

            port_element = Element("port")
            port_element.text = "\n" + (" " * 12)
            child = self.add_child(port_element, "number", port.number, 12)
            child = self.add_child(port_element, "time", port.status_time, 12)
            child = self.add_child(port_element, "status", port.status, 12)
            child = self.add_child(port_element, "speed", port.speed, 12)
            child = self.add_child(port_element, "utilization", port.utilization, 12)
            child = self.add_child(port_element, "dBm", port.dBm, 12)
            child = self.add_child(port_element, "sfp", port.sfp, 12)
            child = self.add_child(port_element, "fcsErrors", port.fcsErrors, 12)
            child = self.add_child(port_element, "framesCount", port.framesCount, 12)
            child = self.add_child(port_element, "framesDropped", port.framesDropped, 12)
            child.tail = "\n" + (" " * 8)   # correction
            port_element.tail = "\n" + (" " * 8)
            card_element.append(port_element)

        if port_element:
            port_element.tail = "\n" + (" " * 4)    # correction
        card_element.tail = "\n" + (" " * 4)
        root_element.append(card_element)
        card_element.tail = "\n"    # correction

        return xml.etree.ElementTree.tostring(root_element)

if __name__ == "__main__":
    try:
        pi = PI_API(url)
        status = pi.get_report(user, password)
        if status:
            hwpath = os.path.join(tempfile.gettempdir(), "xt_hw_probe.txt")
            f = open(hwpath, "w")
            f.write(status)
            f.close()
    except urllib2.URLError as error:
        # Most likely, no PI hardware.  If hardware is present, could be because
        # the web server is done.
        print >> sys.stderr, error.args
    except IOError as error:
        print >> sys.stderr, error.args


#!/usr/bin/env python # Copyright (2013) JDSU T&M Pte Ltd.  All rights reserved. This script calls the PI XML-API to get the card and port status of the PI hardware and writes the result to a temporary file. The IWF reads the result and set the IWF/traffic-hardware config parameter, which is read by the Job-manager and the UI. May throw an exception if url is invalid #print info #print status # correction # correction # correction Return None if no napatech card is installed in the system. #print status # correction # correction # correction # Most likely, no PI hardware.  If hardware is present, could be because # the web server is done.