Merge branch 'develop' into pygui-runtool
This commit is contained in:
commit
f6bd21629d
10 changed files with 289 additions and 52 deletions
|
@ -367,14 +367,12 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
||||||
(LinkTlvs.NETWORK_ID, link_data.network_id),
|
(LinkTlvs.NETWORK_ID, link_data.network_id),
|
||||||
(LinkTlvs.KEY, link_data.key),
|
(LinkTlvs.KEY, link_data.key),
|
||||||
(LinkTlvs.INTERFACE1_NUMBER, link_data.interface1_id),
|
(LinkTlvs.INTERFACE1_NUMBER, link_data.interface1_id),
|
||||||
(LinkTlvs.INTERFACE1_NAME, link_data.interface1_name),
|
|
||||||
(LinkTlvs.INTERFACE1_IP4, link_data.interface1_ip4),
|
(LinkTlvs.INTERFACE1_IP4, link_data.interface1_ip4),
|
||||||
(LinkTlvs.INTERFACE1_IP4_MASK, link_data.interface1_ip4_mask),
|
(LinkTlvs.INTERFACE1_IP4_MASK, link_data.interface1_ip4_mask),
|
||||||
(LinkTlvs.INTERFACE1_MAC, link_data.interface1_mac),
|
(LinkTlvs.INTERFACE1_MAC, link_data.interface1_mac),
|
||||||
(LinkTlvs.INTERFACE1_IP6, link_data.interface1_ip6),
|
(LinkTlvs.INTERFACE1_IP6, link_data.interface1_ip6),
|
||||||
(LinkTlvs.INTERFACE1_IP6_MASK, link_data.interface1_ip6_mask),
|
(LinkTlvs.INTERFACE1_IP6_MASK, link_data.interface1_ip6_mask),
|
||||||
(LinkTlvs.INTERFACE2_NUMBER, link_data.interface2_id),
|
(LinkTlvs.INTERFACE2_NUMBER, link_data.interface2_id),
|
||||||
(LinkTlvs.INTERFACE2_NAME, link_data.interface2_name),
|
|
||||||
(LinkTlvs.INTERFACE2_IP4, link_data.interface2_ip4),
|
(LinkTlvs.INTERFACE2_IP4, link_data.interface2_ip4),
|
||||||
(LinkTlvs.INTERFACE2_IP4_MASK, link_data.interface2_ip4_mask),
|
(LinkTlvs.INTERFACE2_IP4_MASK, link_data.interface2_ip4_mask),
|
||||||
(LinkTlvs.INTERFACE2_MAC, link_data.interface2_mac),
|
(LinkTlvs.INTERFACE2_MAC, link_data.interface2_mac),
|
||||||
|
|
|
@ -37,6 +37,10 @@ TERMINALS = {
|
||||||
"gnome-terminal": "gnome-terminal --window --",
|
"gnome-terminal": "gnome-terminal --window --",
|
||||||
}
|
}
|
||||||
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
|
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
|
||||||
|
DEFAULT_IP4S = ["10.0.0.0", "192.168.0.0", "172.16.0.0"]
|
||||||
|
DEFAULT_IP4 = DEFAULT_IP4S[0]
|
||||||
|
DEFAULT_IP6S = ["2001::", "2002::", "a::"]
|
||||||
|
DEFAULT_IP6 = DEFAULT_IP6S[0]
|
||||||
|
|
||||||
|
|
||||||
class IndentDumper(yaml.Dumper):
|
class IndentDumper(yaml.Dumper):
|
||||||
|
@ -98,11 +102,17 @@ def check_directory():
|
||||||
"alt": 2.0,
|
"alt": 2.0,
|
||||||
"scale": 150.0,
|
"scale": 150.0,
|
||||||
},
|
},
|
||||||
"servers": [{"name": "example", "address": "127.0.0.1", "port": 50051}],
|
"servers": [],
|
||||||
"nodes": [],
|
"nodes": [],
|
||||||
"recentfiles": [],
|
"recentfiles": [],
|
||||||
"observers": [{"name": "hello", "cmd": "echo hello"}],
|
"observers": [],
|
||||||
"scale": 1.0,
|
"scale": 1.0,
|
||||||
|
"ips": {
|
||||||
|
"ip4": DEFAULT_IP4,
|
||||||
|
"ip6": DEFAULT_IP6,
|
||||||
|
"ip4s": DEFAULT_IP4S,
|
||||||
|
"ip6s": DEFAULT_IP6S,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
save(config)
|
save(config)
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,6 @@ if TYPE_CHECKING:
|
||||||
from core.gui.app import Application
|
from core.gui.app import Application
|
||||||
|
|
||||||
GUI_SOURCE = "gui"
|
GUI_SOURCE = "gui"
|
||||||
OBSERVERS = {
|
|
||||||
"List Processes": "ps",
|
|
||||||
"Show Interfaces": "ip address",
|
|
||||||
"IPV4 Routes": "ip -4 ro",
|
|
||||||
"IPV6 Routes": "ip -6 ro",
|
|
||||||
"Listening Sockets": "netstat -tuwnl",
|
|
||||||
"IPv4 MFC Entries": "ip -4 mroute show",
|
|
||||||
"IPv6 MFC Entries": "ip -6 mroute show",
|
|
||||||
"Firewall Rules": "iptables -L",
|
|
||||||
"IPSec Policies": "setkey -DP",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class CoreServer:
|
class CoreServer:
|
||||||
|
|
153
daemon/core/gui/dialogs/ipdialog.py
Normal file
153
daemon/core/gui/dialogs/ipdialog.py
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import messagebox, ttk
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
|
from core.gui import appconfig
|
||||||
|
from core.gui.dialogs.dialog import Dialog
|
||||||
|
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||||
|
from core.gui.widgets import ListboxScroll
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from core.gui.app import Application
|
||||||
|
|
||||||
|
|
||||||
|
class IpConfigDialog(Dialog):
|
||||||
|
def __init__(self, master: "Application", app: "Application") -> None:
|
||||||
|
super().__init__(master, app, "IP Configuration", modal=True)
|
||||||
|
ip_config = self.app.guiconfig.setdefault("ips")
|
||||||
|
self.ip4 = ip_config.setdefault("ip4", appconfig.DEFAULT_IP4)
|
||||||
|
self.ip6 = ip_config.setdefault("ip6", appconfig.DEFAULT_IP6)
|
||||||
|
self.ip4s = ip_config.setdefault("ip4s", appconfig.DEFAULT_IP4S)
|
||||||
|
self.ip6s = ip_config.setdefault("ip6s", appconfig.DEFAULT_IP6S)
|
||||||
|
self.ip4_entry = None
|
||||||
|
self.ip4_listbox = None
|
||||||
|
self.ip6_entry = None
|
||||||
|
self.ip6_listbox = None
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def draw(self) -> None:
|
||||||
|
self.top.columnconfigure(0, weight=1)
|
||||||
|
self.top.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
|
# draw ip4 and ip6 lists
|
||||||
|
frame = ttk.Frame(self.top)
|
||||||
|
frame.columnconfigure(0, weight=1)
|
||||||
|
frame.columnconfigure(1, weight=1)
|
||||||
|
frame.rowconfigure(0, weight=1)
|
||||||
|
frame.grid(sticky="nsew", pady=PADY)
|
||||||
|
|
||||||
|
ip4_frame = ttk.LabelFrame(frame, text="IPv4", padding=FRAME_PAD)
|
||||||
|
ip4_frame.columnconfigure(0, weight=1)
|
||||||
|
ip4_frame.rowconfigure(0, weight=1)
|
||||||
|
ip4_frame.grid(row=0, column=0, stick="nsew")
|
||||||
|
self.ip4_listbox = ListboxScroll(ip4_frame)
|
||||||
|
self.ip4_listbox.listbox.bind("<<ListboxSelect>>", self.select_ip4)
|
||||||
|
self.ip4_listbox.grid(sticky="nsew", pady=PADY)
|
||||||
|
for index, ip4 in enumerate(self.ip4s):
|
||||||
|
self.ip4_listbox.listbox.insert(tk.END, ip4)
|
||||||
|
if self.ip4 == ip4:
|
||||||
|
self.ip4_listbox.listbox.select_set(index)
|
||||||
|
self.ip4_entry = ttk.Entry(ip4_frame)
|
||||||
|
self.ip4_entry.grid(sticky="ew", pady=PADY)
|
||||||
|
ip4_button_frame = ttk.Frame(ip4_frame)
|
||||||
|
ip4_button_frame.columnconfigure(0, weight=1)
|
||||||
|
ip4_button_frame.columnconfigure(1, weight=1)
|
||||||
|
ip4_button_frame.grid(sticky="ew")
|
||||||
|
ip4_add = ttk.Button(ip4_button_frame, text="Add", command=self.click_add_ip4)
|
||||||
|
ip4_add.grid(row=0, column=0, sticky="ew")
|
||||||
|
ip4_del = ttk.Button(
|
||||||
|
ip4_button_frame, text="Delete", command=self.click_del_ip4
|
||||||
|
)
|
||||||
|
ip4_del.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
ip6_frame = ttk.LabelFrame(frame, text="IPv6", padding=FRAME_PAD)
|
||||||
|
ip6_frame.columnconfigure(0, weight=1)
|
||||||
|
ip6_frame.rowconfigure(0, weight=1)
|
||||||
|
ip6_frame.grid(row=0, column=1, stick="nsew")
|
||||||
|
self.ip6_listbox = ListboxScroll(ip6_frame)
|
||||||
|
self.ip6_listbox.listbox.bind("<<ListboxSelect>>", self.select_ip6)
|
||||||
|
self.ip6_listbox.grid(sticky="nsew", pady=PADY)
|
||||||
|
for index, ip6 in enumerate(self.ip6s):
|
||||||
|
self.ip6_listbox.listbox.insert(tk.END, ip6)
|
||||||
|
if self.ip6 == ip6:
|
||||||
|
self.ip6_listbox.listbox.select_set(index)
|
||||||
|
self.ip6_entry = ttk.Entry(ip6_frame)
|
||||||
|
self.ip6_entry.grid(sticky="ew", pady=PADY)
|
||||||
|
ip6_button_frame = ttk.Frame(ip6_frame)
|
||||||
|
ip6_button_frame.columnconfigure(0, weight=1)
|
||||||
|
ip6_button_frame.columnconfigure(1, weight=1)
|
||||||
|
ip6_button_frame.grid(sticky="ew")
|
||||||
|
ip6_add = ttk.Button(ip6_button_frame, text="Add", command=self.click_add_ip6)
|
||||||
|
ip6_add.grid(row=0, column=0, sticky="ew")
|
||||||
|
ip6_del = ttk.Button(
|
||||||
|
ip6_button_frame, text="Delete", command=self.click_del_ip6
|
||||||
|
)
|
||||||
|
ip6_del.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
# draw buttons
|
||||||
|
frame = ttk.Frame(self.top)
|
||||||
|
frame.grid(stick="ew")
|
||||||
|
for i in range(2):
|
||||||
|
frame.columnconfigure(i, weight=1)
|
||||||
|
button = ttk.Button(frame, text="Save", command=self.click_save)
|
||||||
|
button.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||||
|
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||||
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
def click_add_ip4(self) -> None:
|
||||||
|
ip4 = self.ip4_entry.get()
|
||||||
|
if not ip4 or not netaddr.valid_ipv4(ip4):
|
||||||
|
messagebox.showerror("IPv4 Error", f"Invalid IPv4 {ip4}")
|
||||||
|
else:
|
||||||
|
self.ip4_listbox.listbox.insert(tk.END, ip4)
|
||||||
|
|
||||||
|
def click_del_ip4(self) -> None:
|
||||||
|
if self.ip4_listbox.listbox.size() == 1:
|
||||||
|
messagebox.showerror("IPv4 Error", "Must have at least one address")
|
||||||
|
else:
|
||||||
|
selection = self.ip4_listbox.listbox.curselection()
|
||||||
|
self.ip4_listbox.listbox.delete(selection)
|
||||||
|
self.ip4_listbox.listbox.select_set(0)
|
||||||
|
|
||||||
|
def click_add_ip6(self) -> None:
|
||||||
|
ip6 = self.ip6_entry.get()
|
||||||
|
if not ip6 or not netaddr.valid_ipv6(ip6):
|
||||||
|
messagebox.showerror("IPv6 Error", f"Invalid IPv6 {ip6}")
|
||||||
|
else:
|
||||||
|
self.ip6_listbox.listbox.insert(tk.END, ip6)
|
||||||
|
|
||||||
|
def click_del_ip6(self) -> None:
|
||||||
|
if self.ip6_listbox.listbox.size() == 1:
|
||||||
|
messagebox.showerror("IPv6 Error", "Must have at least one address")
|
||||||
|
else:
|
||||||
|
selection = self.ip6_listbox.listbox.curselection()
|
||||||
|
self.ip6_listbox.listbox.delete(selection)
|
||||||
|
self.ip6_listbox.listbox.select_set(0)
|
||||||
|
|
||||||
|
def select_ip4(self, _event: tk.Event) -> None:
|
||||||
|
selection = self.ip4_listbox.listbox.curselection()
|
||||||
|
self.ip4 = self.ip4_listbox.listbox.get(selection)
|
||||||
|
|
||||||
|
def select_ip6(self, _event: tk.Event) -> None:
|
||||||
|
selection = self.ip6_listbox.listbox.curselection()
|
||||||
|
self.ip6 = self.ip6_listbox.listbox.get(selection)
|
||||||
|
|
||||||
|
def click_save(self) -> None:
|
||||||
|
ip4s = []
|
||||||
|
for index in range(self.ip4_listbox.listbox.size()):
|
||||||
|
ip4 = self.ip4_listbox.listbox.get(index)
|
||||||
|
ip4s.append(ip4)
|
||||||
|
ip6s = []
|
||||||
|
for index in range(self.ip6_listbox.listbox.size()):
|
||||||
|
ip6 = self.ip6_listbox.listbox.get(index)
|
||||||
|
ip6s.append(ip6)
|
||||||
|
ip_config = self.app.guiconfig["ips"]
|
||||||
|
ip_config["ip4"] = self.ip4
|
||||||
|
ip_config["ip6"] = self.ip6
|
||||||
|
ip_config["ip4s"] = ip4s
|
||||||
|
ip_config["ip6s"] = ip6s
|
||||||
|
self.app.core.interfaces_manager.update_ips(self.ip4, self.ip6)
|
||||||
|
self.app.save_config()
|
||||||
|
self.destroy()
|
49
daemon/core/gui/dialogs/macdialog.py
Normal file
49
daemon/core/gui/dialogs/macdialog.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
from tkinter import ttk
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from core.gui.dialogs.dialog import Dialog
|
||||||
|
from core.gui.themes import PADX, PADY
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from core.gui.app import Application
|
||||||
|
|
||||||
|
|
||||||
|
class MacConfigDialog(Dialog):
|
||||||
|
def __init__(self, master: "Application", app: "Application") -> None:
|
||||||
|
super().__init__(master, app, "MAC Configuration", modal=True)
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def draw(self) -> None:
|
||||||
|
self.top.columnconfigure(0, weight=1)
|
||||||
|
self.top.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
|
# draw explanation label
|
||||||
|
text = (
|
||||||
|
"MAC addresses will be generated for nodes starting with the\n"
|
||||||
|
"provided value below and increment by value in order."
|
||||||
|
)
|
||||||
|
label = ttk.Label(self.top, text=text)
|
||||||
|
label.grid(sticky="ew", pady=PADY)
|
||||||
|
|
||||||
|
# draw input
|
||||||
|
frame = ttk.Frame(self.top)
|
||||||
|
frame.columnconfigure(0, weight=1)
|
||||||
|
frame.columnconfigure(1, weight=3)
|
||||||
|
frame.grid(stick="ew", pady=PADY)
|
||||||
|
label = ttk.Label(frame, text="Starting MAC")
|
||||||
|
label.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||||
|
entry = ttk.Entry(frame)
|
||||||
|
entry.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
# draw buttons
|
||||||
|
frame = ttk.Frame(self.top)
|
||||||
|
frame.grid(stick="ew")
|
||||||
|
for i in range(2):
|
||||||
|
frame.columnconfigure(i, weight=1)
|
||||||
|
button = ttk.Button(frame, text="Save", command=self.click_save)
|
||||||
|
button.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||||
|
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||||
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
def click_save(self) -> None:
|
||||||
|
pass
|
|
@ -1,5 +1,5 @@
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import messagebox, ttk
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from core.gui.coreclient import Observer
|
from core.gui.coreclient import Observer
|
||||||
|
@ -104,6 +104,11 @@ class ObserverDialog(Dialog):
|
||||||
observer = Observer(name, cmd)
|
observer = Observer(name, cmd)
|
||||||
self.app.core.custom_observers[name] = observer
|
self.app.core.custom_observers[name] = observer
|
||||||
self.observers.insert(tk.END, name)
|
self.observers.insert(tk.END, name)
|
||||||
|
self.name.set("")
|
||||||
|
self.cmd.set("")
|
||||||
|
self.app.menubar.draw_custom_observers()
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Observer Error", f"{name} already exists")
|
||||||
|
|
||||||
def click_save(self):
|
def click_save(self):
|
||||||
name = self.name.get()
|
name = self.name.get()
|
||||||
|
@ -129,6 +134,7 @@ class ObserverDialog(Dialog):
|
||||||
self.observers.selection_clear(0, tk.END)
|
self.observers.selection_clear(0, tk.END)
|
||||||
self.save_button.config(state=tk.DISABLED)
|
self.save_button.config(state=tk.DISABLED)
|
||||||
self.delete_button.config(state=tk.DISABLED)
|
self.delete_button.config(state=tk.DISABLED)
|
||||||
|
self.app.menubar.draw_custom_observers()
|
||||||
|
|
||||||
def handle_observer_change(self, event: tk.Event):
|
def handle_observer_change(self, event: tk.Event):
|
||||||
selection = self.observers.curselection()
|
selection = self.observers.curselection()
|
||||||
|
|
|
@ -32,21 +32,22 @@ class Subnets:
|
||||||
|
|
||||||
|
|
||||||
class InterfaceManager:
|
class InterfaceManager:
|
||||||
def __init__(
|
def __init__(self, app: "Application") -> None:
|
||||||
self,
|
|
||||||
app: "Application",
|
|
||||||
ip4: str = "10.0.0.0",
|
|
||||||
ip4_mask: int = 24,
|
|
||||||
ip6: str = "2001::",
|
|
||||||
ip6_mask=64,
|
|
||||||
) -> None:
|
|
||||||
self.app = app
|
self.app = app
|
||||||
self.ip4_mask = ip4_mask
|
ip_config = self.app.guiconfig.get("ips", {})
|
||||||
self.ip6_mask = ip6_mask
|
ip4 = ip_config.get("ip4", "10.0.0.0")
|
||||||
self.ip4_subnets = IPNetwork(f"{ip4}/{ip4_mask}")
|
ip6 = ip_config.get("ip6", "2001::")
|
||||||
self.ip6_subnets = IPNetwork(f"{ip6}/{ip6_mask}")
|
self.ip4_mask = 24
|
||||||
|
self.ip6_mask = 64
|
||||||
|
self.ip4_subnets = IPNetwork(f"{ip4}/{self.ip4_mask}")
|
||||||
|
self.ip6_subnets = IPNetwork(f"{ip6}/{self.ip6_mask}")
|
||||||
self.current_subnets = None
|
self.current_subnets = None
|
||||||
|
|
||||||
|
def update_ips(self, ip4: str, ip6: str) -> None:
|
||||||
|
self.reset()
|
||||||
|
self.ip4_subnets = IPNetwork(f"{ip4}/{self.ip4_mask}")
|
||||||
|
self.ip6_subnets = IPNetwork(f"{ip6}/{self.ip6_mask}")
|
||||||
|
|
||||||
def next_subnets(self) -> Subnets:
|
def next_subnets(self) -> Subnets:
|
||||||
# define currently used subnets
|
# define currently used subnets
|
||||||
used_subnets = set()
|
used_subnets = set()
|
||||||
|
|
|
@ -7,12 +7,13 @@ from tkinter import filedialog, messagebox
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from core.gui.appconfig import XMLS_PATH
|
from core.gui.appconfig import XMLS_PATH
|
||||||
from core.gui.coreclient import OBSERVERS
|
|
||||||
from core.gui.dialogs.about import AboutDialog
|
from core.gui.dialogs.about import AboutDialog
|
||||||
from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog
|
from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog
|
||||||
from core.gui.dialogs.canvaswallpaper import CanvasWallpaperDialog
|
from core.gui.dialogs.canvaswallpaper import CanvasWallpaperDialog
|
||||||
from core.gui.dialogs.executepython import ExecutePythonDialog
|
from core.gui.dialogs.executepython import ExecutePythonDialog
|
||||||
from core.gui.dialogs.hooks import HooksDialog
|
from core.gui.dialogs.hooks import HooksDialog
|
||||||
|
from core.gui.dialogs.ipdialog import IpConfigDialog
|
||||||
|
from core.gui.dialogs.macdialog import MacConfigDialog
|
||||||
from core.gui.dialogs.observers import ObserverDialog
|
from core.gui.dialogs.observers import ObserverDialog
|
||||||
from core.gui.dialogs.preferences import PreferencesDialog
|
from core.gui.dialogs.preferences import PreferencesDialog
|
||||||
from core.gui.dialogs.servers import ServersDialog
|
from core.gui.dialogs.servers import ServersDialog
|
||||||
|
@ -26,6 +27,17 @@ if TYPE_CHECKING:
|
||||||
from core.gui.app import Application
|
from core.gui.app import Application
|
||||||
|
|
||||||
MAX_FILES = 3
|
MAX_FILES = 3
|
||||||
|
OBSERVERS = {
|
||||||
|
"List Processes": "ps",
|
||||||
|
"Show Interfaces": "ip address",
|
||||||
|
"IPV4 Routes": "ip -4 ro",
|
||||||
|
"IPV6 Routes": "ip -6 ro",
|
||||||
|
"Listening Sockets": "netstat -tuwnl",
|
||||||
|
"IPv4 MFC Entries": "ip -4 mroute show",
|
||||||
|
"IPv6 MFC Entries": "ip -6 mroute show",
|
||||||
|
"Firewall Rules": "iptables -L",
|
||||||
|
"IPSec Policies": "setkey -DP",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Menubar(tk.Menu):
|
class Menubar(tk.Menu):
|
||||||
|
@ -44,6 +56,9 @@ class Menubar(tk.Menu):
|
||||||
self.canvas = app.canvas
|
self.canvas = app.canvas
|
||||||
self.recent_menu = None
|
self.recent_menu = None
|
||||||
self.edit_menu = None
|
self.edit_menu = None
|
||||||
|
self.observers_menu = None
|
||||||
|
self.observers_var = tk.StringVar(value=tk.NONE)
|
||||||
|
self.observers_custom_index = None
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def draw(self) -> None:
|
def draw(self) -> None:
|
||||||
|
@ -173,44 +188,49 @@ class Menubar(tk.Menu):
|
||||||
"""
|
"""
|
||||||
menu = tk.Menu(self)
|
menu = tk.Menu(self)
|
||||||
menu.add_command(label="Auto Grid", command=self.click_autogrid)
|
menu.add_command(label="Auto Grid", command=self.click_autogrid)
|
||||||
menu.add_command(label="IP Addresses", state=tk.DISABLED)
|
menu.add_command(label="IP Addresses", command=self.click_ip_config)
|
||||||
menu.add_command(label="MAC Addresses", state=tk.DISABLED)
|
menu.add_command(label="MAC Addresses", command=self.click_mac_config)
|
||||||
self.add_cascade(label="Tools", menu=menu)
|
self.add_cascade(label="Tools", menu=menu)
|
||||||
|
|
||||||
def create_observer_widgets_menu(self, widget_menu: tk.Menu) -> None:
|
def create_observer_widgets_menu(self, widget_menu: tk.Menu) -> None:
|
||||||
"""
|
"""
|
||||||
Create observer widget menu item and create the sub menu items inside
|
Create observer widget menu item and create the sub menu items inside
|
||||||
"""
|
"""
|
||||||
var = tk.StringVar(value="none")
|
self.observers_menu = tk.Menu(widget_menu)
|
||||||
menu = tk.Menu(widget_menu)
|
self.observers_menu.add_command(
|
||||||
menu.var = var
|
|
||||||
menu.add_command(
|
|
||||||
label="Edit Observers", command=self.click_edit_observer_widgets
|
label="Edit Observers", command=self.click_edit_observer_widgets
|
||||||
)
|
)
|
||||||
menu.add_separator()
|
self.observers_menu.add_separator()
|
||||||
menu.add_radiobutton(
|
self.observers_menu.add_radiobutton(
|
||||||
label="None",
|
label="None",
|
||||||
variable=var,
|
variable=self.observers_var,
|
||||||
value="none",
|
value="none",
|
||||||
command=lambda: self.core.set_observer(None),
|
command=lambda: self.core.set_observer(None),
|
||||||
)
|
)
|
||||||
for name in sorted(OBSERVERS):
|
for name in sorted(OBSERVERS):
|
||||||
cmd = OBSERVERS[name]
|
cmd = OBSERVERS[name]
|
||||||
menu.add_radiobutton(
|
self.observers_menu.add_radiobutton(
|
||||||
label=name,
|
label=name,
|
||||||
variable=var,
|
variable=self.observers_var,
|
||||||
value=name,
|
value=name,
|
||||||
command=partial(self.core.set_observer, cmd),
|
command=partial(self.core.set_observer, cmd),
|
||||||
)
|
)
|
||||||
|
self.observers_custom_index = self.observers_menu.index(tk.END) + 1
|
||||||
|
self.draw_custom_observers()
|
||||||
|
widget_menu.add_cascade(label="Observer Widgets", menu=self.observers_menu)
|
||||||
|
|
||||||
|
def draw_custom_observers(self) -> None:
|
||||||
|
current_observers_index = self.observers_menu.index(tk.END) + 1
|
||||||
|
if self.observers_custom_index < current_observers_index:
|
||||||
|
self.observers_menu.delete(self.observers_custom_index, tk.END)
|
||||||
for name in sorted(self.core.custom_observers):
|
for name in sorted(self.core.custom_observers):
|
||||||
observer = self.core.custom_observers[name]
|
observer = self.core.custom_observers[name]
|
||||||
menu.add_radiobutton(
|
self.observers_menu.add_radiobutton(
|
||||||
label=name,
|
label=name,
|
||||||
variable=var,
|
variable=self.observers_var,
|
||||||
value=name,
|
value=name,
|
||||||
command=partial(self.core.set_observer, observer.cmd),
|
command=partial(self.core.set_observer, observer.cmd),
|
||||||
)
|
)
|
||||||
widget_menu.add_cascade(label="Observer Widgets", menu=menu)
|
|
||||||
|
|
||||||
def create_adjacency_menu(self, widget_menu: tk.Menu) -> None:
|
def create_adjacency_menu(self, widget_menu: tk.Menu) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -465,3 +485,11 @@ class Menubar(tk.Menu):
|
||||||
def click_edge_label_change(self) -> None:
|
def click_edge_label_change(self) -> None:
|
||||||
for edge in self.canvas.edges.values():
|
for edge in self.canvas.edges.values():
|
||||||
edge.draw_labels()
|
edge.draw_labels()
|
||||||
|
|
||||||
|
def click_mac_config(self) -> None:
|
||||||
|
dialog = MacConfigDialog(self.app, self.app)
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
def click_ip_config(self) -> None:
|
||||||
|
dialog = IpConfigDialog(self.app, self.app)
|
||||||
|
dialog.show()
|
||||||
|
|
|
@ -203,7 +203,10 @@ class ListboxScroll(ttk.Frame):
|
||||||
self.scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL)
|
self.scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL)
|
||||||
self.scrollbar.grid(row=0, column=1, sticky="ns")
|
self.scrollbar.grid(row=0, column=1, sticky="ns")
|
||||||
self.listbox = tk.Listbox(
|
self.listbox = tk.Listbox(
|
||||||
self, selectmode=tk.SINGLE, yscrollcommand=self.scrollbar.set
|
self,
|
||||||
|
selectmode=tk.BROWSE,
|
||||||
|
yscrollcommand=self.scrollbar.set,
|
||||||
|
exportselection=False,
|
||||||
)
|
)
|
||||||
themes.style_listbox(self.listbox)
|
themes.style_listbox(self.listbox)
|
||||||
self.listbox.grid(row=0, column=0, sticky="nsew")
|
self.listbox.grid(row=0, column=0, sticky="nsew")
|
||||||
|
|
|
@ -638,14 +638,14 @@ class CoreXmlReader:
|
||||||
session_options = self.scenario.find("session_options")
|
session_options = self.scenario.find("session_options")
|
||||||
if session_options is None:
|
if session_options is None:
|
||||||
return
|
return
|
||||||
|
xml_config = {}
|
||||||
configs = {}
|
for configuration in session_options.iterchildren():
|
||||||
for config in session_options.iterchildren():
|
name = configuration.get("name")
|
||||||
name = config.get("name")
|
value = configuration.get("value")
|
||||||
value = config.get("value")
|
xml_config[name] = value
|
||||||
configs[name] = value
|
logging.info("reading session options: %s", xml_config)
|
||||||
logging.info("reading session options: %s", configs)
|
config = self.session.options.get_configs()
|
||||||
self.session.options.set_configs(configs)
|
config.update(xml_config)
|
||||||
|
|
||||||
def read_session_hooks(self) -> None:
|
def read_session_hooks(self) -> None:
|
||||||
session_hooks = self.scenario.find("session_hooks")
|
session_hooks = self.scenario.find("session_hooks")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue