-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove ssh playground, start with code refactoring create class handl…
…er for SSH and Config (just a friendly rename)
- Loading branch information
Showing
6 changed files
with
291 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
import copy | ||
|
||
class Config: | ||
# https://trinityvalidator.com/docs/node/node-config | ||
# https://github.com/sentinel-official/dvpn-node/blob/development/types/config.go | ||
|
||
node = { | ||
"chain": { | ||
"gas": {"value": 200000, "description": "Gas limit to set per transaction"}, | ||
"gas_adjustment": {"value": 1.05, "description": "Gas adjustment factor"}, | ||
"gas_prices": { | ||
"value": "0.1udvpn", | ||
"description": "Gas prices to determine the transaction fee", | ||
}, | ||
"id": {"value": "sentinelhub-2", "description": "The network chain ID"}, | ||
"rpc_addresses": { | ||
"value": "https://rpc.sentinel.co:443", | ||
"description": "Comma separated Tendermint RPC addresses for the chain", | ||
}, | ||
"rpc_query_timeout": { | ||
"value": 10, | ||
"description": "Timeout seconds for querying the data from the RPC server", | ||
}, | ||
"rpc_tx_timeout": { | ||
"value": 30, | ||
"description": "Timeout seconds for broadcasting the transaction through RPC server", | ||
}, | ||
"simulate_and_execute": { | ||
"value": True, | ||
"description": "Calculate the transaction fee by simulating it", | ||
"options": [True, False], | ||
}, | ||
}, | ||
"handshake": { | ||
"enable": { | ||
"value": True, | ||
"description": "Enable Handshake DNS resolver (if you use v2ray set enable = false)", | ||
"options": [True, False], | ||
}, | ||
"peers": {"value": 8, "description": "Number of peers"}, | ||
}, | ||
"keyring": { | ||
"backend": { | ||
"value": "file", | ||
"description": "Underlying storage mechanism for keys", | ||
}, | ||
"from": { | ||
"value": "operator", | ||
"description": "Name of the key with which to sign", | ||
}, | ||
}, | ||
"node": { | ||
"interval_set_sessions": { | ||
"value": "10s", | ||
"description": "Time interval between each set_sessions operation", | ||
}, | ||
"interval_update_sessions": { | ||
"value": "1h55m0s", | ||
"description": "Time interval between each update_sessions transaction", | ||
}, | ||
"interval_update_status": { | ||
"value": "55m0s", | ||
"description": "Time interval between each set_status transaction", | ||
}, | ||
"ipv4_address": { | ||
"value": "", | ||
"description": "IPv4 address to replace the public IPv4 address with", | ||
}, | ||
"listen_on": { | ||
"value": "0.0.0.0:<tcp_port>", | ||
"description": "API listen-address (tcp port)", | ||
}, | ||
"moniker": {"value": "your_node_name", "description": "Name of the node"}, | ||
"gigabyte_prices": { | ||
"value": "29000000udvpn,39000ibc/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477,525000ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518,700000ibc/31FEE1A2A9F9C01113F90BD0BBCCE8FD6BBB8585FAF109A2101827DD1D5B95B8,52500000ibc/B1C0DDB14F25279A2026BC8794E12B259F8BDA546A3C5132CCAEE4431CE36783", | ||
"description": "Prices for one gigabyte of bandwidth provided", | ||
}, | ||
"hourly_prices": { | ||
"value": "4900000udvpn", | ||
"description": "Prices for one hour", | ||
}, | ||
"remote_url": { | ||
"value": "https://<ip_node>:<tcp_port>", | ||
"description": "Public URL of the node", | ||
}, | ||
"type": { | ||
"value": "wireguard", | ||
"description": "Type of node (you can choose between wireguard and v2ray)", | ||
"options": ["wireguard", "v2ray"], | ||
}, | ||
}, | ||
"qos": { | ||
"max_peers": { | ||
"value": 250, | ||
"description": "Limit max number of concurrent peers", | ||
}, | ||
}, | ||
"extras": { | ||
"udp_port": { | ||
"value": 0, | ||
"description": "UDP port used as listen_port for wireguard or v2ray", | ||
}, | ||
"node_folder": { | ||
"value": None, | ||
"description": "Absolute path, where to save the node configuration", | ||
}, | ||
"wallet_password": { | ||
"value": "", | ||
"description": "Wallet password (only used for keyring = file)" | ||
}, | ||
"wallet_mnemonic": { | ||
"value": "", | ||
"description": "Wallet bip mnemonic (leave empty for create a new wallet)" | ||
} | ||
} | ||
} | ||
|
||
v2ray = { | ||
"vmess": { | ||
"listen_port": { | ||
"value": 0, | ||
"description": "Port number to accept the incoming connections", | ||
}, | ||
"transport": { | ||
"value": "grpc", | ||
"description": "Name of the transport protocol", | ||
}, | ||
} | ||
} | ||
|
||
wireguard = { | ||
"interface": {"value": "wg0", "description": "Name of the network interface"}, | ||
"listen_port": { | ||
"value": "<udp_port>", | ||
"description": "Port number to accept the incoming connections", | ||
}, | ||
"private_key": {"value": None, "description": "Server private key"}, | ||
} | ||
|
||
def validate_config(node_config: dict) -> str | bool: | ||
allowed_empty = ["ipv4_address"] | ||
remote_url = node_config["node"]["remote_url"]["value"] | ||
listen_on = node_config["node"]["listen_on"]["value"] | ||
if remote_url.split(":")[-1].strip() != listen_on.split(":")[-1].strip(): | ||
return "TCP port must be equal" | ||
|
||
for group in node_config: | ||
for key in node_config[group]: | ||
if key not in allowed_empty and node_config[group][key]["value"] == "": | ||
return f"{group}.{key} cannot be empty" | ||
|
||
if node_config["node"]["type"]["value"] == "v2ray": | ||
if node_config["handshake"]["enable"] is True: | ||
return f"{group}.{key} cannot be True" | ||
|
||
return True | ||
|
||
def __handle_type(value): | ||
if value in ["True", "False"]: | ||
return value.lower() | ||
elif value.isdigit(): | ||
return value | ||
else: | ||
return f'"{value}"' | ||
|
||
def tomlize(node_config: dict) -> str: | ||
ignore = ["extras"] | ||
raw = "" | ||
for group in node_config: | ||
if group not in ignore: | ||
# check if is a 'group' | ||
keys = list(node_config[group].keys()) | ||
if "value" not in keys and "description" not in keys: | ||
raw += f"\n[{group}]\n" | ||
for key in keys: | ||
raw += f"\n# {node_config[group][key]['description']}\n" | ||
raw += f"{key} = {__handle_type(node_config[group][key]['value'])}\n" | ||
else: | ||
raw += f"{group} = {__handle_type(node_config[group]['value'])}\n" | ||
return raw | ||
|
||
|
||
def node_toml2wellknow(node_config: dict) -> dict: | ||
default_values = copy.deepcopy(Config.node) | ||
for group in node_config: | ||
if group in default_values: | ||
for key in node_config[group]: | ||
if key in default_values[group]: | ||
default_values[group][key]["value"] = node_config[group][key] | ||
return default_values |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import urllib.request | ||
import paramiko | ||
|
||
from docker import APIClient | ||
from docker.transport import SSHHTTPAdapter | ||
|
||
class SSHAdapterPassword(SSHHTTPAdapter): | ||
def __init__(self, base_url: str, password: str): | ||
self.password = password | ||
super().__init__(base_url) | ||
def _connect(self): | ||
if self.ssh_client: | ||
self.ssh_params["password"] = self.password | ||
self.ssh_client.connect(**self.ssh_params) | ||
|
||
class SSH(): | ||
def __init__(self, host: str, username: str, password: str = None, port: int = 22): | ||
self.host | ||
self.username | ||
self.password | ||
self.port | ||
|
||
self.client = paramiko.SSHClient() | ||
|
||
self.client.load_system_host_keys() | ||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | ||
self.client.connect(host, username=username, password=password, port=port, look_for_keys=True) | ||
|
||
""" | ||
k = paramiko.RSAKey.from_private_key_file(keyfilename) | ||
# OR k = paramiko.DSSKey.from_private_key_file(keyfilename) | ||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | ||
self.client.connect(hostname=host, username=user, pkey=k) | ||
""" | ||
|
||
def sudo_exec_command(self, cmd: str): | ||
ssh_stdin, ssh_stdout, ssh_stderr = self.client.exec_command(cmd, get_pty=True) | ||
if ssh_stdin.closed is False and password is not None and "sudo" in cmd: | ||
ssh_stdin.write(self.password + '\n') | ||
ssh_stdin.flush() | ||
return ssh_stdin, ssh_stdout, ssh_stderr | ||
|
||
def read_file(self, fpath: str) -> str: | ||
sftp = self.client.open_sftp() | ||
rfile = sftp.open(fpath) | ||
content = "" | ||
for line in rfile: | ||
content += line | ||
rfile.close() | ||
sftp.close() | ||
return content | ||
|
||
def get_home(self) -> str: | ||
ssh_stdin, ssh_stdout, ssh_stderr = self.client.exec_command("echo ${HOME}") | ||
return ssh_stdout.read().decode("utf-8").strip() | ||
|
||
def put_file(self, fpath: str) -> bool: | ||
home_directory = ssh_get_home(ssh) | ||
ftp = self.client.open_sftp() | ||
fname = os.path.basename(fpath) | ||
ftp.put(fpath, os.path.join(home_directory, fname)) | ||
ftp.close() | ||
return True | ||
|
||
def close(self): # :) | ||
self.client.close() | ||
|
||
def exec_command(self, cmd: str): # :) | ||
return self.client.exec_command(cmd) | ||
|
||
def docker(self, docker_api_version: str): | ||
client = APIClient(f'ssh://{self.host}:{self.port}', use_ssh_client=True, version=docker_api_version) | ||
ssh_adapter = SSHAdapterPassword(f'ssh://{self.username}@{self.host}:{self.port}', password=self.password) | ||
client.mount('http+docker://ssh', ssh_adapter) | ||
if client.version(api_version=False)["ApiVersion"] == docker_api_version: | ||
return client | ||
return None |
Empty file.
Oops, something went wrong.