DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
restcmd
scripts
send-recv-restcmd.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
3
import
argparse
4
import
requests
5
import
json
6
import
time
7
import
sys
8
from
colorama
import
Fore, Back, Style
9
10
from
flask
import
Flask, request, cli
11
from
multiprocessing
import
Process, SimpleQueue
12
import
logging
13
14
from
rich.logging
import
RichHandler
15
16
logging.basicConfig(
17
level=
"INFO"
,
18
format=
"%(message)s"
,
19
datefmt=
"[%X]"
,
20
handlers=[RichHandler(rich_tracebacks=
True
)]
21
)
22
23
24
log = logging.getLogger(
'werkzeug'
)
25
log.setLevel(logging.ERROR)
26
27
OKGREEN =
'\033[92m'
28
FAIL =
'\033[91m'
29
ENDC =
'\033[0m'
30
31
cli.show_server_banner =
lambda
*_:
None
32
33
parser = argparse.ArgumentParser(description=
'POST command object from file to commanded endpoint.'
)
34
parser.add_argument(
'--host'
, type=str, default=
'localhost'
, help=
'target host/endpoint'
)
35
parser.add_argument(
'-p'
,
'--port'
, type=int, default=12345, help=
'target port'
)
36
parser.add_argument(
'-a'
,
'--answer-port'
, type=int, default=12333, help=
'answer to service listening on this port'
)
37
parser.add_argument(
'-o'
,
'--answer-host'
, type=str, default=
None
, help=
'answer to service listening on this host'
)
38
parser.add_argument(
'-x'
,
'--proxy'
, type=str, default=
None
, help=
'Use proxy for posting requests'
)
39
40
parser.add_argument(
'-r'
,
'--route'
, type=str, default=
'command'
, help=
'target route on endpoint'
)
41
parser.add_argument(
'-f'
,
'--file'
, type=str, required=
True
, help=
'file that contains command to be posted'
)
# This should be an argument
42
group = parser.add_mutually_exclusive_group()
43
group.add_argument(
'-c'
,
'--command'
, type=str, default=
None
, help=
'Only send command COMMAND, not all commands in file'
)
44
parser.add_argument(
'-w'
,
'--wait'
, type=int, default=2, help=
'seconds to wait between sending commands'
)
45
group.add_argument(
'-i'
,
'--interactive'
, dest=
'interactive'
, action=
'store_true'
, help=
'interactive mode'
)
46
parser.add_argument(
'--non-interactive'
, dest=
'interactive'
, action=
'store_false'
)
47
parser.set_defaults(interactive=
False
)
48
49
args = parser.parse_args()
50
51
reply_queue = SimpleQueue()
# command reply queue
52
53
54
app = Flask(__name__)
55
@app.route('/response', methods = ['POST'])
56
def
index
():
57
json = request.get_json(force=
True
)
58
# enqueue command reply
59
reply_queue.put(json)
60
return
'Response received'
61
62
if
__name__ ==
"__main__"
:
63
flask_server = Process(target=app.run, kwargs={
'port'
: args.answer_port})
64
flask_server.start()
65
66
url =
'http://'
+args.host+
':'
+
str
(args.port)+
'/'
+args.route
67
# print(f'Target url: {Fore.YELLOW+url+Style.RESET_ALL}')
68
logging.info(f
'Target url: {url}'
)
69
headers = {
'content-type'
:
'application/json'
,
'X-Answer-Port'
:
str
(args.answer_port)}
70
if
not
args.answer_host
is
None
:
71
headers[
'X-Answer-Host'
] = args.answer_host
72
73
cmdstr =
None
74
try
:
75
with
open(args.file)
as
f:
76
cmdstr = json.load(f)
77
except
:
78
# print(f"\nERROR: failed to open file '{str(args.file)}'.")
79
logging.error(f
"ERROR: failed to open file '{str(args.file)}'."
)
80
raise
SystemExit(0)
81
82
if
isinstance(cmdstr, dict):
83
logging.info(f
'Found single command in {args.file}.'
)
84
try
:
85
response = requests.post(
86
url,
87
data=json.dumps(cmdstr),
88
headers=headers,
89
proxies=({
90
'http'
: f
'socks5h://{args.proxy}'
,
91
'https'
: f
'socks5h://{args.proxy}'
}
92
if
args.proxy
else
None
93
)
94
)
95
logging.info(f
'Response code: {str(response)} with content: {response.content.decode("utf-8")}'
)
96
except
Exception
as
e:
97
logging.error(f
'Failed to send due to: {e}'
)
98
elif
isinstance(cmdstr, list):
99
print(f
'Found a list of commands in {args.file}'
)
100
avacmds = [cdict[
'id'
]
for
cdict
in
cmdstr
if
cdict[
"id"
]]
101
if
args.command
and
not
args.command
in
avacmds:
102
raise
SystemExit(f
"\nERROR: No command '{args.command}' found in file '{str(args.file)}'."
)
103
if
not
args.interactive:
104
for
cmd
in
cmdstr:
105
try
:
106
if
args.command
and
cmd[
'id'
]!=args.command:
107
continue
108
response = requests.post(
109
url,
110
data=json.dumps(cmd),
111
headers=headers,
112
proxies=({
113
'http'
: f
'socks5h://{args.proxy}'
,
114
'https'
: f
'socks5h://{args.proxy}'
}
115
if
args.proxy
else
None
116
)
117
)
118
print(f
'Response code: {str(response)} with content: {response.content.decode("utf-8")}'
)
119
# get command reply from queue
120
r = reply_queue.get()
121
print(
"Reply:"
)
122
print(f
" Application : {Fore.CYAN}{r['appname']}{Style.RESET_ALL}"
)
123
print(f
" Command : {Fore.CYAN}{r['data']['cmdid']}{Style.RESET_ALL}"
)
124
print(f
" Result : {Fore.GREEN if r['success'] else Fore.RED}{r['result']}{Style.RESET_ALL}"
)
125
time.sleep(args.wait)
126
except
:
127
print(
'Failed to send due to: %s'
% sys.exc_info()[0])
128
else
:
129
print(
'\nInteractive mode. Type the ID of the next command to send, or type \'end\' to finish.'
)
130
while
True
:
131
try
:
132
print(f
'\nAvailable commands: {", ".join([Fore.CYAN+c+Style.RESET_ALL for c in avacmds])}'
)
133
nextcmd = input(
'command >> '
)
134
if
nextcmd ==
"end"
:
135
break
136
cmdobj = [cdict
for
cdict
in
cmdstr
if
cdict[
"id"
] == nextcmd]
137
if
not
cmdobj:
138
print(
'Unrecognized command %s. (Not present in the command list?)'
% nextcmd)
139
else
:
140
print(f
'\nSending {Fore.CYAN+nextcmd+Style.RESET_ALL} command.'
)
141
try
:
142
response = requests.post(
143
url,
144
data=json.dumps(cmdobj[0]),
145
headers=headers,
146
proxies=({
147
'http'
: f
'socks5h://{args.proxy}'
,
148
'https'
: f
'socks5h://{args.proxy}'
}
149
if
args.proxy
else
None
150
)
151
)
152
print(f
'Response code: {str(response)} with content: {response.content.decode("utf-8")}'
)
153
# get command reply from queue
154
r = reply_queue.get()
155
print(
"Reply:"
)
156
print(f
" Command : {Fore.CYAN}{r['data']['cmdid']}{Style.RESET_ALL}"
)
157
print(f
" Result : {Fore.GREEN if r['success'] else Fore.RED}{r['result']}{Style.RESET_ALL}"
)
158
except
:
159
print(
'Failed to send due to: %s'
% sys.exc_info()[0])
160
except
KeyboardInterrupt
as
ki:
161
break
162
except
EOFError
as
e:
163
break
164
165
print(
'Exiting...'
)
166
flask_server.terminate()
167
flask_server.join()
send-recv-restcmd.index
index()
Definition
send-recv-restcmd.py:56
send-recv-restcmd.str
str
Definition
send-recv-restcmd.py:34
Generated on
for DUNE-DAQ by
1.17.0