Exemplo n.º 1
0
def reduce_switchport(task):
    from noc.lib.app.simplereport import Report, TableSection,\
        SectionRow, TableColumn
    from noc.lib.text import list_to_ranges
    # Prepare data
    data = []
    for mt in task.maptask_set.filter(status="C"):
        data += [SectionRow("%s (%s)" % (
        mt.managed_object.name, mt.managed_object.profile_name))]
        for r in mt.script_result:
            data += [[
                r["interface"],
                r.get("description", ""),
                r["status"],
                r.get("untagged", ""),
                list_to_ranges(r.get("tagged", [])),
                ", ".join(r.get("members", []))
            ]]
        # Prepare report
    r = Report()
    r.append_section(TableSection(name="",
                                  columns=["Interface", "Description",
                                           TableColumn("Status", format="bool"),
                                           "Untagged", "Tagged", "Members"],
                                  data=data))
    return r
Exemplo n.º 2
0
Arquivo: base.py Projeto: 0pt1on/noc
 def clean(self, value):
     if isinstance(value, six.string_types) and not value.strip():
         return ""
     vp = VLANIDParameter()
     try:
         return list_to_ranges([vp.clean(v) for v in ranges_to_list(value)])
     except SyntaxError:
         self.raise_error(value)
Exemplo n.º 3
0
 def clean(self, value):
     """
     >>> VLANIDMapParameter().clean("1,2,5-10")
     '1-2,5-10'
     >>> VLANIDMapParameter().clean("")
     ''
     """
     if isinstance(value, basestring) and not value.strip():
         return ""
     vp = VLANIDParameter()
     try:
         return list_to_ranges([vp.clean(v) for v in ranges_to_list(value)])
     except SyntaxError:
         self.raise_error(value)
Exemplo n.º 4
0
 def get_data(self, request, sel):
     """Get_data function."""
     data = []
     columns = [
         _("Managed Objects"),
         _("Switch availability status"),
         _("IP address"),
         _("Model"),
         _("Software"),
         _("Port name"),
         _("Port status"),
         _("Link status"),
         _("VLAN id")
     ]
     ip = InterfaceProfile.objects.get(name=sel.name)
     interf = Interface.objects.filter(profile=ip, type="physical")
     for i in interf:
         si = list(i.subinterface_set.filter(enabled_afi="BRIDGE"))
         if len(si) == 1:
             si = si[0]
         try:
             tagged = (list_to_ranges(si.tagged_vlans).replace(
                 ",", ", ")).strip()
             data += [[
                 i.managed_object.name, "Is available" if
                 i.managed_object.get_status() is True else "Not available",
                 i.managed_object.address,
                 str(i.managed_object.vendor) + " " +
                 str(i.managed_object.platform),
                 "\"" + str(i.managed_object.version) + "\"", i.name,
                 "UP" if i.admin_status is True else "Down",
                 "UP" if i.oper_status is True else "Down",
                 ("U: " + str(si.untagged_vlan)
                  if si.untagged_vlan is not None else "" + " T: " +
                  tagged if tagged != "" else "").strip()
             ]]
         except AttributeError:
             pass
     return self.from_dataset(title=self.title,
                              columns=columns,
                              data=data,
                              enumerate=True)
Exemplo n.º 5
0
    def execute(self,
                configs,
                protect_switchport=True,
                protect_type=True,
                debug=False):
        def is_access(c):
            return "untagged" in c and ("tagged" not in c or not c["tagged"])

        # Get existing switchports. interface -> config
        ports = dict(
            (p["interface"], p) for p in self.scripts.get_switchport())
        # Validate restrictions
        errors = []
        for c in configs:
            iface = c["interface"]
            if protect_switchport and iface not in ports:
                errors += ["Interface '%s' is not switchport" % iface]
            if protect_type and is_access(c) != is_access(ports[iface]):
                errors += ["Invalid port type for interface '%s'" % iface]
        if errors:
            return {"status": False, "message": ".\n".join(errors)}
        # Prepare scenario
        commands = []
        for c in configs:
            ic = []
            iface = c["interface"]
            p = ports[iface]
            # Check description
            if ("description" in c and c["description"]
                    and ("description" not in p
                         or c["description"] != p["description"])):
                ic += [" description %s" % c["description"]]
            # Check status
            if c["status"] and not p["status"]:
                ic += [" no shutdown"]
            elif p["status"] and not c["status"]:
                ic += [" shutdown"]
            # Check switchport
            if iface not in ports:
                ic += [" switchport"]
            if is_access(c):
                # Configuring access port
                if not is_access(p):
                    # trunk -> access
                    ic += [" switchport mode access"]
                    ic += [" no switchport trunk allowed vlan"]
                    #                    ic += [" switchport trunk allowed vlan remove all"]  # ???
                    ic += [" no switchport trunk native vlan"]
                # @todo: set vlan only when necessary
                ic += [" switchport access vlan %d" % c["untagged"]]
            else:
                # Configuring trunk port
                if is_access(p):
                    # access -> trunk
                    # ic += [" switchport trunk encapsulation dot1q"]
                    ic += [" switchport mode trunk"]
                    ic += [" no switchport access vlan"]
                if ("untagged" in c and
                    ("untagged" not in p or c["untagged"] != p["untagged"])
                        or is_access(p)):
                    # Add native vlan
                    ic += [" switchport trunk native vlan %d" % c["untagged"]]
                if "untagged" not in c and "untagged" in p:
                    # Remove native vlan
                    ic += [" no switchport trunk native vlan"]
                cv = list_to_ranges(c["tagged"])
                pv = list_to_ranges(p["tagged"])
                if cv != pv:
                    # Change untagged vlans
                    ic += [" switchport trunk allowed vlan add %s" % cv]
            # Configure edge-port
            ept = {
                True: "spanning-tree portfast",
                False: "spanning-tree portfast trunk"
            }
            if is_access(c) != is_access(p):
                # access <-> trunk. Remove old edgeport settings
                ic += [" no %s" % ept[not is_access(c)]]
            if c["edge_port"]:
                ic += [" %s" % ept[is_access(c)]]
            else:
                ic += [" no %s" % ept[is_access(c)]]
            #
            if ic:
                commands += ["interface %s" % iface] + ic + [" exit"]
        # Apply commands
        if not debug and commands:
            with self.configure():
                for c in commands:
                    self.cli(c)
            self.save_config()
        # Return result
        return {"status": True, "message": "Ok", "log": "\n".join(commands)}
Exemplo n.º 6
0
Arquivo: views.py Projeto: 0pt1on/noc
    def api_report(
        self,
        request,
        o_format,
        administrative_domain=None,
        selector=None,
        interface_profile=None,
        zero=None,
        def_profile=None,
        columns=None,
        enable_autowidth=False,
    ):
        def humanize_speed(speed):
            if not speed:
                return "-"
            for t, n in [(1000000, "G"), (1000, "M"), (1, "k")]:
                if speed >= t:
                    if speed // t * t == speed:
                        return "%d%s" % (speed // t, n)
                    else:
                        return "%.2f%s" % (float(speed) / t, n)
            return str(speed)

        def row(row):
            def qe(v):
                if v is None:
                    return ""
                if isinstance(v, unicode):
                    return v.encode("utf-8")
                elif isinstance(v, datetime.datetime):
                    return v.strftime("%Y-%m-%d %H:%M:%S")
                elif not isinstance(v, str):
                    return str(v)
                else:
                    return v

            return [qe(x) for x in row]

        def translate_row(row, cmap):
            return [row[i] for i in cmap]

        cols = [
            "object_name",
            "object_address",
            "object_model",
            "object_software",
            "object_port_name",
            "object_port_profile_name",
            "object_port_status",
            "object_link_status",
            "object_port_speed",
            "object_port_duplex",
            "object_port_untagged_vlan",
            "object_port_tagged_vlans",
        ]

        header_row = [
            "MANAGED_OBJECT",
            "OBJECT_ADDRESS",
            "OBJECT_MODEL",
            "OBJECT_SOFTWARE",
            "PORT_NAME",
            "PORT_PROFILE_NAME",
            "PORT_STATUS",
            "LINK_STATUS",
            "PORT_SPEED",
            "PORT_DUPLEX",
            "PORT_UNTAGGED_VLAN",
            "PORT_TAGGED_VLANS",
        ]

        if columns:
            cmap = []
            for c in columns.split(","):
                try:
                    cmap += [cols.index(c)]
                except ValueError:
                    continue
        else:
            cmap = list(range(len(cols)))

        r = [translate_row(header_row, cmap)]
        mo = {}
        if_p = {}
        DUPLEX = {True: "Full", False: "Half"}

        for ifp in InterfaceProfile.objects.filter():
            if_p[ifp.id] = {"name": ifp.name}
        mos = ManagedObject.objects.filter(is_managed=True)
        if (request.user.is_superuser and not administrative_domain
                and not selector and not interface_profile):
            mos = ManagedObject.objects.filter(is_managed=True)
        if not request.user.is_superuser:
            mos = mos.filter(
                administrative_domain__in=UserAccess.get_domains(request.user))
        if administrative_domain:
            ads = AdministrativeDomain.get_nested_ids(
                int(administrative_domain))
            mos = mos.filter(administrative_domain__in=ads)
        if selector:
            selector = ManagedObjectSelector.get_by_id(int(selector))
            mos = mos.filter(selector.Q)

        for o in mos:
            mo[o.id] = {
                "type": "managedobject",
                "id": str(o.id),
                "name": o.name,
                "status": o.is_managed,
                "address": o.address,
                "vendor": o.vendor,
                "version": o.version,
                "platform": o.platform,
            }

        mos_id = list(mos.values_list("id", flat=True))

        rld = ReportInterfaceStatus(mos_id, zero, def_profile,
                                    interface_profile)

        for i in rld.out:
            untag, tagged = "", ""
            if i["subs"]:
                untag = i["subs"][0].get("untagged_vlan", "")
                tagged = list_to_ranges(i["subs"][0].get("tagged_vlans", []))
            r += [
                translate_row(
                    row([
                        mo[i["managed_object"]]["name"],
                        mo[i["managed_object"]]["address"],
                        "%s %s" % (
                            str(mo[i["managed_object"]]["vendor"]),
                            str(mo[i["managed_object"]]["platform"]),
                        ),
                        str(mo[i["managed_object"]]["version"]),
                        i["name"],
                        if_p[i["profile"]]["name"],
                        "UP" if i["admin_status"] is True else "Down",
                        "UP" if "oper_status" in i and i["oper_status"] is True
                        else "Down",
                        humanize_speed(i["in_speed"])
                        if "in_speed" in i else "-",
                        DUPLEX.get(i["full_duplex"])
                        if "full_duplex" in i and "in_speed" in i else "-",
                        untag,
                        tagged,
                    ]),
                    cmap,
                )
            ]

        filename = "interface_status_report_%s" % datetime.datetime.now(
        ).strftime("%Y%m%d")
        if o_format == "csv":
            response = HttpResponse(content_type="text/csv")
            response[
                "Content-Disposition"] = 'attachment; filename="%s.csv"' % filename
            writer = csv.writer(response, dialect="excel", delimiter=";")
            writer.writerows(r)
            return response
        elif o_format == "xlsx":
            response = StringIO()
            wb = xlsxwriter.Workbook(response)
            cf1 = wb.add_format({"bottom": 1, "left": 1, "right": 1, "top": 1})
            ws = wb.add_worksheet("Objects")
            max_column_data_length = {}
            for rn, x in enumerate(r):
                for cn, c in enumerate(x):
                    if rn and (r[0][cn] not in max_column_data_length or
                               len(str(c)) > max_column_data_length[r[0][cn]]):
                        max_column_data_length[r[0][cn]] = len(str(c))
                    ws.write(rn, cn, c, cf1)
            ws.autofilter(0, 0, rn, cn)
            ws.freeze_panes(1, 0)
            for cn, c in enumerate(r[0]):
                # Set column width
                width = get_column_width(c)
                if enable_autowidth and width < max_column_data_length[c]:
                    width = max_column_data_length[c]
                ws.set_column(cn, cn, width=width)
            wb.close()
            response.seek(0)
            response = HttpResponse(response.getvalue(),
                                    content_type="application/vnd.ms-excel")
            # response = HttpResponse(
            #     content_type="application/x-ms-excel")
            response[
                "Content-Disposition"] = 'attachment; filename="%s.xlsx"' % filename
            response.close()
            return response
Exemplo n.º 7
0
    def process_mstp(self):
        r = {
            "mode": "MSTP",
            "instances": [],
            "configuration": {
                "MSTP": {
                    "region": self.mib_get("hpicfBridgeMSTRegionName"),
                    "revision": self.mib_get("hpicfBridgeMSTRegionRevision")
                }
            }
        }
        # Get bridge id
        bridge_id = self.mib_get("dot1dBaseBridgeAddress").replace(" ", "")
        bridge_id = "%s-%s" % (bridge_id[:6], bridge_id[6:])
        # Create instances
        instances = {}  # id -> {data}
        """
        instance id -> data: interface, port_id, state, role, priority,
        designated_bridge_id, designated_bridge_priority,
        designated_port_id, edge, point_to_point
        """
        interfaces = {}
        v = self.mib_walk("hpicfBridgeMSTInstanceRowStatus")
        for instance_id in v:
            if v[instance_id] == "1":
                instances[instance_id] = {"id": instance_id}
                interfaces[instance_id] = {}
        # Set root id and root priority
        v = self.mib_walk("hpicfBridgeMSTInstanceDesignatedRoot")
        for instance_id in v:
            if instance_id in instances:
                root = v[instance_id].replace(" ", "")
                root_priority = int(root[:2] + "00", 16)
                root = "%s-%s" % (root[4:10], root[10:])
                instances[instance_id]["root_id"] = root
                instances[instance_id]["root_priority"] = root_priority
        # Set bridge priority
        v = self.mib_walk("hpicfBridgeMSTInstancePriority")
        for instance_id in v:
            if instance_id in instances:
                instances[instance_id]["bridge_id"] = bridge_id
                instances[instance_id]["bridge_priority"] = v[
                    instance_id].replace(",", "")
        # Get instance vlans
        vlans = {}  # instance -> vlans
        for i in [1, 2, 3, 4]:
            v = self.mib_walk("hpicfBridgeMSTInstanceVlanMap%dk" % i)
            for instance_id in v:
                if instance_id in instances:
                    try:
                        vlans[instance_id] += v[instance_id]
                    except KeyError:
                        vlans[instance_id] = v[instance_id]

        if not vlans.has_key(0):
            vlans[0] = ''
        # Convert bitmask to vlan list
        rest_vlans = set(range(1, 4096))
        for instance_id in vlans:
            v = set()
            for i, m in enumerate(vlans[instance_id].split()):
                m = int(m, 16)
                for j in range(8):
                    if m & (1 << (7 - j)):
                        vlan = i * 8 + j + 1
                        v.add(vlan)
                        rest_vlans.remove(vlan)
            vlans[instance_id] = v
        # Set instnace vlans
        for instance_id in vlans:
            v = vlans[instance_id]
            if not v and instance_id == 0:
                v = rest_vlans
            instances[instance_id]["vlans"] = list_to_ranges(sorted(v))
        #
        # Process interfaces
        #
        # port_id -> {"interface","port_id","edge","point_to_point"}
        ports = {}
        ifname = self.mib_walk("ifName")
        v = self.mib_walk("dot1dBasePortIfIndex")
        for port_id in v:
            ports[port_id] = {
                "interface": ifname[int(v[port_id])],
                "port_id": port_id
            }
        # Edge port status
        v = self.mib_walk("hpicfBridgeRstpOperEdgePort")
        for port_id in v:
            ports[port_id]["edge"] = v[port_id] == "1"
        # point_to_point status
        v = self.mib_walk("hpicfBridgeRstpOperPointToPointMac")
        for port_id in v:
            ports[port_id]["point_to_point"] = v[port_id] == "1"
        #
        # Process instance interfaces
        #
        instance_ports = {}  # instance_id -> port_id -> data
        for instance_id in instances:
            instance_ports[instance_id] = {}
            for port_id in ports:
                instance_ports[instance_id][port_id] = ports[port_id].copy()
        # Port priority
        v = self.mib_walk("hpicfBridgeMSTPortPriority")
        for instance_id, port_id in v:
            instance_ports[instance_id][port_id]["priority"] = v[instance_id,
                                                                 port_id]
        # Port state
        v = self.mib_walk("hpicfBridgeMSTPortState")
        for instance_id, port_id in v:
            instance_ports[instance_id][port_id]["state"] = {
                "1": "disabled",
                "2": "discarding",
                "??": "learning",
                "5": "forwarding",
                "_": "unknown"
            }[v[instance_id, port_id]]  # @todo: refine states
        # Port role
        v = self.mib_walk("hpicfBridgeMSTPortRole")
        for instance_id, port_id in v:
            instance_ports[instance_id][port_id]["role"] = {
                "1": "disabled",
                "?": "alternate",
                "5": "backup",
                "6": "disabled",
                "2": "root",
                "3": "designated",
                "_": "master",
                "__": "nonstp",
                "!!": "unknown"
            }[v[instance_id, port_id]]  # @todo: refine roles
        # Designated bridge
        v = self.mib_walk("hpicfBridgeMSTPortDesignatedBridge")
        for instance_id, port_id in v:
            bridge = v[instance_id, port_id].replace(" ", "")
            priority = int(bridge[:2] + "00", 16)
            bridge = "%s-%s" % (bridge[4:10], bridge[10:])
            instance_ports[instance_id][port_id][
                "designated_bridge_id"] = bridge
            instance_ports[instance_id][port_id][
                "designated_bridge_priority"] = priority
        # Designated port
        v = self.mib_walk("hpicfBridgeMSTPortDesignatedPort")
        for instance_id, port_id in v:
            x = v[instance_id, port_id]
            if " " in x:
                pr, p = x.split(" ")
                instance_ports[instance_id][port_id][
                    "designated_port_id"] = "%d.%d" % (int(pr, 16), int(p, 16))
            else:
                instance_ports[instance_id][port_id][
                    "designated_port_id"] = "%d.%d" % (ord(x[0]), ord(x[1]))
        # Fill missed designated bridge ids
        for instance_id in instance_ports:
            for port_id in instance_ports[instance_id]:
                v = instance_ports[instance_id][port_id]
                if "designated_bridge_id" not in v:
                    v["designated_bridge_id"] = bridge_id
                if "designated_bridge_priority" not in v:
                    v["designated_bridge_priority"] = 32768
        #
        # Install interfaces
        #
        for instance_id in instances:
            instances[instance_id]["interfaces"] = sorted(
                instance_ports[instance_id].values(),
                lambda x, y: cmp(x["port_id"], y["port_id"]))
        #
        # Install instances
        #
        r["instances"] = sorted(instances.values(),
                                lambda x, y: cmp(x["id"], y["id"]))
        return r
Exemplo n.º 8
0
 def get_db_prep_value(self, value, connection, prepared=False):
     return list_to_ranges(sorted(value))
Exemplo n.º 9
0
def switchport_validation_reduce(task):
    from noc.lib.app.simplereport import Report, TableSection, SectionRow
    from noc.lib.text import list_to_ranges

    switchports = {}  # object -> interface -> (description, set of vlans)
    macs = {}  # object -> interface -> set of vlans
    # Collect data
    for mt in task.maptask_set.filter(status="C"):
        o = mt.managed_object
        if mt.map_script.endswith(".get_mac_address_table"):
            # Populate macs
            macs[o] = {}
            for m in mt.script_result:
                for i in m["interfaces"]:
                    if i not in macs[o]:
                        macs[o][i] = set()
                    macs[o][i].add(m["vlan_id"])
        elif mt.map_script.endswith(".get_switchport"):
            # Populate switchports
            switchports[o] = {}
            for p in mt.script_result:
                if not p["status"]:
                    # Skip ports in shutdown
                    continue
                i = p["interface"]
                if i not in switchports[o]:
                    switchports[o][i] = (p.get("description", ""), set())
                if "untagged" in p and p["untagged"]:
                    switchports[o][i][1].add(p["untagged"])
                if p["tagged"]:
                    switchports[o][i][1].update(p["tagged"])
        else:
            raise Exception("Inconsistent map task")
    if not macs or not switchports:
        return "Failed to retrieve the data!!!"
        # Process data
    data = []
    for o in switchports:
        if o not in macs or not macs[o]:
            continue
        # Find inconsistent ports
        inconsistent_ports = []  # (port, swtichport vlans, excessive vlans)
        for i in switchports[o]:
            if i not in macs[o]:
                # No mac data for port
                inconsistent_ports += [(i, switchports[o][i][0],
                                        switchports[o][i][1], None)]
            else:
                # Remove intersection
                v = switchports[o][i][1] - macs[o][i]
                if v:
                    inconsistent_ports += [(i, switchports[o][i][0],
                                            switchports[o][i][1], v)]
        # Add to data if inconsistent ports found
        if inconsistent_ports:
            data += [SectionRow(o.name)]
            data += [(p, d, list_to_ranges(v),
                      list_to_ranges(e) if e is not None else "No MACs found")
                     for p, d, v, e in sorted(inconsistent_ports,
                                              lambda x, y: cmp(x[0], y[0]))]
        #
    if not data:
        return "Failed to retrieve data!!!"
    # Build report
    r = Report()
    r.append_section(
        TableSection("",
                     columns=[
                         "Port", "Description", "Switchport VLANs",
                         "Excessive VLANs"
                     ],
                     data=data))
    return r
Exemplo n.º 10
0
    def get_data(self):

        def get_container_path(self):
            # Get container path
            if not self.object:
                return None
            cp = []
            if self.object.container:
                c = self.object.container.id
                while c:
                    try:
                        o = Object.objects.get(id=c)
                        # @todo: Address data
                        if o.container:
                            cp.insert(0, {
                                "id": o.id,
                                "name": o.name
                            })
                        c = o.container.id if o.container else None
                    except DoesNotExist:
                        metrics["error", ("type", "no_such_object")] += 1
                        break
            return cp

        if not self.object:
            return None
        # @todo: Stage
        # @todo: Service range
        # @todo: Open TT
        now = datetime.datetime.now()
        # Get object status and uptime

        alarms = list(ActiveAlarm.objects.filter(managed_object=self.object.id))

        current_start = None
        duration = None
        if self.object.is_managed:
            if self.object.get_status():
                if alarms:
                    current_state = "alarm"
                else:
                    current_state = "up"
                uptime = Uptime.objects.filter(object=self.object.id, stop=None).first()
                if uptime:
                    current_start = uptime.start
            else:
                current_state = "down"
                outage = Outage.objects.filter(object=self.object.id, stop=None).first()
                if outage is not None:
                    current_start = outage.start
        else:
            current_state = "unmanaged"
        if current_start:
            duration = now - current_start

        cp = get_container_path(self)

        # MAC addresses
        macs = []
        o_macs = DiscoveryID.macs_for_object(self.object)
        if o_macs:
            for f, l in o_macs:
                if f == l:
                    macs += [f]
                else:
                    macs += ["%s - %s" % (f, l)]

        # Links
        uplinks = set(self.object.data.uplinks)
        if len(uplinks) > 1:
            if self.object.segment.lost_redundancy:
                redundancy = "L"
            else:
                redundancy = "R"
        else:
            redundancy = "N"
        links = []
        for l in Link.object_links(self.object):
            local_interfaces = []
            remote_interfaces = []
            remote_objects = set()
            for i in l.interfaces:
                if i.managed_object.id == self.object.id:
                    local_interfaces += [i]
                else:
                    remote_interfaces += [i]
                    remote_objects.add(i.managed_object)
            if len(remote_objects) == 1:
                ro = remote_objects.pop()
                if ro.id in uplinks:
                    role = "uplink"
                else:
                    role = "downlink"
                links += [{
                    "id": l.id,
                    "role": role,
                    "local_interface": sorted(
                        local_interfaces,
                        key=lambda x: split_alnum(x.name)
                    ),
                    "remote_object": ro,
                    "remote_interface": sorted(
                        remote_interfaces,
                        key=lambda x: split_alnum(x.name)
                    ),
                    "remote_status": "up" if ro.get_status() else "down"
                }]
            links = sorted(links, key=lambda x: (x["role"] != "uplink", split_alnum(x["local_interface"][0].name)))
        # Build global services summary
        service_summary = ServiceSummary.get_object_summary(self.object)

        # Interfaces
        interfaces = []

        mo = ManagedObject.objects.filter(id=self.object.id)

        iface_metrics, last_ts = get_interface_metrics(mo[0])
        iface_metrics = iface_metrics[mo[0]]

        objects_metrics, last_time = get_objects_metrics(mo[0])
        objects_metrics = objects_metrics.get(mo[0])

        meta = ""

        metric_type_name = dict(MetricType.objects.filter().scalar("name", "measure"))
        metric_type_field = dict(MetricType.objects.filter().scalar("field_name", "measure"))

        if objects_metrics is not None:
            if objects_metrics.get("") is not None:
                for key in objects_metrics.get("").keys():
                    if metric_type_name[key] in ["bytes", "bit/s", "bool"]:
                        objects_metrics.get("")[key] = {
                            "type": metric_type_name[key],
                            "value": self.humanize_speed(objects_metrics.get("")[key], metric_type_name[key])
                        }
                    else:
                        objects_metrics.get("")[key] = {
                            "type": metric_type_name[key],
                            "value": objects_metrics.get("")[key]
                        }
                meta = objects_metrics.get("")
            else:
                meta = {}

        if iface_metrics is not None:
            for i in Interface.objects.filter(managed_object=self.object.id, type="physical"):
                load_in = "-"
                load_out = "-"
                errors_in = "-"
                errors_out = "-"
                iface_get_link_name = iface_metrics.get(str(i.name))
                if iface_get_link_name is not None:
                    for key in iface_get_link_name.keys():
                        meta_type = metric_type_name.get(key) or metric_type_field.get(key)
                        iface_get_link_name[key] = {
                            "type": meta_type,
                            "value": self.humanize_speed(
                                str(iface_get_link_name[key]),
                                meta_type)
                        }
                        if key in ['Interface | Load | In',
                                   'Interface | Load | Out',
                                   'Interface | Errors | In',
                                   'Interface | Errors | Out']:
                            try:
                                load_in = iface_get_link_name['Interface | Load | In']["value"] + \
                                    iface_get_link_name['Interface | Load | In']["type"]
                                load_out = iface_get_link_name['Interface | Load | Out']["value"] + \
                                    iface_get_link_name['Interface | Load | Out']["type"]
                                errors_in = iface_get_link_name['Interface | Errors | In']["value"]
                                errors_out = iface_get_link_name['Interface | Errors | Out']["value"]
                            except TypeError:
                                pass
                else:
                    iface_get_link_name = {}

                interfaces += [{
                    "id": i.id,
                    "name": i.name,
                    "admin_status": i.admin_status,
                    "oper_status": i.oper_status,
                    "mac": i.mac or "",
                    "full_duplex": i.full_duplex,
                    "load_in": load_in,
                    "load_out": load_out,
                    "errors_in": errors_in,
                    "errors_out": errors_out,
                    "speed": max([i.in_speed or 0, i.out_speed or 0]) / 1000,
                    "untagged_vlan": None,
                    "tagged_vlan": None,
                    "profile": i.profile,
                    "service": i.service,
                    "service_summary":
                        service_summary.get("interface").get(i.id, {})
                }]

                si = list(i.subinterface_set.filter(enabled_afi="BRIDGE"))
                if len(si) == 1:
                    si = si[0]
                    interfaces[-1]["untagged_vlan"] = si.untagged_vlan
                    interfaces[-1]["tagged_vlans"] = list_to_ranges(si.tagged_vlans).replace(",", ", ")
            interfaces = sorted(interfaces, key=lambda x: split_alnum(x["name"]))
        # Resource groups
        # Service groups (i.e. server)
        static_services = set(self.object.static_service_groups)
        service_groups = []
        for rg_id in self.object.effective_service_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            service_groups += [{
                "id": rg_id,
                "name": rg.name,
                "technology": rg.technology,
                "is_static": rg_id in static_services
            }]
        # Client groups (i.e. client)
        static_clients = set(self.object.static_client_groups)
        client_groups = []
        for rg_id in self.object.effective_client_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            client_groups += [{
                "id": rg_id,
                "name": rg.name,
                "technology": rg.technology,
                "is_static": rg_id in static_clients
            }]
        # @todo: Administrative domain path
        # Alarms
        alarm_list = []
        for a in alarms:
            alarm_list += [{
                "id": a.id,
                "root_id": self.get_root(alarms),
                "timestamp": a.timestamp,
                "duration": now - a.timestamp,
                "subject": a.subject,
                "managed_object": a.managed_object,
                "service_summary": {
                    "service": SummaryItem.items_to_dict(a.total_services),
                    "subscriber": SummaryItem.items_to_dict(a.total_subscribers)},
                "alarm_class": a.alarm_class
            }]
        alarm_list = sorted(alarm_list, key=operator.itemgetter("timestamp"))

        # Maintenance
        maintenance = []
        for m in Maintenance.objects.filter(
            affected_objects__object=self.object.id,
            is_completed=False,
            start__lte=now + datetime.timedelta(hours=1)
        ):
            maintenance += [{
                "maintenance": m,
                "id": m.id,
                "subject": m.subject,
                "start": m.start,
                "stop": m.stop,
                "in_progress": m.start <= now
            }]
        # Get Inventory
        inv = []
        for p in self.object.get_inventory():
            c = self.get_nested_inventory(p)
            c["name"] = p.name or self.object.name
            inv += [c]
        # Build result

        if self.object.platform is not None:
            platform = self.object.platform.name
        else:
            platform = "Unknown"
        if self.object.version is not None:
            version = self.object.version.version
        else:
            version = ""

        r = {
            "id": self.object.id,
            "object": self.object,
            "name": self.object.name,
            "address": self.object.address,
            "platform": platform,
            # self.object.platform.name if self.object.platform else "Unknown",
            "version": version,
            # self.object.version.version if self.object.version else "",
            "description": self.object.description,
            "object_profile": self.object.object_profile.id,
            "object_profile_name": self.object.object_profile.name,
            "macs": ", ".join(sorted(macs)),
            "segment": self.object.segment,
            "firmware_status": FirmwarePolicy.get_status(
                self.object.platform,
                self.object.version),
            "firmware_recommended":
                FirmwarePolicy.get_recommended_version(self.object.platform),
            "service_summary": service_summary,
            "container_path": cp,
            "current_state": current_state,
            # Start of uptime/downtime
            "current_start": current_start,
            # Current uptime/downtime
            "current_duration": duration,
            "service_groups": service_groups,
            "client_groups": client_groups,
            "tt": [],
            "links": links,
            "alarms": alarm_list,
            "interfaces": interfaces,
            "metrics": meta,
            "maintenance": maintenance,
            "redundancy": redundancy,
            "inventory": self.flatten_inventory(inv),
            "serial_number": self.object.get_attr("Serial Number")
        }
        return r