Example #1
0
    def _draw_device_front(self, drawing, device, start, end, text):
        name = str(device)
        if device.devicebay_count:
            name += ' ({}/{})'.format(device.get_children().count(),
                                      device.devicebay_count)

        color = device.device_role.color
        link = drawing.add(
            drawing.a(href='{}{}'.format(
                self.base_url, reverse('dcim:device', kwargs={'pk':
                                                              device.pk})),
                      target='_top',
                      fill='black'))
        link.set_desc(self._get_device_description(device))
        link.add(
            drawing.rect(start,
                         end,
                         style='fill: #{}'.format(color),
                         class_='slot'))
        hex_color = '#{}'.format(foreground_color(color))
        link.add(drawing.text(str(name), insert=text, fill=hex_color))

        # Embed front device type image if one exists
        if self.include_images and device.device_type.front_image:
            image = drawing.image(href=device.device_type.front_image.url,
                                  insert=start,
                                  size=end,
                                  class_='device-image')
            image.fit(scale='slice')
            link.add(image)
Example #2
0
    def _draw_device_front(self, drawing, device, start, end, text):
        name = str(device)
        if device.devicebay_count:
            name += ' ({}/{})'.format(device.get_children().count(),
                                      device.devicebay_count)

        color = device.device_role.color
        link = drawing.add(
            drawing.a(href=reverse('dcim:device', kwargs={'pk': device.pk}),
                      target='_top',
                      fill='black'))
        link.set_desc('{} — {} ({}U) {} {}'.format(
            device.device_role, device.device_type.display_name,
            device.device_type.u_height, device.asset_tag or '', device.serial
            or ''))
        link.add(
            drawing.rect(start,
                         end,
                         style='fill: #{}'.format(color),
                         class_='slot'))
        hex_color = '#{}'.format(foreground_color(color))
        link.add(drawing.text(str(name), insert=text, fill=hex_color))

        # Embed front device type image if one exists
        if self.include_images and device.device_type.front_image:
            url = device.device_type.front_image.url
            image = drawing.image(href=url,
                                  insert=start,
                                  size=end,
                                  class_='device-image')
            image.stretch()
            link.add(image)
Example #3
0
    def render(self, img_format='png'):

        from circuits.models import CircuitTermination
        from dcim.models import CONNECTION_STATUS_CONNECTED, Device, InterfaceConnection

        # Construct the graph
        graph = graphviz.Graph()
        graph.graph_attr['ranksep'] = '1'
        seen = set()
        for i, device_set in enumerate(self.device_sets):

            subgraph = graphviz.Graph(name='sg{}'.format(i))
            subgraph.graph_attr['rank'] = 'same'

            # Add a pseudonode for each device_set to enforce hierarchical layout
            subgraph.node('set{}'.format(i), label='', shape='none', width='0')
            if i:
                graph.edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis')

            # Add each device to the graph
            devices = []
            for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                devices += Device.objects.filter(name__regex=query).select_related('device_role')
            # Remove duplicate devices
            devices = [d for d in devices if d.id not in seen]
            seen.update([d.id for d in devices])
            for d in devices:
                bg_color = '#{}'.format(d.device_role.color)
                fg_color = '#{}'.format(foreground_color(d.device_role.color))
                subgraph.node(d.name, style='filled', fillcolor=bg_color, fontcolor=fg_color, fontname='sans')

            # Add an invisible connection to each successive device in a set to enforce horizontal order
            for j in range(0, len(devices) - 1):
                subgraph.edge(devices[j].name, devices[j + 1].name, style='invis')

            graph.subgraph(subgraph)

        # Compile list of all devices
        device_superset = Q()
        for device_set in self.device_sets:
            for query in device_set.split(';'):  # Split regexes on semicolons
                device_superset = device_superset | Q(name__regex=query)

        # Add all interface connections to the graph
        devices = Device.objects.filter(*(device_superset,))
        connections = InterfaceConnection.objects.filter(
            interface_a__device__in=devices, interface_b__device__in=devices
        )
        for c in connections:
            style = 'solid' if c.connection_status == CONNECTION_STATUS_CONNECTED else 'dashed'
            graph.edge(c.interface_a.device.name, c.interface_b.device.name, style=style)

        # Add all circuits to the graph
        for termination in CircuitTermination.objects.filter(term_side='A', interface__device__in=devices):
            peer_termination = termination.get_peer_termination()
            if (peer_termination is not None and peer_termination.interface is not None and
                    peer_termination.interface.device in devices):
                graph.edge(termination.interface.device.name, peer_termination.interface.device.name, color='blue')

        return graph.pipe(format=img_format)
Example #4
0
    def render(self, img_format='png'):

        from circuits.models import CircuitTermination
        from dcim.models import CONNECTION_STATUS_CONNECTED, Device, InterfaceConnection

        # Construct the graph
        graph = graphviz.Graph()
        graph.graph_attr['ranksep'] = '1'
        seen = set()
        for i, device_set in enumerate(self.device_sets):

            subgraph = graphviz.Graph(name='sg{}'.format(i))
            subgraph.graph_attr['rank'] = 'same'

            # Add a pseudonode for each device_set to enforce hierarchical layout
            subgraph.node('set{}'.format(i), label='', shape='none', width='0')
            if i:
                graph.edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis')

            # Add each device to the graph
            devices = []
            for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                devices += Device.objects.filter(name__regex=query).select_related('device_role')
            # Remove duplicate devices
            devices = [d for d in devices if d.id not in seen]
            seen.update([d.id for d in devices])
            for d in devices:
                bg_color = '#{}'.format(d.device_role.color)
                fg_color = '#{}'.format(foreground_color(d.device_role.color))
                subgraph.node(d.name, style='filled', fillcolor=bg_color, fontcolor=fg_color, fontname='sans')

            # Add an invisible connection to each successive device in a set to enforce horizontal order
            for j in range(0, len(devices) - 1):
                subgraph.edge(devices[j].name, devices[j + 1].name, style='invis')

            graph.subgraph(subgraph)

        # Compile list of all devices
        device_superset = Q()
        for device_set in self.device_sets:
            for query in device_set.split(';'):  # Split regexes on semicolons
                device_superset = device_superset | Q(name__regex=query)

        # Add all interface connections to the graph
        devices = Device.objects.filter(*(device_superset,))
        connections = InterfaceConnection.objects.filter(
            interface_a__device__in=devices, interface_b__device__in=devices
        )
        for c in connections:
            style = 'solid' if c.connection_status == CONNECTION_STATUS_CONNECTED else 'dashed'
            graph.edge(c.interface_a.device.name, c.interface_b.device.name, style=style)

        # Add all circuits to the graph
        for termination in CircuitTermination.objects.filter(term_side='A', interface__device__in=devices):
            peer_termination = termination.get_peer_termination()
            if (peer_termination is not None and peer_termination.interface is not None and
                    peer_termination.interface.device in devices):
                graph.edge(termination.interface.device.name, peer_termination.interface.device.name, color='blue')

        return graph.pipe(format=img_format)
Example #5
0
def fgcolor(value):
    """
    Return black (#000000) or white (#ffffff) given an arbitrary background color in RRGGBB format.
    """
    value = value.lower().strip('#')
    if not re.match('^[0-9a-f]{6}$', value):
        return ''
    return '#{}'.format(foreground_color(value))
Example #6
0
def fgcolor(value):
    """
    Return black (#000000) or white (#ffffff) given an arbitrary background color in RRGGBB format.
    """
    value = value.lower().strip('#')
    if not re.match('^[0-9a-f]{6}$', value):
        return ''
    return '#{}'.format(foreground_color(value))
Example #7
0
    def render(self, img_format='png'):

        from dcim.models import Device

        # Construct the graph
        if self.type == TOPOLOGYMAP_TYPE_NETWORK:
            G = graphviz.Graph
        else:
            G = graphviz.Digraph
        self.graph = G()
        self.graph.graph_attr['ranksep'] = '1'
        seen = set()
        for i, device_set in enumerate(self.device_sets):

            subgraph = G(name='sg{}'.format(i))
            subgraph.graph_attr['rank'] = 'same'
            subgraph.graph_attr['directed'] = 'true'

            # Add a pseudonode for each device_set to enforce hierarchical layout
            subgraph.node('set{}'.format(i), label='', shape='none', width='0')
            if i:
                self.graph.edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis')

            # Add each device to the graph
            devices = []
            for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                devices += Device.objects.filter(name__regex=query).select_related('device_role')
            # Remove duplicate devices
            devices = [d for d in devices if d.id not in seen]
            seen.update([d.id for d in devices])
            for d in devices:
                bg_color = '#{}'.format(d.device_role.color)
                fg_color = '#{}'.format(foreground_color(d.device_role.color))
                subgraph.node(d.name, style='filled', fillcolor=bg_color, fontcolor=fg_color, fontname='sans')

            # Add an invisible connection to each successive device in a set to enforce horizontal order
            for j in range(0, len(devices) - 1):
                subgraph.edge(devices[j].name, devices[j + 1].name, style='invis')

            self.graph.subgraph(subgraph)

        # Compile list of all devices
        device_superset = Q()
        for device_set in self.device_sets:
            for query in device_set.split(';'):  # Split regexes on semicolons
                device_superset = device_superset | Q(name__regex=query)
        devices = Device.objects.filter(*(device_superset,))

        # Draw edges depending on graph type
        if self.type == TOPOLOGYMAP_TYPE_NETWORK:
            self.add_network_connections(devices)
        elif self.type == TOPOLOGYMAP_TYPE_CONSOLE:
            self.add_console_connections(devices)
        elif self.type == TOPOLOGYMAP_TYPE_POWER:
            self.add_power_connections(devices)

        return self.graph.pipe(format=img_format)
Example #8
0
    def render(self, img_format='png'):

        from dcim.models import Device

        # Construct the graph
        if self.type == TOPOLOGYMAP_TYPE_NETWORK:
            G = graphviz.Graph
        else:
            G = graphviz.Digraph
        self.graph = G()
        self.graph.graph_attr['ranksep'] = '1'
        seen = set()
        for i, device_set in enumerate(self.device_sets):

            subgraph = G(name='sg{}'.format(i))
            subgraph.graph_attr['rank'] = 'same'
            subgraph.graph_attr['directed'] = 'true'

            # Add a pseudonode for each device_set to enforce hierarchical layout
            subgraph.node('set{}'.format(i), label='', shape='none', width='0')
            if i:
                self.graph.edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis')

            # Add each device to the graph
            devices = []
            for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                devices += Device.objects.filter(name__regex=query).select_related('device_role')
            # Remove duplicate devices
            devices = [d for d in devices if d.id not in seen]
            seen.update([d.id for d in devices])
            for d in devices:
                bg_color = '#{}'.format(d.device_role.color)
                fg_color = '#{}'.format(foreground_color(d.device_role.color))
                subgraph.node(d.name, style='filled', fillcolor=bg_color, fontcolor=fg_color, fontname='sans')

            # Add an invisible connection to each successive device in a set to enforce horizontal order
            for j in range(0, len(devices) - 1):
                subgraph.edge(devices[j].name, devices[j + 1].name, style='invis')

            self.graph.subgraph(subgraph)

        # Compile list of all devices
        device_superset = Q()
        for device_set in self.device_sets:
            for query in device_set.split(';'):  # Split regexes on semicolons
                device_superset = device_superset | Q(name__regex=query)
        devices = Device.objects.filter(*(device_superset,))

        # Draw edges depending on graph type
        if self.type == TOPOLOGYMAP_TYPE_NETWORK:
            self.add_network_connections(devices)
        elif self.type == TOPOLOGYMAP_TYPE_CONSOLE:
            self.add_console_connections(devices)
        elif self.type == TOPOLOGYMAP_TYPE_POWER:
            self.add_power_connections(devices)

        return self.graph.pipe(format=img_format)