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)
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)
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)
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)
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))
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))
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)
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)