// Package models содержит общие типы данных pulse-lets-go. package models import "time" // --- NATS: метрика от нижестоящей АТС --- // NodeMetric — сообщение, публикуемое нодой в NATS каждые 5 сек. type NodeMetric struct { NodeID string `json:"node_id"` TS int64 `json:"ts"` // unix timestamp Status string `json:"status"` // "ok", "degraded", "down" ActiveCalls int `json:"active_calls"` MaxCalls int `json:"max_calls"` IdleCPU float64 `json:"idle_cpu"` // 0..100 % LoadAvg float64 `json:"load_avg"` // system load average (1m) CallFailureRate float64 `json:"call_failure_rate"` // 0.0..100.0 % SIPGateway string `json:"sip_gateway,omitempty"` // SIP-адрес ноды для авто-создания транка } // --- In-memory состояние ноды в engine --- // NodeState — полное состояние ноды в памяти балансировщика. // Содержит данные последней метрики + поля ручного управления. type NodeState struct { NodeMetric Disabled bool `json:"disabled"` DisabledReason string `json:"disabled_reason"` Score float64 `json:"score"` LethalReason string `json:"lethal_reason,omitempty"` // причина, если score = -100 } // --- Trunk --- // TrunkType — тип транка. type TrunkType string const ( TrunkIngress TrunkType = "ingress" TrunkBalance TrunkType = "balance" TrunkFallback TrunkType = "fallback" ) // Trunk — модель транка (из trunks.json). type Trunk struct { ID string `json:"id"` Name string `json:"name"` Type TrunkType `json:"type"` NodeID string `json:"node_id,omitempty"` // только для balance Gateway string `json:"gateway"` Codecs []string `json:"codecs,omitempty"` Context string `json:"context,omitempty"` Enabled bool `json:"enabled"` Description string `json:"description,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // --- User --- // UserRole — роль пользователя. type UserRole string const ( RoleAdmin UserRole = "admin" RoleViewer UserRole = "viewer" ) // User — модель пользователя (из users.json). type User struct { ID string `json:"id"` Username string `json:"username"` PasswordHash string `json:"password_hash"` Role UserRole `json:"role"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // --- Auth --- // LoginRequest — тело запроса на /api/auth/login. type LoginRequest struct { Username string `json:"username"` Password string `json:"password"` } // LoginResponse — тело ответа /api/auth/login. type LoginResponse struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` ExpiresIn int64 `json:"expires_in"` } // --- /api/route --- // RouteResponse — ответ на запрос маршрутизации. type RouteResponse struct { // Успех NodeID string `json:"node_id,omitempty"` Score float64 `json:"score,omitempty"` SIPGateway string `json:"sip_gateway,omitempty"` // Fallback Fallback bool `json:"fallback,omitempty"` Reason string `json:"reason,omitempty"` // Общая информация о нодах Nodes []RouteNodeInfo `json:"nodes,omitempty"` // Ошибка Error string `json:"error,omitempty"` } // RouteNodeInfo — информация о ноде в ответе маршрутизации. type RouteNodeInfo struct { ID string `json:"id"` Score float64 `json:"score"` Reason string `json:"reason,omitempty"` Status string `json:"status"` } // --- API: Nodes --- // ToggleNodeRequest — запрос на включение/выключение ноды. type ToggleNodeRequest struct { Disabled bool `json:"disabled"` Reason string `json:"reason,omitempty"` } // NodeInfo — информация о ноде для фронта. type NodeInfo struct { NodeID string `json:"node_id"` TS int64 `json:"ts"` Status string `json:"status"` ActiveCalls int `json:"active_calls"` MaxCalls int `json:"max_calls"` IdleCPU float64 `json:"idle_cpu"` LoadAvg float64 `json:"load_avg"` CallFailureRate float64 `json:"call_failure_rate"` Disabled bool `json:"disabled"` DisabledReason string `json:"disabled_reason,omitempty"` Score float64 `json:"score"` LethalReason string `json:"lethal_reason,omitempty"` IsStale bool `json:"is_stale"` SecondsAgo float64 `json:"seconds_ago"` } // --- API: Users --- // CreateUserRequest — запрос на создание пользователя. type CreateUserRequest struct { Username string `json:"username"` Password string `json:"password"` Role UserRole `json:"role"` } // UpdateUserRequest — запрос на обновление пользователя. type UpdateUserRequest struct { Username *string `json:"username,omitempty"` Password *string `json:"password,omitempty"` Role *UserRole `json:"role,omitempty"` } // --- API: Trunks --- // CreateTrunkRequest — запрос на создание транка. type CreateTrunkRequest struct { Name string `json:"name"` Type TrunkType `json:"type"` NodeID string `json:"node_id,omitempty"` Gateway string `json:"gateway"` Codecs []string `json:"codecs,omitempty"` Context string `json:"context,omitempty"` Enabled bool `json:"enabled"` Description string `json:"description,omitempty"` } // UpdateTrunkRequest — запрос на обновление транка. type UpdateTrunkRequest struct { Name *string `json:"name,omitempty"` Type *TrunkType `json:"type,omitempty"` NodeID *string `json:"node_id,omitempty"` Gateway *string `json:"gateway,omitempty"` Codecs []string `json:"codecs,omitempty"` Context *string `json:"context,omitempty"` Enabled *bool `json:"enabled,omitempty"` Description *string `json:"description,omitempty"` } // --- Monitoring --- // ZabbixNode — элемент LLD (Low-Level Discovery) для Zabbix. type ZabbixNode struct { NodeID string `json:"{#NODE_ID}"` Status string `json:"{#STATUS}"` ActiveCalls int `json:"{#ACTIVE_CALLS}"` MaxCalls int `json:"{#MAX_CALLS}"` IdleCPU float64 `json:"{#IDLE_CPU}"` LoadAvg float64 `json:"{#LOAD_AVG}"` CallFailureRate float64 `json:"{#CALL_FAILURE_RATE}"` Score float64 `json:"{#SCORE}"` Disabled bool `json:"{#DISABLED}"` IsStale bool `json:"{#IS_STALE}"` SecondsAgo float64 `json:"{#SECONDS_AGO}"` } // ZabbixResponse — ответ на запрос Zabbix LLD. type ZabbixResponse struct { Data []ZabbixNode `json:"data"` } // --- WebSocket --- // WsMetricsMessage — сообщение, отправляемое по WebSocket. type WsMetricsMessage struct { Type string `json:"type"` // "nodes_update", "node_toggle", etc Payload interface{} `json:"payload"` }