Home | History | Annotate | Download | only in ssh
      1 # Copyright 2016 - The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 
     16 class SshFormatter(object):
     17     """Handles formatting ssh commands.
     18 
     19     Handler for formatting chunks of the ssh command to run.
     20     """
     21 
     22     def format_ssh_executable(self, settings):
     23         """Format the executable name.
     24 
     25         Formats the executable name as a string.
     26 
     27         Args:
     28             settings: The ssh settings being used.
     29 
     30         Returns:
     31             A string for the ssh executable name.
     32         """
     33         return settings.executable
     34 
     35     def format_host_name(self, settings):
     36         """Format hostname.
     37 
     38         Formats the hostname to connect to.
     39 
     40         Args:
     41             settings: The ssh settings being used.
     42 
     43         Returns:
     44             A string of the connection host name to connect to.
     45         """
     46         return '%s@%s' % (settings.username, settings.hostname)
     47 
     48     def format_value(self, value):
     49         """Formats a command line value.
     50 
     51         Takes in a value and formats it so it can be safely used in the
     52         command line.
     53 
     54         Args:
     55             value: The value to format.
     56 
     57         Returns:
     58             A string representation of the formatted value.
     59         """
     60         if isinstance(value, bool):
     61             return 'yes' if value else 'no'
     62 
     63         return str(value)
     64 
     65     def format_options_list(self, options):
     66         """Format the option list.
     67 
     68         Formats a dictionary of options into a list of strings to be used
     69         on the command line.
     70 
     71         Args:
     72             options: A dictionary of options.
     73 
     74         Returns:
     75             An iterator of strings that should go on the command line.
     76         """
     77         for option_name in options:
     78             option = options[option_name]
     79 
     80             yield '-o'
     81             yield '%s=%s' % (option_name, self.format_value(option))
     82 
     83     def format_flag_list(self, flags):
     84         """Format the flags list.
     85 
     86         Formats a dictionary of flags into a list of strings to be used
     87         on the command line.
     88 
     89         Args:
     90             flags: A dictonary of options.
     91 
     92         Returns:
     93             An iterator of strings that should be used on the command line.
     94         """
     95         for flag_name in flags:
     96             flag = flags[flag_name]
     97 
     98             yield flag_name
     99             if flag is not None:
    100                 yield self.format_value(flag)
    101 
    102     def format_ssh_local_command(self,
    103                                  settings,
    104                                  extra_flags={},
    105                                  extra_options={}):
    106         """Formats the local part of the ssh command.
    107 
    108         Formats the local section of the ssh command. This is the part of the
    109         command that will actual launch ssh on our local machine with the
    110         specified settings.
    111 
    112         Args:
    113             settings: The ssh settings.
    114             extra_flags: Extra flags to inlcude.
    115             extra_options: Extra options to include.
    116 
    117         Returns:
    118             An array of strings that make up the command and its local
    119             arguments.
    120         """
    121         options = settings.construct_ssh_options()
    122         for extra_option_name in extra_options:
    123             options[extra_option_name] = extra_options[extra_option_name]
    124         options_list = list(self.format_options_list(options))
    125 
    126         flags = settings.construct_ssh_flags()
    127         for extra_flag_name in extra_flags:
    128             flags[extra_flag_name] = extra_flags[extra_flag_name]
    129         flags_list = list(self.format_flag_list(flags))
    130 
    131         all_options = options_list + flags_list
    132         host_name = self.format_host_name(settings)
    133         executable = self.format_ssh_executable(settings)
    134 
    135         base_command = [executable] + all_options + [host_name]
    136 
    137         return base_command
    138 
    139     def format_ssh_command(self,
    140                            remote_command,
    141                            settings,
    142                            extra_flags={},
    143                            extra_options={}):
    144         """Formats the full ssh command.
    145 
    146         Creates the full format for an ssh command.
    147 
    148         Args:
    149             remote_command: A string that represents the remote command to
    150                             execute.
    151             settings: The ssh settings to use.
    152             extra_flags: Extra flags to include in the settings.
    153             extra_options: Extra options to include in the settings.
    154 
    155         Returns:
    156             A list of strings that make up the total ssh command.
    157         """
    158         local_command = self.format_ssh_local_command(settings, extra_flags,
    159                                                       extra_options)
    160 
    161         local_command.append(remote_command)
    162         return local_command
    163 
    164     def format_remote_command(self, command, env):
    165         """Formats the remote part of the ssh command.
    166 
    167         Formatts the command that will run on the remote machine.
    168 
    169         Args:
    170             command: string, The command to be executed.
    171             env: Enviroment variables to add to the remote envirment.
    172 
    173         Returns:
    174             A string that represents the command line to execute on the remote
    175             machine.
    176         """
    177         if not env:
    178             env_str = ''
    179         else:
    180             env_str = 'export '
    181             for name in env:
    182                 value = env[name]
    183                 env_str += '%s=%s ' % (name, str(value))
    184             env_str += ';'
    185 
    186         execution_line = '%s %s;' % (env_str, command)
    187         return execution_line
    188 
    189     def format_command(self,
    190                        command,
    191                        env,
    192                        settings,
    193                        extra_flags={},
    194                        extra_options={}):
    195         """Formats a full command.
    196 
    197         Formats the full command to run in order to run a command on a remote
    198         machine.
    199 
    200         Args:
    201             command: The command to run on the remote machine. Can either be
    202                      a string or a list.
    203             env: The enviroment variables to include on the remote machine.
    204             settings: The ssh settings to use.
    205             extra_flags: Extra flags to include with the settings.
    206             extra_options: Extra options to include with the settings.
    207         """
    208         remote_command = self.format_remote_command(command, env)
    209         return self.format_ssh_command(remote_command, settings, extra_flags,
    210                                        extra_options)
    211