def get_client(self): " Return an instance of a connected and active `paramiko.SSHClient`. " # Use existing connection if active if self._client: return self._client # Create the client and connect to proxy server client = SSHClient() client.load_host_keys(hosts_file) client.connect( settings.PROXY_HOSTNAME, port=settings.PROXY_PORT, username=settings.PROXY_USERNAME, key_filename=key_filename ) # Get the transport and find create a `direct-tcpip` channel transport = client.get_transport() dest_addr = ('0.0.0.0', dest_port) src_addr = ('127.0.0.1', local_port) channel = transport.open_channel("direct-tcpip", dest_addr, src_addr) self._client = SSHClient() target_client.load_host_keys(hosts_file) target_client.connect('localhost', port=local_port, username=dest_username, password=dest_password, sock=channel) return target_client
def __connect(self): server, p, username = self.__ini_manager.get_connection_settings() ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) ssh.connect(server, username=username, password=p) return ssh
def run_script(targets): print("[+] Running install script...") for target in targets: client = SSHClient() client.load_host_keys(HOSTS) client.connect( target, username=USER, password=PASS, ) run_script = "bash /home/wisp/install_vmtools.sh" stdin, stdout, stderr = client.exec_command(run_script) # Print any output or errors as they arise if stdout: print(stdout.read().decode("utf-8")) if stderr: print(stderr.read().decode("utf-8")) # Get recturn code print(f"\nReturn Code: {stdout.channel.recv_exit_status()}") # Close all file objects stdin.close() stdout.close() stderr.close() client.close() print(f"[+] Process for host {target} completed!")
def ssh_scp_files(file_list: list, check_dir: str) -> None: ''' 这种方式先使用paramiko进行ssh链接,然后使用scp同步文件列表 好处是在同步的过程中不会暴露用户名和密码,同时在windows和linux平台下都可以使用 前提条件是需要把远端服务器的地址存储到本地的~/.ssh/known_hosts 文件中, 也就是第一次使用之前要成功手工执行一下scp的命令并存储远端服务器的地址 ''' # ssh_host, ssh_user, ssh_password, ssh_port, source_volume, destination_volume): local_project_path = LOCAL_Project_PATH_BASE + os.sep + check_dir remote_project_path = REMOTE_WORKSPACE_PATH_BASE + '/' + check_dir ssh = SSHClient() # ssh.load_system_host_keys() ssh.load_host_keys( os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) ssh.connect(REMOTE_IP, username=REMOTE_USER_NAME, password=REMOTE_USER_PASSWORD, look_for_keys=False) with SCPClient(ssh.get_transport()) as scp: local_project_path = LOCAL_Project_PATH_BASE + os.sep + check_dir remote_project_path = REMOTE_WORKSPACE_PATH_BASE + '/' + check_dir for file in file_list: local_file_path = local_project_path + os.sep + file remote_file_path = remote_project_path + '/' + os.path.dirname( file) + "/" print('正在处理 ', local_file_path) scp.put(local_file_path, recursive=True, remote_path=remote_file_path)
def list_remote_backups(self): out = [] if 'port' in self.connection: ssh_port = self.connection['port'] else: ssh_port = 22 ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.load_host_keys( filename=path.join(path.expanduser('~'), '.ssh', 'known_hosts')) try: ssh.connect(hostname=self.connection['host'], username=self.connection['user'], port=ssh_port, key_filename=self.connection['keyfile']) except SSHException as e: logging.critical('SSH Failed: {}'.format(e)) ssh.close() return False try: stdin, stdout, ssh_stderr = ssh.exec_command( 'cd {} && find . -type d -mindepth 1 -iname {}'.format( '/var/backups', "backup-\*")) stdin.flush() except SSHException as e: logging.critical('SSH error: {}'.format(e)) del ssh return False del ssh retrieved_data = stdout.readlines() return self._convert_backup_list_to_string(retrieved_data)
def commands(request): command_to_run = '' output = '' error = '' if request.method == 'POST': form = CommandForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] command_to_run = form.cleaned_data['command_to_run'] ssh = SSHClient() ssh.load_host_keys(settings.CMDS_HOST_KEYS_FILENAME) try: ssh.connect(settings.CMDS_HOST, username=username, password=password) except AuthenticationException: error = 'Authentication failed. Did you type the wrong' + \ 'username or password?' if not error: _, ssh_stdout, ssh_stderr = ssh.exec_command(command_to_run) output = ssh_stdout.read() error = ssh_stderr.read() else: form = CommandForm() return render_to_response('commands.html', { 'form': form, 'command': command_to_run, 'output': output, 'error': error, }, context_instance=RequestContext(request))
def create_client(self): private = RSAKey(filename=self.get_private_key_file()) client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.load_host_keys(self.get_host_keys_file()) client.connect(self.server.host, pkey=private, look_for_keys=False, port=self.server.port, username=self.server.user) return client
def create_backup(self): current_backup_dir = None out = [] if 'port' in self.connection: ssh_port = self.connection['port'] else: ssh_port = 22 ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) vm = self.find_virtual_machine() if vm is None: logging.critical('Failed to obtain VM') return False, current_backup_dir else: vm_status = vm.isActive() logging.warning('VM "{}" found [Status: {}]'.format( self.connection['vm_name'], vm_status)) if vm.isActive() == 1: deactivation = self._deactivate_vm(vm) if not deactivation: logging.critical('Could not shutdown machine.') return False, current_backup_dir # return True images_to_save = self._print_all_vm_disks(vm) ssh.load_host_keys( filename=path.join(path.expanduser('~'), '.ssh', 'known_hosts')) try: ssh.connect(hostname=self.connection['host'], username=self.connection['user'], port=ssh_port, key_filename=self.connection['keyfile']) except SSHException as e: logging.critical('SSH Failed: {}'.format(e)) ssh.close() return False, current_backup_dir try: current_backup_dir = datetime.today().strftime("backup-%Y%m%d%H%M") stdin, stdout, ssh_stderr = ssh.exec_command('mkdir {}/{}'.format( self.remote_path, current_backup_dir)) stdin.flush() for image_to_save in images_to_save: stdin, stdout, ssh_stderr = ssh.exec_command( 'cp -v {} {}/{}'.format(image_to_save, self.remote_path, current_backup_dir)) out.append(stdout.readlines()) stdin.flush() # Dump XML too ftp = ssh.open_sftp() ftp.chdir(self.remote_path + '/' + current_backup_dir) with ftp.open('VMdump.xml') as xml_dump_fp: xml_dump_fp.write(vm.XMLDesc()) ftp.close() except SSHException as e: logging.critical('SSH error: {}'.format(e)) return False, current_backup_dir if not self._activate_vm(vm): out.append("Failed to reactivate VM\n") return out, current_backup_dir
def setup_sshclient(host): client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) #client.load_system_host_keys() client.load_host_keys(get_homedir() + '/.ssh/known_hosts') print("connection to: " + host) client.connect(host, username=get_username()) return client
def scp(local, remote): server = '10.10.141.44' # setup ssh ssh = SSHClient() ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) ssh.connect(server, username='******', password='******') scp = SCPClient(ssh.get_transport(), progress=scp_progress) # transfer to remote scp.put(files=local, remote_path=remote)
def get(self, remotepath, localpath): ssh = SSHClient() ssh.load_host_keys(self.sshpath) ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect(self.server, username=self.username, password=self.password) sftp = ssh.open_sftp() sftp.get(remotepath, localpath) sftp.close() ssh.close()
class SSH_Client (autosuper) : def __init__ \ (self, host, privkey, remote_dir = '/tmp', local_dir = '/tmp' , password = None, port = 22, user = '******' ) : self.ssh = SSHClient () self.host = host self.remote_dir = remote_dir self.local_dir = local_dir self.key = RSAKey.from_private_key_file (privkey, password = password) home = os.environ.get ('HOME', '/root') path = os.path.join (home, '.ssh', 'known_hosts_paramiko') self.known_hosts = path self.ssh.load_host_keys (path) self.ssh.set_missing_host_key_policy (AutoAddPolicy ()) self.ssh.connect \ ( host , pkey = self.key , port = port , username = user , look_for_keys = False , allow_agent = False ) self.sftp = self.ssh.open_sftp () self.sftp.chdir (self.remote_dir) # end def __init__ def get_files (self, * fn) : for f in fn : dest = os.path.join (self.local_dir, os.path.basename (f)) self.sftp.get (f, dest) # end def get_files def list_files (self) : for f in self.sftp.listdir_attr () : if stat.S_ISREG (f.st_mode) : yield (f.filename) # end def list_files def put_files (self, *fn) : for f in fn : dest = os.path.join (self.remote_dir, os.path.basename (f)) self.sftp.put (f, dest) # end def put_files def close (self) : self.ssh.save_host_keys (self.known_hosts) self.ssh.close () # end def close def __getattr__ (self, name) : return getattr (self.sftp, name)
def download_datasets(host, login, source_dir, target_dir): from paramiko import SSHClient from scp import SCPClient print("Download datasets into {}".format(target_dir)) ssh = SSHClient() ssh.load_host_keys('.ssh/known_hosts') # ssh.load_system_host_keys() # ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) # ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=host, username=login) with SCPClient(ssh.get_transport(), sanitize=lambda x: x) as scp: scp.get(remote_path=source_dir + "*.json", local_path=target_dir) scp.get(remote_path=source_dir + "*.save", local_path=target_dir)
def create_client(self): """ Create and configure SSHClient """ private = RSAKey(filename=self.get_private_key_file()) client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.load_host_keys(self.get_host_keys_file()) if self.server.authentication_method == self.server.OPENSSH_PASSWORD: client.connect(self.server.host, password=self.server.password, look_for_keys=False, port=self.server.port, username=self.server.user) elif self.server.authentication_method == self.server.OPENSSH_CERTIFICATE: client.connect(self.server.host, pkey=private, look_for_keys=False, port=self.server.port, username=self.server.user) return client
def SSHConnect(dest_targzfile, filename): stdout.write("envoi au serveur: %s\n" % SSH_IP) ssh = SSHClient() ssh.load_host_keys( os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) try: ssh.connect(SSH_IP, username=SSH_LOGIN, password=SSH_PASWD) except Exception as e: stderr.write("ERREUR lors de la connexion: %s\n" % e) os.remove(dest_targzfile) exit(0) with SCPClient(ssh.get_transport()) as scp: scp.put(dest_targzfile, filename) stdout.write("Transfer terminé !\n")
class BaseClient(object): """API client.""" ssh = None sftp = None def __init__(self, url, host_keys=None): self.user, self.host, self.path = parse_url(url) self.host_keys = host_keys or join(expanduser('~'), '.ssh', 'known_hosts') def __enter__(self): self.ssh = SSHClient() try: self.ssh.load_host_keys(self.host_keys) except IOError: raise ClientError(8, (self.host_keys, )) try: self.ssh.connect(self.host, username=self.user) except (SSHException, error): raise ClientError(1, (self.user, self.host)) else: self.sftp = self.ssh.open_sftp() try: self.sftp.chdir(self.path) except IOError: raise ClientError(6, (self.path, )) def __exit__(self, type, value, traceback): if self.sftp: self.sftp.close() self.sftp = None self.ssh.close() self.ssh = None def transfer(self, remote_filepath, reader=None, writer=None, callback=None): """Transfer file. Doesn't check if overwrites.""" try: if reader and not writer: # upload self.sftp.putfo(reader, remote_filepath, callback=callback) elif writer and not reader: # download self.sftp.getfo(remote_filepath, writer, callback=callback) else: raise ValueError('Exactly one of reader or writer can be specified.') except IOError: # missing remote file raise ClientError(2, (remote_filepath, )) except UnicodeDecodeError: raise ClientError(7)
def scpSender(self, filename): ssh = SSHClient() ##In terminal, run: ssh -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=./known_hosts [email protected] to create a separate known_hosts file ssh.load_host_keys(os.path.join(os.path.dirname(__file__), 'known_hosts')) if len(self.p) > 0: ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.p) else: try: ssh.connect(hostname=self.hostname, port=self.port, username=self.username) except PasswordRequiredException: ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.p) scp = SCPClient(ssh.get_transport()) scp.put(filename, recursive=True, remote_path=self.remote_dir) scp.close() ssh.close()
def __init__(self, hostname, port=222, timeout=10.0): self.hostname = hostname if not self.connection_cache.get(hostname): ssh = SSHClient() ssh.load_system_host_keys() ssh.load_host_keys(os.path.expanduser("~/.ssh/known_hosts")) ssh.set_missing_host_key_policy(AllowAnythingPolicy()) ssh.connect( self.hostname, port=port, username=os.environ.get("SSH_USER"), timeout=timeout, ) self.connection_cache[hostname] = ssh self.ssh = self.connection_cache[hostname]
def send(self, localpath, remotepath): ssh = SSHClient() ssh.load_host_keys(self.sshpath) ssh.set_missing_host_key_policy(AutoAddPolicy()) if self.password != "": ssh.connect(self.server, username=self.username, password=self.password) else: k = RSAKey.from_private_key_file( path.expanduser(path.join("~", ".ssh", "id_rsa"))) ssh.connect(self.server, port=22, username=self.username, pkey=k) sftp = ssh.open_sftp() sftp.put(localpath, remotepath) sftp.close() ssh.close()
def _build_ssh_client(self): """Prepare for Paramiko SSH connection. See base_connection.py file for any updates. """ # Create instance of SSHClient object remote_conn_pre = SSHClient() # Load host_keys for better SSH security if self.system_host_keys: remote_conn_pre.load_system_host_keys() if self.alt_host_keys and path.isfile(self.alt_key_file): remote_conn_pre.load_host_keys(self.alt_key_file) # Default is to automatically add untrusted hosts (make sure appropriate for your env) remote_conn_pre.set_missing_host_key_policy(self.key_policy) return remote_conn_pre
def _build_ssh_client(self) -> SSHClient: """Prepare for Paramiko SSH connection.""" # Create instance of SSHClient object # If not using SSH keys, we use noauth if not self.use_keys: remote_conn_pre: SSHClient = SSHClient_noauth() else: remote_conn_pre = SSHClient() # Load host_keys for better SSH security if self.system_host_keys: remote_conn_pre.load_system_host_keys() if self.alt_host_keys and path.isfile(self.alt_key_file): remote_conn_pre.load_host_keys(self.alt_key_file) # Default is to automatically add untrusted hosts (make sure appropriate for your env) remote_conn_pre.set_missing_host_key_policy(self.key_policy) return remote_conn_pre
class SSH: def __init__(self, host="", user="", senha="", porta=22): self.ssh = SSHClient() ## this method has been depreciated #self.ssh.load_system_host_keys() self.ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.connect(hostname=host, username=user, password=senha, port=porta) def exec_cmd(self, cmd): stdin, stdout, stderr = self.ssh.exec_command(cmd) if stderr.channel.recv_exit_status() != 0: print(stderr.read()) else: ##print stdout.read() ## so sucesso pass
def deploy_key(key, server, username, password): client = SSHClient() try: client.load_system_host_keys(user_home + '/.ssh/known_hosts') client.load_host_keys(user_home + '/.ssh/known_hosts') client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(server, username=username, password=password) #allow_agent=False client.exec_command('mkdir -p ~/.ssh/') client.exec_command('echo "%s" >> ~/.ssh/authorized_keys' % key) client.exec_command('chmod 644 ~/.ssh/authorized_keys') client.exec_command('chmod 700 ~/.ssh/') pretty_print("Public key successfully added.") except Exception as e: pretty_print( "There was an error trying to add the public key to the server, pls check..." ) print e exit(1) finally: client.close()
def connect(self): """ Open connection to remote host. :return: client """ self.__check_ping() try: client = SSHClient() client.load_host_keys(path.expanduser('~/.ssh/known_hosts')) client.set_missing_host_key_policy(AutoAddPolicy) client.connect(self.connection.host, username=self.connection.user, password='', look_for_keys=False, timeout=5000) except AuthenticationException as error: log.error(f'{error}, exit program') exit(1) else: log.info('Create client') return client
def retrieve_backup(self, backup_name=None): if not backup_name: logging.warning('Tried to obtain a backup but no name was given') return False out = [] if 'port' in self.connection: ssh_port = self.connection['port'] else: ssh_port = 22 ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.load_host_keys( filename=path.join(path.expanduser('~'), '.ssh', 'known_hosts')) try: ssh.connect(hostname=self.connection['host'], username=self.connection['user'], port=ssh_port, key_filename=self.connection['keyfile']) except SSHException as e: logging.critical('SSH Failed: {}'.format(e)) ssh.close() return False try: ftp = ssh.open_sftp() ftp.chdir(self.remote_path + '/' + backup_name) data = ftp.listdir() if not path.isdir('/app/backups/' + backup_name): mkdir('/app/backups/' + backup_name) for to_retrieve in data: logging.warning('Retrieving {} from backup {}'.format( to_retrieve, '/app/backups/' + backup_name)) ftp.get(to_retrieve, '/app/backups/' + backup_name + '/' + to_retrieve) except SSHException as e: logging.critical('SSH error: {}'.format(e)) return False except FileNotFoundError: out = 'Backup not found in remote server' return out
def ssh_connection_test(host): pretty_print("Testing connection to the server " + host + " ...") client = SSHClient() try: client.load_host_keys(user_home + '/.ssh/known_hosts') client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(host, username=username, key_filename=user_home + "/.ssh/id_rsa", timeout=4) #allow_agent=False pretty_print( "Looks like you already have access with public key to this server " + host + "...") return True except gaierror: pretty_print("Not able to connect to server: " + host + ", it's not reachable...") exit(1) except AuthenticationException: pretty_print("Connection to the server failed...") return False finally: client.close()
def commands(request): command_to_run = '' output = '' error = '' if request.method == "POST": form = CommandForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] command_to_run = form.cleaned_data['command_to_run'] ssh = SSHClient() ssh.load_host_keys(settings.CMDS_HOST_KEYS_FILENAME) try: ssh.connect(settings.CMDS_HOST, username=username, password=password) except AuthenticationException, ae: error = "Authentication failed. Did you type the wrong username or password?" if not error: ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command_to_run) output = ssh_stdout.read() error = ssh_stderr.read()
def main(): args = sys.argv[1:] if len(args) < 3: sys.exit('%s server command\nInvalid number of arguments.' % os.path.basename(sys.argv[0])) # extract the username, the server and the port from command line # argument username, server, port = SERVER_PATTERN.match(args[0]).groups() command = ' '.join(args[1:]) # create the client client = SSHClient() # load the keys of known hosts for host key verification client.load_host_keys( os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) # etablish the connection. A passwort is not supplied, only key-based # authentication works client.connect(server, int(port or 22), username) # execute the command and print its output stdin, stdout, stderr = client.exec_command(command) stderr.flush() stdout.flush() sys.stderr.write(stderr.read()) sys.stdout.write(stdout.read())
def main(): args = sys.argv[1:] if len(args) < 3: sys.exit('%s server command\nInvalid number of arguments.' % os.path.basename(sys.argv[0])) # extract the username, the server and the port from command line # argument username, server, port = SERVER_PATTERN.match(args[0]).groups() command = ' '.join(args[1:]) # create the client client = SSHClient() # load the keys of known hosts for host key verification client.load_host_keys(os.path.expanduser( os.path.join('~', '.ssh', 'known_hosts'))) # etablish the connection. A passwort is not supplied, only key-based # authentication works client.connect(server, int(port or 22), username) # execute the command and print its output stdin, stdout, stderr = client.exec_command(command) stderr.flush() stdout.flush() sys.stderr.write(stderr.read()) sys.stdout.write(stdout.read())
class SDKDInstaller(object): def __init__(self, args, **kwargs): logging.config.fileConfig('logging.conf') self.logger = logging.getLogger('SDKInstaller') self.remote = kwargs['remote'] self.remote_connection = SSHClient() self.remote_channel = None self.remote_path = kwargs['remote_path'] def start_remote_connection(self): self.remote_connection.load_host_keys() try: self.remote_connection.connect(self, self.remote) self.remote_channel = self.remote_connection.get_transport( ).open_session() except Exception as e: raise e def execute_command(self, command): self.remote_channel.exec_command(command) error = None if self.remote_channel.recv_stderr_ready() == True: error = self.remote_channel.recv_stderr(1024) if self.remote_channel.recv_exit_status() != 0: self.logger.error("Failed to execute command", command, error) exit(1) def install(self): pass def install_sdkd(self): pass def install_harness(self): pass
def get(self): if not self.remote_path: logging.critical('Remote file not specified') return False try: if 'host' not in self.connection or 'user' not in self.connection or 'keyfile' not in self.connection: logging.critical('No correct connection definition data set') return False except KeyError as e: logging.critical('Error while reading key: {}'.format(e)) if 'port' in self.connection: ssh_port = self.connection['port'] else: ssh_port = 22 ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.load_host_keys(filename=path.join(path.expanduser('~'), '.ssh', 'known_hosts')) try: ssh.connect( hostname=self.connection['host'], username=self.connection['user'], port=ssh_port, key_filename=self.connection['keyfile'], ) except SSHException as e: logging.critical('SSH Failed: {}'.format(e)) ssh.close() return False try: with SCPClient(ssh.get_transport()) as scp: scp.get(self.remote_path, self.local_path) return True except SCPException as e: logging.critical("Failed to retrieve backup: {}".format(e)) ssh.close() return False
def checkconnection(self): try: ssh = SSHClient() ssh.load_host_keys(self.sshpath) ssh.set_missing_host_key_policy(AutoAddPolicy()) if self.password != "": ssh.connect(self.server, username=self.username, password=self.password) else: k = RSAKey.from_private_key_file( path.expanduser(path.join("~", ".ssh", "id_rsa"))) ssh.connect(self.server, port=22, username=self.username, pkey=k, timeout=10, banner_timeout=5, auth_timeout=5) ssh.close() return True except (SSHException, socket.error) as se: print(se) ssh.close()
def ssh_connection(dest_host): """ Open a ssh connection. @param dest_host: fqdn of target host @type dest_host: string @rtype: paramiko.SSHClient (connected transport) @exceptions: If unable to connect """ client = SSHClient() client.load_host_keys(expanduser('~/.ssh/known_hosts')) sld('Connecting to {}'.format(dest_host)) try: client.connect(dest_host, username=Misc.SSH_CLIENT_USER_NAME) except Exception: sln('Failed to connect to host {}, because {} [{}]'.format( dest_host, sys.exc_info()[0].__name__, str(sys.exc_info()[1]))) raise else: sld('Connected to host {}'.format(dest_host)) return client
class RemoteClient: """Client to interact with a remote host via SSH & SCP.""" def __init__(self, gitServer, pxe, user, pxe_user, ssh_key_filepath, git_ssh_key_filepath, known_hosts_filepath, remote_path, gitServer2, pw1, pw2): self.gitServer = gitServer #gitserver ip self.pxe = pxe #pxe server ip self.user = user #gitserver username self.pxe_user = pxe_user #pxe server username self.gitServer2 = gitServer2 #second git Server IP for sending files back. self.known_hosts_filepath = known_hosts_filepath self.ssh_key_filepath = ssh_key_filepath #local windows machine path to the ssh id_rsa self.git_ssh_key_filepath = git_ssh_key_filepath self.remote_path = remote_path #place to put logs self.client = None self.scp = None self.conn = None self.query = None # for asking if ssh key already exists self.pw1 = pw1 self.pw2 = pw2 #self.upload_ssh_key()manually doing inline now def _get_ssh_key(self): """ Fetch locally stored SSH key. """ try: print(self.ssh_key_filepath) self.ssh_key = RSAKey.from_private_key_file(self.ssh_key_filepath) logging.info(f'Found SSH key at {self.ssh_key_filepath}') except SSHException as error: logging.error(error) return self.ssh_key def upload_ssh_key(self): while self.query != "yes": self.query = str.lower( input("Did you already send your ssh to the git server? ")) if self.query == "no" or self.query == "n": try: print(self.ssh_key_filepath, self.gitServer) """ Original Meant for a UNIX/LINUX system os.system(f'ssh-copy-id -i {self.ssh_key_filepath} {self.user}@{self.gitServer}>/dev/null 2>&1') os.system(f'ssh-copy-id -i {self.ssh_key_filepath}.pub {self.user}@{self.gitServer}>/dev/null 2>&1') """ print("SENDING OUR KEY TO THE GIT SERVER!") cmd = f"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe type {self.ssh_key_filepath}.pub | ssh {self.user}@{self.gitServer} \"cat >> ~/.ssh/authorized_keys\"" print(cmd) """Have to disable the line below because it causes Pycharm to hang up""" subprocess.call(cmd, shell=True) """ print("KEY SUCCESSFULLY SENT!") cmd = f"scp {self.user}@{self.gitServer}:~/.ssh/id_rsa {self.git_ssh_key_filepath}" try: subprocess.call(cmd) print("Received key from git!") except: print("Couldn't get key from git!") """ #logging.info(f'{self.ssh_key_filepath} uploaded to {self.gitServer}') except FileNotFoundError as error: logging.error(error) sleep(3) elif self.query == "yes" or self.query == "y": self.query = "yes" print("Skipping the ssh key copy") def _connect(self): """ Open connection to remote host. """ if self.conn is None: try: self.client = paramiko.SSHClient() self.client.load_system_host_keys() self.client.set_missing_host_key_policy(AutoAddPolicy()) self.client.connect( self.gitServer, username=self.user, #key_filename=self.ssh_key_filepath, password=self.pw1, look_for_keys=True, timeout=5000) #chan = self.client.invoke_shell() self.scp = SCPClient(self.client.get_transport()) except AuthenticationException as error: logging.error( f'Authentication failed: did you remember to create an SSH key? {error}' ) raise error return self.client def disconnect(self): """Close ssh connection.""" if self.client: self.client.close() if self.scp: self.scp.close() def execute_cmd_git(self, commands): """ Execute multiple commands in succession. :param commands: List of unix commands as strings. :type commands: List[str] """ self.conn = self._connect() output = [] for cmd in commands: stdin, stdout, stderr = self.client.exec_command(cmd) stdout.channel.recv_exit_status() response = stdout.readlines() print("EXECUTING IN GIT\n" "______________________________") print(cmd) for line in response: #print(f'INPUT: {cmd} | OUTPUT: {line}') line = line.replace("\n", "") print(line) output.append(line) return (output) def execute_cmd_pxe(self, commands): """ This version is meant to be used with the pxe and not the git server Execute multiple commands in succession. :param commands: List of unix commands as strings. :type commands: List[str] """ self.conn = self._connect2() output = [] print("EXECUTING IN PXE\n" "______________________________") for cmd in commands: stdin, stdout, stderr = self.remote_client.exec_command(cmd) stdout.channel.recv_exit_status() response = stdout.readlines() print(cmd) for line in response: #print(f'INPUT: {cmd} | OUTPUT: {line}') line = line.replace("\n", "") #print(line) output.append(line) return (output) def _connect2(self): #we need to go deeper """ This is specifically for the second ssh session into the PXE after bouncing off the git server Taken from: https://stackoverflow.com/questions/18968069/paramiko-port-forwarding-around-a-nat-router/19039769#19039769 modified to work within this class """ # Set up the proxy (forwarding server) credentials proxy_hostname = self.gitServer proxy_username = self.user proxy_port = 22 #pw1 = getpass.getpass("What is the Git Password? ") # Instantiate a client and connect to the proxy server self.proxy_client = SSHClient() self.proxy_client.load_host_keys(self.known_hosts_filepath) self.proxy_client.connect( proxy_hostname, port=proxy_port, username=proxy_username, #key_filename=self.ssh_key_filepath password=self.pw1) # Get the client's transport and open a `direct-tcpip` channel passing # the destination hostname:port and the local hostname:port transport = self.proxy_client.get_transport() dest_addr = (self.pxe, 22) local_addr = ('127.0.0.1', 1234) channel = transport.open_channel("direct-tcpip", dest_addr, local_addr) #pw2 = getpass.getpass("What is the PXE Password? ") # Create a NEW client and pass this channel to it as the `sock` (along with # whatever credentials you need to auth into your REMOTE box self.remote_client = SSHClient() self.remote_client.load_host_keys(self.known_hosts_filepath) self.remote_client.connect( self.pxe, port=22, username=self.pxe_user, #key_filename=self.git_ssh_key_filepath, password=self.pw2, sock=channel) # `remote_client` should now be able to issue commands to the REMOTE box return self.remote_client def bulk_upload(self, files): """ Upload multiple files to a remote directory. :param files: List of paths to local files. :type files: List[str] """ self.conn = self._connect() uploads = [self._upload_single_file(file) for file in files] logging.info( f'Finished uploading {len(uploads)} files to {self.remote_path} on {self.gitServer}' ) def download_file(self, file, destination): """Download file from remote host.""" if self.conn is None: self.conn = self.connect() self.scp.get(file, local_path=destination) def bulk_download_file(self, file, destination): """Download file from remote host.""" if self.conn is None: self.conn = self.connect() self.scp.get(file, local_path=destination, recursive=True) def change_pxe(self, pxe): self.pxe = pxe def qpn_finder(self, racksn): #originally for qpn. Now used for model and qpn. cmd = f"grep -rl {racksn} /WIN/" dirs = self.execute_cmd_pxe([cmd]) qpn = [] important_info = { } #this dictionary will be returned with the model name and qpn #traits = ("RACKPN", "MLBSN", "MODEL", "PDNUM") traits = ("RACKPN", "MLBSN", "MODEL") for dir in dirs: for trait in traits: cmd = f"grep -h \"{trait}=\" {dir}" # print(cmd) qpn = self.execute_cmd_pxe([cmd]) if qpn: item = qpn[0] item = item.replace(f"{trait}=", "") item = item.replace("\r", "") print(f"{item} WAS FOUND!") important_info[trait] = item return important_info
def check_remote_status(self): """ Make a call to check the status of a box and to optionally check the status of any processes specified in the config for the particular box. Returns a tuple of statuses: 1. Box Status: True/False if the box is reachable/unreachable 2. Process Statuses: A dictionary of processes (keyed by self.processes) and each of their statuses (True/False if they are running/not running). Sample Response: >>> box = RemoteBox(...., processes=['foo', 'bar']) >>> box.check_remote_status() >>> >>> # Box is up; `foo` is running; `bar` is not running >>> (True, {'foo': True, 'bar': False}) """ box_status = False proc_statuses = {} # Create the client and connect to proxy server # NOTE: I would love to move this connection logic to a # `get_client()` method but it appears paramiko's SSHClient # disconnects after it loses scope - even if attempting to # save the `client` as a class variable. Any refactor help # would be appreciated. # - http://stackoverflow.com/a/17317516/329902 try: proxy_client = SSHClient() proxy_client.load_host_keys(DEFAULT_KNOWN_HOSTS_FILE) proxy_client.connect( DEFAULT_PROXY_HOSTNAME, port=DEFAULT_PROXY_PORT, username=DEFAULT_PROXY_USERNAME, key_filename=DEFAULT_KEY_FILE ) print 'connected to proxy' # Get the transport and find create a `direct-tcpip` channel transport = proxy_client.get_transport() dest_addr = ('0.0.0.0', self.remote_port) src_addr = ('127.0.0.1', self.forwarded_port) channel = transport.open_channel("direct-tcpip", dest_addr, src_addr) # Create a connection to the remote box through the tunnel remote_client = SSHClient() remote_client.load_host_keys(DEFAULT_KNOWN_HOSTS_FILE) remote_client.connect( 'localhost', port=self.forwarded_port, username=self.remote_username, password=self.remote_password, sock=channel ) print 'connected to remote host' # The remote box is up box_status = True # If we cannot connect to the box, assume that all processes are down as well except ChannelException: for proc in self.processes: proc_statuses.update({proc: False}) return (box_status, proc_statuses) # Box is up, check the status of each process in the list for proc in self.processes: print 'checking process: `%s`' % proc x, stdout, e = remote_client.exec_command('ps aux | grep %s | grep -v grep' % proc) out = stdout.readlines() print 'out', out print '-------' proc_statuses.update({proc: len(out) > 0}) return (box_status, proc_statuses)
class SshClient(object): ''' @Desc : SSH Library for Marvin. Facilitates SSH,SCP services to marvin users @Input: host: Host to connect port: port on host to connect user: Username to be used for connecting passwd: Password for connection retries and delay applies for establishing connection timeout : Applies while executing command ''' def __init__(self, host, port, user, passwd, retries=60, delay=10, log_lvl=logging.DEBUG, keyPairFiles=None, timeout=10.0): self.host = None self.port = 22 self.user = user self.passwd = passwd self.keyPairFiles = keyPairFiles self.ssh = SSHClient() self.ssh.set_missing_host_key_policy(AutoAddPolicy()) self.logger = logging.getLogger('sshClient') self.retryCnt = 0 self.delay = 0 self.timeout = 3.0 ch = logging.StreamHandler() ch.setLevel(log_lvl) self.logger.addHandler(ch) # Check invalid host value and raise exception # Atleast host is required for connection if host is not None and host != '': self.host = host if retries is not None and retries > 0: self.retryCnt = retries if delay is not None and delay > 0: self.delay = delay if timeout is not None and timeout > 0: self.timeout = timeout if port is not None and port >= 0: self.port = port if self.createConnection() == FAILED: raise internalError("SSH Connection Failed") def execute(self, command): stdin, stdout, stderr = self.ssh.exec_command(command) output = stdout.readlines() errors = stderr.readlines() results = [] if output is not None and len(output) == 0: if errors is not None and len(errors) > 0: for error in errors: results.append(error.rstrip()) else: for strOut in output: results.append(strOut.rstrip()) self.logger.debug("{Cmd: %s via Host: %s} {returns: %s}" % (command, str(self.host), results)) return results def createConnection(self): ''' @Name: createConnection @Desc: Creates an ssh connection for retries mentioned,along with sleep mentioned @Output: SUCCESS on successful connection FAILED If connection through ssh failed ''' ret = FAILED except_msg = '' while self.retryCnt >= 0: try: self.logger.debug("====Trying SSH Connection: Host:%s User:%s\ Port:%s RetryCnt:%s===" % (self.host, self.user, str(self.port), str(self.retryCnt))) if self.keyPairFiles is None: self.ssh.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, timeout=self.timeout) else: self.ssh.load_host_keys(self.keyPairFiles) self.ssh.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, key_filename=self.keyPairFiles, timeout=self.timeout, look_for_keys=True ) self.logger.debug("===SSH to Host %s port : %s SUCCESSFUL===" % (str(self.host), str(self.port))) ret = SUCCESS break except BadHostKeyException as e: except_msg = GetDetailExceptionInfo(e) except AuthenticationException as e: except_msg = GetDetailExceptionInfo(e) except SSHException as e: except_msg = GetDetailExceptionInfo(e) except socket.error as e: except_msg = GetDetailExceptionInfo(e) except Exception as e: except_msg = GetDetailExceptionInfo(e) finally: if self.retryCnt == 0 or ret == SUCCESS: break if except_msg != '': self.logger.\ exception("SshClient: Exception under " "createConnection: %s" % except_msg) self.retryCnt = self.retryCnt - 1 time.sleep(self.delay) return ret def runCommand(self, command): ''' @Name: runCommand @Desc: Runs a command over ssh and returns the result along with status code @Input: command to execute @Output: 1: status of command executed. SUCCESS : If command execution is successful FAILED : If command execution has failed 2: stdin,stdout,stderr values of command output ''' ret = {"status": FAILED, "stdin": None, "stdout": None, "stderr": INVALID_INPUT} if command is None or command == '': return ret try: status_check = 1 stdin, stdout, stderr = self.ssh.\ exec_command(command, timeout=self.timeout) if stdout is not None: status_check = stdout.channel.recv_exit_status() if status_check == 0: ret["status"] = SUCCESS ret["stdout"] = stdout.readlines() if stderr is not None: ret["stderr"] = stderr.readlines() except Exception as e: ret["stderr"] = GetDetailExceptionInfo(e) self.logger.exception("SshClient: Exception under runCommand :%s" % GetDetailExceptionInfo(e)) finally: self.logger.debug(" Host: %s Cmd: %s Output:%s" % (self.host, command, str(ret))) return ret def scp(self, srcFile, destPath): transport = Transport((self.host, int(self.port))) transport.connect(username=self.user, password=self.passwd) sftp = SFTPClient.from_transport(transport) try: sftp.put(srcFile, destPath) except IOError as e: raise e def __del__(self): self.close() def close(self): if self.ssh is not None: self.ssh.close() self.ssh = None
#!/usr/bin/python from paramiko import SSHClient from userpass import Userpass import os, sys if len(sys.argv) < 3: print "usage: {} <path_to_authfile> <router>".format(sys.argv[0]) exit() #create ssh handler and read in keys ssh = SSHClient() keypath = os.path.expanduser('~/.ssh/known_hosts') ssh.load_host_keys(keypath) #load userpass file userpass = Userpass(sys.argv[1]) #connect host = sys.argv[2] ssh.connect( host, username=userpass.user, password=userpass.passwd ) stdin, stdout, stderr = ssh.exec_command( 'show version' ) for line in stdout: print '... ' + line.strip('\n') print "===" stdin, stdout, stderr = ssh.exec_command( 'show chassis hardware' ) for line in stdout: print '... ' + line.strip('\n')
import local_config import remote_config import sqlite3 #First check that our storage folder exists if not os.access(local_config.db_storage_dir, os.R_OK or os.W_OK): try: os.mkdir(local_config.db_storage_dir) except OSError as err: print("Could not create the storage directory at " + local_config.db_storage_dir) print(err.strerror) exit() ssh = SSHClient() ssh.load_system_host_keys() ssh.load_host_keys(local_config.local_host_keys_path) #Not recommended, but needed as for some reason it wouldn't recognise abe ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect('abe.cs.ox.ac.uk', port=2150, username="******", key_filename=local_config.pi_collect_key_path) except SSHException as e: print(e) #Grab the log containing the new filenames #with SCPClient scp = SCPClient(ssh.get_transport()) scp.get(remote_config.logging_dir + "/" + "new_updates.log") #Copy database over into storage directory
class Sloth(cls): def __init__(self, config): super().__init__(config) self._ssh_config = extension['config'] self._ssh_client = SSHClient() self.logger.debug('Loading system host keys.') self._ssh_client.load_system_host_keys() keys = self._ssh_config.get('keys') if keys: self.logger.debug('Loading additional host keys: %s' % keys) for key in keys: self._ssh_client.load_host_keys(key) if self._ssh_config.get('auto_add_unknown_hosts'): self.logger.debug('Automatically adding unknown hosts.') self._ssh_client.set_missing_host_key_policy(AutoAddPolicy()) def execute(self, action): '''Execute an action on remote hosts. :param action: action to be executed :returns: True if the execution was successful; raises exception otherwise ''' for host in self._ssh_config.get('hosts'): try: split_host = host.split(':') hostname = split_host[0] if len(split_host) == 2: port = int(split_host[1]) else: port = 22 username = self._ssh_config.get('username') password = self._ssh_config.get('password') self.exec_logger.debug( 'Connecting to %s:%d with username %s)' % (hostname, port, username)) self._ssh_client.connect( hostname=hostname, port=port, username=username, password=password, ) stdin, stdout, stderr = self._ssh_client.exec_command( action) for out in stdout: self.exec_logger.debug('%s' % out) for err in stderr: self.exec_logger.debug('%s' % err) self.exec_logger.info('Action executed: %s' % action) return True except Exception: raise
from findtools.find_files import (find_files, Match) import paramiko # from paramiko import SSHClient from scp import SCPClient ssh = SSHClient() ssh.load_system_host_keys() ssh.load_host_keys('/Users/dev/.ssh/known_hosts') #ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ### add key if needed?? ssh.connect('104.155.76.134', username='******') scp = SCPClient(ssh.get_transport()) sh_files_pattern = Match(filetype='f', name='*') found_files = find_files(path='/Users/dev/Desktop/repos/tmp', match=sh_files_pattern) for found_file in found_files: print found_file scp.put(found_file, remote_path='/home/dm/Projects/faces') #scp.put('/Users/xxxx/Documents/linux.txt', remote_path='/home/xxx') #scp.get('test2.txt')
def update_server(): for name in [args.server]: name = str(name).rstrip() print "Name:" + name client = SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(name, username="******", timeout=5) command = 'dzdo /usr/sbin/adflush -f' stdin, stdout, stderr = client.exec_command(command) output = stdout.readlines() error = stderr.readlines() for line in output: print "STDOUT:" + line.rstrip() for line in error: print "STDERR:" + line.rstrip() sys.exit() # Parse the arguments and create a merge serverd list if args.aix: print "Finding AIX servers" if args.aix == 'all': print 'All' if username == 'wrehfiel': server_list += AIXServer.objects.filter(active=True, exception=True, decommissioned=False) else: server_list += AIXServer.objects.filter(active=True, decommissioned=False) print server_list else: for server in [args.aix]: server_list += AIXServer.objects.filter(name=server) print server_list if args.linux: print 'Finding Linux servers' if args.linux == 'all': print 'Linux All' if username == 'wrehfiel': server_list += LinuxServer.objects.filter(active=True, exception=True, decommissioned=False) else: server_list += LinuxServer.objects.filter(active=True, decommissioned=False) print server_list else: for server in [args.linux]: server_list += LinuxServer.objects.filter(name=server) print server_list # sys.exit() counter = 0 total = len(server_list) for server in server_list: counter = counter + 1 print '--------------------------------------' print 'Working on server ' + str(counter) + "/" + str(total) + " - " + str(server) if utilities.ping(server): print "Ping test is good" keys_file_does_not_exist = 0 client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(str(server), username=username, password=password) # FIXME if this works, we should continue to the next server, right?? # there is nothing to do right? or should I be testing with keys not pass?? except: print 'SSH has failed' print 'Removing key from known_hosts' known_hosts = '/home/' + username + '/.ssh/known_hosts' file = open(known_hosts) lines = file.readlines() file.close() # now reopen it in write mode file = open(known_hosts, "w") for line in lines: if not re.search(server.name, line): file.write(line) file.close() file = open(known_hosts) lines = file.readlines() file.close() file = open(known_hosts, 'w') for line in lines: if not re.search(server.ip_address, line): file.write(line) file.close() print 'Trying SSH again' # Now lets try to use SSH again client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # FIXME the below box still isn't working?? try: client.connect(str(server), username=username, password=password) print "Ok, removing the entry worked." except: print "SSH STILL NOT WORKING!!!!!!!!!!!!!!!!!!!!!!" continue command = '[ -d /home/' + username + '/.ssh ] && echo 1 || echo 0' # command = 'ls /home' sdtin, stdout, stderr = client.exec_command(command) directory_exists = stdout.readlines() client.close() # print "stdout!" # print directory_exists[0].rstrip() if directory_exists[0].rstrip() == '0': print 'SSH directory does not exist. Creating' # directory does not exist so we need to create it client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) client.connect(str(server), username=username, password=password, allow_agent=True, look_for_keys=True) command = 'mkdir /home/' + username + '/.ssh;chmod 700 /home/' + username + '/.ssh' sdtin, stdout, stderr = client.exec_command(command) client.close() # directory doesn't exist, so the keys file doesn't either keys_file_does_not_exist = 1 print 'SSH Directory created' else: print 'SSH directory exists, checking for authorized_keys' # if the directory exists, test if authorized_keys exists client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) try: client.connect(str(server), username=username, password=password) except: print "Connection timed out or errored out" continue # this is a one off for red hat 6 and selinux, but it needs some testing # command = "restorecon -R ~/.ssh" # stdin, stdout, stderr = client.exec_command(command) command = '[ -e /home/' + username + '/.ssh/authorized_keys ] || [-e /home/' + username + '/.ssh/authorized_keys2 ] && echo 1 || echo 0' sdtin, stdout, stderr = client.exec_command(command) output = stdout.readlines()[0].rstrip() if output == '1': print output print 'Authorized keys file exists, moving on to the next server.' command = '/sbin/restorecon -R /home/' + username + '/.ssh' stdin, stdout, stderr = client.exec_command(command) continue else: print output print 'Authorized keys file does not exist.' keys_file_does_not_exist = 1 client.close() if keys_file_does_not_exist: print 'Transferring key' # sftp our key over transport = paramiko.Transport((str(server), 22)) try: transport.connect(username=username, password=password) except: # FIXME if the try isn't working, this isn't getting printed out print "Connection is timing out for some reason............" continue sftp = paramiko.SFTPClient.from_transport(transport) local = '/home/' + username + '/.ssh/id_rsa.pub' remote = '/home/' + username + '/.ssh/authorized_keys' sftp.put(remote, local) sftp.close() transport.close() # we've transferred it, but we need to rename the file now # the paramiko sftp won't rename it (or I haven't figured it out yet -Boomer) client.connect(str(server), username=username, password=password) command = 'mv /home/' + username + '/.ssh/id_rsa.pub /home/' + username + '/.ssh/authorized_keys' sdtin, stdout, stderr = client.exec_command(command) command = 'chmod 600 /home/' + username + '/.ssh/authorized*' sdtin, stdout, stderr = client.exec_command(command) print '-Key transferred and renamed' command = "dzdo restorecon -R ~/.ssh" stdin, stdout, stderr = client.exec_command(command) client.close() else: print '-Server is unreachable by ping!!!!!!!!!!'
class freetimeConfig(myConfigParser): def __init__(self): self.error = None self.groups_pos = 0 defaults_dir = os.path.join( sys.prefix, 'share', 'nugsl-freetime') path = homeDir( topdir='FreeTime' ) path = os.path.join( path, 'FreeTime') if not os.path.exists( path ): os.makedirs( path ) config_path = os.path.join( path, 'Config') if not os.path.exists( config_path ): os.makedirs( config_path ) data_path = os.path.join( path, 'Calendars') if not os.path.exists( data_path ): os.makedirs( data_path ) self.data_path = data_path self.category_path = {} p = os.path.join( data_path, 'Staff') if not os.path.exists( p ): os.makedirs( p ) self.category_path[ 'Staff' ] = p p = os.path.join( data_path, 'Student') if not os.path.exists( p ): os.makedirs( p ) self.category_path[ 'Student' ] = p config_file = os.path.join( config_path, 'profile.txt' ) if not os.path.exists( config_file ): default_file = os.path.join( defaults_dir, 'profile-default.txt') default = open( default_file ).read() open( config_file, 'w+' ).write( default ) self.error = 'Please edit your profile at %s.' % config_file return myConfigParser.__init__(self, {'language': 'en'}) self.paranoid_read( config_file ) if not 'User' in self.sections(): self.error = 'Missing section [User] in config file %s' % config_file return elif not self.has_option('User','name'): self.error = 'Missing option "name:" in section [User] of config file %s' % config_file return elif not self.has_option('User','email'): self.error = 'Missing option "email:" in section [User] of config file %s' % config_file return elif not self.has_option('User','telephone'): self.error = 'Missing option "telephone:" in section [User] of config file %s' % config_file return lang = self.get('User','language') self.name = self.get('User', 'name') if self.name == 'Unknown User': self.error = 'Please edit your profile at %s.' % config_file return self.email = self.get('User', 'email') self.telephone = self.get('User', 'telephone') repeat_icon_file = os.path.join( defaults_dir, 'repeat.png') img = Image.open( repeat_icon_file, 'r' ) self.repeat_icon = ImageTk.PhotoImage( img ) empty_icon_file = os.path.join( defaults_dir, 'empty.png') img = Image.open( empty_icon_file, 'r' ) self.empty_icon = ImageTk.PhotoImage( img ) right_file = os.path.join( defaults_dir, 'right.png') img = Image.open( right_file, 'r' ) self.right = ImageTk.PhotoImage( img ) left_file = os.path.join( defaults_dir, 'left.png') img = Image.open( left_file, 'r' ) self.left = ImageTk.PhotoImage( img ) self.times = freetimeTimes( defaults_dir, lang=lang ).times self.weekdays = freetimeWeekdays( defaults_dir, lang=lang ).weekdays self.month = monthConfig( self.weekdays ) userkey = userkeyConfig( defaults_dir, config_path ) self.error = userkey.error if self.error: self.error = 'Please add your Freetime key to use the calendar.' return self.userkey = userkey.get('UserKey', 'userkey') if self.userkey == 'UnknownUser': self.error = 'Please add your Freetime key to use the calendar.' return self.category = userkey.get('UserKey', 'category') pkey = StringIO() pkey.write( userkey.get('UserKey','rsa').lstrip() ) pkey.seek(0) self.pkey = RSAKey.from_private_key( pkey ) self.server = userkey.get('UserKey', 'server') self.server_account = userkey.get('UserKey','account') groups_file = os.path.join( config_path, 'groups.txt' ) if os.path.exists( groups_file ): text = open( groups_file ).read() try: text = text.decode('utf8') except: text = text.decode('shift_jis') print 'Barfed on groups file, using shift-jis encoding' self.groups = [x[1:-1] for x in re.findall('\[[^]]+\]'.decode('utf8'), text )] else: self.groups = [] if self.groups: self.groups.insert(0, 'Personal') ##print self.groups # # Reconcile old group data and current groups configuration self.groups_data_file = os.path.join( config_path, 'groups.pkl' ) if os.path.exists( self.groups_data_file ): ph = open( self.groups_data_file ) self.groups_data = Unpickler( ph ).load() ph.close() else: self.groups_data = {} for key in self.groups_data.keys(): if not key in self.groups: self.groups_data.pop(key) for group in self.groups: if not self.groups_data.has_key( group ): self.groups_data[ group ] = [] self.build_user_info() self.known_hosts_file = os.path.join( defaults_dir, 'known_hosts') self.user_data_file = os.path.join( data_path, self.category, self.userkey ) self.freetime = freeTime() def build_user_info(self): self.users = {'Staff': [], 'Student': []} today = date.today() self.user_index = {} for category in ['Staff','Student']: ids = os.listdir( self.category_path[ category ] ) for userid in ids: userfile = os.path.join( self.category_path[ category ], userid ) ph = open( userfile ) try: userdata = Unpickler( ph ).load() doit = True except EOFError: ph.close() os.unlink( userfile ) doit = False if doit: ph.close() fullname = userdata[1].strip() email = userdata[2].strip() telephone = userdata[3].strip() mtime = os.stat( userfile ).st_mtime filedate = date.fromtimestamp( mtime ) delta = today - filedate age = delta.days self.users[ category ].append( (userid, fullname, email, telephone, age) ) self.users[ category ].sort( self.sort_ids ) for pos in range(0, len(self.users[ category ]),1): # # Ugly but effective. We'll need a wrapper function to keep the # usage of this unified key straight. self.user_index[ category + '::' + self.users[ category][pos][0] ] = pos def sort_ids(self, a, b): a = a[0].split('_')[-1] b = b[0].split('_')[-1] if a > b: return 1 elif a == b: return 0 else: return -1 def network_setup(self): dict = {} self.net_mtime = self.network_connect() if self.net_mtime != None: if os.path.exists( self.user_data_file ): self.network_update() local_mtime = int(os.stat( self.user_data_file ).st_mtime) if local_mtime > self.net_mtime: self.network_upload() elif local_mtime < self.net_mtime: self.network_download() else: self.network_download() if os.path.exists( self.user_data_file ): ph = open( self.user_data_file ) dict = Unpickler( ph ).load()[-1] if not os.path.exists( self.user_data_file ) and self.net_mtime == None: ph = open( self.user_data_file, 'w+' ) Pickler( ph ).dump( dict ) ph.close() os.utime( self.user_data_file, (0,0) ) last_month = dateDelta( date.today() ).get_last_month() keys = dict.keys() keys.sort() for key in keys: if key[:7] < '%0.4d-%0.2d' % (last_month.year,last_month.month): dict.pop( key ) else: break self.freetime.update( dict ) def groups_save(self): ph = open(self.groups_data_file, 'w+' ) Pickler( ph ).dump( self.groups_data ) ph.close() def network_connect(self): self.sshclient = SSHClient() self.sshclient.set_missing_host_key_policy(AutoAddPolicy) self.sshclient.load_host_keys( self.known_hosts_file ) try: self.sshclient.connect( self.server, username=self.server_account, pkey=self.pkey, timeout=20 ) except: # Should have logging for this. self.sshclient.close() self.sshclient = None return None self.sftp = self.sshclient.open_sftp() if self.userkey in self.sftp.listdir( self.category ): return self.sftp.stat( self.category + '/' + self.userkey ).st_mtime else: return 0 def network_close(self): if self.sshclient: self.sftp.close() self.sshclient.close() else: # # Setting the mtime to zero will force a merge, rather # than an overwrite, when the Net is next accessed. os.utime( self.user_data_file, (0,0)) def network_upload(self): #if self.sshclient and self.userkey in self.sftp.listdir( self.category ): if self.sshclient and self.userkey in os.listdir( os.path.join( self.data_path, self.category ) ): self.sftp.put( self.user_data_file, self.category + '/' + self.userkey ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) def network_download(self): if self.sshclient and self.userkey in self.sftp.listdir( self.category ): self.sftp.get( self.category + '/' + self.userkey, self.user_data_file ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) # # The mtime of the local file is held at zero until # the first network connection from this instance. # If the local mtime is zero when network is available, # update from the server rather than overwriting, to # avoid losing data. def network_update(self): # # We have network, we have local file, we may not have # remote file. if self.userkey in self.sftp.listdir( self.category ): local_mtime = os.stat( self.user_data_file ).st_mtime if int(local_mtime) == 0: self.sftp.get( self.category + '/' + self.userkey, self.user_data_file + '.tmp' ) ph = open( self.user_data_file + '.tmp' ) net_data = Unpickler( ph ).load()[-1] ph.close() os.unlink( self.user_data_file + '.tmp' ) ph = open( self.user_data_file ) local_data = Unpickler( ph ).load()[-1] ph.close() local_data.update( net_data ) self.freetime = freeTime( dict=local_data ) ph = open( self.user_data_file, 'w+' ) Pickler( ph ).dump( self.bundle_data() ) ph.close() else: self.sftp.put( self.user_data_file, self.category + '/' + self.userkey ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) def network_update_others(self, category): """ Download files of other users for use in coordinating group schedules """ for file in self.sftp.listdir( category ): if category == self.category and file == self.userkey: continue self.sftp.get( category + '/' + file, os.path.join( self.data_path, category, file ) ) mtime = self.sftp.stat( category + '/' + file ).st_mtime os.utime( os.path.join( self.data_path, category, file ), (mtime,mtime) ) self.build_user_info() def bundle_data(self): bundle = [] bundle.append( self.userkey ) bundle.append( self.name ) bundle.append( self.email ) bundle.append( self.telephone ) bundle.append( self.freetime.copy() ) return bundle