docs: def connect(self, keyfile=None):
          """Connect to the node via ssh using the paramiko library.
  
          :return: :py:class:`paramiko.SSHClient` - ssh connection or None on
                   failure
          """
          ssh = paramiko.SSHClient()
          ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
          if keyfile and os.path.exists(keyfile):
              ssh.load_host_keys(keyfile)
  
          # Try connecting using the `preferred_ip`, if
          # present. Otherwise, try all of them and set `preferred_ip`
          # using the first that is working.
          ips = self.ips[:]
          # This is done in order to "sort" the IPs and put the preferred_ip first.
          if self.preferred_ip:
              if self.preferred_ip in ips:
                  ips.remove(self.preferred_ip)
              else:
                  # Preferred is changed?
                  log.debug("IP %s does not seem to belong to %s anymore. Ignoring!", self.preferred_ip, self.name)
                  self.preferred_ip = ips[0]
  
          for ip in itertools.chain([self.preferred_ip], ips):
              if not ip:
                  continue
              try:
                  log.debug("Trying to connect to host %s (%s)",
                            self.name, ip)
                  addr, port = parse_ip_address_and_port(ip, SSH_PORT)
                  ssh.connect(str(addr),
                              username=self.image_user,
                              allow_agent=True,
                              key_filename=self.user_key_private,
                              timeout=Node.connection_timeout,
                              port=port)
                  log.debug("Connection to %s succeeded on port %d!", ip, port)
                  if ip != self.preferred_ip:
                      log.debug("Setting `preferred_ip` to %s", ip)
                      self.preferred_ip = ip
                  # Connection successful.
                  return ssh
              except socket.error as ex:
                  log.debug("Host %s (%s) not reachable: %s.",
                            self.name, ip, ex)
              except paramiko.BadHostKeyException as ex:
                  log.error("Invalid host key: host %s (%s); check keyfile: %s",
                            self.name, ip, keyfile)
              except paramiko.SSHException as ex:
                  log.debug("Ignoring error %s connecting to %s",
                            str(ex), self.name)
  
          return None