-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathnamesilo.go
More file actions
135 lines (107 loc) · 2.8 KB
/
namesilo.go
File metadata and controls
135 lines (107 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Package namesilo A Go client library for accessing the Namesilo API.
package namesilo
import (
"context"
"encoding/xml"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"time"
querystring "github.com/google/go-querystring/query"
)
const (
// DefaultAPIEndpoint The default API endpoint.
DefaultAPIEndpoint = "https://www.namesilo.com/api"
// SandboxAPIEndpoint The sandbox API endpoint.
SandboxAPIEndpoint = "https://sandbox.namesilo.com/api"
// OTEAPIEndpoint The OTE sandbox API endpoint.
OTEAPIEndpoint = "https://ote.namesilo.com/api"
)
// Response Codes.
const (
SuccessfulAPIOperation = "300"
SuccessfulRegistration = "301"
SuccessfulOrder = "302"
)
// Client the Namesilo client.
type Client struct {
apiKey string
Endpoint *url.URL
HTTPClient *http.Client
}
// NewClient Creates a Namesilo client.
func NewClient(apiKey string) *Client {
endpoint, _ := url.Parse(DefaultAPIEndpoint)
return &Client{
apiKey: apiKey,
Endpoint: endpoint,
HTTPClient: &http.Client{Timeout: 10 * time.Second},
}
}
func (c *Client) do(ctx context.Context, name string, params, op any) error {
endpoint := c.Endpoint.JoinPath(name)
query, err := querystring.Values(params)
if err != nil {
return err
}
query.Set("version", "1")
query.Set("type", "xml")
query.Set("key", c.apiKey)
endpoint.RawQuery = query.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
if err != nil {
return err
}
resp, err := c.HTTPClient.Do(req)
if err != nil {
return err
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
data, _ := io.ReadAll(resp.Body)
return fmt.Errorf("error: %d: %s", resp.StatusCode, string(data))
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
err = xml.Unmarshal(data, op)
if err != nil {
return fmt.Errorf("failed to decode: %w: %s", err, data)
}
return nil
}
func GetEndpoint(prod, ote bool) (*url.URL, error) {
if prod && ote {
return nil, errors.New("prod and ote are mutually exclusive")
}
if prod {
return url.Parse(DefaultAPIEndpoint)
}
if ote {
return url.Parse(OTEAPIEndpoint)
}
return url.Parse(SandboxAPIEndpoint)
}
type replyGetter interface {
getCode() string
getDetail() string
}
func checkReply(reply replyGetter) error {
switch reply.getCode() {
case SuccessfulAPIOperation:
// Successful API operation
return nil
case SuccessfulRegistration:
// Successful registration, but not all provided hosts were valid resulting in our nameservers being used
return nil
case SuccessfulOrder:
// Successful order, but there was an error with the contact information provided so your account default contact profile was used
return nil
default:
// error
return fmt.Errorf("code: %s, details: %s", reply.getCode(), reply.getDetail())
}
}