core-cli: updates to add back json output

This commit is contained in:
Blake Harnden 2022-03-21 20:59:18 -07:00
parent 5398cdd2d5
commit b941395100
2 changed files with 139 additions and 68 deletions

View file

@ -637,6 +637,15 @@ class SessionSummary:
dir=proto.dir, dir=proto.dir,
) )
def to_proto(self) -> core_pb2.SessionSummary:
return core_pb2.SessionSummary(
id=self.id,
state=self.state.value,
nodes=self.nodes,
file=self.file,
dir=self.dir,
)
@dataclass @dataclass
class Hook: class Hook:

View file

@ -1,22 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json
import sys import sys
from argparse import ( from argparse import (
ArgumentDefaultsHelpFormatter, ArgumentDefaultsHelpFormatter,
ArgumentParser, ArgumentParser,
ArgumentTypeError, ArgumentTypeError,
Namespace, Namespace,
_SubParsersAction,
) )
from functools import wraps from functools import wraps
from pathlib import Path from pathlib import Path
from typing import Optional, Tuple from typing import Any, Dict, Optional, Tuple
import grpc import grpc
import netaddr import netaddr
from google.protobuf.json_format import MessageToDict
from netaddr import EUI, AddrFormatError, IPNetwork from netaddr import EUI, AddrFormatError, IPNetwork
from core.api.grpc.client import CoreGrpcClient from core.api.grpc.client import CoreGrpcClient
from core.api.grpc.wrappers import ( from core.api.grpc.wrappers import (
ConfigOption,
Geo, Geo,
Interface, Interface,
Link, Link,
@ -29,6 +31,15 @@ from core.api.grpc.wrappers import (
NODE_TYPES = [x for x in NodeType if x != NodeType.PEER_TO_PEER] NODE_TYPES = [x for x in NodeType if x != NodeType.PEER_TO_PEER]
def protobuf_to_json(message: Any) -> Dict[str, Any]:
return MessageToDict(message, including_default_value_fields=True, preserving_proto_field_name=True)
def print_json(data: Any) -> None:
data = json.dumps(data, indent=2)
print(data)
def coreclient(func): def coreclient(func):
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
@ -140,6 +151,9 @@ def print_iface(iface: Interface) -> None:
def get_wlan_config(core: CoreGrpcClient, args: Namespace) -> None: def get_wlan_config(core: CoreGrpcClient, args: Namespace) -> None:
session_id = get_current_session(core, args.session) session_id = get_current_session(core, args.session)
config = core.get_wlan_config(session_id, args.node) config = core.get_wlan_config(session_id, args.node)
if args.json:
print_json(ConfigOption.to_dict(config))
else:
size = 0 size = 0
for option in config.values(): for option in config.values():
size = max(size, len(option.name)) size = max(size, len(option.name))
@ -163,18 +177,28 @@ def set_wlan_config(core: CoreGrpcClient, args: Namespace) -> None:
if args.range: if args.range:
config["range"] = str(args.range) config["range"] = str(args.range)
result = core.set_wlan_config(session_id, args.node, config) result = core.set_wlan_config(session_id, args.node, config)
if args.json:
print_json(dict(result=result))
else:
print(f"set wlan config: {result}") print(f"set wlan config: {result}")
@coreclient @coreclient
def open_xml(core: CoreGrpcClient, args: Namespace) -> None: def open_xml(core: CoreGrpcClient, args: Namespace) -> None:
result, session_id = core.open_xml(args.file, args.start) result, session_id = core.open_xml(args.file, args.start)
if args.json:
print_json(dict(result=result, session_id=session_id))
else:
print(f"opened xml: {result},{session_id}") print(f"opened xml: {result},{session_id}")
@coreclient @coreclient
def query_sessions(core: CoreGrpcClient, args: Namespace) -> None: def query_sessions(core: CoreGrpcClient, args: Namespace) -> None:
sessions = core.get_sessions() sessions = core.get_sessions()
if args.json:
sessions = [protobuf_to_json(x.to_proto()) for x in sessions]
print_json(sessions)
else:
print("Session ID | Session State | Nodes") print("Session ID | Session State | Nodes")
for session in sessions: for session in sessions:
print(f"{session.id:<10} | {session.state.name:<13} | {session.nodes}") print(f"{session.id:<10} | {session.state.name:<13} | {session.nodes}")
@ -183,6 +207,10 @@ def query_sessions(core: CoreGrpcClient, args: Namespace) -> None:
@coreclient @coreclient
def query_session(core: CoreGrpcClient, args: Namespace) -> None: def query_session(core: CoreGrpcClient, args: Namespace) -> None:
session = core.get_session(args.id) session = core.get_session(args.id)
if args.json:
session = protobuf_to_json(session.to_proto())
print_json(session)
else:
print("Nodes") print("Nodes")
print("Node ID | Node Name | Node Type") print("Node ID | Node Name | Node Type")
for node in session.nodes.values(): for node in session.nodes.values():
@ -210,6 +238,11 @@ def query_session(core: CoreGrpcClient, args: Namespace) -> None:
def query_node(core: CoreGrpcClient, args: Namespace) -> None: def query_node(core: CoreGrpcClient, args: Namespace) -> None:
session = core.get_session(args.id) session = core.get_session(args.id)
node, ifaces, _ = core.get_node(args.id, args.node) node, ifaces, _ = core.get_node(args.id, args.node)
if args.json:
node = protobuf_to_json(node.to_proto())
ifaces = [protobuf_to_json(x.to_proto()) for x in ifaces]
print_json(dict(node=node, ifaces=ifaces))
else:
print("ID | Name | Type | XY") print("ID | Name | Type | XY")
xy_pos = f"{int(node.position.x)},{int(node.position.y)}" xy_pos = f"{int(node.position.x)},{int(node.position.y)}"
print(f"{node.id:<4} | {node.name[:7]:<7} | {node.type.name[:7]:<7} | {xy_pos}") print(f"{node.id:<4} | {node.name[:7]:<7} | {node.type.name[:7]:<7} | {xy_pos}")
@ -236,6 +269,9 @@ def query_node(core: CoreGrpcClient, args: Namespace) -> None:
@coreclient @coreclient
def delete_session(core: CoreGrpcClient, args: Namespace) -> None: def delete_session(core: CoreGrpcClient, args: Namespace) -> None:
result = core.delete_session(args.id) result = core.delete_session(args.id)
if args.json:
print_json(dict(result=result))
else:
print(f"delete session({args.id}): {result}") print(f"delete session({args.id}): {result}")
@ -263,6 +299,9 @@ def add_node(core: CoreGrpcClient, args: Namespace) -> None:
geo=geo, geo=geo,
) )
node_id = core.add_node(session_id, node) node_id = core.add_node(session_id, node)
if args.json:
print_json(dict(node_id=node_id))
else:
print(f"created node: {node_id}") print(f"created node: {node_id}")
@ -270,6 +309,9 @@ def add_node(core: CoreGrpcClient, args: Namespace) -> None:
def edit_node(core: CoreGrpcClient, args: Namespace) -> None: def edit_node(core: CoreGrpcClient, args: Namespace) -> None:
session_id = get_current_session(core, args.session) session_id = get_current_session(core, args.session)
result = core.edit_node(session_id, args.id, args.icon) result = core.edit_node(session_id, args.id, args.icon)
if args.json:
print_json(dict(result=result))
else:
print(f"edit node: {result}") print(f"edit node: {result}")
@ -285,6 +327,9 @@ def move_node(core: CoreGrpcClient, args: Namespace) -> None:
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)
result = core.move_node(session_id, args.id, pos, geo) result = core.move_node(session_id, args.id, pos, geo)
if args.json:
print_json(dict(result=result))
else:
print(f"move node: {result}") print(f"move node: {result}")
@ -292,6 +337,9 @@ def move_node(core: CoreGrpcClient, args: Namespace) -> None:
def delete_node(core: CoreGrpcClient, args: Namespace) -> None: def delete_node(core: CoreGrpcClient, args: Namespace) -> None:
session_id = get_current_session(core, args.session) session_id = get_current_session(core, args.session)
result = core.delete_node(session_id, args.id) result = core.delete_node(session_id, args.id)
if args.json:
print_json(dict(result=result))
else:
print(f"deleted node: {result}") print(f"deleted node: {result}")
@ -313,7 +361,12 @@ def add_link(core: CoreGrpcClient, args: Namespace) -> None:
unidirectional=args.uni, unidirectional=args.uni,
) )
link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2, options=options) link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2, options=options)
result, _, _ = core.add_link(session_id, link) result, iface1, iface2 = core.add_link(session_id, link)
if args.json:
iface1 = protobuf_to_json(iface1.to_proto())
iface2 = protobuf_to_json(iface2.to_proto())
print_json(dict(result=result, iface1=iface1, iface2=iface2))
else:
print(f"add link: {result}") print(f"add link: {result}")
@ -332,6 +385,9 @@ def edit_link(core: CoreGrpcClient, args: Namespace) -> None:
iface2 = Interface(args.iface2) iface2 = Interface(args.iface2)
link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2, options=options) link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2, options=options)
result = core.edit_link(session_id, link) result = core.edit_link(session_id, link)
if args.json:
print_json(dict(result=result))
else:
print(f"edit link: {result}") print(f"edit link: {result}")
@ -342,10 +398,13 @@ def delete_link(core: CoreGrpcClient, args: Namespace) -> None:
iface2 = Interface(args.iface2) iface2 = Interface(args.iface2)
link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2) link = Link(args.node1, args.node2, iface1=iface1, iface2=iface2)
result = core.delete_link(session_id, link) result = core.delete_link(session_id, link)
if args.json:
print_json(dict(result=result))
else:
print(f"delete link: {result}") print(f"delete link: {result}")
def setup_sessions_parser(parent: _SubParsersAction) -> None: def setup_sessions_parser(parent) -> None:
parser = parent.add_parser("session", help="session interactions") parser = parent.add_parser("session", help="session interactions")
parser.formatter_class = ArgumentDefaultsHelpFormatter parser.formatter_class = ArgumentDefaultsHelpFormatter
parser.add_argument("-i", "--id", type=int, help="session id to use", required=True) parser.add_argument("-i", "--id", type=int, help="session id to use", required=True)
@ -358,7 +417,7 @@ def setup_sessions_parser(parent: _SubParsersAction) -> None:
delete_parser.set_defaults(func=delete_session) delete_parser.set_defaults(func=delete_session)
def setup_node_parser(parent: _SubParsersAction) -> None: def setup_node_parser(parent) -> None:
parser = parent.add_parser("node", help="node interactions") parser = parent.add_parser("node", help="node interactions")
parser.formatter_class = ArgumentDefaultsHelpFormatter parser.formatter_class = ArgumentDefaultsHelpFormatter
parser.add_argument("-s", "--session", type=int, help="session to interact with") parser.add_argument("-s", "--session", type=int, help="session to interact with")
@ -402,7 +461,7 @@ def setup_node_parser(parent: _SubParsersAction) -> None:
delete_parser.set_defaults(func=delete_node) delete_parser.set_defaults(func=delete_node)
def setup_link_parser(parent: _SubParsersAction) -> None: def setup_link_parser(parent) -> None:
parser = parent.add_parser("link", help="link interactions") parser = parent.add_parser("link", help="link interactions")
parser.formatter_class = ArgumentDefaultsHelpFormatter parser.formatter_class = ArgumentDefaultsHelpFormatter
parser.add_argument("-s", "--session", type=int, help="session to interact with") parser.add_argument("-s", "--session", type=int, help="session to interact with")
@ -455,7 +514,7 @@ def setup_link_parser(parent: _SubParsersAction) -> None:
delete_parser.set_defaults(func=delete_link) delete_parser.set_defaults(func=delete_link)
def setup_query_parser(parent: _SubParsersAction) -> None: def setup_query_parser(parent) -> None:
parser = parent.add_parser("query", help="query interactions") parser = parent.add_parser("query", help="query interactions")
subparsers = parser.add_subparsers(help="query commands") subparsers = parser.add_subparsers(help="query commands")
subparsers.required = True subparsers.required = True
@ -477,7 +536,7 @@ def setup_query_parser(parent: _SubParsersAction) -> None:
node_parser.set_defaults(func=query_node) node_parser.set_defaults(func=query_node)
def setup_xml_parser(parent: _SubParsersAction) -> None: def setup_xml_parser(parent) -> None:
parser = parent.add_parser("xml", help="open session xml") parser = parent.add_parser("xml", help="open session xml")
parser.formatter_class = ArgumentDefaultsHelpFormatter parser.formatter_class = ArgumentDefaultsHelpFormatter
parser.add_argument("-f", "--file", type=file_type, help="xml file to open", required=True) parser.add_argument("-f", "--file", type=file_type, help="xml file to open", required=True)
@ -485,7 +544,7 @@ def setup_xml_parser(parent: _SubParsersAction) -> None:
parser.set_defaults(func=open_xml) parser.set_defaults(func=open_xml)
def setup_wlan_parser(parent: _SubParsersAction) -> None: def setup_wlan_parser(parent) -> None:
parser = parent.add_parser("wlan", help="wlan specific interactions") parser = parent.add_parser("wlan", help="wlan specific interactions")
parser.formatter_class = ArgumentDefaultsHelpFormatter parser.formatter_class = ArgumentDefaultsHelpFormatter
parser.add_argument("-s", "--session", type=int, help="session to interact with") parser.add_argument("-s", "--session", type=int, help="session to interact with")
@ -511,6 +570,9 @@ def setup_wlan_parser(parent: _SubParsersAction) -> None:
def main() -> None: def main() -> None:
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument(
"-js", "--json", action="store_true", help="print responses to terminal as json"
)
subparsers = parser.add_subparsers(help="supported commands") subparsers = parser.add_subparsers(help="supported commands")
subparsers.required = True subparsers.required = True
subparsers.dest = "command" subparsers.dest = "command"