71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
opp-dm.py: Operator Direct Messages
|
||
|
|
|
||
|
|
For operator-to-operator communication (646, operator-main).
|
||
|
|
Operators have SSH access and infrastructure tools.
|
||
|
|
This is bidirectional and reliable.
|
||
|
|
|
||
|
|
Distinct from dev-dm.py (for task agents: muse, pip).
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
opp-dm.py send --to 646 "message" # operator-main -> 646
|
||
|
|
opp-dm.py send --to operator-main "msg" # 646 -> operator-main (via SSH)
|
||
|
|
opp-dm.py read [--from 646] # Read operator messages
|
||
|
|
"""
|
||
|
|
import argparse
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
import time
|
||
|
|
|
||
|
|
# Operators have SSH access to bl
|
||
|
|
# Messages stored in a shared location on bl
|
||
|
|
BL_MSG_DIR = "/home/super/Projects/NetVM/opp-dms"
|
||
|
|
|
||
|
|
def bl_run(cmd):
|
||
|
|
"""Run command on bl via SSH."""
|
||
|
|
full = f"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@100.123.153.75 '{cmd}'"
|
||
|
|
# Via VM
|
||
|
|
vm_cmd = f"ssh -i ~/.ssh/vm_to_gcp -o ProxyCommand=\"$HOME/workspace/bin/ssh-via-proxy %h %p\" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@34.139.37.135 \"{full}\""
|
||
|
|
result = subprocess.run(vm_cmd, shell=True, capture_output=True, text=True, timeout=30)
|
||
|
|
return result.stdout.strip()
|
||
|
|
|
||
|
|
def opp_send(to, message, from_who="operator-main"):
|
||
|
|
"""Send an operator DM (stored on bl, both can access via SSH)."""
|
||
|
|
import datetime
|
||
|
|
ts = datetime.datetime.now().isoformat()
|
||
|
|
# Escape for shell
|
||
|
|
safe = message.replace("'", "'\"'\"'")[:1000]
|
||
|
|
cmd = f"mkdir -p {BL_MSG_DIR} && echo '{ts} [{from_who}]: {safe}' >> {BL_MSG_DIR}/{to}.log && echo 'sent'"
|
||
|
|
result = bl_run(cmd)
|
||
|
|
print(f"OPP-DM sent to {to}")
|
||
|
|
return result
|
||
|
|
|
||
|
|
def opp_read(who="operator-main", n=5):
|
||
|
|
"""Read operator DMs."""
|
||
|
|
cmd = f"tail -n {n*2} {BL_MSG_DIR}/{who}.log 2>/dev/null || echo 'no messages'"
|
||
|
|
result = bl_run(cmd)
|
||
|
|
print(result)
|
||
|
|
return result
|
||
|
|
|
||
|
|
def main():
|
||
|
|
p = argparse.ArgumentParser(description="OPP-DM: Operator Direct Messages")
|
||
|
|
sub = p.add_subparsers(dest='cmd', required=True)
|
||
|
|
|
||
|
|
ps = sub.add_parser('send', help='Send operator DM')
|
||
|
|
ps.add_argument('--to', required=True, choices=['646', 'operator-main'])
|
||
|
|
ps.add_argument('--from', dest='from_who', default='operator-main')
|
||
|
|
ps.add_argument('message', help='Message')
|
||
|
|
ps.set_defaults(func=lambda a: opp_send(a.to, a.message, a.from_who))
|
||
|
|
|
||
|
|
pr = sub.add_parser('read', help='Read operator DMs')
|
||
|
|
pr.add_argument('--who', default='operator-main', choices=['646', 'operator-main'])
|
||
|
|
pr.add_argument('--n', type=int, default=5)
|
||
|
|
pr.set_defaults(func=lambda a: opp_read(a.who, a.n))
|
||
|
|
|
||
|
|
args = p.parse_args()
|
||
|
|
args.func(args)
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
main()
|