Compare commits
2 commits
master
...
coretk-enh
Author | SHA1 | Date | |
---|---|---|---|
|
c86323abac | ||
|
9b8caf813e |
4 changed files with 197 additions and 7 deletions
|
@ -1,4 +1,5 @@
|
|||
import tkinter as tk
|
||||
import webbrowser
|
||||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
@ -41,3 +42,7 @@ class Dialog(tk.Toplevel):
|
|||
frame.grid(row=row, sticky="nsew")
|
||||
frame.rowconfigure(0, weight=1)
|
||||
self.top.rowconfigure(frame.grid_info()["row"], weight=1)
|
||||
|
||||
@classmethod
|
||||
def navigate_link(cls, link: str):
|
||||
webbrowser.open_new(link)
|
||||
|
|
|
@ -3,6 +3,7 @@ emane configuration
|
|||
"""
|
||||
import tkinter as tk
|
||||
import webbrowser
|
||||
from enum import Enum
|
||||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
|
@ -20,6 +21,18 @@ if TYPE_CHECKING:
|
|||
from core.gui.graph.node import CanvasNode
|
||||
|
||||
|
||||
class EmaneModelEnum(Enum):
|
||||
RFPIPE = "emane_rfpipe"
|
||||
IEEE80211ABG = "emane_ieee80211abg"
|
||||
COMMEFFECT = "emane_commeffect"
|
||||
BYPASS = "emane_bypass"
|
||||
TDMA = "emane_tdma"
|
||||
|
||||
|
||||
def get_model(enum_class: EmaneModelEnum):
|
||||
return enum_class.value
|
||||
|
||||
|
||||
class GlobalEmaneDialog(Dialog):
|
||||
def __init__(self, master: Any, app: "Application"):
|
||||
super().__init__(master, app, "EMANE Configuration", modal=True)
|
||||
|
@ -38,7 +51,7 @@ class GlobalEmaneDialog(Dialog):
|
|||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
for i in range(3):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||
|
@ -46,6 +59,15 @@ class GlobalEmaneDialog(Dialog):
|
|||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
button = ttk.Button(
|
||||
frame,
|
||||
text="Info Link",
|
||||
command=lambda: self.navigate_link(
|
||||
"https://github.com/adjacentlink/emane/wiki/Configuring-the-Emulator"
|
||||
),
|
||||
)
|
||||
button.grid(row=0, column=2, sticky="ew")
|
||||
|
||||
def click_apply(self):
|
||||
self.config_frame.parse_config()
|
||||
self.destroy()
|
||||
|
@ -86,7 +108,7 @@ class EmaneModelDialog(Dialog):
|
|||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
for i in range(3):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||
|
@ -94,6 +116,9 @@ class EmaneModelDialog(Dialog):
|
|||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
button = ttk.Button(frame, text="Info Link ", command=self.wiki_link)
|
||||
button.grid(row=0, column=2, sticky="ew")
|
||||
|
||||
def click_apply(self):
|
||||
self.config_frame.parse_config()
|
||||
self.app.core.set_emane_model_config(
|
||||
|
@ -101,6 +126,24 @@ class EmaneModelDialog(Dialog):
|
|||
)
|
||||
self.destroy()
|
||||
|
||||
def wiki_link(self):
|
||||
if self.model == get_model(EmaneModelEnum.RFPIPE):
|
||||
self.navigate_link(
|
||||
"https://github.com/adjacentlink/emane/wiki/RF-Pipe-Model"
|
||||
)
|
||||
elif self.model == get_model(EmaneModelEnum.COMMEFFECT):
|
||||
self.navigate_link(
|
||||
"https://github.com/adjacentlink/emane/wiki/Comm-Effect-Model"
|
||||
)
|
||||
elif self.model == get_model(EmaneModelEnum.TDMA):
|
||||
self.navigate_link("https://github.com/adjacentlink/emane/wiki/TDMA-Model")
|
||||
elif self.model == get_model(EmaneModelEnum.IEEE80211ABG):
|
||||
self.navigate_link(
|
||||
"https://github.com/adjacentlink/emane/wiki/IEEE-802.11abg-Model"
|
||||
)
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
class EmaneConfigDialog(Dialog):
|
||||
def __init__(
|
||||
|
|
|
@ -133,11 +133,12 @@ class NodeServiceDialog(Dialog):
|
|||
|
||||
def click_configure(self):
|
||||
current_selection = self.current.listbox.curselection()
|
||||
service_name = self.current.listbox.get(current_selection[0])
|
||||
if len(current_selection):
|
||||
dialog = ServiceConfigDialog(
|
||||
master=self,
|
||||
app=self.app,
|
||||
service_name=self.current.listbox.get(current_selection[0]),
|
||||
service_name=service_name,
|
||||
node_id=self.node_id,
|
||||
)
|
||||
dialog.show()
|
||||
|
|
|
@ -65,7 +65,7 @@ class ServiceConfigDialog(Dialog):
|
|||
self.temp_service_files = {}
|
||||
self.modified_files = set()
|
||||
self.load()
|
||||
self.draw()
|
||||
# self.draw()
|
||||
|
||||
def load(self):
|
||||
try:
|
||||
|
@ -108,8 +108,12 @@ class ServiceConfigDialog(Dialog):
|
|||
):
|
||||
for file, data in file_configs[self.node_id][self.service_name].items():
|
||||
self.temp_service_files[file] = data
|
||||
self.draw()
|
||||
except grpc.RpcError as e:
|
||||
show_grpc_error(e)
|
||||
if not self.is_ipsec():
|
||||
show_grpc_error(e)
|
||||
else:
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
self.top.columnconfigure(0, weight=1)
|
||||
|
@ -127,13 +131,139 @@ class ServiceConfigDialog(Dialog):
|
|||
# draw notebook
|
||||
self.notebook = ttk.Notebook(self.top)
|
||||
self.notebook.grid(sticky="nsew", pady=PADY)
|
||||
self.draw_tab_files()
|
||||
if not self.is_ipsec():
|
||||
self.draw_tab_files()
|
||||
else:
|
||||
self.draw_ipsec_tab()
|
||||
self.draw_tab_directories()
|
||||
self.draw_tab_startstop()
|
||||
self.draw_tab_configuration()
|
||||
|
||||
self.draw_buttons()
|
||||
|
||||
def draw_ipsec_tab(self):
|
||||
tab = ttk.Frame(self.notebook, padding=FRAME_PAD)
|
||||
tab.grid(sticky="nsew")
|
||||
tab.columnconfigure(0, weight=1)
|
||||
self.notebook.add(tab, text="IPsec")
|
||||
|
||||
text = (
|
||||
"This IPsec service helper will assist with building an ipsec.sh file (located on the Files tab).\nThe IPsec service builds ESP tunnels between"
|
||||
"the specified peers using the racoon IKEv2\nkeying daemon. You need to provide keys and the addresses of peers, along with the\nsubnet to tunnel."
|
||||
)
|
||||
label = ttk.Label(tab, text=text)
|
||||
label.grid(row=0, column=0, sticky="nsew")
|
||||
|
||||
label_frame = ttk.LabelFrame(tab, text="Keys", padding=FRAME_PAD)
|
||||
label_frame.grid(row=1, column=0, sticky="nsew")
|
||||
label_frame.columnconfigure(0, weight=1)
|
||||
for i in range(3):
|
||||
label_frame.rowconfigure(i, weight=1)
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=0, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=2)
|
||||
frame.columnconfigure(2, weight=1)
|
||||
|
||||
label = ttk.Label(frame, text="Key directory: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
entry = ttk.Entry(frame)
|
||||
entry.grid(row=0, column=1, stick="ew")
|
||||
button = ttk.Button(frame, text="...")
|
||||
button.grid(row=0, column=2, sticky="ew")
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=1, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=3)
|
||||
label = ttk.Label(frame, text="Key base name: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
entry = ttk.Entry(frame)
|
||||
entry.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
text = (
|
||||
"The (name).pem x509 certificate and (name).key RSA private key need to exist in the\n"
|
||||
"specified directory. These can be generated using the openssl tool. Also, a ca-cert.pem\n"
|
||||
"file should exist in the key directory for the CA that issue the certs."
|
||||
)
|
||||
label = ttk.Label(label_frame, text=text, padding=FRAME_PAD)
|
||||
label.grid(row=2, column=0, sticky="ew")
|
||||
|
||||
label_frame = ttk.LabelFrame(
|
||||
tab, text="IPsec Tunnel Endpoints", padding=FRAME_PAD
|
||||
)
|
||||
label_frame.grid(row=2, column=0, sticky="nsew")
|
||||
|
||||
i = 0
|
||||
text = (
|
||||
"(1) Define tunnel endpoints (select peer node using the button, then select"
|
||||
"address from the list)"
|
||||
)
|
||||
label = ttk.Label(label_frame, text=text, padding=FRAME_PAD)
|
||||
label.grid(row=i, column=0, sticky="nsew")
|
||||
i = i + 1
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=i, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=3)
|
||||
i = i + 1
|
||||
label = ttk.Label(frame, text="Local: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
combobox = ttk.Combobox(frame)
|
||||
combobox.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=i, column=0, sticky="nsew")
|
||||
i = i + 1
|
||||
label = ttk.Label(frame, text="Peer node: (none)")
|
||||
label.grid(row=0, column=0)
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=i, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=3)
|
||||
i = i + 1
|
||||
label = ttk.Label(frame, text="Peer: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
combobox = ttk.Combobox(frame)
|
||||
combobox.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
text = "(2) Select endpoints below and add the subnets to be encrypted"
|
||||
label = ttk.Label(label_frame, text=text, padding=FRAME_PAD)
|
||||
label.grid(row=i, column=0, sticky="ew")
|
||||
i = i + i
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=i, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=3)
|
||||
i = i + 1
|
||||
label = ttk.Label(frame, text="Local subnet: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
combobox = ttk.Combobox(frame)
|
||||
combobox.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
frame = ttk.Frame(label_frame, padding=FRAME_PAD)
|
||||
frame.grid(row=i, column=0, sticky="nsew")
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=3)
|
||||
i = i + 1
|
||||
label = ttk.Label(frame, text="Remote subnet: ")
|
||||
label.grid(row=0, column=0, sticky="ew")
|
||||
combobox = ttk.Combobox(frame)
|
||||
combobox.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
frame = ttk.Frame(tab, padding=FRAME_PAD)
|
||||
frame.grid(row=3, column=0, sticky="nsew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Trash")
|
||||
button.grid(row=0, column=0, sticky="ew")
|
||||
button = ttk.Button(frame, text="Generate ipsec.sh")
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def draw_tab_files(self):
|
||||
tab = ttk.Frame(self.notebook, padding=FRAME_PAD)
|
||||
tab.grid(sticky="nsew")
|
||||
|
@ -342,7 +472,7 @@ class ServiceConfigDialog(Dialog):
|
|||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(4):
|
||||
for i in range(5):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, sticky="ew", padx=PADX)
|
||||
|
@ -352,6 +482,14 @@ class ServiceConfigDialog(Dialog):
|
|||
button.grid(row=0, column=2, sticky="ew", padx=PADX)
|
||||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=3, sticky="ew")
|
||||
button = ttk.Button(
|
||||
frame,
|
||||
text="Info Link",
|
||||
command=lambda: self.navigate_link(
|
||||
"http://coreemu.github.io/core/services.html"
|
||||
),
|
||||
)
|
||||
button.grid(row=0, column=4, sticky="ew")
|
||||
|
||||
def add_filename(self, event: tk.Event):
|
||||
# not worry about it for now
|
||||
|
@ -504,3 +642,6 @@ class ServiceConfigDialog(Dialog):
|
|||
for cmd in to_add:
|
||||
commands.append(cmd)
|
||||
listbox.insert(tk.END, cmd)
|
||||
|
||||
def is_ipsec(self):
|
||||
return self.service_name == "IPsec"
|
||||
|
|
Loading…
Reference in a new issue