Skip to content

Commit

Permalink
CRUD operations for zone_delegated (#85)
Browse files Browse the repository at this point in the history
* Initial ZoneDelegated management

* Implement UpdateZoneDelegated

* Fqdn update is forbidden so only `delegate_to` is in action

* DeleteZoneDelegated

* GetZoneDelegated by Fqdn

* Add GetZoneDelegated tests

* Return nil when fqdn is empty

With empty object API return list of all existing zones
and  GetZoneDelegated was picking first from the slice.

It could lead to dangerous situation when we are dealing
with completely unrelated Ref in further api interactions

* No EA required for ZoneDelegated

It actually breaks creation in e2e test

* Unit tests for UpdateZoneDelegated

* Test UpdateZoneDelegated
* Reposition test case closer to common semantics

* Finalize tests for ZoneDelegated
  • Loading branch information
ytsarev authored Feb 12, 2020
1 parent dd50c40 commit 1da13c0
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 19 deletions.
74 changes: 63 additions & 11 deletions object_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ type ObjectManager struct {
tenantID string
}


func NewObjectManager(connector IBConnector, cmpType string, tenantID string) *ObjectManager {
objMgr := new(ObjectManager)

Expand All @@ -68,10 +67,10 @@ func (objMgr *ObjectManager) getBasicEA(cloudAPIOwned Bool) EA {
return ea
}

func (objMgr *ObjectManager) extendEA(ea EA) EA{
func (objMgr *ObjectManager) extendEA(ea EA) EA {
eas := objMgr.getBasicEA(true)
for k,v :=range ea{
eas[k]=v
for k, v := range ea {
eas[k] = v
}
return eas
}
Expand Down Expand Up @@ -284,7 +283,7 @@ func (objMgr *ObjectManager) AllocateIP(netview string, cidr string, ipAddr stri
Cidr: cidr,
Mac: macAddress,
Name: name,
Ea: eas})
Ea: eas})

if ipAddr == "" {
fixedAddr.IPAddress = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview)
Expand Down Expand Up @@ -381,7 +380,7 @@ func (objMgr *ObjectManager) UpdateFixedAddress(fixedAddrRef string, matchClient
if validateMatchClient(matchClient) {
updateFixedAddr.MatchClient = matchClient
} else {
return nil , fmt.Errorf("wrong value for match_client passed %s \n ", matchClient)
return nil, fmt.Errorf("wrong value for match_client passed %s \n ", matchClient)
}
}

Expand Down Expand Up @@ -514,7 +513,6 @@ func (objMgr *ObjectManager) CreateARecord(netview string, dnsview string, recor

eas := objMgr.extendEA(ea)


recordA := NewRecordA(RecordA{
View: dnsview,
Name: recordname,
Expand All @@ -539,15 +537,15 @@ func (objMgr *ObjectManager) DeleteARecord(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}

func (objMgr *ObjectManager) CreateCNAMERecord(canonical string, recordname string, dnsview string, ea EA)(*RecordCNAME, error) {
func (objMgr *ObjectManager) CreateCNAMERecord(canonical string, recordname string, dnsview string, ea EA) (*RecordCNAME, error) {

eas := objMgr.extendEA(ea)

recordCNAME := NewRecordCNAME(RecordCNAME{
View: dnsview,
Name: recordname,
Canonical: canonical,
Ea: eas})
Ea: eas})

ref, err := objMgr.connector.CreateObject(recordCNAME)
recordCNAME.Ref = ref
Expand All @@ -566,10 +564,8 @@ func (objMgr *ObjectManager) DeleteCNAMERecord(ref string) (string, error) {

func (objMgr *ObjectManager) CreatePTRRecord(netview string, dnsview string, recordname string, cidr string, ipAddr string, ea EA) (*RecordPTR, error) {


eas := objMgr.extendEA(ea)


recordPTR := NewRecordPTR(RecordPTR{
View: dnsview,
PtrdName: recordname,
Expand Down Expand Up @@ -677,3 +673,59 @@ func (objMgr *ObjectManager) GetGridInfo() ([]Grid, error) {
err := objMgr.connector.GetObject(gridObj, "", &res)
return res, err
}

// GetZoneAuth returns the authoritatives zones
func (objMgr *ObjectManager) GetZoneAuth() ([]ZoneAuth, error) {
var res []ZoneAuth

zoneAuth := NewZoneAuth(ZoneAuth{})
err := objMgr.connector.GetObject(zoneAuth, "", &res)

return res, err
}

// GetZoneDelegated returns the delegated zone
func (objMgr *ObjectManager) GetZoneDelegated(fqdn string) (*ZoneDelegated, error) {
if len(fqdn) == 0 {
return nil, nil
}
var res []ZoneDelegated

zoneDelegated := NewZoneDelegated(ZoneDelegated{Fqdn: fqdn})

err := objMgr.connector.GetObject(zoneDelegated, "", &res)

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

return &res[0], nil
}

// CreateZoneDelegated creates delegated zone
func (objMgr *ObjectManager) CreateZoneDelegated(fqdn string, delegate_to []NameServer) (*ZoneDelegated, error) {
zoneDelegated := NewZoneDelegated(ZoneDelegated{
Fqdn: fqdn,
DelegateTo: delegate_to})

ref, err := objMgr.connector.CreateObject(zoneDelegated)
zoneDelegated.Ref = ref

return zoneDelegated, err
}

// UpdateZoneDelegated updates delegated zone
func (objMgr *ObjectManager) UpdateZoneDelegated(ref string, delegate_to []NameServer) (*ZoneDelegated, error) {
zoneDelegated := NewZoneDelegated(ZoneDelegated{
Ref: ref,
DelegateTo: delegate_to})

refResp, err := objMgr.connector.UpdateObject(zoneDelegated, ref)
zoneDelegated.Ref = refResp
return zoneDelegated, err
}

// DeleteZoneDelegated deletes delegated zone
func (objMgr *ObjectManager) DeleteZoneDelegated(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}
129 changes: 121 additions & 8 deletions object_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func (c *fakeConnector) GetObject(obj IBObject, ref string, res interface{}) (er
*res.(*[]License) = c.resultObject.([]License)
case *HostRecord:
*res.(*[]HostRecord) = c.resultObject.([]HostRecord)
case *ZoneDelegated:
*res.(*[]ZoneDelegated) = c.resultObject.([]ZoneDelegated)
}
} else {
switch obj.(type) {
Expand Down Expand Up @@ -323,7 +325,7 @@ var _ = Describe("Object Manager", func() {
}

objMgr := NewObjectManager(aniFakeConnector, cmpType, tenantID)

ea := objMgr.getBasicEA(true)
aniFakeConnector.createObjectObj.(*FixedAddress).Ea = ea
aniFakeConnector.createObjectObj.(*FixedAddress).Ea["VM ID"] = vmID
Expand Down Expand Up @@ -391,7 +393,7 @@ var _ = Describe("Object Manager", func() {
}

objMgr := NewObjectManager(aniFakeConnector, cmpType, tenantID)

ea := objMgr.getBasicEA(true)
aniFakeConnector.createObjectObj.(*HostRecord).Ea = ea
aniFakeConnector.createObjectObj.(*HostRecord).Ea["VM ID"] = vmID
Expand Down Expand Up @@ -665,7 +667,7 @@ var _ = Describe("Object Manager", func() {
}

objMgr := NewObjectManager(aniFakeConnector, cmpType, tenantID)

ea := objMgr.getBasicEA(true)
aniFakeConnector.createObjectObj.(*RecordA).Ea = ea
aniFakeConnector.createObjectObj.(*RecordA).Ea["VM ID"] = vmID
Expand Down Expand Up @@ -785,7 +787,7 @@ var _ = Describe("Object Manager", func() {
}

objMgr := NewObjectManager(aniFakeConnector, cmpType, tenantID)

ea := objMgr.getBasicEA(true)
aniFakeConnector.createObjectObj.(*RecordPTR).Ea = ea
aniFakeConnector.createObjectObj.(*RecordPTR).Ea["VM ID"] = vmID
Expand All @@ -795,7 +797,7 @@ var _ = Describe("Object Manager", func() {
aniFakeConnector.resultObject.(*RecordPTR).Ea["VM ID"] = vmID
aniFakeConnector.resultObject.(*RecordPTR).Ea["VM Name"] = vmName

aniFakeConnector.getObjectObj.(*RecordPTR).Ea = ea
aniFakeConnector.getObjectObj.(*RecordPTR).Ea = ea
aniFakeConnector.getObjectObj.(*RecordPTR).Ea["VM ID"] = vmID
aniFakeConnector.getObjectObj.(*RecordPTR).Ea["VM Name"] = vmName

Expand Down Expand Up @@ -855,7 +857,7 @@ var _ = Describe("Object Manager", func() {
aniFakeConnector.resultObject.(*RecordPTR).Ea["VM ID"] = vmID
aniFakeConnector.resultObject.(*RecordPTR).Ea["VM Name"] = vmName

aniFakeConnector.getObjectObj.(*RecordPTR).Ea = ea
aniFakeConnector.getObjectObj.(*RecordPTR).Ea = ea
aniFakeConnector.getObjectObj.(*RecordPTR).Ea["VM ID"] = vmID
aniFakeConnector.getObjectObj.(*RecordPTR).Ea["VM Name"] = vmName

Expand Down Expand Up @@ -912,13 +914,13 @@ var _ = Describe("Object Manager", func() {
aniFakeConnector.resultObject.(*RecordCNAME).Ea["VM ID"] = vmID
aniFakeConnector.resultObject.(*RecordCNAME).Ea["VM Name"] = vmName

aniFakeConnector.getObjectObj.(*RecordCNAME).Ea = ea
aniFakeConnector.getObjectObj.(*RecordCNAME).Ea = ea
aniFakeConnector.getObjectObj.(*RecordCNAME).Ea["VM ID"] = vmID
aniFakeConnector.getObjectObj.(*RecordCNAME).Ea["VM Name"] = vmName
var actualRecord *RecordCNAME
var err error
It("should pass expected CNAME record Object to CreateObject", func() {
actualRecord, err = objMgr.CreateCNAMERecord(canonical, recordName, dnsView,ea)
actualRecord, err = objMgr.CreateCNAMERecord(canonical, recordName, dnsView, ea)
})
It("should return expected CNAME record Object", func() {
Expect(actualRecord).To(Equal(aniFakeConnector.resultObject))
Expand Down Expand Up @@ -1532,4 +1534,115 @@ var _ = Describe("Object Manager", func() {
Expect(err).To(BeNil())
})
})

Describe("Get Zone Delegated", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
fqdn := "dzone.example.com"
fakeRefReturn := "zone_delegated/ZG5zLnpvbmUkLl9kZWZhdWx0LnphLmNvLmFic2EuY2Fhcy5vaG15Z2xiLmdzbGJpYmNsaWVudA:dzone.example.com/default"
zdFakeConnector := &fakeConnector{
getObjectObj: NewZoneDelegated(ZoneDelegated{Fqdn: fqdn}),
getObjectRef: "",
resultObject: []ZoneDelegated{*NewZoneDelegated(ZoneDelegated{Fqdn: fqdn, Ref: fakeRefReturn})},
}

objMgr := NewObjectManager(zdFakeConnector, cmpType, tenantID)

var actualZoneDelegated *ZoneDelegated
var err error
It("should pass expected ZoneDelegated Object to GetObject", func() {
actualZoneDelegated, err = objMgr.GetZoneDelegated(fqdn)
})
It("should return expected ZoneDelegated Object", func() {
Expect(*actualZoneDelegated).To(Equal(zdFakeConnector.resultObject.([]ZoneDelegated)[0]))
Expect(err).To(BeNil())
})
It("should return nil if fqdn is empty", func() {
zdFakeConnector.getObjectObj.(*ZoneDelegated).Fqdn = ""
actualZoneDelegated, err = objMgr.GetZoneDelegated("")
Expect(actualZoneDelegated).To(BeNil())
Expect(err).To(BeNil())
})
})

Describe("Create Zone Delegated", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
fqdn := "dzone.example.com"
delegateTo := []NameServer{
{Address: "10.0.0.1", Name: "test1.dzone.example.com"},
{Address: "10.0.0.2", Name: "test2.dzone.example.com"}}
fakeRefReturn := "zone_delegated/ZG5zLnpvbmUkLl9kZWZhdWx0LnphLmNvLmFic2EuY2Fhcy5vaG15Z2xiLmdzbGJpYmNsaWVudA:dzone.example.com/default"
zdFakeConnector := &fakeConnector{
createObjectObj: NewZoneDelegated(ZoneDelegated{Fqdn: fqdn, DelegateTo: delegateTo}),
resultObject: NewZoneDelegated(ZoneDelegated{Fqdn: fqdn, DelegateTo: delegateTo, Ref: fakeRefReturn}),
fakeRefReturn: fakeRefReturn,
}

objMgr := NewObjectManager(zdFakeConnector, cmpType, tenantID)

var actualZoneDelegated *ZoneDelegated
var err error
It("should pass expected ZoneDelegated Object to CreateObject", func() {
actualZoneDelegated, err = objMgr.CreateZoneDelegated(fqdn, delegateTo)
})
It("should return expected ZoneDelegated Object", func() {
Expect(actualZoneDelegated).To(Equal(zdFakeConnector.resultObject))
Expect(err).To(BeNil())
})
})

Describe("Update Zone Delegated", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
fakeRefReturn := "zone_delegated/ZG5zLnpvbmUkLl9kZWZhdWx0LnphLmNvLmFic2EuY2Fhcy5vaG15Z2xiLmdzbGJpYmNsaWVudA:dzone.example.com/default"
delegateTo := []NameServer{
{Address: "10.0.0.1", Name: "test1.dzone.example.com"},
{Address: "10.0.0.2", Name: "test2.dzone.example.com"}}

receiveUpdateObject := NewZoneDelegated(ZoneDelegated{Ref: fakeRefReturn, DelegateTo: delegateTo})
returnUpdateObject := NewZoneDelegated(ZoneDelegated{DelegateTo: delegateTo, Ref: fakeRefReturn})
zdFakeConnector := &fakeConnector{
fakeRefReturn: fakeRefReturn,
resultObject: returnUpdateObject,
updateObjectObj: receiveUpdateObject,
updateObjectRef: fakeRefReturn,
}

objMgr := NewObjectManager(zdFakeConnector, cmpType, tenantID)

var updatedObject *ZoneDelegated
var err error
It("should pass expected updated object to UpdateObject", func() {
updatedObject, err = objMgr.UpdateZoneDelegated(fakeRefReturn, delegateTo)
})
It("should update zone with new delegation server list with no error", func() {
Expect(updatedObject).To(Equal(returnUpdateObject))
Expect(err).To(BeNil())
})
})

Describe("Delete ZoneDelegated", func() {
cmpType := "Docker"
tenantID := "01234567890abcdef01234567890abcdef"
deleteRef := "zone_delegated/ZG5zLnpvbmUkLl9kZWZhdWx0LnphLmNvLmFic2EuY2Fhcy5vaG15Z2xiLmdzbGJpYmNsaWVudA:dzone.example.com/default"
fakeRefReturn := deleteRef
zdFakeConnector := &fakeConnector{
deleteObjectRef: deleteRef,
fakeRefReturn: fakeRefReturn,
}

objMgr := NewObjectManager(zdFakeConnector, cmpType, tenantID)

var actualRef string
var err error
It("should pass expected ZoneDelegated Ref to DeleteObject", func() {
actualRef, err = objMgr.DeleteZoneDelegated(deleteRef)
})
It("should return expected ZoneDelegated Ref", func() {
Expect(actualRef).To(Equal(fakeRefReturn))
Expect(err).To(BeNil())
})
})

})
22 changes: 22 additions & 0 deletions objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,28 @@ func NewZoneAuth(za ZoneAuth) *ZoneAuth {
return &res
}

type NameServer struct {
Address string `json:"address,omitempty"`
Name string `json:"name,omitempty"`
}

type ZoneDelegated struct {
IBBase `json:"-"`
Ref string `json:"_ref,omitempty"`
Fqdn string `json:"fqdn,omitempty"`
DelegateTo []NameServer `json:"delegate_to,omitempty"`
View string `json:"view,omitempty"`
Ea EA `json:"extattrs,omitempty"`
}

func NewZoneDelegated(za ZoneDelegated) *ZoneDelegated {
res := za
res.objectType = "zone_delegated"
res.returnFields = []string{"extattrs", "fqdn", "view"}

return &res
}

func (ea EA) MarshalJSON() ([]byte, error) {
m := make(map[string]interface{})
for k, v := range ea {
Expand Down
19 changes: 19 additions & 0 deletions objects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,25 @@ var _ = Describe("Objects", func() {
})
})

Context("ZoneDelegated object", func() {
fqdn := "delegated_zone.domain.com"
view := "default"

za := NewZoneDelegated(ZoneDelegated{
Fqdn: fqdn,
View: view})

It("should set fields correctly", func() {
Expect(za.Fqdn).To(Equal(fqdn))
Expect(za.View).To(Equal(view))
})

It("should set base fields correctly", func() {
Expect(za.ObjectType()).To(Equal("zone_delegated"))
Expect(za.ReturnFields()).To(ConsistOf("extattrs", "fqdn", "view"))
})
})

})

Context("Unmarshalling malformed JSON", func() {
Expand Down

0 comments on commit 1da13c0

Please sign in to comment.