mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
HEXONET: Update hexonet-sdk to v2.2.3+incompatible (#662)
* Update hexonet-sdk to v2.2.3+incompatible * Update vendor * Go mod tidy
This commit is contained in:
404
vendor/github.com/hexonet/go-sdk/apiclient/apiclient.go
generated
vendored
Normal file
404
vendor/github.com/hexonet/go-sdk/apiclient/apiclient.go
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
// Copyright (c) 2018 Kai Schwarz (HEXONET GmbH). All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by the MIT
|
||||
// license that can be found in the LICENSE.md file.
|
||||
|
||||
// Package apiclient contains all you need to communicate with the insanely fast HEXONET backend API.
|
||||
package apiclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
R "github.com/hexonet/go-sdk/response"
|
||||
RTM "github.com/hexonet/go-sdk/responsetemplatemanager"
|
||||
SC "github.com/hexonet/go-sdk/socketconfig"
|
||||
)
|
||||
|
||||
var rtm = RTM.GetInstance()
|
||||
|
||||
// APIClient is the entry point class for communicating with the insanely fast HEXONET backend api.
|
||||
// It allows two ways of communication:
|
||||
// * session based communication
|
||||
// * sessionless communication
|
||||
//
|
||||
// A session based communication makes sense in case you use it to
|
||||
// build your own frontend on top. It allows also to use 2FA
|
||||
// (2 Factor Auth) by providing "otp" in the config parameter of
|
||||
// the login method.
|
||||
// A sessionless communication makes sense in case you do not need
|
||||
// to care about the above and you have just to request some commands.
|
||||
//
|
||||
// Possible commands can be found at https://github.com/hexonet/hexonet-api-documentation/tree/master/API
|
||||
type APIClient struct {
|
||||
socketTimeout time.Duration
|
||||
socketURL string
|
||||
socketConfig *SC.SocketConfig
|
||||
debugMode bool
|
||||
ua string
|
||||
}
|
||||
|
||||
// NewAPIClient represents the constructor for struct APIClient.
|
||||
func NewAPIClient() *APIClient {
|
||||
cl := &APIClient{
|
||||
debugMode: false,
|
||||
socketTimeout: 300 * time.Second,
|
||||
socketURL: "https://api.ispapi.net/api/call.cgi",
|
||||
socketConfig: SC.NewSocketConfig(),
|
||||
ua: "",
|
||||
}
|
||||
cl.UseLIVESystem()
|
||||
return cl
|
||||
}
|
||||
|
||||
// EnableDebugMode method to enable Debug Output to logger
|
||||
func (cl *APIClient) EnableDebugMode() *APIClient {
|
||||
cl.debugMode = true
|
||||
return cl
|
||||
}
|
||||
|
||||
// DisableDebugMode method to disable Debug Output to logger
|
||||
func (cl *APIClient) DisableDebugMode() *APIClient {
|
||||
cl.debugMode = false
|
||||
return cl
|
||||
}
|
||||
|
||||
// GetPOSTData method to Serialize given command for POST request
|
||||
// including connection configuration data
|
||||
func (cl *APIClient) GetPOSTData(cmd map[string]string) string {
|
||||
data := cl.socketConfig.GetPOSTData()
|
||||
var tmp strings.Builder
|
||||
keys := []string{}
|
||||
for key := range cmd {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
val := cmd[key]
|
||||
tmp.WriteString(key)
|
||||
tmp.WriteString("=")
|
||||
val = strings.Replace(val, "\r", "", -1)
|
||||
val = strings.Replace(val, "\n", "", -1)
|
||||
tmp.WriteString(val)
|
||||
tmp.WriteString("\n")
|
||||
}
|
||||
str := tmp.String()
|
||||
str = str[:len(str)-1] //remove \n at end
|
||||
return strings.Join([]string{
|
||||
data,
|
||||
url.QueryEscape("s_command"),
|
||||
"=",
|
||||
url.QueryEscape(str),
|
||||
}, "")
|
||||
}
|
||||
|
||||
// GetSession method to get the API Session that is currently set
|
||||
func (cl *APIClient) GetSession() (string, error) {
|
||||
sessid := cl.socketConfig.GetSession()
|
||||
if len(sessid) == 0 {
|
||||
return "", errors.New("Could not find an active session")
|
||||
}
|
||||
return sessid, nil
|
||||
}
|
||||
|
||||
// GetURL method to get the API connection url that is currently set
|
||||
func (cl *APIClient) GetURL() string {
|
||||
return cl.socketURL
|
||||
}
|
||||
|
||||
// SetUserAgent method to customize user-agent header (useful for tools that use our SDK)
|
||||
func (cl *APIClient) SetUserAgent(str string, rv string) *APIClient {
|
||||
cl.ua = str + " (" + runtime.GOOS + "; " + runtime.GOARCH + "; rv:" + rv + ") go-sdk/" + cl.GetVersion() + " go/" + runtime.Version()
|
||||
return cl
|
||||
}
|
||||
|
||||
// GetUserAgent method to return the user agent string
|
||||
func (cl *APIClient) GetUserAgent() string {
|
||||
if len(cl.ua) == 0 {
|
||||
cl.ua = "GO-SDK (" + runtime.GOOS + "; " + runtime.GOARCH + "; rv:" + cl.GetVersion() + ") go/" + runtime.Version()
|
||||
}
|
||||
return cl.ua
|
||||
}
|
||||
|
||||
// GetVersion method to get current module version
|
||||
func (cl *APIClient) GetVersion() string {
|
||||
return "2.2.3"
|
||||
}
|
||||
|
||||
// SaveSession method to apply data to a session for later reuse
|
||||
// Please save/update that map into user session
|
||||
func (cl *APIClient) SaveSession(sessionobj map[string]interface{}) *APIClient {
|
||||
sessionobj["socketcfg"] = map[string]string{
|
||||
"entity": cl.socketConfig.GetSystemEntity(),
|
||||
"session": cl.socketConfig.GetSession(),
|
||||
}
|
||||
return cl
|
||||
}
|
||||
|
||||
// ReuseSession method to reuse given configuration out of a user session
|
||||
// to rebuild and reuse connection settings
|
||||
func (cl *APIClient) ReuseSession(sessionobj map[string]interface{}) *APIClient {
|
||||
cfg := sessionobj["socketcfg"].(map[string]string)
|
||||
cl.socketConfig.SetSystemEntity(cfg["entity"])
|
||||
cl.SetSession(cfg["session"])
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetURL method to set another connection url to be used for API communication
|
||||
func (cl *APIClient) SetURL(value string) *APIClient {
|
||||
cl.socketURL = value
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetOTP method to set one time password to be used for API communication
|
||||
func (cl *APIClient) SetOTP(value string) *APIClient {
|
||||
cl.socketConfig.SetOTP(value)
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetSession method to set an API session id to be used for API communication
|
||||
func (cl *APIClient) SetSession(value string) *APIClient {
|
||||
cl.socketConfig.SetSession(value)
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetRemoteIPAddress method to set an Remote IP Address to be used for API communication
|
||||
func (cl *APIClient) SetRemoteIPAddress(value string) *APIClient {
|
||||
cl.socketConfig.SetRemoteAddress(value)
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetCredentials method to set Credentials to be used for API communication
|
||||
func (cl *APIClient) SetCredentials(uid string, pw string) *APIClient {
|
||||
cl.socketConfig.SetLogin(uid)
|
||||
cl.socketConfig.SetPassword(pw)
|
||||
return cl
|
||||
}
|
||||
|
||||
// SetRoleCredentials method to set Role User Credentials to be used for API communication
|
||||
func (cl *APIClient) SetRoleCredentials(uid string, role string, pw string) *APIClient {
|
||||
if len(role) > 0 {
|
||||
return cl.SetCredentials(uid+"!"+role, pw)
|
||||
}
|
||||
return cl.SetCredentials(uid, pw)
|
||||
}
|
||||
|
||||
// Login method to perform API login to start session-based communication
|
||||
// 1st parameter: one time password
|
||||
func (cl *APIClient) Login(params ...string) *R.Response {
|
||||
otp := ""
|
||||
if len(params) > 0 {
|
||||
otp = params[0]
|
||||
}
|
||||
cl.SetOTP(otp)
|
||||
rr := cl.Request(map[string]string{"COMMAND": "StartSession"})
|
||||
if rr.IsSuccess() {
|
||||
col := rr.GetColumn("SESSION")
|
||||
if col != nil {
|
||||
cl.SetSession(col.GetData()[0])
|
||||
} else {
|
||||
cl.SetSession("")
|
||||
}
|
||||
}
|
||||
return rr
|
||||
}
|
||||
|
||||
// LoginExtended method to perform API login to start session-based communication.
|
||||
// 1st parameter: map of additional command parameters
|
||||
// 2nd parameter: one time password
|
||||
func (cl *APIClient) LoginExtended(params ...interface{}) *R.Response {
|
||||
otp := ""
|
||||
parameters := map[string]string{}
|
||||
if len(params) == 2 {
|
||||
otp = params[1].(string)
|
||||
}
|
||||
cl.SetOTP(otp)
|
||||
if len(params) > 0 {
|
||||
parameters = params[0].(map[string]string)
|
||||
}
|
||||
cmd := map[string]string{
|
||||
"COMMAND": "StartSession",
|
||||
}
|
||||
for k, v := range parameters {
|
||||
cmd[k] = v
|
||||
}
|
||||
rr := cl.Request(cmd)
|
||||
if rr.IsSuccess() {
|
||||
col := rr.GetColumn("SESSION")
|
||||
if col != nil {
|
||||
cl.SetSession(col.GetData()[0])
|
||||
} else {
|
||||
cl.SetSession("")
|
||||
}
|
||||
}
|
||||
return rr
|
||||
}
|
||||
|
||||
// Logout method to perform API logout to close API session in use
|
||||
func (cl *APIClient) Logout() *R.Response {
|
||||
rr := cl.Request(map[string]string{
|
||||
"COMMAND": "EndSession",
|
||||
})
|
||||
if rr.IsSuccess() {
|
||||
cl.SetSession("")
|
||||
}
|
||||
return rr
|
||||
}
|
||||
|
||||
// Request method to perform API request using the given command
|
||||
func (cl *APIClient) Request(cmd map[string]string) *R.Response {
|
||||
data := cl.GetPOSTData(cmd)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: cl.socketTimeout,
|
||||
}
|
||||
req, err := http.NewRequest("POST", cl.socketURL, strings.NewReader(data))
|
||||
if err != nil {
|
||||
tpl := rtm.GetTemplate("httperror").GetPlain()
|
||||
r := R.NewResponse(tpl, cmd)
|
||||
if cl.debugMode {
|
||||
j, _ := json.Marshal(cmd)
|
||||
fmt.Printf("%s\n", j)
|
||||
fmt.Println("POST: " + data)
|
||||
fmt.Println("HTTP communication failed: " + err.Error())
|
||||
fmt.Println(r.GetPlain())
|
||||
}
|
||||
return r
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Add("Expect", "")
|
||||
req.Header.Add("User-Agent", cl.GetUserAgent())
|
||||
resp, err2 := client.Do(req)
|
||||
if err2 != nil {
|
||||
tpl := rtm.GetTemplate("httperror").GetPlain()
|
||||
r := R.NewResponse(tpl, cmd)
|
||||
if cl.debugMode {
|
||||
j, _ := json.Marshal(cmd)
|
||||
fmt.Printf("%s\n", j)
|
||||
fmt.Println("POST: " + data)
|
||||
fmt.Println("HTTP communication failed: " + err2.Error())
|
||||
fmt.Println(r.GetPlain())
|
||||
}
|
||||
return r
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
response, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
tpl := rtm.GetTemplate("httperror").GetPlain()
|
||||
r := R.NewResponse(tpl, cmd)
|
||||
if cl.debugMode {
|
||||
j, _ := json.Marshal(cmd)
|
||||
fmt.Printf("%s\n", j)
|
||||
fmt.Println("POST: " + data)
|
||||
fmt.Println("HTTP communication failed: " + err.Error())
|
||||
fmt.Println(r.GetPlain())
|
||||
}
|
||||
return r
|
||||
}
|
||||
r := R.NewResponse(string(response), cmd)
|
||||
if cl.debugMode {
|
||||
j, _ := json.Marshal(cmd)
|
||||
fmt.Printf("%s\n", j)
|
||||
fmt.Println("POST: " + data)
|
||||
fmt.Println(r.GetPlain())
|
||||
}
|
||||
return r
|
||||
}
|
||||
tpl := rtm.GetTemplate("httperror").GetPlain()
|
||||
r := R.NewResponse(tpl, cmd)
|
||||
if cl.debugMode {
|
||||
j, _ := json.Marshal(cmd)
|
||||
fmt.Printf("%s\n", j)
|
||||
fmt.Println("POST: " + data)
|
||||
fmt.Println(r.GetPlain())
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// RequestNextResponsePage method to request the next page of list entries for the current list query
|
||||
// Useful for lists
|
||||
func (cl *APIClient) RequestNextResponsePage(rr *R.Response) (*R.Response, error) {
|
||||
mycmd := cl.toUpperCaseKeys(rr.GetCommand())
|
||||
if _, ok := mycmd["LAST"]; ok {
|
||||
return nil, errors.New("Parameter LAST in use. Please remove it to avoid issues in requestNextPage")
|
||||
}
|
||||
first := 0
|
||||
if v, ok := mycmd["FIRST"]; ok {
|
||||
first, _ = fmt.Sscan("%s", v)
|
||||
}
|
||||
total := rr.GetRecordsTotalCount()
|
||||
limit := rr.GetRecordsLimitation()
|
||||
first += limit
|
||||
if first < total {
|
||||
mycmd["FIRST"] = fmt.Sprintf("%d", first)
|
||||
mycmd["LIMIT"] = fmt.Sprintf("%d", limit)
|
||||
return cl.Request(mycmd), nil
|
||||
}
|
||||
return nil, errors.New("Could not find further existing pages")
|
||||
}
|
||||
|
||||
// RequestAllResponsePages method to request all pages/entries for the given query command
|
||||
// Use this method with caution as it requests all list data until done.
|
||||
func (cl *APIClient) RequestAllResponsePages(cmd map[string]string) []R.Response {
|
||||
var err error
|
||||
responses := []R.Response{}
|
||||
mycmd := map[string]string{
|
||||
"FIRST": "0",
|
||||
}
|
||||
for k, v := range cmd {
|
||||
mycmd[k] = v
|
||||
}
|
||||
rr := cl.Request(mycmd)
|
||||
tmp := rr
|
||||
for {
|
||||
responses = append(responses, *tmp)
|
||||
tmp, err = cl.RequestNextResponsePage(tmp)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return responses
|
||||
}
|
||||
|
||||
// SetUserView method to set a data view to a given subuser
|
||||
func (cl *APIClient) SetUserView(uid string) *APIClient {
|
||||
cl.socketConfig.SetUser(uid)
|
||||
return cl
|
||||
}
|
||||
|
||||
// ResetUserView method to reset data view back from subuser to user
|
||||
func (cl *APIClient) ResetUserView() *APIClient {
|
||||
cl.socketConfig.SetUser("")
|
||||
return cl
|
||||
}
|
||||
|
||||
// UseOTESystem method to set OT&E System for API communication
|
||||
func (cl *APIClient) UseOTESystem() *APIClient {
|
||||
cl.socketConfig.SetSystemEntity("1234")
|
||||
return cl
|
||||
}
|
||||
|
||||
// UseLIVESystem method to set LIVE System for API communication
|
||||
// Usage of LIVE System is active by default.
|
||||
func (cl *APIClient) UseLIVESystem() *APIClient {
|
||||
cl.socketConfig.SetSystemEntity("54cd")
|
||||
return cl
|
||||
}
|
||||
|
||||
// toUpperCaseKeys method to translate all command parameter names to uppercase
|
||||
func (cl *APIClient) toUpperCaseKeys(cmd map[string]string) map[string]string {
|
||||
newcmd := map[string]string{}
|
||||
for k, v := range cmd {
|
||||
newcmd[strings.ToUpper(k)] = v
|
||||
}
|
||||
return newcmd
|
||||
}
|
||||
Reference in New Issue
Block a user