Xenviz
Материал из Xgu.ru
- Автор: Игорь Чубин
Xenviz -- инструмент для визуализации виртуальных сетей, базирующихся на Xen.
Xenviz это скрипт Python, который преобразует описание топологии виртуальной сети в формат DOT пакета Graphviz -- известного инструмента для построения графов. Полученный файл обрабатывается с помощью программы neato, одной из программ Graphviz, предназначенной для построения ненаправленных графов.
Входными данными для построения являются несколько таблиц и списков:
- bridges -- список мостов;
- physical_bridge_table -- таблица привязки виртуальных мостов к физическим интерфейсам (не обязательно привязывать все интерфейсы);
- host_bridge_table -- таблица соединений виртуальных машин и виртуальных мостов;
- bridge_bridge_table -- таблица соединений виртуальных мостов между собой.
Таблицы physical_bridge_table и bridge_bridge_table могут быть пустыми.
Xenviz может строить не только графическое представление сети. С его помощью можно подготовить shell-скрипт, который настроит домен 0 для запуска виртуальной сети с соответствующей топологией. Созданный Xenviz скрипт будет создавать и включать виртуальные мосты, а также привязывать их к физическим интерфейсам.
Для построения графа Xenviz вызывается без аргументов. Для того чтобы Xenviz генерировал не схему, а скрипт настройки домена, его необходимо вызвать с аргументом script.
Пример вызова Xenviz для построения схемы:
%# python xenviz.py > 1.dot && neato -Tpng -o 1.png 1.dot && gqview 1.png
Пример вызова для получения скрипта:
%# python xenviz.py script
Пример вызова для получения скрипта и его исполнения:
%# python xenviz.py script | sh -s
Пример топологии:
<python/>
bridges= ['xenbr0', 'xenbr1', 'xenbr2', 'xenbr3', 'tagged0']
host_bridge_table = {
'gw' : ['xenbr2','xenbr3','xenbr0'], 'pgw' : ['xenbr0','xenbr1'], 'dns' : ['xenbr1'], 'vpn' : ['xenbr1'], 'apt' : ['xenbr1'], 'igw' : ['tagged0'], }
bridge_bridge_table = {
'xenbr1' : ['tagged0'], 'vlan3' : ['tagged0'], 'vlan4' : ['tagged0'], 'vlan5' : ['tagged0'], 'inet0' : ['xenbr2'], 'inet1' : ['xenbr3'], }
physical_bridge_table = {
'tagged0' : 'eth0', 'xenbr2' : 'eth0_5', 'xenbr3' : 'eth0_6', }
Полученный с помощью Xenviz скрипт подготовки домена 0,
который соответствует этой топологии:
<sh/>
$ python xenviz.py script
- !/bin/sh
- create unbound bridges
brctl addbr xenbr1 brctl addbr xenbr0 ip link set xenbr1 up ip link set xenbr0 up
- create bridges bound to physical interfaces
/etc/xen/scripts/network-bridge start bridge=tagged0 netdev=eth0 vifnum=?? /etc/xen/scripts/network-bridge start bridge=xenbr3 netdev=eth0_6 vifnum=?? /etc/xen/scripts/network-bridge start bridge=xenbr2 netdev=eth0_5 vifnum=??
Построенная с помощью Xenviz схема, которая соответствует этой топологии:
[править] Дальнейшая работа
Что необходимо сделать:
- Визуализация различных типов машин
- Визуализация различных типов связей (виртуальные/физические, тегированные/нетегированные)
- Скрипт конфигурирования сети (создание мостов, подключение мостов)
[править] Приложение. Код скрипта
<python/>
- !/usr/bin/python
import sys
bridges= ['xenbr0', 'xenbr1', 'xenbr2', 'xenbr3', 'tagged0']
host_bridge_table = {
'gw' : ['xenbr2','xenbr3','xenbr0'], 'pgw' : ['xenbr0','xenbr1'], 'dns' : ['xenbr1'], 'vpn' : ['xenbr1'], 'apt' : ['xenbr1'], 'igw' : ['tagged0'], }
bridge_bridge_table = {
'xenbr1' : ['tagged0'], 'vlan3' : ['tagged0'], 'vlan4' : ['tagged0'], 'vlan5' : ['tagged0'], 'inet0' : ['xenbr2'], 'inet1' : ['xenbr3'], }
physical_bridge_table = {
'tagged0' : 'eth0', 'xenbr2' : 'eth0_5', 'xenbr3' : 'eth0_6', }
def create_bridges_script(bridges, physical_bridge_table):
bound_bridges=physical_bridge_table.keys() unbound_bridges=set(bridges)-set(bound_bridges) create_unbound_bridges="\n".join("brctl addbr "+x for x in unbound_bridges) create_unbound_bridges+="\n"+"\n".join("ip link set "+x+" up" for x in unbound_bridges)
create_bound_bridges="\n".join("/etc/xen/scripts/network-bridge start bridge="+bridge+" netdev="+physical_bridge_table[bridge]+" vifnum=??" for bridge in bound_bridges)
print """#!/bin/sh
- create unbound bridges
%(create_unbound_bridges)s
- create bridges bound to physical interfaces
%(create_bound_bridges)s """ % {'create_unbound_bridges' : create_unbound_bridges, 'create_bound_bridges' : create_bound_bridges}
nodelist=";\n ".join(host_bridge_table.keys())
networks=[]
for node,bridges_raw in host_bridge_table.iteritems():
networks.extend(bridges_raw)
for bridge,bridges_raw in bridge_bridge_table.iteritems():
networks.extend(bridges_raw)
networklist=";\n ".join(set(networks)-set(bridges)) if networklist: networklist += ";"
bridgelist=";\n ".join(set(bridges)) if bridgelist: bridgelist += ";"
physicallist=";\n ".join(set(physical_bridge_table.values())) if physicallist: physicallist += ";"
links=[] for host, bridges_raw in host_bridge_table.iteritems():
for this_bridge in bridges_raw: links.append(host+" -- "+this_bridge)
linklist=";\n ".join(links)
bridge_links=[] for bridge, bridges_raw in bridge_bridge_table.iteritems():
for this_bridge in bridges_raw: links.append(bridge+" -- "+this_bridge)
linklist=";\n ".join(links)
virtual_to_physical_links=[] for virtual, physical in physical_bridge_table.iteritems():
links.append(virtual+" -- "+physical+" [color=red]")
linklist=";\n ".join(links) graph_dot = {
'nodelist' : nodelist, 'bridgelist' : bridgelist, 'linklist' : linklist, 'physicallist' : physicallist, 'networklist' : networklist, }
if len(sys.argv) > 1 and sys.argv[1] == 'script':
create_bridges_script(bridges, physical_bridge_table) sys.exit(0)
print """
graph G {
// nodes
node [shape=rectangle]; %(nodelist)s
// bridges
node [shape=ellipse]; %(bridgelist)s
// physical
node [shape=ellipse,color=blue]; %(physicallist)s
// networks (not bridges, not physical)
node [shape=ellipse,color=green]; %(networklist)s
%(linklist)s
}; """ % graph_dot
|
---|
|
---|