code: func BuildPrincipals(hostID string, nodeName string, clusterName string, roles teleport.Roles) []string {
  	// TODO(russjones): This should probably be clusterName, but we need to
  	// verify changing this won't break older clients.
  	if roles.Include(teleport.RoleAdmin) {
  		return []string{hostID}
  	}
  
  	// if no hostID was passed it, the user might be specifying an exact list of principals
  	if hostID == "" {
  		return []string{}
  	}
  
  	// always include the hostID, this is what teleport uses internally to find nodes
  	principals := []string{
  		fmt.Sprintf("%v.%v", hostID, clusterName),
  	}
  
  	// nodeName is the DNS name, this is for OpenSSH interoperability
  	if nodeName != "" {
  		principals = append(principals, fmt.Sprintf("%s.%s", nodeName, clusterName))
  		principals = append(principals, nodeName)
  	}
  
  	// deduplicate (in-case hostID and nodeName are the same) and return
  	return utils.Deduplicate(principals)
  }
docs: // BuildPrincipals takes a hostID, nodeName, clusterName, and role and builds a list of
  // principals to insert into a certificate. This function is backward compatible with
  // older clients which means:
  //    * If RoleAdmin is in the list of roles, only a single principal is returned: hostID
  //    * If nodename is empty, it is not included in the list of principals.