package atlas import ( "fmt" "strings" ) const ( FleetGossipHaveShard = "have_shard" FleetGossipHealthy = "healthy" FleetGossipKnowNode = "know_node" ) type FleetGossipRecord struct { Kind string `json:"kind"` AgentID string `json:"agent_id,omitempty"` Subnet string `json:"subnet,omitempty"` Token string `json:"token,omitempty"` ShardIndex int `json:"shard_index,omitempty"` ShardHash string `json:"shard_hash,omitempty"` Region string `json:"region,omitempty"` ShardAdvert string `json:"shard_advert,omitempty"` TargetAgentID string `json:"target_agent_id,omitempty"` Healthy bool `json:"healthy,omitempty"` FetchURL string `json:"fetch_url,omitempty"` } func NormalizeFleetGossipRecord(r FleetGossipRecord) (FleetGossipRecord, bool) { r.Kind = strings.TrimSpace(strings.ToLower(r.Kind)) r.AgentID = strings.TrimSpace(r.AgentID) r.Subnet = strings.TrimSpace(r.Subnet) r.Token = strings.TrimSpace(r.Token) r.ShardHash = strings.TrimSpace(strings.ToLower(r.ShardHash)) r.Region = strings.TrimSpace(r.Region) r.ShardAdvert = strings.TrimSpace(r.ShardAdvert) r.TargetAgentID = strings.TrimSpace(r.TargetAgentID) r.FetchURL = strings.TrimSpace(r.FetchURL) switch r.Kind { case FleetGossipHaveShard: if r.AgentID == "" || r.Token == "" || r.ShardHash == "" { return FleetGossipRecord{}, false } if r.Region == "" && r.ShardAdvert != "" { if region, idx, ok := parseShardAdvert(r.ShardAdvert); ok { r.Region = region if r.ShardIndex == 0 { r.ShardIndex = idx } } } if r.ShardAdvert == "" && r.Region != "" { r.ShardAdvert = fmt.Sprintf("%s:%d", r.Region, r.ShardIndex) } case FleetGossipHealthy: if r.AgentID == "" { return FleetGossipRecord{}, false } case FleetGossipKnowNode: if r.AgentID == "" || r.TargetAgentID == "" { return FleetGossipRecord{}, false } default: return FleetGossipRecord{}, false } return r, true } func NormalizeFleetGossipRecords(in []FleetGossipRecord) []FleetGossipRecord { if len(in) == 0 { return nil } out := make([]FleetGossipRecord, 0, len(in)) for _, r := range in { if norm, ok := NormalizeFleetGossipRecord(r); ok { out = append(out, norm) } } return out } func parseShardAdvert(advert string) (region string, index int, ok bool) { colon := strings.LastIndex(strings.TrimSpace(advert), ":") if colon <= 0 { return "", 0, false } region = strings.TrimSpace(advert[:colon]) if _, err := fmt.Sscanf(strings.TrimSpace(advert[colon+1:]), "%d", &index); err != nil { return "", 0, false } return region, index, region != "" }