dnscontrol/providers/loopia/types.go
Paul Dee 8e643c2856
New provider: Loopia DNS service provider (#2140)
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
2023-03-15 09:54:07 -04:00

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"`
}