Files
elmprodvpn/selective-vpn-api/app/types.go

392 lines
15 KiB
Go

package app
// ---------------------------------------------------------------------
// структуры
// ---------------------------------------------------------------------
// EN: Shared DTO/model definitions exchanged between HTTP handlers, workers,
// EN: SSE stream, and internal orchestration logic.
// RU: Общие DTO/модели, которыми обмениваются HTTP-обработчики, воркеры,
// RU: SSE-поток и внутренняя оркестрация.
type Status struct {
Timestamp string `json:"timestamp"`
IPCount int `json:"ip_count"`
DomainCount int `json:"domain_count"`
Iface string `json:"iface"`
Table string `json:"table"`
Mark string `json:"mark"`
PolicyRouteOK *bool `json:"policy_route_ok,omitempty"`
RouteOK *bool `json:"route_ok,omitempty"`
}
type cmdResult struct {
OK bool `json:"ok"`
Message string `json:"message,omitempty"`
ExitCode int `json:"exitCode,omitempty"`
Stdout string `json:"stdout,omitempty"`
Stderr string `json:"stderr,omitempty"`
}
type VPNLoginState struct {
State string `json:"state"`
Email string `json:"email,omitempty"`
Msg string `json:"msg,omitempty"`
// для GUI
Text string `json:"text,omitempty"`
Color string `json:"color,omitempty"`
}
type DNSUpstreams struct {
Default1 string `json:"default1"`
Default2 string `json:"default2"`
Meta1 string `json:"meta1"`
Meta2 string `json:"meta2"`
}
type DNSResolverMode string
const (
DNSModeDirect DNSResolverMode = "direct"
DNSModeSmartDNS DNSResolverMode = "smartdns"
DNSModeHybridWildcard DNSResolverMode = "hybrid_wildcard"
)
type DNSMode struct {
ViaSmartDNS bool `json:"via_smartdns"`
SmartDNSAddr string `json:"smartdns_addr"`
Mode DNSResolverMode `json:"mode"`
}
type DNSStatusResponse struct {
ViaSmartDNS bool `json:"via_smartdns"`
SmartDNSAddr string `json:"smartdns_addr"`
Mode DNSResolverMode `json:"mode"`
UnitState string `json:"unit_state"`
RuntimeNftset bool `json:"runtime_nftset"`
WildcardSource string `json:"wildcard_source"`
RuntimeCfgPath string `json:"runtime_config_path,omitempty"`
RuntimeCfgError string `json:"runtime_config_error,omitempty"`
}
type DNSModeRequest struct {
ViaSmartDNS bool `json:"via_smartdns"`
SmartDNSAddr string `json:"smartdns_addr"`
Mode DNSResolverMode `json:"mode"`
}
type DNSBenchmarkUpstream struct {
Addr string `json:"addr"`
Enabled bool `json:"enabled"`
}
type DNSBenchmarkRequest struct {
Upstreams []DNSBenchmarkUpstream `json:"upstreams"`
Domains []string `json:"domains"`
TimeoutMS int `json:"timeout_ms"`
Attempts int `json:"attempts"`
Concurrency int `json:"concurrency"`
}
type DNSBenchmarkResult struct {
Upstream string `json:"upstream"`
Attempts int `json:"attempts"`
OK int `json:"ok"`
Fail int `json:"fail"`
NXDomain int `json:"nxdomain"`
Timeout int `json:"timeout"`
Temporary int `json:"temporary"`
Other int `json:"other"`
AvgMS int `json:"avg_ms"`
P95MS int `json:"p95_ms"`
Score float64 `json:"score"`
Color string `json:"color"`
}
type DNSBenchmarkResponse struct {
Results []DNSBenchmarkResult `json:"results"`
DomainsUsed []string `json:"domains_used"`
TimeoutMS int `json:"timeout_ms"`
AttemptsPerDomain int `json:"attempts_per_domain"`
RecommendedDefault []string `json:"recommended_default"`
RecommendedMeta []string `json:"recommended_meta"`
}
type SmartDNSRuntimeStatusResponse struct {
Enabled bool `json:"enabled"`
AppliedEnable bool `json:"applied_enabled"`
WildcardSource string `json:"wildcard_source"`
UnitState string `json:"unit_state"`
ConfigPath string `json:"config_path"`
Changed bool `json:"changed,omitempty"`
Restarted bool `json:"restarted,omitempty"`
Message string `json:"message,omitempty"`
}
type SmartDNSRuntimeRequest struct {
Enabled *bool `json:"enabled"`
Restart *bool `json:"restart,omitempty"`
}
type TrafficMode string
const (
TrafficModeSelective TrafficMode = "selective"
TrafficModeFullTunnel TrafficMode = "full_tunnel"
TrafficModeDirect TrafficMode = "direct"
)
type TrafficModeState struct {
Mode TrafficMode `json:"mode"`
PreferredIface string `json:"preferred_iface,omitempty"`
AutoLocalBypass bool `json:"auto_local_bypass"`
IngressReplyBypass bool `json:"ingress_reply_bypass"`
ForceVPNSubnets []string `json:"force_vpn_subnets,omitempty"`
ForceVPNUIDs []string `json:"force_vpn_uids,omitempty"`
ForceVPNCGroups []string `json:"force_vpn_cgroups,omitempty"`
ForceDirectSubnets []string `json:"force_direct_subnets,omitempty"`
ForceDirectUIDs []string `json:"force_direct_uids,omitempty"`
ForceDirectCGroups []string `json:"force_direct_cgroups,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
}
type TrafficModeRequest struct {
Mode TrafficMode `json:"mode"`
PreferredIface *string `json:"preferred_iface,omitempty"`
AutoLocalBypass *bool `json:"auto_local_bypass,omitempty"`
IngressReplyBypass *bool `json:"ingress_reply_bypass,omitempty"`
ForceVPNSubnets *[]string `json:"force_vpn_subnets,omitempty"`
ForceVPNUIDs *[]string `json:"force_vpn_uids,omitempty"`
ForceVPNCGroups *[]string `json:"force_vpn_cgroups,omitempty"`
ForceDirectSubnets *[]string `json:"force_direct_subnets,omitempty"`
ForceDirectUIDs *[]string `json:"force_direct_uids,omitempty"`
ForceDirectCGroups *[]string `json:"force_direct_cgroups,omitempty"`
}
type TrafficModeStatusResponse struct {
Mode TrafficMode `json:"mode"`
DesiredMode TrafficMode `json:"desired_mode"`
AppliedMode TrafficMode `json:"applied_mode"`
PreferredIface string `json:"preferred_iface,omitempty"`
AdvancedActive bool `json:"advanced_active"`
AutoLocalBypass bool `json:"auto_local_bypass"`
AutoLocalActive bool `json:"auto_local_active"`
IngressReplyBypass bool `json:"ingress_reply_bypass"`
IngressReplyActive bool `json:"ingress_reply_active"`
BypassCandidates int `json:"bypass_candidates"`
ForceVPNSubnets []string `json:"force_vpn_subnets,omitempty"`
ForceVPNUIDs []string `json:"force_vpn_uids,omitempty"`
ForceVPNCGroups []string `json:"force_vpn_cgroups,omitempty"`
ForceDirectSubnets []string `json:"force_direct_subnets,omitempty"`
ForceDirectUIDs []string `json:"force_direct_uids,omitempty"`
ForceDirectCGroups []string `json:"force_direct_cgroups,omitempty"`
OverridesApplied int `json:"overrides_applied"`
CgroupResolvedUIDs int `json:"cgroup_resolved_uids"`
CgroupWarning string `json:"cgroup_warning,omitempty"`
ActiveIface string `json:"active_iface,omitempty"`
IfaceReason string `json:"iface_reason,omitempty"`
RuleMark bool `json:"rule_mark"`
RuleFull bool `json:"rule_full"`
IngressRulePresent bool `json:"ingress_rule_present"`
IngressNftActive bool `json:"ingress_nft_active"`
TableDefault bool `json:"table_default"`
ProbeOK bool `json:"probe_ok"`
ProbeMessage string `json:"probe_message,omitempty"`
Healthy bool `json:"healthy"`
Message string `json:"message,omitempty"`
}
type TrafficCandidateSubnet struct {
CIDR string `json:"cidr"`
Dev string `json:"dev,omitempty"`
Kind string `json:"kind,omitempty"` // lan|docker|link
LinkDown bool `json:"linkdown,omitempty"`
}
type TrafficCandidateUnit struct {
Unit string `json:"unit"`
Description string `json:"description,omitempty"`
Cgroup string `json:"cgroup,omitempty"`
}
type TrafficCandidateUID struct {
UID int `json:"uid"`
User string `json:"user,omitempty"`
Examples []string `json:"examples,omitempty"`
}
type TrafficCandidatesResponse struct {
GeneratedAt string `json:"generated_at"`
Subnets []TrafficCandidateSubnet `json:"subnets,omitempty"`
Units []TrafficCandidateUnit `json:"units,omitempty"`
UIDs []TrafficCandidateUID `json:"uids,omitempty"`
}
type TrafficInterfacesResponse struct {
Interfaces []string `json:"interfaces"`
PreferredIface string `json:"preferred_iface,omitempty"`
ActiveIface string `json:"active_iface,omitempty"`
IfaceReason string `json:"iface_reason,omitempty"`
}
// ---------------------------------------------------------------------
// traffic app marks (per-app routing via cgroup -> fwmark)
// ---------------------------------------------------------------------
type TrafficAppMarksOp string
const (
TrafficAppMarksAdd TrafficAppMarksOp = "add"
TrafficAppMarksDel TrafficAppMarksOp = "del"
TrafficAppMarksClear TrafficAppMarksOp = "clear"
)
// EN: Runtime app marking request. Used by per-app launcher wrappers.
// RU: Runtime app marking запрос. Используется wrapper-лаунчером per-app.
type TrafficAppMarksRequest struct {
Op TrafficAppMarksOp `json:"op"`
Target string `json:"target"` // vpn|direct
Cgroup string `json:"cgroup,omitempty"`
// EN: Optional metadata to deduplicate marks per-app across restarts / re-runs.
// RU: Опциональные метаданные, чтобы не плодить метки на одно и то же приложение.
Unit string `json:"unit,omitempty"`
Command string `json:"command,omitempty"`
AppKey string `json:"app_key,omitempty"`
TimeoutSec int `json:"timeout_sec,omitempty"` // only for add; 0 = persistent
}
type TrafficAppMarksResponse struct {
OK bool `json:"ok"`
Message string `json:"message,omitempty"`
Op string `json:"op,omitempty"`
Target string `json:"target,omitempty"`
Cgroup string `json:"cgroup,omitempty"`
CgroupID uint64 `json:"cgroup_id,omitempty"`
TimeoutSec int `json:"timeout_sec,omitempty"`
}
type TrafficAppMarksStatusResponse struct {
VPNCount int `json:"vpn_count"`
DirectCount int `json:"direct_count"`
Message string `json:"message,omitempty"`
}
// EN: Detailed list item for runtime per-app marks (for UI).
// RU: Детальный элемент списка runtime per-app меток (для UI).
type TrafficAppMarkItemView struct {
ID uint64 `json:"id"`
Target string `json:"target"` // vpn|direct
Cgroup string `json:"cgroup,omitempty"`
CgroupRel string `json:"cgroup_rel,omitempty"`
Level int `json:"level,omitempty"`
Unit string `json:"unit,omitempty"`
Command string `json:"command,omitempty"`
AppKey string `json:"app_key,omitempty"`
AddedAt string `json:"added_at,omitempty"`
ExpiresAt string `json:"expires_at,omitempty"`
RemainingSec int `json:"remaining_sec,omitempty"` // -1 = persistent
}
type TrafficAppMarksItemsResponse struct {
Items []TrafficAppMarkItemView `json:"items"`
Message string `json:"message,omitempty"`
}
// ---------------------------------------------------------------------
// traffic app profiles (persistent app launcher configs)
// ---------------------------------------------------------------------
// EN: Persistent per-app launcher profile (separate from runtime marks).
// RU: Постоянный профиль запуска приложения (отдельно от runtime marks).
type TrafficAppProfile struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
AppKey string `json:"app_key,omitempty"`
Command string `json:"command,omitempty"`
Target string `json:"target,omitempty"` // vpn|direct
TTLSec int `json:"ttl_sec,omitempty"` // 0 = persistent
VPNProfile string `json:"vpn_profile,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
}
type TrafficAppProfilesResponse struct {
Profiles []TrafficAppProfile `json:"profiles"`
Message string `json:"message,omitempty"`
}
type TrafficAppProfileUpsertRequest struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
AppKey string `json:"app_key,omitempty"`
Command string `json:"command,omitempty"`
Target string `json:"target,omitempty"` // vpn|direct
TTLSec int `json:"ttl_sec,omitempty"` // 0 = persistent
VPNProfile string `json:"vpn_profile,omitempty"`
}
type SystemdState struct {
State string `json:"state"`
}
// ---------------------------------------------------------------------
// события / SSE
// ---------------------------------------------------------------------
type Event struct {
ID int64 `json:"id"`
Kind string `json:"kind"`
Ts string `json:"ts"`
Data interface{} `json:"data,omitempty"`
}
// EN: Callback for streaming user-visible progress from long-running nft updates.
// RU: Колбэк для отправки прогресса длительных nft-операций в пользовательский интерфейс.
type ProgressCallback func(percent int, message string)
// ---------------------------------------------------------------------
// resolver модели
// ---------------------------------------------------------------------
// EN: Input contract for the Go-based domain resolver job.
// RU: Контракт входных параметров для Go-резолвера доменов.
type ResolverOpts struct {
DomainsPath string
MetaPath string
StaticPath string
CachePath string
PtrCachePath string
TraceLog string
TTL int
Workers int
DNSConfigPath string
ViaSmartDNS bool
Mode DNSResolverMode
SmartDNSAddr string
SmartDNSWildcards []string
}
// EN: Aggregated resolver outputs consumed by routes update pipeline.
// RU: Агрегированные результаты резолвера, используемые пайплайном обновления маршрутов.
type resolverResult struct {
IPs []string
IPMap [][2]string
DirectIPs []string
DirectIPMap [][2]string
WildcardIPs []string
WildcardIPMap [][2]string
DomainCache map[string]any
PtrCache map[string]any
}
// EN: Runtime DNS upstream pools for standard and meta-special lookups.
// RU: Наборы DNS-апстримов для обычных и meta-special резолвов.
type dnsConfig struct {
Default []string
Meta []string
SmartDNS string
Mode DNSResolverMode
}