133 lines
3.2 KiB
Go
133 lines
3.2 KiB
Go
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}
|
|
}
|