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)
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)
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()
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)
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)
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)
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)