core-cli: cleaned up core client usage by way of a decorator, helps provide convenient grpc error catching
This commit is contained in:
parent
3477e84e9d
commit
7a6c602369
1 changed files with 170 additions and 176 deletions
|
@ -7,6 +7,7 @@ from argparse import (
|
||||||
Namespace,
|
Namespace,
|
||||||
_SubParsersAction,
|
_SubParsersAction,
|
||||||
)
|
)
|
||||||
|
from functools import wraps
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Optional, Tuple
|
from typing import Any, Optional, Tuple
|
||||||
|
|
||||||
|
@ -29,6 +30,19 @@ from core.api.grpc.core_pb2 import (
|
||||||
NODE_TYPES = [k for k, v in NodeType.Enum.items() if v != NodeType.PEER_TO_PEER]
|
NODE_TYPES = [k for k, v in NodeType.Enum.items() if v != NodeType.PEER_TO_PEER]
|
||||||
|
|
||||||
|
|
||||||
|
def coreclient(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
core = CoreGrpcClient()
|
||||||
|
try:
|
||||||
|
with core.context_connect():
|
||||||
|
return func(core, *args, **kwargs)
|
||||||
|
except grpc.RpcError as e:
|
||||||
|
print(f"grpc error: {e.details()}")
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def mac_type(value: str) -> str:
|
def mac_type(value: str) -> str:
|
||||||
try:
|
try:
|
||||||
mac = EUI(value, dialect=netaddr.mac_unix_expanded)
|
mac = EUI(value, dialect=netaddr.mac_unix_expanded)
|
||||||
|
@ -88,12 +102,10 @@ def file_type(value: str) -> str:
|
||||||
return str(path.absolute())
|
return str(path.absolute())
|
||||||
|
|
||||||
|
|
||||||
def get_current_session(session_id: Optional[int]) -> int:
|
def get_current_session(core: CoreGrpcClient, session_id: Optional[int]) -> int:
|
||||||
if session_id:
|
if session_id:
|
||||||
return session_id
|
return session_id
|
||||||
core = CoreGrpcClient()
|
response = core.get_sessions()
|
||||||
with core.context_connect():
|
|
||||||
response = core.get_sessions()
|
|
||||||
if not response.sessions:
|
if not response.sessions:
|
||||||
print("no current session to interact with")
|
print("no current session to interact with")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -130,27 +142,24 @@ def print_json(message: Any) -> None:
|
||||||
print(json)
|
print(json)
|
||||||
|
|
||||||
|
|
||||||
def get_wlan_config(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def get_wlan_config(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
core = CoreGrpcClient()
|
session_id = get_current_session(core, args.session)
|
||||||
try:
|
response = core.get_wlan_config(session_id, args.node)
|
||||||
with core.context_connect():
|
if args.json:
|
||||||
response = core.get_wlan_config(session_id, args.node)
|
print_json(response)
|
||||||
if args.json:
|
else:
|
||||||
print_json(response)
|
size = 0
|
||||||
else:
|
for option in response.config.values():
|
||||||
size = 0
|
size = max(size, len(option.name))
|
||||||
for option in response.config.values():
|
print(f"{'Name':<{size}.{size}} | Value")
|
||||||
size = max(size, len(option.name))
|
for option in response.config.values():
|
||||||
print(f"{'Name':<{size}.{size}} | Value")
|
print(f"{option.name:<{size}.{size}} | {option.value}")
|
||||||
for option in response.config.values():
|
|
||||||
print(f"{option.name:<{size}.{size}} | {option.value}")
|
|
||||||
except grpc.RpcError as e:
|
|
||||||
print(f"grpc error: {e.details()}")
|
|
||||||
|
|
||||||
|
|
||||||
def set_wlan_config(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def set_wlan_config(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
session_id = get_current_session(core, args.session)
|
||||||
config = {}
|
config = {}
|
||||||
if args.bandwidth:
|
if args.bandwidth:
|
||||||
config["bandwidth"] = str(args.bandwidth)
|
config["bandwidth"] = str(args.bandwidth)
|
||||||
|
@ -162,108 +171,100 @@ def set_wlan_config(args: Namespace) -> None:
|
||||||
config["jitter"] = str(args.jitter)
|
config["jitter"] = str(args.jitter)
|
||||||
if args.range:
|
if args.range:
|
||||||
config["range"] = str(args.range)
|
config["range"] = str(args.range)
|
||||||
core = CoreGrpcClient()
|
response = core.set_wlan_config(session_id, args.node, config)
|
||||||
try:
|
if args.json:
|
||||||
with core.context_connect():
|
print_json(response)
|
||||||
response = core.set_wlan_config(session_id, args.node, config)
|
else:
|
||||||
if args.json:
|
print(f"set wlan config: {response.result}")
|
||||||
print_json(response)
|
|
||||||
else:
|
|
||||||
print(f"set wlan config: {response.result}")
|
|
||||||
except grpc.RpcError as e:
|
|
||||||
print(f"grpc error: {e.details()}")
|
|
||||||
|
|
||||||
|
|
||||||
def open_xml(args: Namespace) -> None:
|
@coreclient
|
||||||
core = CoreGrpcClient()
|
def open_xml(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
with core.context_connect():
|
response = core.open_xml(args.file, args.start)
|
||||||
response = core.open_xml(args.file, args.start)
|
if args.json:
|
||||||
if args.json:
|
print_json(response)
|
||||||
print_json(response)
|
else:
|
||||||
else:
|
print(f"opened xml: {response.result}")
|
||||||
print(f"opened xml: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def query_sessions(args: Namespace) -> None:
|
@coreclient
|
||||||
core = CoreGrpcClient()
|
def query_sessions(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
with core.context_connect():
|
response = core.get_sessions()
|
||||||
response = core.get_sessions()
|
if args.json:
|
||||||
if args.json:
|
print_json(response)
|
||||||
print_json(response)
|
else:
|
||||||
else:
|
print("Session ID | Session State | Nodes")
|
||||||
print("Session ID | Session State | Nodes")
|
for s in response.sessions:
|
||||||
for s in response.sessions:
|
state = SessionState.Enum.Name(s.state)
|
||||||
state = SessionState.Enum.Name(s.state)
|
print(f"{s.id:<10} | {state:<13} | {s.nodes}")
|
||||||
print(f"{s.id:<10} | {state:<13} | {s.nodes}")
|
|
||||||
|
|
||||||
|
|
||||||
def query_session(args: Namespace) -> None:
|
@coreclient
|
||||||
core = CoreGrpcClient()
|
def query_session(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
with core.context_connect():
|
response = core.get_session(args.id)
|
||||||
response = core.get_session(args.id)
|
if args.json:
|
||||||
if args.json:
|
print_json(response)
|
||||||
print_json(response)
|
else:
|
||||||
else:
|
print("Nodes")
|
||||||
print("Nodes")
|
print("Node ID | Node Name | Node Type")
|
||||||
print("Node ID | Node Name | Node Type")
|
|
||||||
names = {}
|
|
||||||
for node in response.session.nodes:
|
|
||||||
names[node.id] = node.name
|
|
||||||
node_type = NodeType.Enum.Name(node.type)
|
|
||||||
print(f"{node.id:<7} | {node.name:<9} | {node_type}")
|
|
||||||
|
|
||||||
print("\nLinks")
|
|
||||||
for link in response.session.links:
|
|
||||||
n1 = names[link.node1_id]
|
|
||||||
n2 = names[link.node2_id]
|
|
||||||
print(f"Node | ", end="")
|
|
||||||
print_iface_header()
|
|
||||||
print(f"{n1:<6} | ", end="")
|
|
||||||
if link.HasField("iface1"):
|
|
||||||
print_iface(link.iface1)
|
|
||||||
else:
|
|
||||||
print()
|
|
||||||
print(f"{n2:<6} | ", end="")
|
|
||||||
if link.HasField("iface2"):
|
|
||||||
print_iface(link.iface2)
|
|
||||||
else:
|
|
||||||
print()
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def query_node(args: Namespace) -> None:
|
|
||||||
core = CoreGrpcClient()
|
|
||||||
with core.context_connect():
|
|
||||||
names = {}
|
names = {}
|
||||||
response = core.get_session(args.id)
|
|
||||||
for node in response.session.nodes:
|
for node in response.session.nodes:
|
||||||
names[node.id] = node.name
|
names[node.id] = node.name
|
||||||
|
|
||||||
response = core.get_node(args.id, args.node)
|
|
||||||
if args.json:
|
|
||||||
print_json(response)
|
|
||||||
else:
|
|
||||||
node = response.node
|
|
||||||
node_type = NodeType.Enum.Name(node.type)
|
node_type = NodeType.Enum.Name(node.type)
|
||||||
print("ID | Name | Type")
|
print(f"{node.id:<7} | {node.name:<9} | {node_type}")
|
||||||
print(f"{node.id:<4} | {node.name:<7} | {node_type}")
|
|
||||||
print("Interfaces")
|
print("\nLinks")
|
||||||
print("Connected To | ", end="")
|
for link in response.session.links:
|
||||||
|
n1 = names[link.node1_id]
|
||||||
|
n2 = names[link.node2_id]
|
||||||
|
print(f"Node | ", end="")
|
||||||
print_iface_header()
|
print_iface_header()
|
||||||
for iface in response.ifaces:
|
print(f"{n1:<6} | ", end="")
|
||||||
if iface.net_id == node.id:
|
if link.HasField("iface1"):
|
||||||
if iface.node_id:
|
print_iface(link.iface1)
|
||||||
name = names[iface.node_id]
|
else:
|
||||||
else:
|
print()
|
||||||
name = names[iface.net2_id]
|
print(f"{n2:<6} | ", end="")
|
||||||
|
if link.HasField("iface2"):
|
||||||
|
print_iface(link.iface2)
|
||||||
|
else:
|
||||||
|
print()
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
@coreclient
|
||||||
|
def query_node(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
names = {}
|
||||||
|
response = core.get_session(args.id)
|
||||||
|
for node in response.session.nodes:
|
||||||
|
names[node.id] = node.name
|
||||||
|
|
||||||
|
response = core.get_node(args.id, args.node)
|
||||||
|
if args.json:
|
||||||
|
print_json(response)
|
||||||
|
else:
|
||||||
|
node = response.node
|
||||||
|
node_type = NodeType.Enum.Name(node.type)
|
||||||
|
print("ID | Name | Type")
|
||||||
|
print(f"{node.id:<4} | {node.name:<7} | {node_type}")
|
||||||
|
print("Interfaces")
|
||||||
|
print("Connected To | ", end="")
|
||||||
|
print_iface_header()
|
||||||
|
for iface in response.ifaces:
|
||||||
|
if iface.net_id == node.id:
|
||||||
|
if iface.node_id:
|
||||||
|
name = names[iface.node_id]
|
||||||
else:
|
else:
|
||||||
name = names[iface.net_id]
|
name = names[iface.net2_id]
|
||||||
print(f"{name:<12} | ", end="")
|
else:
|
||||||
print_iface(iface)
|
name = names[iface.net_id]
|
||||||
|
print(f"{name:<12} | ", end="")
|
||||||
|
print_iface(iface)
|
||||||
|
|
||||||
|
|
||||||
def add_node(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def add_node(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
session_id = get_current_session(core, args.session)
|
||||||
node_type = NodeType.Enum.Value(args.type)
|
node_type = NodeType.Enum.Value(args.type)
|
||||||
pos = None
|
pos = None
|
||||||
if args.pos:
|
if args.pos:
|
||||||
|
@ -273,28 +274,27 @@ def add_node(args: Namespace) -> None:
|
||||||
if args.geo:
|
if args.geo:
|
||||||
lon, lat, alt = args.geo
|
lon, lat, alt = args.geo
|
||||||
geo = Geo(lon=lon, lat=lat, alt=alt)
|
geo = Geo(lon=lon, lat=lat, alt=alt)
|
||||||
core = CoreGrpcClient()
|
node = Node(
|
||||||
with core.context_connect():
|
id=args.id,
|
||||||
node = Node(
|
name=args.name,
|
||||||
id=args.id,
|
type=node_type,
|
||||||
name=args.name,
|
model=args.model,
|
||||||
type=node_type,
|
emane=args.emane,
|
||||||
model=args.model,
|
icon=args.icon,
|
||||||
emane=args.emane,
|
image=args.image,
|
||||||
icon=args.icon,
|
position=pos,
|
||||||
image=args.image,
|
geo=geo,
|
||||||
position=pos,
|
)
|
||||||
geo=geo,
|
response = core.add_node(session_id, node)
|
||||||
)
|
if args.json:
|
||||||
response = core.add_node(session_id, node)
|
print_json(response)
|
||||||
if args.json:
|
else:
|
||||||
print_json(response)
|
print(f"created node: {response.node_id}")
|
||||||
else:
|
|
||||||
print(f"created node: {response.node_id}")
|
|
||||||
|
|
||||||
|
|
||||||
def edit_node(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def edit_node(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
session_id = get_current_session(core, args.session)
|
||||||
pos = None
|
pos = None
|
||||||
if args.pos:
|
if args.pos:
|
||||||
x, y = args.pos
|
x, y = args.pos
|
||||||
|
@ -303,28 +303,26 @@ def edit_node(args: Namespace) -> None:
|
||||||
if args.geo:
|
if args.geo:
|
||||||
lon, lat, alt = args.geo
|
lon, lat, alt = args.geo
|
||||||
geo = Geo(lon=lon, lat=lat, alt=alt)
|
geo = Geo(lon=lon, lat=lat, alt=alt)
|
||||||
core = CoreGrpcClient()
|
response = core.edit_node(session_id, args.id, pos, args.icon, geo)
|
||||||
with core.context_connect():
|
if args.json:
|
||||||
response = core.edit_node(session_id, args.id, pos, args.icon, geo)
|
print_json(response)
|
||||||
if args.json:
|
else:
|
||||||
print_json(response)
|
print(f"edit node: {response.result}")
|
||||||
else:
|
|
||||||
print(f"edit node: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def delete_node(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def delete_node(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
core = CoreGrpcClient()
|
session_id = get_current_session(core, args.session)
|
||||||
with core.context_connect():
|
response = core.delete_node(session_id, args.id)
|
||||||
response = core.delete_node(session_id, args.id)
|
if args.json:
|
||||||
if args.json:
|
print_json(response)
|
||||||
print_json(response)
|
else:
|
||||||
else:
|
print(f"deleted node: {response.result}")
|
||||||
print(f"deleted node: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def add_link(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def add_link(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
session_id = get_current_session(core, args.session)
|
||||||
iface1 = None
|
iface1 = None
|
||||||
if args.iface1_id is not None:
|
if args.iface1_id is not None:
|
||||||
iface1 = create_iface(args.iface1_id, args.iface1_mac, args.iface1_ip4, args.iface1_ip6)
|
iface1 = create_iface(args.iface1_id, args.iface1_mac, args.iface1_ip4, args.iface1_ip6)
|
||||||
|
@ -339,17 +337,16 @@ def add_link(args: Namespace) -> None:
|
||||||
dup=args.duplicate,
|
dup=args.duplicate,
|
||||||
unidirectional=args.uni,
|
unidirectional=args.uni,
|
||||||
)
|
)
|
||||||
core = CoreGrpcClient()
|
response = core.add_link(session_id, args.node1, args.node2, iface1, iface2, options)
|
||||||
with core.context_connect():
|
if args.json:
|
||||||
response = core.add_link(session_id, args.node1, args.node2, iface1, iface2, options)
|
print_json(response)
|
||||||
if args.json:
|
else:
|
||||||
print_json(response)
|
print(f"add link: {response.result}")
|
||||||
else:
|
|
||||||
print(f"add link: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def edit_link(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def edit_link(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
|
session_id = get_current_session(core, args.session)
|
||||||
options = LinkOptions(
|
options = LinkOptions(
|
||||||
bandwidth=args.bandwidth,
|
bandwidth=args.bandwidth,
|
||||||
loss=args.loss,
|
loss=args.loss,
|
||||||
|
@ -358,26 +355,23 @@ def edit_link(args: Namespace) -> None:
|
||||||
dup=args.duplicate,
|
dup=args.duplicate,
|
||||||
unidirectional=args.uni,
|
unidirectional=args.uni,
|
||||||
)
|
)
|
||||||
core = CoreGrpcClient()
|
response = core.edit_link(
|
||||||
with core.context_connect():
|
session_id, args.node1, args.node2, options, args.iface1, args.iface2
|
||||||
response = core.edit_link(
|
)
|
||||||
session_id, args.node1, args.node2, options, args.iface1, args.iface2
|
if args.json:
|
||||||
)
|
print_json(response)
|
||||||
if args.json:
|
else:
|
||||||
print_json(response)
|
print(f"edit link: {response.result}")
|
||||||
else:
|
|
||||||
print(f"edit link: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def delete_link(args: Namespace) -> None:
|
@coreclient
|
||||||
session_id = get_current_session(args.session)
|
def delete_link(core: CoreGrpcClient, args: Namespace) -> None:
|
||||||
core = CoreGrpcClient()
|
session_id = get_current_session(core, args.session)
|
||||||
with core.context_connect():
|
response = core.delete_link(session_id, args.node1, args.node2, args.iface1, args.iface2)
|
||||||
response = core.delete_link(session_id, args.node1, args.node2, args.iface1, args.iface2)
|
if args.json:
|
||||||
if args.json:
|
print_json(response)
|
||||||
print_json(response)
|
else:
|
||||||
else:
|
print(f"delete link: {response.result}")
|
||||||
print(f"delete link: {response.result}")
|
|
||||||
|
|
||||||
|
|
||||||
def setup_node_parser(parent: _SubParsersAction) -> None:
|
def setup_node_parser(parent: _SubParsersAction) -> None:
|
||||||
|
|
Loading…
Add table
Reference in a new issue