mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-01-12 02:17:43 +08:00
8e643c2856
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
208 lines
4.9 KiB
Go
208 lines
4.9 KiB
Go
package loopia
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
)
|
|
|
|
// types for XML-RPC method calls and parameters
|
|
|
|
type param interface {
|
|
param()
|
|
}
|
|
|
|
type paramString struct {
|
|
XMLName xml.Name `xml:"param"`
|
|
Value string `xml:"value>string"`
|
|
}
|
|
|
|
func (p paramString) param() {}
|
|
|
|
type paramInt struct {
|
|
XMLName xml.Name `xml:"param"`
|
|
Value uint32 `xml:"value>int"`
|
|
}
|
|
|
|
func (p paramInt) param() {}
|
|
|
|
// payload of values for a subdomain record
|
|
type paramStruct struct {
|
|
XMLName xml.Name `xml:"param"`
|
|
StructMembers []structMember `xml:"value>struct>member"`
|
|
}
|
|
|
|
func (p paramStruct) param() {}
|
|
|
|
type structMember interface {
|
|
structMember()
|
|
}
|
|
|
|
type structMemberString struct {
|
|
Name string `xml:"name"`
|
|
Value string `xml:"value>string"`
|
|
}
|
|
|
|
func (m structMemberString) structMember() {}
|
|
|
|
type structMemberInt struct {
|
|
Name string `xml:"name"`
|
|
Value uint32 `xml:"value>int"`
|
|
}
|
|
|
|
func (m structMemberInt) structMember() {}
|
|
|
|
type structMemberBool struct {
|
|
Name string `xml:"name"`
|
|
Value bool `xml:"value>boolean"`
|
|
}
|
|
|
|
func (m structMemberBool) structMember() {}
|
|
|
|
type methodCall struct {
|
|
XMLName xml.Name `xml:"methodCall"`
|
|
MethodName string `xml:"methodName"`
|
|
Params []param `xml:"params>param"`
|
|
}
|
|
|
|
// types for XML-RPC responses
|
|
|
|
type response interface {
|
|
faultCode() uint32
|
|
faultString() string
|
|
}
|
|
|
|
type responseString struct {
|
|
responseFault
|
|
Value string `xml:"params>param>value>string"`
|
|
}
|
|
|
|
type responseFault struct {
|
|
FaultCode uint32 `xml:"fault>value>struct>member>value>int"`
|
|
FaultString string `xml:"fault>value>struct>member>value>string"`
|
|
}
|
|
|
|
func (r responseFault) faultCode() uint32 { return r.FaultCode }
|
|
func (r responseFault) faultString() string { return r.FaultString }
|
|
|
|
type rpcError struct {
|
|
faultCode uint32
|
|
faultString string
|
|
}
|
|
|
|
func (e rpcError) Error() string {
|
|
return fmt.Sprintf("RPC Error: (%d) %s", e.faultCode, e.faultString)
|
|
}
|
|
|
|
type zRec struct {
|
|
// "name" "value"
|
|
Type string
|
|
Rdata string
|
|
Priority uint16 // the next 4 ints are 112 bits
|
|
TTL uint32
|
|
RecordID uint32
|
|
}
|
|
|
|
// zoneRecord and domainObject are synonymous (but belong to different parts of
|
|
// XML structure in req/resp). Can we unify them?
|
|
type zoneRecord struct {
|
|
XMLName xml.Name `xml:"struct"`
|
|
Properties []Property `xml:"member"`
|
|
// Properties map[string]interface{}
|
|
}
|
|
|
|
type zoneRecordsResponse struct {
|
|
responseFault
|
|
XMLName xml.Name `xml:"methodResponse"`
|
|
ZoneRecords []zoneRecord `xml:"params>param>value>array>data>value>struct"`
|
|
}
|
|
|
|
type Property struct {
|
|
Key string `xml:"name"`
|
|
Value Value `xml:"value"`
|
|
}
|
|
|
|
type Value struct {
|
|
// String string `xml:",any"`
|
|
String string `xml:"string"`
|
|
Int int `xml:"int"`
|
|
Bool bool `xml:"bool"`
|
|
}
|
|
|
|
func (p Property) Name() string { return p.Key }
|
|
func (p Property) String() string { return p.Value.String }
|
|
func (p Property) Int() int { return p.Value.Int }
|
|
func (p Property) Bool() bool { return p.Value.Bool }
|
|
|
|
func (zr *zoneRecord) GetZR() zRec {
|
|
record := zRec{}
|
|
for _, prop := range zr.Properties {
|
|
switch prop.Key {
|
|
case "type":
|
|
record.Type = prop.String()
|
|
case "ttl":
|
|
record.TTL = uint32(prop.Int())
|
|
case "priority":
|
|
record.Priority = uint16(prop.Int())
|
|
case "rdata":
|
|
record.Rdata = prop.String()
|
|
case "record_id":
|
|
record.RecordID = uint32(prop.Int())
|
|
}
|
|
}
|
|
return record
|
|
}
|
|
|
|
func (zrec *zRec) SetZR() zoneRecord {
|
|
//This method creates a zoneRecord to receive from responses.
|
|
return zoneRecord{
|
|
XMLName: xml.Name{Local: "struct"},
|
|
Properties: []Property{
|
|
Property{Key: "type", Value: Value{String: zrec.Type}},
|
|
Property{Key: "ttl", Value: Value{Int: int(zrec.TTL)}},
|
|
Property{Key: "priority", Value: Value{Int: int(zrec.Priority)}},
|
|
Property{Key: "rdata", Value: Value{String: zrec.Rdata}},
|
|
Property{Key: "record_id", Value: Value{Int: int(zrec.RecordID)}},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (zrec *zRec) SetPS() paramStruct {
|
|
//This method creates a paramStruct for sending in requests.
|
|
return paramStruct{
|
|
XMLName: xml.Name{Local: "struct"},
|
|
StructMembers: []structMember{
|
|
structMemberString{Name: "type", Value: zrec.Type},
|
|
structMemberInt{Name: "ttl", Value: uint32(zrec.TTL)},
|
|
structMemberInt{Name: "priority", Value: uint32(zrec.Priority)},
|
|
structMemberString{Name: "rdata", Value: zrec.Rdata},
|
|
structMemberInt{Name: "record_id", Value: uint32(zrec.RecordID)},
|
|
},
|
|
}
|
|
}
|
|
|
|
type domainObject struct {
|
|
XMLName xml.Name `xml:"struct"`
|
|
Properties []Property `xml:"member"`
|
|
}
|
|
|
|
// type LoopiaDomainObject struct {
|
|
// "name" "value"
|
|
// ReferenceNo int32
|
|
// Domain string
|
|
// RenewalStatus string
|
|
// ExpirationDate string
|
|
// Paid bool
|
|
// Registered bool
|
|
// }
|
|
|
|
type domainObjectsResponse struct {
|
|
responseFault
|
|
XMLName xml.Name `xml:"methodResponse"`
|
|
Domains []domainObject `xml:"params>param>value>array>data>value>struct"`
|
|
}
|
|
|
|
type subDomainsResponse struct {
|
|
responseFault
|
|
XMLName xml.Name `xml:"methodResponse"`
|
|
Params []string `xml:"params>param>value>array>data>value>string"`
|
|
}
|