Skip to content

Commit

Permalink
Adding full support for txt records (#151)
Browse files Browse the repository at this point in the history
Co-authored-by: Shad Timm <[email protected]>
  • Loading branch information
shadtimm and shadtimm committed Apr 8, 2022
1 parent 6f4c714 commit e4a3ca6
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 85 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ This library is compatible with Go 1.2+
* GetNetworkViewByRef
* GetPTRRecordByRef
* GetPTRRecord
* GetTXTRecord
* GetTXTRecordByRef
* GetZoneAuthByRef
* GetZoneDelegated
* GetUpgradeStatus (2.7 or above)
Expand All @@ -125,6 +127,7 @@ This library is compatible with Go 1.2+
* UpdateNetworkContainer
* UpdateNetworkView
* UpdatePTRRecord
* UpdateTXTRecord
* UpdateARecord
* UpdateZoneDelegated

Expand Down
5 changes: 4 additions & 1 deletion object_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type IBObjectManager interface {
CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error)
CreateNetworkView(name string, comment string, setEas EA) (*NetworkView, error)
CreatePTRRecord(networkView string, dnsView string, ptrdname string, recordName string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, eas EA) (*RecordPTR, error)
CreateTXTRecord(recordname string, text string, ttl uint, dnsview string) (*RecordTXT, error)
CreateTXTRecord(dnsView string, recordName string, text string, ttl uint32, useTtl bool, comment string, eas EA) (*RecordTXT, error)
CreateZoneDelegated(fqdn string, delegate_to []NameServer) (*ZoneDelegated, error)
DeleteARecord(ref string) (string, error)
DeleteAAAARecord(ref string) (string, error)
Expand Down Expand Up @@ -58,6 +58,8 @@ type IBObjectManager interface {
GetNetworkViewByRef(ref string) (*NetworkView, error)
GetPTRRecord(dnsview string, ptrdname string, recordName string, ipAddr string) (*RecordPTR, error)
GetPTRRecordByRef(ref string) (*RecordPTR, error)
GetTXTRecord(dnsview string, name string) (*RecordTXT, error)
GetTXTRecordByRef(ref string) (*RecordTXT, error)
GetZoneAuthByRef(ref string) (*ZoneAuth, error)
GetZoneDelegated(fqdn string) (*ZoneDelegated, error)
GetCapacityReport(name string) ([]CapacityReport, error)
Expand All @@ -74,6 +76,7 @@ type IBObjectManager interface {
UpdateNetworkContainer(ref string, setEas EA, comment string) (*NetworkContainer, error)
UpdateNetworkView(ref string, name string, comment string, setEas EA) (*NetworkView, error)
UpdatePTRRecord(ref string, netview string, ptrdname string, name string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, setEas EA) (*RecordPTR, error)
UpdateTXTRecord(ref string, recordName string, text string, ttl uint32, useTtl bool, comment string, eas EA) (*RecordTXT, error)
UpdateARecord(ref string, name string, ipAddr string, cidr string, netview string, ttl uint32, useTTL bool, comment string, eas EA) (*RecordA, error)
UpdateZoneDelegated(ref string, delegate_to []NameServer) (*ZoneDelegated, error)
}
Expand Down
4 changes: 4 additions & 0 deletions object_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func (c *fakeConnector) GetObject(obj IBObject, ref string, qp *QueryParams, res
*res.(*[]RecordAAAA) = c.resultObject.([]RecordAAAA)
case *RecordPTR:
*res.(*[]RecordPTR) = c.resultObject.([]RecordPTR)
case *RecordTXT:
*res.(*[]RecordTXT) = c.resultObject.([]RecordTXT)
case *ZoneDelegated:
*res.(*[]ZoneDelegated) = c.resultObject.([]ZoneDelegated)
case *RecordCNAME:
Expand All @@ -99,6 +101,8 @@ func (c *fakeConnector) GetObject(obj IBObject, ref string, qp *QueryParams, res
**res.(**HostRecord) = *c.resultObject.(*HostRecord)
case *RecordPTR:
**res.(**RecordPTR) = *c.resultObject.(*RecordPTR)
case *RecordTXT:
**res.(**RecordTXT) = *c.resultObject.(*RecordTXT)
case *RecordCNAME:
**res.(**RecordCNAME) = *c.resultObject.(*RecordCNAME)
case *RecordA:
Expand Down
75 changes: 39 additions & 36 deletions object_manager_txt-record.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,77 @@ package ibclient
import "fmt"

// Creates TXT Record. Use TTL of 0 to inherit TTL from the Zone
func (objMgr *ObjectManager) CreateTXTRecord(recordname string, text string, ttl uint, dnsview string) (*RecordTXT, error) {
func (objMgr *ObjectManager) CreateTXTRecord(
dnsView string,
recordName string,
text string,
ttl uint32,
useTtl bool,
comment string,
eas EA) (*RecordTXT, error) {

recordTXT := NewRecordTXT(RecordTXT{
View: dnsview,
Name: recordname,
Text: text,
Ttl: ttl,
})
recordTXT := NewRecordTXT(dnsView, "", recordName, text, ttl, useTtl, comment, eas)

ref, err := objMgr.connector.CreateObject(recordTXT)
recordTXT.Ref = ref
if err != nil {
return nil, err
}
recordTXT, err = objMgr.GetTXTRecordByRef(ref)
return recordTXT, err
}

func (objMgr *ObjectManager) GetTXTRecordByRef(ref string) (*RecordTXT, error) {
recordTXT := NewRecordTXT(RecordTXT{})
recordTXT := NewEmptyRecordTXT()
err := objMgr.connector.GetObject(
recordTXT, ref, NewQueryParams(false, nil), &recordTXT)
return recordTXT, err
}

func (objMgr *ObjectManager) GetTXTRecord(name string) (*RecordTXT, error) {
if name == "" {
return nil, fmt.Errorf("name can not be empty")
func (objMgr *ObjectManager) GetTXTRecord(dnsview string, name string) (*RecordTXT, error) {
if dnsview == "" || name == "" {
return nil, fmt.Errorf("DNS view and name are required to retrieve a unique txt record")
}
var res []RecordTXT

recordTXT := NewRecordTXT(RecordTXT{})
recordTXT := NewEmptyRecordTXT()

sf := map[string]string{
"view": dnsview,
"name": name,
}
queryParams := NewQueryParams(false, sf)
err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res)

if err != nil || res == nil || len(res) == 0 {
if err != nil {
return nil, err
} else if res == nil || len(res) == 0 {
return nil, NewNotFoundError(
fmt.Sprintf(
"TXT record with name '%s' in DNS view '%s' is not found",
name, dnsview))
}

return &res[0], nil
}

func (objMgr *ObjectManager) UpdateTXTRecord(recordname string, text string) (*RecordTXT, error) {
var res []RecordTXT

recordTXT := NewRecordTXT(RecordTXT{Name: recordname})

sf := map[string]string{
"name": recordname,
}
queryParams := NewQueryParams(false, sf)
err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res)

if len(res) == 0 {
return nil, nil
}

res[0].Text = text
func (objMgr *ObjectManager) UpdateTXTRecord(
ref string,
recordName string,
text string,
ttl uint32,
useTtl bool,
comment string,
eas EA) (*RecordTXT, error) {

res[0].Zone = "" // set the Zone value to "" as its a non writable field

_, err = objMgr.connector.UpdateObject(&res[0], res[0].Ref)
recordTXT := NewRecordTXT("", "", recordName, text, ttl, useTtl, comment, eas)
recordTXT.Ref = ref

if err != nil || res == nil || len(res) == 0 {
reference, err := objMgr.connector.UpdateObject(recordTXT, ref)
if err != nil {
return nil, err
}

return &res[0], nil
recordTXT, err = objMgr.GetTXTRecordByRef(reference)
return recordTXT, err
}

func (objMgr *ObjectManager) DeleteTXTRecord(ref string) (string, error) {
Expand Down
91 changes: 65 additions & 26 deletions object_manager_txt-record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,93 @@ import (
)

var _ = Describe("Object Manager: TXT-record", func() {
Describe("Allocate TXT Record ", func() {
Describe("Create TXT Record ", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
text := "test-text"
dnsView := "default"
text := "test-text"
recordName := "test"
ttl := uint(30)
useTtl := true
ttl := uint32(70)
comment := "creation test"
eas := EA{"Country": "test"}
fakeRefReturn := fmt.Sprintf("record:txt/ZG5zLmJpbmRfY25h:%s/%20%20", recordName)

aniFakeConnector := &fakeConnector{
createObjectObj: NewRecordTXT(RecordTXT{
Name: recordName,
Text: text,
Ttl: ttl,
View: dnsView,
}),
getObjectRef: fakeRefReturn,
getObjectObj: NewRecordTXT(RecordTXT{
Name: recordName,
Text: text,
View: dnsView,
Ref: fakeRefReturn,
Ttl: ttl,
}),
createObjectObj: NewRecordTXT(dnsView, "", recordName, text, ttl, useTtl, comment, eas),
getObjectRef: fakeRefReturn,
getObjectObj: NewEmptyRecordTXT(),
getObjectQueryParams: NewQueryParams(false, nil),
resultObject: NewRecordTXT(RecordTXT{
Name: recordName,
Text: text,
View: dnsView,
Ttl: ttl,
Ref: fakeRefReturn,
}),
fakeRefReturn: fakeRefReturn,
resultObject: NewRecordTXT(dnsView, "", recordName, text, ttl, useTtl, comment, eas),
fakeRefReturn: fakeRefReturn,
}

objMgr := NewObjectManager(aniFakeConnector, cmpType, tenantID)

var actualRecord *RecordTXT
var err error
It("should pass expected TXT record Object to CreateObject", func() {
actualRecord, err = objMgr.CreateTXTRecord(recordName, text, 30, dnsView)
actualRecord, err = objMgr.CreateTXTRecord(dnsView, recordName, text, ttl, useTtl, comment, eas)
})
It("should return expected TXT record Object", func() {
Expect(actualRecord).To(Equal(aniFakeConnector.resultObject))
Expect(err).To(BeNil())
})
})

Describe("Update TXT record", func() {
var (
err error
objMgr IBObjectManager
conn *fakeConnector
ref string
actualObj *RecordTXT
)

cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
recordName := "test"

It("Updating text, ttl, useTtl, comment and EAs", func() {
ref = fmt.Sprintf("record:txt/ZG5zLmJpbmRfY25h:%s/%20%20", recordName)
initialEas := EA{"Country": "old value"}
initObj := NewRecordTXT("", "", recordName, "old-text", uint32(70), true, "old comment", initialEas)
initObj.Ref = ref

expectedEas := EA{"Country": "new value"}

updateText := ""
updateComment := "new comment"
updateUseTtl := true
updateTtl := uint32(10)
updatedRef := fmt.Sprintf("record:txt/ZG5zLmJpbmRfY25h:%s/%20%20", recordName)
updateObjIn := NewRecordTXT("", "", recordName, updateText, updateTtl, updateUseTtl, updateComment, expectedEas)
updateObjIn.Ref = ref

expectedObj := NewRecordTXT("", "", recordName, updateText, updateTtl, updateUseTtl, updateComment, expectedEas)
expectedObj.Ref = updatedRef

conn = &fakeConnector{
getObjectObj: NewEmptyRecordTXT(),
getObjectQueryParams: NewQueryParams(false, nil),
getObjectRef: updatedRef,
getObjectError: nil,
resultObject: expectedObj,

updateObjectObj: updateObjIn,
updateObjectRef: ref,
updateObjectError: nil,

fakeRefReturn: updatedRef,
}
objMgr = NewObjectManager(conn, cmpType, tenantID)

actualObj, err = objMgr.UpdateTXTRecord(ref, recordName, updateText, updateTtl, updateUseTtl, updateComment, expectedEas)
Expect(err).To(BeNil())
Expect(*actualObj).To(BeEquivalentTo(*expectedObj))
})
})

Describe("Delete TXT Record", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
Expand Down
48 changes: 36 additions & 12 deletions objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,25 +729,49 @@ func NewHostRecord(
}

type RecordTXT struct {
IBBase `json:"-"`
Ref string `json:"_ref,omitempty"`
Name string `json:"name,omitempty"`
Text string `json:"text,omitempty"`
Ttl uint `json:"ttl,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
Ea EA `json:"extattrs"`
UseTtl bool `json:"use_ttl"`
IBBase `json:"-"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
Ref string `json:"_ref,omitempty"`
Name string `json:"name,omitempty"`
Text string `json:"text,omitempty"`
Ttl uint32 `json:"ttl"`
UseTtl bool `json:"use_ttl"`
Comment string `json:"comment"`
Ea EA `json:"extattrs"`
}

func NewRecordTXT(rt RecordTXT) *RecordTXT {
res := rt
func NewEmptyRecordTXT() *RecordTXT {
res := RecordTXT{}
res.objectType = "record:txt"
res.returnFields = []string{"extattrs", "name", "text", "view", "zone", "ttl", "use_ttl"}
res.returnFields = []string{"view", "zone", "name", "text", "ttl", "use_ttl", "comment", "extattrs"}

return &res
}

func NewRecordTXT(
dnsview string,
zone string,
recordname string,
text string,
ttl uint32,
useTtl bool,
comment string,
eas EA) *RecordTXT {

res := NewEmptyRecordTXT()
res.View = dnsview
res.Zone = zone
res.Name = recordname
res.Text = text
res.Ttl = ttl
res.UseTtl = useTtl
res.Comment = comment
res.Ea = eas

return res
}

type ZoneAuth struct {
IBBase `json:"-"`
Ref string `json:"_ref,omitempty"`
Expand Down
18 changes: 8 additions & 10 deletions objects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,27 +604,25 @@ var _ = Describe("Objects", func() {
})

Context("RecordTXT object", func() {
view := "default"
name := "txt.domain.com"
text := "this is text string"
view := "default"
zone := "domain.com"
ttl := uint32(70)
useTtl := true
comment := "test client"
eas := EA{"Country": "test"}

rt := NewRecordTXT(RecordTXT{
Name: name,
Text: text,
View: view,
Zone: zone})
rt := NewRecordTXT(view, "", name, text, ttl, useTtl, comment, eas)

It("should set fields correctly", func() {
Expect(rt.View).To(Equal(view))
Expect(rt.Name).To(Equal(name))
Expect(rt.Text).To(Equal(text))
Expect(rt.View).To(Equal(view))
Expect(rt.Zone).To(Equal(zone))
})

It("should set base fields correctly", func() {
Expect(rt.ObjectType()).To(Equal("record:txt"))
Expect(rt.ReturnFields()).To(ConsistOf("extattrs", "name", "text", "view", "zone", "ttl", "use_ttl"))
Expect(rt.ReturnFields()).To(ConsistOf("view", "zone", "name", "text", "ttl", "use_ttl", "comment", "extattrs"))
})
})

Expand Down

0 comments on commit e4a3ca6

Please sign in to comment.