more work on coretk

This commit is contained in:
Huy Pham 2019-10-21 16:33:18 -07:00
parent 38683cb0d0
commit f18d07985a
7 changed files with 256 additions and 10 deletions

View file

@ -93,6 +93,8 @@ class Application(tk.Frame):
self.core_grpc = CoreGrpc(self) self.core_grpc = CoreGrpc(self)
self.core_grpc.set_up() self.core_grpc.set_up()
self.canvas.core_grpc = self.core_grpc 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() self.canvas.draw_existing_component()
def on_closing(self): def on_closing(self):

View file

@ -18,6 +18,9 @@ class CoreGrpc:
""" """
self.core = client.CoreGrpcClient() self.core = client.CoreGrpcClient()
self.session_id = sid self.session_id = sid
self.node_ids = []
self.master = app.master self.master = app.master
# self.set_up() # self.set_up()
@ -32,8 +35,14 @@ class CoreGrpc:
def log_throughput(self, event): def log_throughput(self, event):
interface_throughputs = event.interface_throughputs 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 # 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): def create_new_session(self):
""" """
@ -147,6 +156,7 @@ class CoreGrpc:
def add_node(self, node_type, model, x, y, name, node_id): def add_node(self, node_type, model, x, y, name, node_id):
position = core_pb2.Position(x=x, y=y) position = core_pb2.Position(x=x, y=y)
node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model) 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) response = self.core.add_node(self.session_id, node)
logging.info("created node: %s", response) logging.info("created node: %s", response)
if node_type == core_pb2.NodeType.WIRELESS_LAN: if node_type == core_pb2.NodeType.WIRELESS_LAN:

View file

@ -8,6 +8,7 @@ from coretk.grpcmanagement import GrpcManager
from coretk.images import Images from coretk.images import Images
from coretk.interface import Interface from coretk.interface import Interface
from coretk.linkinfo import LinkInfo from coretk.linkinfo import LinkInfo
from coretk.nodeconfigtable import NodeConfig
class GraphMode(enum.Enum): class GraphMode(enum.Enum):
@ -37,8 +38,8 @@ class CanvasGraph(tk.Canvas):
self.setup_bindings() self.setup_bindings()
self.draw_grid() self.draw_grid()
self.grpc_manager = GrpcManager()
self.core_grpc = grpc self.core_grpc = grpc
self.grpc_manager = GrpcManager(grpc)
self.helper = GraphHelper(self) self.helper = GraphHelper(self)
# self.core_id_to_canvas_id = {} # self.core_id_to_canvas_id = {}
@ -69,7 +70,8 @@ class CanvasGraph(tk.Canvas):
self.nodes = {} self.nodes = {}
self.edges = {} self.edges = {}
self.drawing_edge = None self.drawing_edge = None
self.grpc_manager = GrpcManager()
self.grpc_manager = GrpcManager(new_grpc)
# new grpc # new grpc
self.core_grpc = new_grpc self.core_grpc = new_grpc
@ -463,6 +465,9 @@ class CanvasNode:
state = self.canvas.core_grpc.get_session_state() state = self.canvas.core_grpc.get_session_state()
if state == core_pb2.SessionState.RUNTIME: if state == core_pb2.SessionState.RUNTIME:
self.canvas.core_grpc.launch_terminal(node_id) 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): def update_coords(self):
self.x_coord, self.y_coord = self.canvas.coords(self.id) self.x_coord, self.y_coord = self.canvas.coords(self.id)

View file

@ -54,14 +54,17 @@ class Edge:
class GrpcManager: class GrpcManager:
def __init__(self): def __init__(self, grpc):
self.nodes = {} self.nodes = {}
self.edges = {} self.edges = {}
self.id = 1 self.id = None
# A list of id for re-use, keep in increasing order # A list of id for re-use, keep in increasing order
self.reusable = [] self.reusable = []
self.preexisting = [] self.preexisting = []
self.core_grpc = None
# self.update_preexisting_ids()
# self.core_id_to_canvas_id = {} # self.core_id_to_canvas_id = {}
self.interfaces_manager = InterfaceManager() self.interfaces_manager = InterfaceManager()
@ -69,6 +72,23 @@ class GrpcManager:
# self.node_id_and_interface_to_edge_token = {} # self.node_id_and_interface_to_edge_token = {}
self.core_mapping = CoreToCanvasMapping() 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): def peek_id(self):
""" """
Peek the next id to be used Peek the next id to be used
@ -211,6 +231,8 @@ class GrpcManager:
src_interface = None src_interface = None
dst_interface = None dst_interface = None
self.interfaces_manager.new_subnet()
src_node = self.nodes[src_canvas_id] src_node = self.nodes[src_canvas_id]
if src_node.model in network_layer_nodes: if src_node.model in network_layer_nodes:
ifid = len(src_node.interfaces) ifid = len(src_node.interfaces)

View file

@ -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: class InterfaceManager:
def __init__(self): def __init__(self):
self.addresses = list(ipaddress.ip_network("10.0.0.0/24").hosts()) # self.prefix = None
self.index = 0 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): def get_address(self):
""" """
@ -43,6 +72,24 @@ class InterfaceManager:
:return: :return:
""" """
i = self.index # i = self.index
self.index = self.index + 1 # self.address_index = self.index + 1
return self.addresses[i] # 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())

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

View file

@ -7,6 +7,11 @@ from coretk.images import ImageEnum, Images
class SessionTable: class SessionTable:
def __init__(self, grpc, master): def __init__(self, grpc, master):
"""
create session table instance
:param coretk.coregrpc.CoreGrpc grpc: coregrpc
:param root.master master:
"""
self.grpc = grpc self.grpc = grpc
self.selected = False self.selected = False
self.selected_sid = None self.selected_sid = None
@ -22,6 +27,10 @@ class SessionTable:
self.draw() self.draw()
def description_definition(self): def description_definition(self):
"""
write a short description
:return: nothing
"""
lable = tk.Label( lable = tk.Label(
self.top, self.top,
text="Below is a list of active CORE sessions. Double-click to " text="Below is a list of active CORE sessions. Double-click to "