summaryrefslogtreecommitdiff
path: root/internal/sync/fetcher.go
diff options
context:
space:
mode:
authorSergeiEU <39683682+SergeiEU@users.noreply.github.com>2026-04-01 10:17:15 +0400
committerSergeiEU <39683682+SergeiEU@users.noreply.github.com>2026-04-01 10:17:15 +0400
commit1bd203c5555046b7ee4fbfe2f822eb3d03571ad7 (patch)
treed8c85273ede547e03a5727bf185f5d07e87b4a08 /internal/sync/fetcher.go
downloadvpnem-1bd203c5555046b7ee4fbfe2f822eb3d03571ad7.tar.gz
vpnem-1bd203c5555046b7ee4fbfe2f822eb3d03571ad7.tar.bz2
vpnem-1bd203c5555046b7ee4fbfe2f822eb3d03571ad7.zip
Initial importHEADmain
Diffstat (limited to 'internal/sync/fetcher.go')
-rw-r--r--internal/sync/fetcher.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/internal/sync/fetcher.go b/internal/sync/fetcher.go
new file mode 100644
index 0000000..74c2bd6
--- /dev/null
+++ b/internal/sync/fetcher.go
@@ -0,0 +1,82 @@
+package sync
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "time"
+
+ "vpnem/internal/models"
+)
+
+// Fetcher pulls configuration from the vpnem server API.
+type Fetcher struct {
+ baseURL string
+ client *http.Client
+}
+
+// NewFetcher creates a new Fetcher.
+func NewFetcher(baseURL string) *Fetcher {
+ return &Fetcher{
+ baseURL: baseURL,
+ client: &http.Client{
+ Timeout: 15 * time.Second,
+ },
+ }
+}
+
+// FetchServers retrieves the server list from the API.
+func (f *Fetcher) FetchServers() (*models.ServersResponse, error) {
+ var resp models.ServersResponse
+ if err := f.getJSON("/api/v1/servers", &resp); err != nil {
+ return nil, fmt.Errorf("fetch servers: %w", err)
+ }
+ return &resp, nil
+}
+
+// FetchRuleSets retrieves the rule-set manifest from the API.
+func (f *Fetcher) FetchRuleSets() (*models.RuleSetManifest, error) {
+ var resp models.RuleSetManifest
+ if err := f.getJSON("/api/v1/ruleset/manifest", &resp); err != nil {
+ return nil, fmt.Errorf("fetch rulesets: %w", err)
+ }
+ return &resp, nil
+}
+
+// FetchVersion retrieves the latest client version info.
+func (f *Fetcher) FetchVersion() (*models.VersionResponse, error) {
+ var resp models.VersionResponse
+ if err := f.getJSON("/api/v1/version", &resp); err != nil {
+ return nil, fmt.Errorf("fetch version: %w", err)
+ }
+ return &resp, nil
+}
+
+// ServerIPs extracts all unique server IPs from the server list.
+func ServerIPs(servers []models.Server) []string {
+ seen := make(map[string]bool)
+ var ips []string
+ for _, s := range servers {
+ if !seen[s.Server] {
+ seen[s.Server] = true
+ ips = append(ips, s.Server)
+ }
+ }
+ return ips
+}
+
+func (f *Fetcher) getJSON(path string, v any) error {
+ resp, err := f.client.Get(f.baseURL + path)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(resp.Body)
+ return fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
+ }
+
+ return json.NewDecoder(resp.Body).Decode(v)
+}