code: func prepareSSHConfig(connInfo *connectionInfo) (*sshConfig, error) {
  	sshAgent, err := connectToAgent(connInfo)
  	if err != nil {
  		return nil, err
  	}
  
  	host := fmt.Sprintf("%s:%d", connInfo.Host, connInfo.Port)
  
  	sshConf, err := buildSSHClientConfig(sshClientConfigOpts{
  		user:        connInfo.User,
  		host:        host,
  		privateKey:  connInfo.PrivateKey,
  		password:    connInfo.Password,
  		hostKey:     connInfo.HostKey,
  		certificate: connInfo.Certificate,
  		sshAgent:    sshAgent,
  	})
  	if err != nil {
  		return nil, err
  	}
  
  	connectFunc := ConnectFunc("tcp", host)
  
  	var bastionConf *ssh.ClientConfig
  	if connInfo.BastionHost != "" {
  		bastionHost := fmt.Sprintf("%s:%d", connInfo.BastionHost, connInfo.BastionPort)
  
  		bastionConf, err = buildSSHClientConfig(sshClientConfigOpts{
  			user:       connInfo.BastionUser,
  			host:       bastionHost,
  			privateKey: connInfo.BastionPrivateKey,
  			password:   connInfo.BastionPassword,
  			hostKey:    connInfo.HostKey,
  			sshAgent:   sshAgent,
  		})
  		if err != nil {
  			return nil, err
  		}
  
  		connectFunc = BastionConnectFunc("tcp", bastionHost, bastionConf, "tcp", host)
  	}
  
  	config := &sshConfig{
  		config:     sshConf,
  		connection: connectFunc,
  		sshAgent:   sshAgent,
  	}
  	return config, nil
  }
docs: // prepareSSHConfig is used to turn the *ConnectionInfo provided into a
  // usable *SSHConfig for client initialization.