Beispiel #1
0
def CreateSSHPoller(remote,
                    identity_file,
                    options,
                    iap_tunnel_helper,
                    extra_flags=None,
                    port=None):
    """Creates and returns an SSH poller."""

    ssh_poller_args = {
        'remote': remote,
        'identity_file': identity_file,
        'options': options,
        'extra_flags': extra_flags,
        'max_wait_ms': SSH_KEY_PROPAGATION_TIMEOUT_SEC
    }

    # Do not include default port since that will prevent users from
    # specifying a custom port (b/121998342).
    if port:
        ssh_poller_args['port'] = str(port)

    if iap_tunnel_helper:
        ssh_poller_args['remote'] = ssh.Remote('localhost', remote.user)
        ssh_poller_args['port'] = str(iap_tunnel_helper.GetLocalPort())

    return ssh.SSHPoller(**ssh_poller_args)
Beispiel #2
0
def CreateSSHPoller(remote, identity_file, options, iap_tunnel_helper,
                    extra_flags=None, port=DEFAULT_SSH_PORT):
  if iap_tunnel_helper:
    remote = ssh.Remote('localhost', remote.user)
    port = iap_tunnel_helper.GetLocalPort()
  return ssh.SSHPoller(
      remote, port=str(port) if port else None, identity_file=identity_file,
      options=options, extra_flags=extra_flags,
      max_wait_ms=SSH_KEY_PROPAGATION_TIMEOUT_SEC)
Beispiel #3
0
 def _WaitForSSHKeysToPropagate(self, ssh_helper, remote, identity_file,
                                user, instance, options):
     """Waits for SSH keys to propagate in order to SSH to the instance."""
     ssh_helper.EnsureSSHKeyExists(
         self.client, user, instance,
         ssh_helper.GetProject(
             self.client,
             properties.VALUES.core.project.Get(required=True)),
         times.Now() + datetime.timedelta(seconds=300))
     ssh_poller = ssh.SSHPoller(remote=remote,
                                identity_file=identity_file,
                                options=options,
                                max_wait_ms=120 * 1000)
     try:
         ssh_poller.Poll(ssh_helper.env, force_connect=True)
     except retry.WaitException:
         raise ssh_utils.NetworkError()
Beispiel #4
0
def CreateSSHPoller(remote, identity_file, options, iap_tunnel_args,
                    extra_flags=None, port=None):
  """Creates and returns an SSH poller."""

  ssh_poller_args = {'remote': remote,
                     'identity_file': identity_file,
                     'options': options,
                     'iap_tunnel_args': iap_tunnel_args,
                     'extra_flags': extra_flags,
                     'max_wait_ms': SSH_KEY_PROPAGATION_TIMEOUT_MS}

  # Do not include default port since that will prevent users from
  # specifying a custom port (b/121998342).
  if port:
    ssh_poller_args['port'] = six.text_type(port)

  return ssh.SSHPoller(**ssh_poller_args)
Beispiel #5
0
    def Run(self, args):
        """See ssh_utils.BaseSSHCLICommand.Run."""
        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        client = holder.client

        ssh_helper = ssh_utils.BaseSSHCLIHelper()
        ssh_helper.Run(args)
        user, instance_name = ssh_utils.GetUserAndInstance(args.user_host)
        instance_ref = instance_flags.SSH_INSTANCE_RESOLVER.ResolveResources(
            [instance_name],
            compute_scope.ScopeEnum.ZONE,
            args.zone,
            holder.resources,
            scope_lister=instance_flags.GetInstanceZoneScopeLister(client))[0]
        instance = ssh_helper.GetInstance(client, instance_ref)
        project = ssh_helper.GetProject(client, instance_ref.project)
        if args.plain:
            use_oslogin = False
        else:
            user, use_oslogin = ssh_helper.CheckForOsloginAndGetUser(
                instance, project, user, self.ReleaseTrack())
        if self._use_internal_ip:
            ip_address = ssh_utils.GetInternalIPAddress(instance)
        else:
            ip_address = ssh_utils.GetExternalIPAddress(instance)

        remote = ssh.Remote(ip_address, user)

        identity_file = None
        options = None
        if not args.plain:
            identity_file = ssh_helper.keys.key_file
            options = ssh_helper.GetConfig(ssh_utils.HostKeyAlias(instance),
                                           args.strict_host_key_checking)

        extra_flags = ssh.ParseAndSubstituteSSHFlags(args, remote, ip_address)
        remainder = []

        if args.ssh_args:
            remainder.extend(args.ssh_args)

        # Transform args.command into arg list or None if no command
        command_list = args.command.split(' ') if args.command else None
        tty = containers.GetTty(args.container, command_list)
        remote_command = containers.GetRemoteCommand(args.container,
                                                     command_list)

        cmd = ssh.SSHCommand(remote,
                             identity_file=identity_file,
                             options=options,
                             extra_flags=extra_flags,
                             remote_command=remote_command,
                             tty=tty,
                             remainder=remainder)
        if args.dry_run:
            log.out.Print(' '.join(cmd.Build(ssh_helper.env)))
            return

        if args.plain or use_oslogin:
            keys_newly_added = False
        else:
            keys_newly_added = ssh_helper.EnsureSSHKeyExists(
                client, remote.user, instance, project)

        if keys_newly_added:
            poller = ssh.SSHPoller(
                remote,
                identity_file=identity_file,
                options=options,
                extra_flags=extra_flags,
                max_wait_ms=ssh_utils.SSH_KEY_PROPAGATION_TIMEOUT_SEC)
            log.status.Print('Waiting for SSH key to propagate.')
            # TODO(b/35355795): Don't force_connect
            try:
                poller.Poll(ssh_helper.env, force_connect=True)
            except retry.WaitException:
                raise ssh_utils.NetworkError()

        if self._use_internal_ip:
            ssh_helper.PreliminarilyVerifyInstance(instance.id, remote,
                                                   identity_file, options)

        return_code = cmd.Run(ssh_helper.env, force_connect=True)
        if return_code:
            # Can't raise an exception because we don't want any "ERROR" message
            # printed; the output from `ssh` will be enough.
            sys.exit(return_code)
Beispiel #6
0
  def Run(self, args, port=None, recursive=False, extra_flags=None):
    """SCP files between local and remote GCE instance.

    Run this method from subclasses' Run methods.

    Args:
      args: argparse.Namespace, the args the command was invoked with.
      port: str, int or None, Port number to use for SSH connection.
      recursive: bool, Whether to use recursive copying using -R flag.
      extra_flags: [str] or None, extra flags to add to command invocation.

    Raises:
      ssh_utils.NetworkError: Network issue which likely is due to failure
        of SSH key propagation.
      ssh.CommandError: The SSH command exited with SSH exit code, which
        usually implies that a connection problem occurred.
    """
    super(BaseScpCommand, self).Run(args)

    dst = ssh.FileReference.FromPath(args.destination)
    srcs = [ssh.FileReference.FromPath(src) for src in args.sources]

    # Make sure we have a unique remote
    ssh.SCPCommand.Verify(srcs, dst, single_remote=True)

    remote = dst.remote or srcs[0].remote
    if not dst.remote:  # Make sure all remotes point to the same ref
      for src in srcs:
        src.remote = remote

    instance_ref = instance_flags.SSH_INSTANCE_RESOLVER.ResolveResources(
        [remote.host], compute_scope.ScopeEnum.ZONE, args.zone, self.resources,
        scope_lister=flags.GetDefaultScopeLister(self.compute_client))[0]
    instance = self.GetInstance(instance_ref)

    # Now replace the instance name with the actual IP/hostname
    remote.host = ssh_utils.GetExternalIPAddress(instance)
    if not remote.user:
      remote.user = ssh.GetDefaultSshUsername(warn_on_account_user=True)

    identity_file = None
    options = None
    if not args.plain:
      identity_file = self.keys.key_file
      options = self.GetConfig(ssh_utils.HostKeyAlias(instance),
                               args.strict_host_key_checking)

    cmd = ssh.SCPCommand(
        srcs, dst, identity_file=identity_file, options=options,
        recursive=recursive, port=port, extra_flags=extra_flags)

    if args.dry_run:
      log.out.Print(' '.join(cmd.Build(self.env)))
      return

    if args.plain:
      keys_newly_added = False
    else:
      keys_newly_added = self.EnsureSSHKeyExists(
          remote.user, instance, instance_ref.project,
          use_account_service=self._use_account_service)

    if keys_newly_added:
      poller = ssh.SSHPoller(
          remote, identity_file=identity_file, options=options,
          max_wait_ms=ssh_utils.SSH_KEY_PROPAGATION_TIMEOUT_SEC)
      log.status.Print('Waiting for SSH key to propagate.')
      # TODO(b/35355795): Don't force_connect
      try:
        poller.Poll(self.env, force_connect=True)
      except retry.WaitException:
        raise ssh_utils.NetworkError()
    return_code = cmd.Run(self.env, force_connect=True)
    if return_code:
      # Can't raise an exception because we don't want any "ERROR" message
      # printed; the output from `ssh` will be enough.
      sys.exit(return_code)
Beispiel #7
0
    def Run(self, args):
        """See ssh_utils.BaseSSHCLICommand.Run."""
        super(SshGA, self).Run(args)
        user, instance_name = ssh_utils.GetUserAndInstance(
            args.user_host, self._use_account_service, self.http)
        instance_ref = instance_flags.SSH_INSTANCE_RESOLVER.ResolveResources(
            [instance_name],
            compute_scope.ScopeEnum.ZONE,
            args.zone,
            self.resources,
            scope_lister=flags.GetDefaultScopeLister(self.compute_client))[0]
        instance = self.GetInstance(instance_ref)
        if self._use_internal_ip:
            ip_address = ssh_utils.GetInternalIPAddress(instance)
        else:
            ip_address = ssh_utils.GetExternalIPAddress(instance)

        remote = ssh.Remote(ip_address, user)

        identity_file = None
        options = None
        if not args.plain:
            identity_file = self.keys.key_file
            options = self.GetConfig(ssh_utils.HostKeyAlias(instance),
                                     args.strict_host_key_checking)

        extra_flags = []
        remainder = []

        if args.ssh_flag:
            for flag in args.ssh_flag:
                for flag_part in flag.split():  # We want grouping here
                    dereferenced_flag = (flag_part.replace(
                        '%USER%', remote.user).replace('%INSTANCE%',
                                                       ip_address))
                    extra_flags.append(dereferenced_flag)

        if args.ssh_args:
            remainder.extend(args.ssh_args)

        tty = ssh_utils.GetTty(args.container, args.command)
        remote_command = ssh_utils.GetRemoteCommand(args.container,
                                                    args.command)

        cmd = ssh.SSHCommand(remote,
                             identity_file=identity_file,
                             options=options,
                             extra_flags=extra_flags,
                             remote_command=remote_command,
                             tty=tty,
                             remainder=remainder)
        if args.dry_run:
            log.out.Print(' '.join(cmd.Build(self.env)))
            return

        if args.plain:
            keys_newly_added = False
        else:
            keys_newly_added = self.EnsureSSHKeyExists(
                remote.user,
                instance,
                instance_ref.project,
                use_account_service=self._use_account_service)

        if keys_newly_added:
            poller = ssh.SSHPoller(
                remote,
                identity_file=identity_file,
                options=options,
                extra_flags=extra_flags,
                max_wait_ms=ssh_utils.SSH_KEY_PROPAGATION_TIMEOUT_SEC)
            log.status.Print('Waiting for SSH key to propagate.')
            # TODO(b/35355795): Don't force_connect
            try:
                poller.Poll(self.env, force_connect=True)
            except retry.WaitException:
                raise ssh_utils.NetworkError()

        if self._use_internal_ip:
            self._PreliminarylyVerifyInstance(instance.id, remote,
                                              identity_file, options,
                                              extra_flags)

        return_code = cmd.Run(self.env, force_connect=True)
        if return_code:
            # Can't raise an exception because we don't want any "ERROR" message
            # printed; the output from `ssh` will be enough.
            sys.exit(return_code)