all: add starting service with Control D config

This commit is contained in:
Cuong Manh Le
2022-12-22 23:27:45 +07:00
committed by Cuong Manh Le
parent ec72af1916
commit 114ef9aad6
7 changed files with 216 additions and 23 deletions
+90
View File
@@ -0,0 +1,90 @@
package controld
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
)
const resolverDataURL = "https://api.controld.com/utility"
// ResolverConfig represents Control D resolver data.
type ResolverConfig struct {
V4 []string `json:"v4"`
V6 []string `json:"v6"`
DOH string `json:"doh"`
Exclude []string `json:"exclude"`
}
func (r *ResolverConfig) IP(v6 bool) string {
ip4 := r.v4()
ip6 := r.v6()
if v6 && ip6 != "" {
return ip6
}
return ip4
}
func (r *ResolverConfig) v4() string {
for _, ip := range r.V4 {
return ip
}
return ""
}
func (r *ResolverConfig) v6() string {
for _, ip := range r.V6 {
return ip
}
return ""
}
type utilityResponse struct {
Success bool `json:"success"`
Body struct {
Resolver ResolverConfig `json:"resolver"`
} `json:"body"`
}
type utilityErrorResponse struct {
Error struct {
Message string `json:"message"`
} `json:"error"`
}
type utilityRequest struct {
UID string `json:"uid"`
}
// FetchResolverConfig fetch Control D config for given uid.
func FetchResolverConfig(uid string) (*ResolverConfig, error) {
body, _ := json.Marshal(utilityRequest{UID: uid})
req, err := http.NewRequest("POST", resolverDataURL, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("http.NewRequest: %w", err)
}
req.Header.Add("Content-Type", "application/json")
client := http.Client{Timeout: 5 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("client.Do: %w", err)
}
defer resp.Body.Close()
d := json.NewDecoder(resp.Body)
if resp.StatusCode != http.StatusOK {
errResp := &utilityErrorResponse{}
if err := d.Decode(errResp); err != nil {
return nil, err
}
return nil, errors.New(errResp.Error.Message)
}
ur := &utilityResponse{}
if err := d.Decode(ur); err != nil {
return nil, err
}
return &ur.Body.Resolver, nil
}
+33
View File
@@ -0,0 +1,33 @@
//go:build controld
package controld
import (
"testing"
"github.com/stretchr/testify/assert"
)
const utilityURL = "https://api.controld.com/utility"
func TestFetchResolverConfig(t *testing.T) {
tests := []struct {
name string
uid string
wantErr bool
}{
{"valid", "p2", false},
{"invalid uid", "abcd1234", true},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
got, err := FetchResolverConfig(tc.uid)
assert.False(t, (err != nil) != tc.wantErr)
if !tc.wantErr {
assert.NotEmpty(t, got.DOH)
}
})
}
}