Enrols a Fleetspeak-enabled client for use with GRR.

    Args:
      client_id: GRR client-id for the client.

    Returns:
      True if the client is new, and actually got enrolled. This method
      is a no-op if the client already exists (in which case False is returned).

def EnrolFleetspeakClient(self, client_id):
    """Enrols a Fleetspeak-enabled client for use with GRR.

    Args:
      client_id: GRR client-id for the client.

    Returns:
      True if the client is new, and actually got enrolled. This method
      is a no-op if the client already exists (in which case False is returned).
    """
    client_urn = rdf_client.ClientURN(client_id)

    # If already enrolled, return.
    if data_store.RelationalDBEnabled():
      try:
        data_store.REL_DB.ReadClientMetadata(client_id)
        return False
      except db.UnknownClientError:
        pass
    else:
      if aff4.FACTORY.ExistsWithType(
          client_urn, aff4_type=aff4_grr.VFSGRRClient, token=self.token):
        return False

    logging.info("Enrolling a new Fleetspeak client: %r", client_id)

    if data_store.RelationalDBEnabled():
      now = rdfvalue.RDFDatetime.Now()
      data_store.REL_DB.WriteClientMetadata(
          client_id, first_seen=now, fleetspeak_enabled=True, last_ping=now)

    if data_store.AFF4Enabled():
      # TODO(fleetspeak-team,grr-team): If aff4 isn't reliable enough, we can
      # catch exceptions from it and forward them to Fleetspeak by failing its
      # gRPC call. Fleetspeak will then retry with a random, perhaps healthier,
      # instance of the GRR frontend.
      with aff4.FACTORY.Create(
          client_urn,
          aff4_type=aff4_grr.VFSGRRClient,
          mode="rw",
          token=self.token) as client:

        client.Set(client.Schema.FLEETSPEAK_ENABLED, rdfvalue.RDFBool(True))

        index = client_index.CreateClientIndex(token=self.token)
        index.AddClient(client)
        if data_store.RelationalDBEnabled():
          client_obj = rdf_objects.ClientSnapshot(
              client_id=client_urn.Basename())
          index = client_index.ClientIndex()
          index.AddClient(client_obj)

    # Publish the client enrollment message.
    events.Events.PublishEvent("ClientEnrollment", client_urn, token=self.token)
    return True