Skip to content

Commit

Permalink
implemented gateway with portFunction using sympy
Browse files Browse the repository at this point in the history
  • Loading branch information
XaverStiensmeier committed Sep 18, 2023
1 parent 29a04d5 commit a6a3b44
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 21 deletions.
4 changes: 3 additions & 1 deletion bibigrid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@
# Depends on cloud site and project
subnet: # existing subnet on your cloud. See https://openstack.cebitec.uni-bielefeld.de/project/networks/
# or network:
# gatewayIp: # [NOT FULLY IMPLEMENTED YET] if you want to use a gateway for master or vpnwkr setup
# gateway: # if you want to use a gateway for create.
# ip: # IP of gateway to use
# portFunction: 30000 + oct4 # variables are called: oct1.oct2.oct3.oct4

# Uncomment if no full DNS service for started instances is available.
# Currently, the case in Berlin, DKFZ, Heidelberg and Tuebingen.
Expand Down
6 changes: 3 additions & 3 deletions bibigrid/core/actions/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@ def initialize_instances(self):
ssh_handler.ansible_preparation(floating_ip=configuration["floating_ip"],
private_key=KEY_FOLDER + self.key_name, username=self.ssh_user,
commands=self.ssh_add_public_key_commands, log=self.log,
gateway_ip=configuration.get("gatewayIp"))
gateway=configuration.get("gateway", {}))
elif configuration.get("vpnInstance"):
ssh_handler.execute_ssh(floating_ip=configuration["floating_ip"],
private_key=KEY_FOLDER + self.key_name, username=self.ssh_user,
commands=ssh_handler.VPN_SETUP, log=self.log,
gateway_ip=configuration.get("gatewayIp"))
gateway=configuration.get("gateway", {}))

def prepare_volumes(self, provider, mounts):
"""
Expand Down Expand Up @@ -312,7 +312,7 @@ def upload_data(self):
cluster_id=self.cluster_id))] + ssh_handler.ANSIBLE_START
ssh_handler.execute_ssh(floating_ip=self.master_ip, private_key=KEY_FOLDER + self.key_name,
username=self.ssh_user, filepaths=FILEPATHS, commands=commands, log=self.log,
gateway_ip=self.configurations[0].get("gatewayIp"))
gateway=self.configurations[0].get("gateway", {}))

def start_start_instance_threads(self):
"""
Expand Down
31 changes: 15 additions & 16 deletions bibigrid/core/utility/handler/ssh_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import paramiko
import yaml
import sympy

from bibigrid.core.utility import ansible_commands as aC
from bibigrid.models.exceptions import ConnectionException, ExecutionException
Expand Down Expand Up @@ -86,7 +87,7 @@ def copy_to_server(sftp, local_path, remote_path, log):
copy_to_server(sftp, os.path.join(local_path, filename), os.path.join(remote_path, filename), log)


def is_active(client, floating_ip_address, private_key, username, log, timeout=5, gateway_ip=None):
def is_active(client, floating_ip_address, private_key, username, log, gateway, timeout=5):
"""
Checks if connection is possible and therefore if server is active.
Raises paramiko.ssh_exception.NoValidConnectionsError if timeout is reached
Expand All @@ -96,7 +97,7 @@ def is_active(client, floating_ip_address, private_key, username, log, timeout=5
:param username: SSH-username
:param log:
:param timeout: how long to wait between ping
:param gateway_ip: if node should be reached over a gateway port is set to 30000 + subnet * 256 + host
:param gateway: if node should be reached over a gateway port is set to 30000 + subnet * 256 + host
(waiting grows quadratically till 2**timeout before accepting failure)
"""
attempts = 0
Expand All @@ -105,13 +106,11 @@ def is_active(client, floating_ip_address, private_key, username, log, timeout=5
try:
# Add Port
port = 22
if gateway_ip:
log.info("Using SSH Gateway...")
ip_split = floating_ip_address.split(".") # is not floating but local ip here
host = int(ip_split[-1])
# subnet = int(ip_split[-2])
port = 30000 + host
client.connect(hostname=gateway_ip or floating_ip_address, username=username,
if gateway:
log.info(f"Using SSH Gateway {gateway.get('ip')}")
octets = {f'oct{enum+1}': int(elem) for enum, elem in floating_ip_address.split(".")}
port = sympy.sympify(gateway["portFunction"]).subs(dict(octets))
client.connect(hostname=gateway.get("ip") or floating_ip_address, username=username,
pkey=private_key, timeout=7, auth_timeout=5, port=port)
establishing_connection = False
log.info(f"Successfully connected to {floating_ip_address}")
Expand Down Expand Up @@ -184,7 +183,7 @@ def execute_ssh_cml_commands(client, commands, log):
raise ExecutionException(msg)


def ansible_preparation(floating_ip, private_key, username, log, commands=None, filepaths=None, gateway_ip=None):
def ansible_preparation(floating_ip, private_key, username, log, gateway, commands=None, filepaths=None):
"""
Installs python and pip. Then installs ansible over pip.
Copies private key to instance so cluster-nodes are reachable and sets permission as necessary.
Expand All @@ -197,7 +196,7 @@ def ansible_preparation(floating_ip, private_key, username, log, commands=None,
:param log:
:param commands: additional commands to execute
:param filepaths: additional files to copy: (localpath, remotepath)
:param gateway_ip
:param gateway
"""
if filepaths is None:
filepaths = []
Expand All @@ -206,10 +205,10 @@ def ansible_preparation(floating_ip, private_key, username, log, commands=None,
log.info("Ansible preparation...")
commands = ANSIBLE_SETUP + commands
filepaths.append((private_key, PRIVATE_KEY_FILE))
execute_ssh(floating_ip, private_key, username, log, commands, filepaths, gateway_ip)
execute_ssh(floating_ip, private_key, username, log, gateway, commands, filepaths)


def execute_ssh(floating_ip, private_key, username, log, commands=None, filepaths=None, gateway_ip=None):
def execute_ssh(floating_ip, private_key, username, log, gateway, commands=None, filepaths=None):
"""
Executes commands on remote and copies files given in filepaths
:param floating_ip: public ip of remote
Expand All @@ -218,7 +217,7 @@ def execute_ssh(floating_ip, private_key, username, log, commands=None, filepath
:param commands: commands
:param log:
:param filepaths: filepaths (localpath, remotepath)
:param gateway_ip: IP of gateway if used
:param gateway: gateway if used
"""
if commands is None:
commands = []
Expand All @@ -227,9 +226,9 @@ def execute_ssh(floating_ip, private_key, username, log, commands=None, filepath
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
is_active(client=client, floating_ip_address=floating_ip, username=username, private_key=paramiko_key,
log=log, gateway_ip=gateway_ip)
log=log, gateway=gateway)
except ConnectionException as exc:
log.error(f"Couldn't connect to ip {gateway_ip or floating_ip} using private key {private_key}.")
log.error(f"Couldn't connect to ip {gateway or floating_ip} using private key {private_key}.")
raise exc
else:
log.debug(f"Setting up {floating_ip}")
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ python-novaclient
python-openstackclient==6.0.0
PyYAML
shortuuid
sshtunnel
sshtunnel
sympy

0 comments on commit a6a3b44

Please sign in to comment.