From 68d23e1f50d6cc6a96107394e73c376fdb54cbfa Mon Sep 17 00:00:00 2001 From: Marcelo Diop-Gonzalez Date: Fri, 27 Oct 2023 14:00:34 -0400 Subject: [PATCH 1/3] feat(mocknet): change HTTP request logic We'll change things to bind to "localhost" instead of "0.0.0.0", and make HTTP requests by SSH + curl on the remote server. It's also possible to set up an explicit SSH/SOCKS proxy, but that would require one for each server and would be long-lived, which might be a bit annoying for people running the test scripts --- pytest/tests/mocknet/helpers/neard_runner.py | 2 +- pytest/tests/mocknet/mirror.py | 22 +++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pytest/tests/mocknet/helpers/neard_runner.py b/pytest/tests/mocknet/helpers/neard_runner.py index fb10a6dc0d2..e837b7d9d63 100644 --- a/pytest/tests/mocknet/helpers/neard_runner.py +++ b/pytest/tests/mocknet/helpers/neard_runner.py @@ -828,7 +828,7 @@ def serve(self, port): # something so lightweight main_loop = threading.Thread(target=self.main_loop) main_loop.start() - s = RpcServer(('0.0.0.0', port), self) + s = RpcServer(('localhost', port), self) s.serve_forever() diff --git a/pytest/tests/mocknet/mirror.py b/pytest/tests/mocknet/mirror.py index c3b7ad5ffda..e0b241ca37a 100755 --- a/pytest/tests/mocknet/mirror.py +++ b/pytest/tests/mocknet/mirror.py @@ -4,6 +4,7 @@ """ from argparse import ArgumentParser, BooleanOptionalAction import pathlib +import json import random from rc import pmap, run import requests @@ -328,14 +329,21 @@ def stop_traffic_cmd(args, traffic_generator, nodes): def neard_runner_jsonrpc(node, method, params=[]): - j = {'method': method, 'params': params, 'id': 'dontcare', 'jsonrpc': '2.0'} - r = requests.post(f'http://{node.machine.ip}:3000', json=j, timeout=30) - if r.status_code != 200: - logger.warning( - f'bad response {r.status_code} trying to send {method} JSON RPC to neard runner on {node.instance_name}:\n{r.content}' + body = { + 'method': method, + 'params': params, + 'id': 'dontcare', + 'jsonrpc': '2.0' + } + body = json.dumps(body) + r = run_cmd(node, f'curl localhost:3000 -d \'{body}\'') + response = json.loads(r.stdout) + if 'error' in response: + # TODO: errors should be handled better here in general but just exit for now + sys.exit( + f'bad response trying to send {method} JSON RPC to neard runner on {node.instance_name}:\n{response}' ) - r.raise_for_status() - return r.json()['result'] + return response['result'] def neard_runner_start(node): From 05e744aee8785da47b888d9ad2dcc415d90ae2dd Mon Sep 17 00:00:00 2001 From: Marcelo Diop-Gonzalez Date: Fri, 27 Oct 2023 15:20:29 -0400 Subject: [PATCH 2/3] escape single quotes --- pytest/tests/mocknet/mirror.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pytest/tests/mocknet/mirror.py b/pytest/tests/mocknet/mirror.py index e0b241ca37a..d96455ed339 100755 --- a/pytest/tests/mocknet/mirror.py +++ b/pytest/tests/mocknet/mirror.py @@ -336,6 +336,10 @@ def neard_runner_jsonrpc(node, method, params=[]): 'jsonrpc': '2.0' } body = json.dumps(body) + # '"'"' will be interpreted as ending the first quote and then concatenating it with "'", + # followed by a new quote started with ' and the rest of the string, to get any single quotes + # in method or params into the command correctly + body = body.replace("'", "'\"'\"'") r = run_cmd(node, f'curl localhost:3000 -d \'{body}\'') response = json.loads(r.stdout) if 'error' in response: From 868f8db18b0e912316a543b2ab3d2cf95e1900bf Mon Sep 17 00:00:00 2001 From: Marcelo Diop-Gonzalez Date: Mon, 30 Oct 2023 14:14:53 -0400 Subject: [PATCH 3/3] add comment --- pytest/tests/mocknet/helpers/neard_runner.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pytest/tests/mocknet/helpers/neard_runner.py b/pytest/tests/mocknet/helpers/neard_runner.py index e837b7d9d63..c754bc715aa 100644 --- a/pytest/tests/mocknet/helpers/neard_runner.py +++ b/pytest/tests/mocknet/helpers/neard_runner.py @@ -828,6 +828,9 @@ def serve(self, port): # something so lightweight main_loop = threading.Thread(target=self.main_loop) main_loop.start() + # this will listen only on the loopback interface and won't be accessible + # over the internet. If connecting to another machine, we can SSH and then make + # the request locally s = RpcServer(('localhost', port), self) s.serve_forever()