Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding full support for txt records #151

Merged
merged 2 commits into from
Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
shadtimm marked this conversation as resolved.
Show resolved Hide resolved
* 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
76 changes: 39 additions & 37 deletions object_manager_txt-record.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,79 @@ 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
shadtimm marked this conversation as resolved.
Show resolved Hide resolved
}

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

recordTXT := NewRecordTXT(RecordTXT{Name: recordname})
func (objMgr *ObjectManager) UpdateTXTRecord(
ref string,
recordName string,
text string,
ttl uint32,
useTtl bool,
comment string,
eas EA) (*RecordTXT, error) {

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

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) {
return objMgr.connector.DeleteObject(ref)
}

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 @@ -594,27 +594,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