#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.

"""This class creates SSH session to Device.

This file defines the command/console interaction between the test
instance and the CPE device. This includes ssh tunnel establishment,
shell command passing, and device log collection, etc.

"""

__author__ = 'Lehan Meng (lmeng@google.com)'


import os
import tempfile
import time

import pexpect


class SSH(object):
  """SSH class that create a ssh tunnel to the CPE device.

  ssh tunnel can be established from various locations:
    - from PC that on the same LAN of the device
    - from PC that must ssh to device over authentication server (e.g., jump)
    - from PC that must ssh to device over lab server (e.g., athenasrv3)

  """

  def __init__(self, dev=None, **kwargs):
    """Initiated the SSH class.

    If a device is used to initiate the SSH Class, try to create an ssh tunnel
    using parameters provided by this device, otherwise use default parameter
    values.

    Args:
      dev: a device instance, which has necessary parameters to create a
              tunnel
      kwargs['user']: ssh user name
      kwargs['addr']: device ip address
      kwargs['pwd']: ssh password
      kwargs['bruno_prompt']: device shell command prompt
      etc.
    """

    self.params = {
      'user': 'root',
      'addr': None,
      'addr_ipv6': None,
      'pwd': 'google',
      'bruno_prompt': '\(none\)#',
      'jump_server': 'jmp.googlefiber.net',
      'jump_prompt': None,
      'athena_user': 'lmeng',
      'athena_pwd': 'changeme',
      'athena_prompt': None,
      'ssh_use_athena': False}

    self.tmp_file = tempfile.TemporaryFile(mode='w+t')

    self.__short_delay = 5  # 5 seconds delay
    self.__delay = 10  # medium delay
    self.__long_delay = 30  #long delay

    for s in kwargs:
      self.params[s] = kwargs[s]
    #populate prompt on jump and athena server:
    if self.params['athena_user']:
      self.params['jump_prompt'] = self.params['athena_user'] + '@jmp101.nuq1:'
      self.params['athena_prompt'] = ('[' + self.params['athena_user']
                                      + '@athenasrv3 ~]$')

  def SetLogging(self, logging):
    """Setup the logging file(s)."""
    self.log = logging

  def Ssh(self):
    """Setup an ssh tunnel to device, return immediately upon failure.

    This method create an ssh tunnel from PC that on the same network of device
    Returns:
      return True when succeed, return False otherwise
    """
    # clear the temp file
    self.tmp_file.close()
    self.tmp_file = tempfile.TemporaryFile(mode='w+t')
    ssh_newkey = 'Are you sure you want to continue connecting'

    if self.params['addr_ipv6']:
      addr = self.params['addr_ipv6']
    else:
      addr = self.params['addr']

    p_ssh = pexpect.spawn('ssh '+self.params['user']+'@'+addr)
    i = p_ssh.expect(
        [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF,
         '\(none\)#', 'gfibertv#', pexpect.TIMEOUT], self.__long_delay)

    while 1:
      if i == 0:
        print 'choose Yes'
        p_ssh.sendline('yes')
        i = p_ssh.expect(
            [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF])
      if i == 1:
        print 'need password'
        p_ssh.sendline(self.param['pwd'])
        i = p_ssh.expect(
            [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF])
      if i == 2 or i == 4 or i == 5:
        print 'Login OK'
        p_ssh.logfile = self.tmp_file
        self.p_ssh = p_ssh
        if i == 4: self.params['bruno_prompt'] = '\(none\)#'
        if i == 5: self.params['bruno_prompt'] = 'gfibertv#'
        return True
      if i == 3 or i == 6:
        print 'ssh did not respond, or connection timeout'
        return False
      if i < 0 or i > 6:
        print 'Error, quit'
        return False

  def SetDeviceSSHKey(self):
    """Setup ssh-agent on athena server."""
    self.p_ssh.sendline('ssh-agent /bin/bash')
    self.p_ssh.expect(self.params['athena_prompt'])
    #p_ssh.expect(self.params['athena_prompt'])
    #print self.p_ssh.before, self.p_ssh.after
    print '========================'
    print 'add bruno key file:'
    self.p_ssh.sendline('ssh-add /home/' + self.params['athena_user']
                        + '/.ssh/bruno-sshkey')
    self.p_ssh.expect(self.params['athena_prompt'])
    #print self.p_ssh.before

  def SshFromAthena(self, set_key=False):
    """Initiate an ssh tunnel from the athenasrv3 to the device.

    Args:
      set_key: if set True, ssh-key will be reset before ssh
    Returns:
      return True when succeed, return False otherwise
    """
    # clear the temp file
    self.tmp_file.close()
    self.tmp_file = tempfile.TemporaryFile(mode='w+t')
    self.p_ssh.logfile = self.tmp_file
    #Const
    ssh_newkey = 'Are you sure you want to continue connecting'

    if set_key:
      self.SetDeviceSSHKey()

    if self.params['addr_ipv6']:
      addr = self.params['addr_ipv6']
    else:
      addr = self.params['addr']

    self.p_ssh.sendline('ssh '+self.params['user']+'@'+addr)
    i = self.p_ssh.expect(
        [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF,
         '\(none\)#', 'gfibertv#', pexpect.TIMEOUT])

    while 1:
      if i == 0:
        print 'choose Yes'
        self.p_ssh.sendline('yes')
        i = self.p_ssh.expect(
            [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF])
      if i == 1:
        print 'need password'
        self.p_ssh.sendline(self.params['pwd'])
        i = self.p_ssh.expect(
            [ssh_newkey, 'password:', self.params['bruno_prompt'], pexpect.EOF])
      if i == 2 or i == 4 or i == 5:
        print 'Login OK'
        self.p_ssh.logfile = self.tmp_file
        if i == 4: self.params['bruno_prompt'] = '\(none\)#'
        if i == 5: self.params['bruno_prompt'] = 'gfibertv#'
        return True
      if i == 3 or i == 6:
        print 'Key or connection timeout'
        return False
      if i < 0 or i > 6:
        print 'Error, quit'
        return False

  def ExitToAthena(self):
    """Terminate the ssh tunnel to device, and exit to athenasrv3."""
    #self.p_ssh.sendline('exit')
    #self.p_ssh.expect(self.params['athena_prompt'])
    self.p_ssh.sendline('exit')
    self.p_ssh.expect(self.params['athena_prompt'])

  def SshToAthena(self):
    """ssh to athenasrv3, over jump server from a Google PC.

    This is for the reason that some test environment can only be accessed via
    corp PC, authentication server (e.g., jump) and lab server
    (e.g., athenasrv3)
    Returns:
      return True upon success
    """
    self.params['ssh_use_athena'] = True
    p_ssh = pexpect.spawn('ssh -a ' + self.params['jump_server'])
    print 'ssh -a jmp.googlefiber.net ...'
    #p_ssh.expect('lmeng@jmp101.nuq1:.*[\\$]')
    i = p_ssh.expect(
        [self.params['jump_prompt'], pexpect.TIMEOUT, pexpect.EOF],
        self.__short_delay*3)
    if i == 1 or i == 2:
      info = self.log.CreateErrorInfo(
            'critical', 'Cannot establish SSH tunnel to jump server.'
            'Timeout or incorrect prompt!')
      self.log.SendLine(None, info)

    print p_ssh.before, p_ssh.after
    print '========================'
    p_ssh.sendline('ssh -a ' + self.params['athena_user'] + '@10.1.16.250')
    print 'ssh -a ' + self.params['athena_user'] + '@10.1.16.250 ...'
    i = p_ssh.expect([self.params['athena_user'] + '@10.1.16.250\'s password:',
                      pexpect.TIMEOUT, pexpect.EOF], self.__short_delay)
    if i == 1 or i == 2:
      info = self.log.CreateErrorInfo(
            'critical', 'Cannot establish SSH tunnel to athena server.'
            'Timeout or incorrect prompt!')
      self.log.SendLine(None, info)

    print '========================'
    print self.params['athena_user'] + '@10.1.16.250\'s password:'
    p_ssh.sendline(self.params['athena_pwd'])
    p_ssh.expect(self.params['athena_prompt'])
    p_ssh.expect(self.params['athena_prompt'])
    print p_ssh.before
    print '========================'
    print 'login athena3'
    self.p_ssh = p_ssh

  def SshRetry(self, max_retry=20, retry_delay=15):
    """Establish ssh connection to Device, retry upon failure.

    Args:
      max_retry: the total number of retry
      retry_delay: delay between each ssh try
    """
    tunnel = self.Ssh()
    if not tunnel:
      retry = 0
      while not tunnel and retry < max_retry:
        delay = retry_delay
        info = self.log.CreateErrorInfo(
            'Warning', 'Failed to create ssh tunnel, retry after '
            + str(delay) + ' seconds')
        self.log.SendLine(None, info)
        time.sleep(delay)
        tunnel = self.Ssh()
        retry += 1

      if retry >= max_retry:
        info = self.log.CreateErrorInfo(
            'critical', 'Cannot establish ssh tunnel to Device within '
            + str(max_retry*delay)
            + ' seconds! Timeout or incorrect command prompt!')
        self.log.SendLine(None, info)
        os.sys.exit(1)

    info = self.log.CreateProgressInfo(
        '---', 'ssh session to Device successfully established!')
    self.log.SendLine(None, info)

  def SshRetryFromAthena(self, max_retry=5, retry_delay=15, set_key=False):
    """Establish ssh connection to Device from athenasrv3, retry upon failure.

    Args:
      max_retry: the total number of retry
      retry_delay: delay between each ssh try
      set_key: if ssh-key needs to be set
    """
    tunnel = self.SshFromAthena(set_key)
    if not tunnel:
      retry = 0
      while not tunnel and retry < max_retry:
        delay = retry_delay
        info = self.log.CreateErrorInfo(
            'Warning', 'Failed to create ssh tunnel, retry after '
            + str(delay) + ' seconds')
        self.log.SendLine(None, info)
        time.sleep(delay)
        tunnel = self.SshFromAthena()
        retry += 1

      if retry >= max_retry:
        info = self.log.CreateErrorInfo(
            'critical', 'Cannot establish ssh tunnel to Device within '
            + str(max_retry*delay)
            + ' seconds! Timeout or incorrect command prompt!')
        self.log.SendLine(None, info)
        os.sys.exit(1)

    info = self.log.CreateProgressInfo(
        '---', 'ssh session to Device successfully established!')
    self.log.SendLine(None, info)

  def SendCmd(self, cmd, delay=10):
    """Send a command to the Device over ssh tunnel.

    Args:
      cmd: the shell command to execute
      delay: time delay while waiting for shell prompt after command is
             executed
    Returns:
      return True if send command succeeded
    """
    self.p_ssh.sendline(cmd)
    i = self.p_ssh.expect(
        [self.params['bruno_prompt'], pexpect.EOF, pexpect.TIMEOUT], delay)

    while 1:
      if i == 0:
        # send command successfully
        return True
      if i == 1 or i == 2:
        # prompt not returned
        info = self.log.CreateErrorInfo(
            'Warning', 'Device not responding to shell command or timeout.'
            ' Connect after 10 seconds ...')
        self.log.SendLine(None, info)
        time.sleep(10)
        if self.params['ssh_use_athena']:
          self.SshRetryFromAthena()
        else:
          self.SshRetry()
        self.p_ssh.sendline(cmd)
        i = self.p_ssh.expect(
            [self.params['bruno_prompt'], pexpect.EOF, pexpect.TIMEOUT], delay)

  def GetCmdOutput(self, buff_size=0):
    """Get lines from the command output of the device, in a bottom up manner.

    Args:
      buff_size: if buff_size<=0, return all output of a command
                if buff_size>0, return 'buff_size' from command output
    Returns:
      f_list: The most recent output lines comes at the begging of the f_list
    """
    self.tmp_file.seek(0)
    if buff_size > 0:
      f_list = reversed(self.tmp_file.readlines()[-buff_size:])
    else:
      f_list = reversed(self.tmp_file.readlines())
    f_list = list(f_list)
    return f_list

  def IsClosed(self):
    """Verify if the ssh tunnel is closed.

    Returns:
      return the status of ssh tunnel
    """
    return self.p_ssh.closed

  def ExitStatus(self):
    """Exit status of the ssh process.

    Returns:
      return the exit status of ssh process
    """
    return self.p_ssh.ExitStatus

  def SignalStatus(self):
    """Signal status of the ssh process.

    Returns:
      return the signal status of ssh process
    """
    return self.p_ssh.SignalStatus

  def Close(self):
    # exit the ssh tunnel
    self.p_ssh.sendline('exit')
    i = self.p_ssh.expect([self.params['athena_prompt'],
                           self.params['jump_prompt'],
                           self.params['bruno_prompt'],
                           pexpect.EOF, pexpect.TIMEOUT])
    while 1:
      if i == 0:
        # now at athena server:
        self.p_ssh.sendline('exit')
        i = self.p_ssh.expect([self.params['athena_prompt'],
                               self.params['jump_prompt'],
                               self.params['bruno_prompt'],
                               pexpect.EOF, pexpect.TIMEOUT])
      elif i == 1:
        # now at jump server:
        self.p_ssh.sendline('exit')
        break
      elif i == 2:
        # now at bruno:
        self.p_ssh.sendline('exit')
        i = self.expect([self.params['athena_prompt'],
                         self.params['jump_prompt'],
                         self.params['bruno_prompt'],
                         pexpect.EOF, pexpect.TIMEOUT])
      elif i == 3 or i == 4:
        # time out:
        print 'Exit from Device.'
        break
      else:
        break

  def __del__(self):
    self.tmp_file.close()
    #self.Close()

# End of SSH class

