def PreliminarilyVerifyInstance(self, instance_id, remote, identity_file,
                                    options):
        """Verify the instance's identity by connecting and running a command.

    Args:
      instance_id: str, id of the compute instance.
      remote: ssh.Remote, remote to connect to.
      identity_file: str, optional key file.
      options: dict, optional ssh options.

    Raises:
      ssh.CommandError: The ssh command failed.
      core_exceptions.NetworkIssueError: The instance id does not match.
    """
        metadata_id_url = (
            'http://metadata.google.internal/computeMetadata/v1/instance/id')
        # Exit codes 255 and 1 are taken by OpenSSH and PuTTY.
        # 23 chosen by fair dice roll.
        remote_command = [
            '[ `curl "{}" -H "Metadata-Flavor: Google" -q` = {} ] || exit 23'.
            format(metadata_id_url, instance_id)
        ]
        cmd = ssh.SSHCommand(remote,
                             identity_file=identity_file,
                             options=options,
                             remote_command=remote_command)
        return_code = cmd.Run(self.env, force_connect=True)  # pytype: disable=attribute-error
        if return_code == 0:
            return
        elif return_code == 23:
            raise core_exceptions.NetworkIssueError(
                'Established connection with host {} but was unable to '
                'confirm ID of the instance.'.format(remote.host))
        raise ssh.CommandError(cmd, return_code=return_code)
示例#2
0
 def testSSHErrorException(self):
     args = SSHTest.Args('fake-name', 'central2-a', True)
     instance = self._makeFakeInstance('fake-instance')
     self.make_requests.side_effect = iter([
         [self._makeFakeProjectResource()],
         [self._makeFakeProjectResource()],
         [self._makeFakeProjectResource()],
     ])
     ssh_util = tpu_utils.SSH(self.track)
     self.ssh_run.side_effect = ssh.CommandError('ssh', return_code=255)
     with self.assertRaisesRegex(
             ssh.CommandError, r'\[ssh\] exited with return code \[255\].'):
         ssh_util.SSHToInstance(args, instance)
示例#3
0
    def ObtainSelfIp(self, instance, user, dry_run, resource_registry):
        """Returns the localhost ip as seen from the VM.

    Args:
      instance: Google Compute Engine VM.
      user: The user to use to SSH into the instance.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    Returns:
      A string containing the local ip,
      None if the obtaining was unsuccessful
    Raises:
      ssh.CommandError: there was an error running a SSH command
    """
        instance_string = internal_helpers.GetInstanceNetworkTitleString(
            instance)
        log.out.write('Obtaining self ip from %s: ' % instance_string)
        # Sometimes this call will appear after the actual result
        log.out.flush()
        if dry_run:
            log.out.Print('<SELF-IP>')

        temp = tempfile.TemporaryFile()
        cmd = ['echo', '$SSH_CLIENT']
        try:
            external_helper.RunSSHCommandToInstance(
                command_list=cmd,
                instance=instance,
                user=user,
                args=self._args,
                ssh_helper=self._ssh_helper,
                explicit_output_file=temp,
                dry_run=dry_run)
        except Exception as e:  # pylint: disable=broad-exception
            log.out.write('\n')  # Close the open print stmt
            log.out.flush()
            raise ssh.CommandError(' '.join(cmd), str(e))

        temp.seek(0)
        who_am_i_str = temp.read()
        result = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',
                           who_am_i_str)
        if result:
            res = result.group(1)
            log.out.Print(res)
            log.out.flush()
            return res

        return None
示例#4
0
 def testScpError(self):
     self.make_requests.side_effect = iter([
         [self.instance],
         [self.project_resource],
     ])
     self.scp_run.side_effect = ssh.CommandError('scp', return_code=255)
     with self.assertRaisesRegex(
             ssh.CommandError, r'\[scp\] exited with return code \[255\].'):
         self.Run("""\
       compute scp
       instance-1:~/remote-file
       ~/local-dir
       --zone zone-1
       """)
示例#5
0
    def CheckTraceroute(self, instance, user, dry_run, resource_registry):
        """Checks whether the instance has traceroute in PATH.

    Args:
      instance: Google Compute Engine VM.
      user: The user to use to SSH into the instance.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    Returns:
      True if the instance has traceroute in PATH,
      False otherwise
    Raises:
      ssh.CommandError: there was an error running a SSH command
    """
        instance_string = internal_helpers.GetInstanceNetworkTitleString(
            instance)
        log.out.write('Checking traceroute for %s: ' % instance_string)
        if dry_run:
            log.out.Print('[DRY-RUN] No command executed.')
        log.out.flush()

        cmd = ['which', 'traceroute']
        try:
            # This command is silent
            with open(os.devnull) as dev_null:
                return_code = external_helper.RunSSHCommandToInstance(
                    command_list=cmd,
                    instance=instance,
                    user=user,
                    args=self._args,
                    ssh_helper=self._ssh_helper,
                    explicit_output_file=dev_null,
                    dry_run=dry_run)
        except Exception as e:
            log.out.write(str(e))
            log.out.write('\n')  # Close the open print stmt
            log.out.flush()
            raise ssh.CommandError(' '.join(cmd), str(e))

        if return_code == 0:
            log.out.Print('Traceroute found in PATH')
        else:
            log.out.Print('Traceroute not found in PATH')
        log.out.flush()
        return return_code == 0
示例#6
0
  def PreliminarilyVerifyInstance(self, instance_id, remote, identity_file,
                                  options):
    """Verify the instance's identity by connecting and running a command.

    Args:
      instance_id: str, id of the compute instance.
      remote: ssh.Remote, remote to connect to.
      identity_file: str, optional key file.
      options: dict, optional ssh options.

    Raises:
      ssh.CommandError: The ssh command failed.
      core_exceptions.NetworkIssueError: The instance id does not match.
    """
    if not properties.VALUES.ssh.verify_internal_ip.GetBool():
      log.warning(
          'Skipping internal IP verification connection and connecting to [{}] '
          'in the current subnet. This may be the wrong host if the instance '
          'is in a different subnet!'.format(remote.host))
      return

    metadata_id_url = (
        'http://metadata.google.internal/computeMetadata/v1/instance/id')
    # Exit codes 255 and 1 are taken by OpenSSH and PuTTY.
    # 23 chosen by fair dice roll.
    remote_command = [
        '[ `curl "{}" -H "Metadata-Flavor: Google" -q` = {} ] || exit 23'
        .format(metadata_id_url, instance_id)]
    cmd = ssh.SSHCommand(remote, identity_file=identity_file,
                         options=options, remote_command=remote_command)
    return_code = cmd.Run(
        self.env,
        force_connect=properties.VALUES.ssh.putty_force_connect.GetBool())
    if return_code == 0:
      return
    elif return_code == 23:
      raise core_exceptions.NetworkIssueError(
          'Established connection with host {} but was unable to '
          'confirm ID of the instance.'.format(remote.host))
    raise ssh.CommandError(cmd, return_code=return_code)