forked from steigr/goinwx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
goinwx.go
133 lines (106 loc) · 3.19 KB
/
goinwx.go
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
package goinwx
import (
"fmt"
"net/url"
"github.com/kolo/xmlrpc"
)
const (
libraryVersion = "0.4.0"
APIBaseUrl = "https://api.domrobot.com/xmlrpc/"
APISandboxBaseUrl = "https://api.ote.domrobot.com/xmlrpc/"
APILanguage = "eng"
)
// Client manages communication with INWX API.
type Client struct {
// HTTP client used to communicate with the INWX API.
RPCClient *xmlrpc.Client
// Base URL for API requests.
BaseURL *url.URL
// API username
Username string
// API password
Password string
// User agent for client
APILanguage string
// Services used for communicating with the API
Account AccountService
Domains DomainService
Nameservers NameserverService
Contacts ContactService
}
type ClientOptions struct {
Sandbox bool
}
type Request struct {
ServiceMethod string
Args map[string]interface{}
}
// Response is a INWX API response. This wraps the standard http.Response returned from INWX.
type Response struct {
Code int `xmlrpc:"code"`
Message string `xmlrpc:"msg"`
ReasonCode string `xmlrpc:"reasonCode"`
Reason string `xmlrpc:"reason"`
ResponseData map[string]interface{} `xmlrpc:"resData"`
}
// An ErrorResponse reports the error caused by an API request
type ErrorResponse struct {
Code int `xmlrpc:"code"`
Message string `xmlrpc:"msg"`
ReasonCode string `xmlrpc:"reasonCode"`
Reason string `xmlrpc:"reason"`
}
// NewClient returns a new INWX API client.
func NewClient(username, password string, opts *ClientOptions) *Client {
var useSandbox bool
if opts != nil {
useSandbox = opts.Sandbox
}
var baseURL *url.URL
if useSandbox {
baseURL, _ = url.Parse(APISandboxBaseUrl)
} else {
baseURL, _ = url.Parse(APIBaseUrl)
}
rpcClient, _ := xmlrpc.NewClient(baseURL.String(), nil)
client := &Client{RPCClient: rpcClient,
BaseURL: baseURL,
Username: username,
Password: password,
}
client.Account = &AccountServiceOp{client: client}
client.Domains = &DomainServiceOp{client: client}
client.Nameservers = &NameserverServiceOp{client: client}
client.Contacts = &ContactServiceOp{client: client}
return client
}
// NewRequest creates an API request.
func (c *Client) NewRequest(serviceMethod string, args map[string]interface{}) *Request {
if args != nil {
args["lang"] = APILanguage
}
return &Request{ServiceMethod: serviceMethod, Args: args}
}
// Do sends an API request and returns the API response.
func (c *Client) Do(req Request) (*map[string]interface{}, error) {
var resp Response
err := c.RPCClient.Call(req.ServiceMethod, req.Args, &resp)
if err != nil {
return nil, err
}
return &resp.ResponseData, CheckResponse(&resp)
}
func (r *ErrorResponse) Error() string {
if r.Reason != "" {
return fmt.Sprintf("(%d) %s. Reason: (%s) %s",
r.Code, r.Message, r.ReasonCode, r.Reason)
}
return fmt.Sprintf("(%d) %s", r.Code, r.Message)
}
// CheckResponse checks the API response for errors, and returns them if present.
func CheckResponse(r *Response) error {
if c := r.Code; c >= 1000 && c <= 1500 {
return nil
}
return &ErrorResponse{Code: r.Code, Message: r.Message, Reason: r.Reason, ReasonCode: r.ReasonCode}
}