class RemoteHost: def __init__(self, host, user, password, rootdir, keyfile=None): self.host = host self.user = user self.password = password self.rootdir = rootdir self.keyfile = keyfile self.lib = SSHLibrary() self.lib.open_connection(self.host) if self.keyfile is not None: self.lib.login_with_public_key(username=self.user, keyfile=self.keyfile) else: self.lib.login(username=self.user, password=self.password) def __del__(self): self.lib.close_connection() def exec_cmd(self, command): print "Executing command " + command + " on host " + self.host rc = self.lib.execute_command(command, return_rc=True) if rc[1] != 0: raise Exception('remote command failed [{0}] with exit code {1}.' 'For linux-based vms, Please make sure requiretty is disabled in the /etc/sudoers file' .format(command, rc)) def mkdir(self, dir_name): self.exec_cmd("mkdir -p " + dir_name) def copy_file(self, src, dest): if src is None: print "src is None not copy anything to " + dest return if os.path.exists(src) is False: print "Src file " + src + " was not found" return print "Copying " + src + " to " + dest + " on " + self.host self.lib.put_file(src, dest) def kill_controller(self): self.exec_cmd("sudo ps axf | grep karaf | grep -v grep " "| awk '{print \"kill -9 \" $1}' | sudo sh") def start_controller(self, dir_name): self.exec_cmd(dir_name + "/odl/bin/start")
def create_ssh_connection(self, server, uname, psky): obj = SSHLibrary() obj.open_connection(server) obj.login_with_public_key(uname, psky) return obj
class SSHLibraryPlugInWrapper(plugin_runner_abstract, metaclass=ABCMeta): def __init__(self, parameters: DotDict, data_handler, *user_args, **user_options): self._sudo_expected = is_truthy(user_options.pop('sudo', False)) self._sudo_password_expected = is_truthy( user_options.pop('sudo_password', False)) super().__init__(parameters, data_handler, *user_args, **user_options) self._execution_counter = 0 self._ssh = SSHLibrary() @property def content_object(self): return self._ssh @property def sudo_expected(self): return self._sudo_expected @property def sudo_password_expected(self): return self._sudo_password_expected def _close_ssh_library_connection_from_thread(self): try: with self._lock: self._ssh.close_connection() except RuntimeError: pass except Exception as e: if 'Logging background messages is only allowed from the main thread' in str( e): logger.warn(f"Ignore SSHLibrary error: '{e}'") return True raise def _evaluate_tolerance(self): if len(self._session_errors) == self._fault_tolerance: e = PlugInError( f"{self}", "PlugIn stop invoked; Errors count arrived to limit ({})". format( self.host_alias, self._fault_tolerance, ), *self._session_errors) logger.error(f"{e}") GlobalErrors().append(e) return False return True def login(self): host = self.parameters.host port = self.parameters.port username = self.parameters.username password = self.parameters.password certificate = self.parameters.certificate if len(self._session_errors) == 0: logger.info(f"Host '{self.host_alias}': Connecting") else: logger.warn( f"Host '{self.host_alias}': Restoring at {len(self._session_errors)} time" ) self._ssh.open_connection(host, repr(self), port) start_ts = datetime.now() while True: try: if certificate: logger.debug( f"Host '{self.host_alias}': Login with user/certificate" ) self._ssh.login_with_public_key(username, certificate, '') else: logger.debug( f"Host '{self.host_alias}': Login with user/password") self._ssh.login(username, password) except paramiko.AuthenticationException: raise except Exception as e: logger.warn( f"Host '{self.host_alias}': Connection failed; Reason: {e}" ) else: self._is_logged_in = True logger.info( f"Host '{self.host_alias}': Connection established") break finally: duration = (datetime.now() - start_ts).total_seconds() if duration >= self.parameters.timeout: raise TimeoutError( f"Cannot connect to '{self.host_alias}' during {self.parameters.timeout}s" ) def exit(self): if self._is_logged_in: self._ssh.switch_connection(repr(self)) self._close_ssh_library_connection_from_thread() self._is_logged_in = False logger.info( f"Host '{self.id}::{self.host_alias}': Connection closed") else: logger.info( f"Host '{self.id}::{self.host_alias}': Connection close not required (not opened)" )