more work on coretk
This commit is contained in:
parent
38683cb0d0
commit
f18d07985a
7 changed files with 256 additions and 10 deletions
|
@ -93,6 +93,8 @@ class Application(tk.Frame):
|
|||
self.core_grpc = CoreGrpc(self)
|
||||
self.core_grpc.set_up()
|
||||
self.canvas.core_grpc = self.core_grpc
|
||||
self.canvas.grpc_manager.core_grpc = self.core_grpc
|
||||
self.canvas.grpc_manager.update_preexisting_ids()
|
||||
self.canvas.draw_existing_component()
|
||||
|
||||
def on_closing(self):
|
||||
|
|
|
@ -18,6 +18,9 @@ class CoreGrpc:
|
|||
"""
|
||||
self.core = client.CoreGrpcClient()
|
||||
self.session_id = sid
|
||||
|
||||
self.node_ids = []
|
||||
|
||||
self.master = app.master
|
||||
|
||||
# self.set_up()
|
||||
|
@ -32,8 +35,14 @@ class CoreGrpc:
|
|||
|
||||
def log_throughput(self, event):
|
||||
interface_throughputs = event.interface_throughputs
|
||||
throughputs_belong_to_session = []
|
||||
for if_tp in interface_throughputs:
|
||||
if if_tp.node_id in self.node_ids:
|
||||
throughputs_belong_to_session.append(if_tp)
|
||||
# bridge_throughputs = event.bridge_throughputs
|
||||
self.throughput_draw.process_grpc_throughput_event(interface_throughputs)
|
||||
self.throughput_draw.process_grpc_throughput_event(
|
||||
throughputs_belong_to_session
|
||||
)
|
||||
|
||||
def create_new_session(self):
|
||||
"""
|
||||
|
@ -147,6 +156,7 @@ class CoreGrpc:
|
|||
def add_node(self, node_type, model, x, y, name, node_id):
|
||||
position = core_pb2.Position(x=x, y=y)
|
||||
node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model)
|
||||
self.node_ids.append(node_id)
|
||||
response = self.core.add_node(self.session_id, node)
|
||||
logging.info("created node: %s", response)
|
||||
if node_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||
|
|
|
@ -8,6 +8,7 @@ from coretk.grpcmanagement import GrpcManager
|
|||
from coretk.images import Images
|
||||
from coretk.interface import Interface
|
||||
from coretk.linkinfo import LinkInfo
|
||||
from coretk.nodeconfigtable import NodeConfig
|
||||
|
||||
|
||||
class GraphMode(enum.Enum):
|
||||
|
@ -37,8 +38,8 @@ class CanvasGraph(tk.Canvas):
|
|||
self.setup_bindings()
|
||||
self.draw_grid()
|
||||
|
||||
self.grpc_manager = GrpcManager()
|
||||
self.core_grpc = grpc
|
||||
self.grpc_manager = GrpcManager(grpc)
|
||||
|
||||
self.helper = GraphHelper(self)
|
||||
# self.core_id_to_canvas_id = {}
|
||||
|
@ -69,7 +70,8 @@ class CanvasGraph(tk.Canvas):
|
|||
self.nodes = {}
|
||||
self.edges = {}
|
||||
self.drawing_edge = None
|
||||
self.grpc_manager = GrpcManager()
|
||||
|
||||
self.grpc_manager = GrpcManager(new_grpc)
|
||||
|
||||
# new grpc
|
||||
self.core_grpc = new_grpc
|
||||
|
@ -463,6 +465,9 @@ class CanvasNode:
|
|||
state = self.canvas.core_grpc.get_session_state()
|
||||
if state == core_pb2.SessionState.RUNTIME:
|
||||
self.canvas.core_grpc.launch_terminal(node_id)
|
||||
else:
|
||||
print("config table show up")
|
||||
NodeConfig(self, self.image, self.node_type, self.name)
|
||||
|
||||
def update_coords(self):
|
||||
self.x_coord, self.y_coord = self.canvas.coords(self.id)
|
||||
|
|
|
@ -54,14 +54,17 @@ class Edge:
|
|||
|
||||
|
||||
class GrpcManager:
|
||||
def __init__(self):
|
||||
def __init__(self, grpc):
|
||||
self.nodes = {}
|
||||
self.edges = {}
|
||||
self.id = 1
|
||||
self.id = None
|
||||
# A list of id for re-use, keep in increasing order
|
||||
self.reusable = []
|
||||
|
||||
self.preexisting = []
|
||||
self.core_grpc = None
|
||||
|
||||
# self.update_preexisting_ids()
|
||||
# self.core_id_to_canvas_id = {}
|
||||
self.interfaces_manager = InterfaceManager()
|
||||
|
||||
|
@ -69,6 +72,23 @@ class GrpcManager:
|
|||
# self.node_id_and_interface_to_edge_token = {}
|
||||
self.core_mapping = CoreToCanvasMapping()
|
||||
|
||||
def update_preexisting_ids(self):
|
||||
"""
|
||||
get preexisting node ids
|
||||
:return:
|
||||
"""
|
||||
max_id = 0
|
||||
client = self.core_grpc.core
|
||||
sessions = client.get_sessions().sessions
|
||||
for session_summary in sessions:
|
||||
session = client.get_session(session_summary.id).session
|
||||
for node in session.nodes:
|
||||
if node.id > max_id:
|
||||
max_id = node.id
|
||||
self.preexisting.append(node.id)
|
||||
self.id = max_id + 1
|
||||
self.update_reusable_id()
|
||||
|
||||
def peek_id(self):
|
||||
"""
|
||||
Peek the next id to be used
|
||||
|
@ -211,6 +231,8 @@ class GrpcManager:
|
|||
src_interface = None
|
||||
dst_interface = None
|
||||
|
||||
self.interfaces_manager.new_subnet()
|
||||
|
||||
src_node = self.nodes[src_canvas_id]
|
||||
if src_node.model in network_layer_nodes:
|
||||
ifid = len(src_node.interfaces)
|
||||
|
|
|
@ -32,10 +32,39 @@ class Interface:
|
|||
)
|
||||
|
||||
|
||||
class SubnetAddresses:
|
||||
def __init__(self, network, addresses):
|
||||
self.network = network
|
||||
self.address = addresses
|
||||
self.address_index = 0
|
||||
|
||||
def get_new_ip_address(self):
|
||||
ipaddr = self.address[self.address_index]
|
||||
self.address_index = self.address_index + 1
|
||||
return ipaddr
|
||||
|
||||
|
||||
class InterfaceManager:
|
||||
def __init__(self):
|
||||
self.addresses = list(ipaddress.ip_network("10.0.0.0/24").hosts())
|
||||
self.index = 0
|
||||
# self.prefix = None
|
||||
self.core_subnets = list(
|
||||
ipaddress.ip_network("10.0.0.0/12").subnets(prefixlen_diff=12)
|
||||
)
|
||||
self.subnet_index = 0
|
||||
self.address_index = None
|
||||
|
||||
# self.network = ipaddress.ip_network("10.0.0.0/24")
|
||||
# self.addresses = list(self.network.hosts())
|
||||
self.network = None
|
||||
self.addresses = None
|
||||
# self.start_interface_manager()
|
||||
|
||||
def start_interface_manager(self):
|
||||
self.subnet_index = 0
|
||||
self.network = self.core_subnets[self.subnet_index]
|
||||
self.subnet_index = self.subnet_index + 1
|
||||
self.addresses = list(self.network.hosts())
|
||||
self.address_index = 0
|
||||
|
||||
def get_address(self):
|
||||
"""
|
||||
|
@ -43,6 +72,24 @@ class InterfaceManager:
|
|||
|
||||
:return:
|
||||
"""
|
||||
i = self.index
|
||||
self.index = self.index + 1
|
||||
return self.addresses[i]
|
||||
# i = self.index
|
||||
# self.address_index = self.index + 1
|
||||
# return self.addresses[i]
|
||||
ipaddr = self.addresses[self.address_index]
|
||||
self.address_index = self.address_index + 1
|
||||
return ipaddr
|
||||
|
||||
def new_subnet(self):
|
||||
self.network = self.core_subnets[self.subnet_index]
|
||||
self.subnet_index = self.subnet_index + 1
|
||||
self.addresses = list(self.network.hosts())
|
||||
self.address_index = 0
|
||||
|
||||
# def new_subnet(self):
|
||||
# """
|
||||
# retrieve a new subnet
|
||||
# :return:
|
||||
# """
|
||||
# if self.prefix is None:
|
||||
# self.prefix =
|
||||
# self.addresses = list(ipaddress.ip_network("10.0.0.0/24").hosts())
|
||||
|
|
151
coretk/coretk/nodeconfigtable.py
Normal file
151
coretk/coretk/nodeconfigtable.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
"""
|
||||
Create toplevel for node configuration
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
ICONS_DIR = os.path.join(PATH, "icons")
|
||||
|
||||
NETWORKNODETYPES = ["switch", "hub", "wlan", "rj45", "tunnel"]
|
||||
DEFAULTNODES = ["router", "host", "PC"]
|
||||
|
||||
|
||||
class NodeConfig:
|
||||
def __init__(self, canvas_node, image, node_type, name):
|
||||
self.image = image
|
||||
self.node_type = node_type
|
||||
self.name = name
|
||||
self.canvas_node = canvas_node
|
||||
|
||||
self.top = tk.Toplevel()
|
||||
self.top.title(node_type + " configuration")
|
||||
self.namevar = tk.StringVar(self.top, value="default name")
|
||||
self.name_and_image_definition()
|
||||
self.type_and_service_definition()
|
||||
self.select_definition()
|
||||
|
||||
def open_icon_dir(self, toplevel, entry_text):
|
||||
imgfile = filedialog.askopenfilename(
|
||||
initialdir=ICONS_DIR,
|
||||
title="Open",
|
||||
filetypes=(
|
||||
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
|
||||
("All Files", "*"),
|
||||
),
|
||||
)
|
||||
if len(imgfile) > 0:
|
||||
img = Image.open(imgfile)
|
||||
tk_img = ImageTk.PhotoImage(img)
|
||||
lb = toplevel.grid_slaves(1, 0)[0]
|
||||
lb.configure(image=tk_img)
|
||||
lb.image = tk_img
|
||||
entry_text.set(imgfile)
|
||||
|
||||
def click_apply(self, toplevel, entry_text):
|
||||
print("click apply")
|
||||
imgfile = entry_text.get()
|
||||
if imgfile:
|
||||
img = Image.open(imgfile)
|
||||
tk_img = ImageTk.PhotoImage(img)
|
||||
lb = self.top.grid_slaves(row=0, column=3)[0]
|
||||
lb.configure(image=tk_img)
|
||||
lb.image = tk_img
|
||||
self.image = tk_img
|
||||
toplevel.destroy()
|
||||
|
||||
def img_modification(self):
|
||||
print("image modification")
|
||||
t = tk.Toplevel()
|
||||
t.title(self.name + " image")
|
||||
|
||||
f = tk.Frame(t)
|
||||
entry_text = tk.StringVar()
|
||||
image_file_label = tk.Label(f, text="Image file: ")
|
||||
image_file_label.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
image_file_entry = tk.Entry(f, textvariable=entry_text, width=60)
|
||||
image_file_entry.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
image_file_button = tk.Button(
|
||||
f, text="...", command=lambda: self.open_icon_dir(t, entry_text)
|
||||
)
|
||||
image_file_button.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
f.grid(sticky=tk.W + tk.E)
|
||||
|
||||
img = tk.Label(t, image=self.image)
|
||||
img.grid(sticky=tk.W + tk.E)
|
||||
|
||||
f = tk.Frame(t)
|
||||
apply_button = tk.Button(
|
||||
f, text="Apply", command=lambda: self.click_apply(t, entry_text)
|
||||
)
|
||||
apply_button.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
apply_to_multiple_button = tk.Button(f, text="Apply to multiple...")
|
||||
apply_to_multiple_button.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
cancel_button = tk.Button(f, text="Cancel", command=t.destroy)
|
||||
cancel_button.pack(side=tk.LEFT, padx=2, pady=2)
|
||||
f.grid(sticky=tk.E + tk.W)
|
||||
|
||||
def name_and_image_definition(self):
|
||||
name_label = tk.Label(self.top, text="Node name: ")
|
||||
name_label.grid()
|
||||
name_entry = tk.Entry(self.top, textvariable=self.namevar)
|
||||
name_entry.grid(row=0, column=1)
|
||||
|
||||
core_button = tk.Button(self.top, text="None")
|
||||
core_button.grid(row=0, column=2)
|
||||
img_button = tk.Button(
|
||||
self.top,
|
||||
image=self.image,
|
||||
width=40,
|
||||
height=40,
|
||||
command=self.img_modification,
|
||||
)
|
||||
img_button.grid(row=0, column=3)
|
||||
|
||||
def type_and_service_definition(self):
|
||||
f = tk.Frame(self.top)
|
||||
type_label = tk.Label(f, text="Type: ")
|
||||
type_label.pack(side=tk.LEFT)
|
||||
|
||||
type_button = tk.Button(f, text="None")
|
||||
type_button.pack(side=tk.LEFT)
|
||||
|
||||
service_button = tk.Button(f, text="Services...")
|
||||
service_button.pack(side=tk.LEFT)
|
||||
|
||||
f.grid(row=1, column=1, columnspan=2, sticky=tk.W)
|
||||
|
||||
def config_apply(self):
|
||||
"""
|
||||
modify image of the canvas node
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("nodeconfigtable.py configuration apply")
|
||||
self.canvas_node.image = self.image
|
||||
self.canvas_node.canvas.itemconfig(self.canvas_node.id, image=self.image)
|
||||
self.top.destroy()
|
||||
|
||||
def config_cancel(self):
|
||||
"""
|
||||
save chosen image but not modify canvas node
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("nodeconfigtable.py configuration cancel")
|
||||
self.canvas_node.image = self.image
|
||||
self.top.destroy()
|
||||
|
||||
def select_definition(self):
|
||||
f = tk.Frame(self.top)
|
||||
apply_button = tk.Button(f, text="Apply", command=self.config_apply)
|
||||
apply_button.pack(side=tk.LEFT)
|
||||
cancel_button = tk.Button(f, text="Cancel", command=self.config_cancel)
|
||||
cancel_button.pack(side=tk.LEFT)
|
||||
f.grid(row=3, column=1, sticky=tk.W)
|
||||
|
||||
def network_node_config(self):
|
||||
self.name_and_image_definition()
|
||||
self.select_definition()
|
|
@ -7,6 +7,11 @@ from coretk.images import ImageEnum, Images
|
|||
|
||||
class SessionTable:
|
||||
def __init__(self, grpc, master):
|
||||
"""
|
||||
create session table instance
|
||||
:param coretk.coregrpc.CoreGrpc grpc: coregrpc
|
||||
:param root.master master:
|
||||
"""
|
||||
self.grpc = grpc
|
||||
self.selected = False
|
||||
self.selected_sid = None
|
||||
|
@ -22,6 +27,10 @@ class SessionTable:
|
|||
self.draw()
|
||||
|
||||
def description_definition(self):
|
||||
"""
|
||||
write a short description
|
||||
:return: nothing
|
||||
"""
|
||||
lable = tk.Label(
|
||||
self.top,
|
||||
text="Below is a list of active CORE sessions. Double-click to "
|
||||
|
|
Loading…
Add table
Reference in a new issue