@@ -28,7 +28,9 @@ import (
2828 "reflect"
2929 "strconv"
3030 "strings"
31+ "time"
3132
33+ "github.com/AbsaOSS/external-dns-infoblox-webhook/internal/metrics"
3234 ibclient "github.com/infobloxopen/infoblox-go-client/v2"
3335 log "github.com/sirupsen/logrus"
3436
@@ -199,6 +201,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
199201 objA .Zone = zone .Fqdn
200202 err = PagingGetObject (p .client , objA , "" , searchParams , & resA )
201203 if err != nil && ! isNotFoundError (err ) {
204+ metrics .FailedApiCallsTotal .Inc ()
202205 return nil , fmt .Errorf ("could not fetch A records from zone '%s': %w" , zone .Fqdn , err )
203206 }
204207 endpointsA := ToAResponseMap (resA ).ToEndpoints ()
@@ -212,6 +215,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
212215 objH .Zone = zone .Fqdn
213216 err = PagingGetObject (p .client , objH , "" , searchParams , & resH )
214217 if err != nil && ! isNotFoundError (err ) {
218+ metrics .FailedApiCallsTotal .Inc ()
215219 return nil , fmt .Errorf ("could not fetch host records from zone '%s': %w" , zone .Fqdn , err )
216220 }
217221 endpointsHost := ToHostResponseMap (resH ).ToEndpoints ()
@@ -224,6 +228,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
224228 objC .Zone = zone .Fqdn
225229 err = PagingGetObject (p .client , objC , "" , searchParams , & resC )
226230 if err != nil && ! isNotFoundError (err ) {
231+ metrics .FailedApiCallsTotal .Inc ()
227232 return nil , fmt .Errorf ("could not fetch CNAME records from zone '%s': %w" , zone .Fqdn , err )
228233 }
229234 endpointsCNAME := ToCNAMEResponseMap (resC ).ToEndpoints ()
@@ -236,6 +241,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
236241 objT .Zone = zone .Fqdn
237242 err = PagingGetObject (p .client , objT , "" , searchParams , & resT )
238243 if err != nil && ! isNotFoundError (err ) {
244+ metrics .FailedApiCallsTotal .Inc ()
239245 return nil , fmt .Errorf ("could not fetch TXT records from zone '%s': %w" , zone .Fqdn , err )
240246 }
241247 endpointsTXT := ToTXTResponseMap (resT ).ToEndpoints ()
@@ -247,6 +253,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
247253 objNS .Zone = zone .Fqdn
248254 err = PagingGetObject (p .client , objNS , "" , searchParams , & resNS )
249255 if err != nil && ! isNotFoundError (err ) {
256+ metrics .FailedApiCallsTotal .Inc ()
250257 return nil , fmt .Errorf ("could not fetch NS records from zone '%s': %w" , zone .Fqdn , err )
251258 }
252259 endpointsNS := ToNSResponseMap (resNS ).ToEndpoints ()
@@ -262,6 +269,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
262269 objP .Zone = arpaZone
263270 err = PagingGetObject (p .client , objP , "" , map [string ]string {"zone" : arpaZone , "view" : p .config .View }, & resP )
264271 if err != nil && ! isNotFoundError (err ) {
272+ metrics .FailedApiCallsTotal .Inc ()
265273 return nil , fmt .Errorf ("could not fetch PTR records from zone '%s': %w" , zone .Fqdn , err )
266274 }
267275 endpointsPTR := ToPTRResponseMap (resP ).ToEndpoints ()
@@ -371,6 +379,7 @@ func (p *Provider) submitChanges(changes []*infobloxChange) error {
371379
372380 zones , err := p .zones ()
373381 if err != nil {
382+ metrics .FailedApiCallsTotal .Inc ()
374383 return fmt .Errorf ("could not fetch zones: %w" , err )
375384 }
376385
@@ -399,14 +408,24 @@ func (p *Provider) submitChanges(changes []*infobloxChange) error {
399408
400409 log .WithFields (logFields ).Info ("Changing record" )
401410 var actionErr error
411+ startTime := time .Now ()
402412
403413 switch change .Action {
404414 case infobloxCreate :
405415 _ , actionErr = p .client .CreateObject (record .obj )
416+ duration := time .Since (startTime )
417+ metrics .ApiCallLatency .WithLabelValues ("GetObject" ).Observe (duration .Seconds ())
418+ metrics .TotalApiCalls .Inc ()
406419 case infobloxDelete :
407420 _ , actionErr = p .client .DeleteObject (refId )
421+ duration := time .Since (startTime )
422+ metrics .ApiCallLatency .WithLabelValues ("DeleteObject" ).Observe (duration .Seconds ())
423+ metrics .TotalApiCalls .Inc ()
408424 case infobloxUpdate :
409425 _ , actionErr = p .client .UpdateObject (record .obj , refId )
426+ duration := time .Since (startTime )
427+ metrics .ApiCallLatency .WithLabelValues ("UpdateObject" ).Observe (duration .Seconds ())
428+ metrics .TotalApiCalls .Inc ()
410429 default :
411430 actionErr = fmt .Errorf ("unknown action '%s'" , change .Action )
412431 }
@@ -600,6 +619,7 @@ func (p *Provider) zones() ([]ibclient.ZoneAuth, error) {
600619 }
601620 err := PagingGetObject (p .client , obj , "" , searchFields , & res )
602621 if err != nil && ! isNotFoundError (err ) {
622+ metrics .FailedApiCallsTotal .Inc ()
603623 return nil , err
604624 }
605625
@@ -695,13 +715,15 @@ func (p *Provider) findReverseZone(zones []*ibclient.ZoneAuth, name string) *ibc
695715
696716func (p * Provider ) recordSet (ep * endpoint.Endpoint , getObject bool ) (recordSet infobloxRecordSet , err error ) {
697717 var ttl uint32
718+ var startTime time.Time
698719 if ep .RecordTTL .IsConfigured () {
699720 ttl = uint32 (ep .RecordTTL )
700721 }
701722 extAttrs , err := deserializeEAs (p .config .ExtAttrsJSON )
702723 if err != nil {
703724 return
704725 }
726+ startTime = time .Now ()
705727 ptrToBoolTrue := true
706728 switch ep .RecordType {
707729 case endpoint .RecordTypeA :
@@ -716,10 +738,14 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
716738 if getObject {
717739 queryParams := ibclient .NewQueryParams (false , map [string ]string {"name" : * obj .Name , "ipv4addr" : * obj .Ipv4Addr })
718740 err = p .client .GetObject (obj , "" , queryParams , & res )
741+ duration := time .Since (startTime )
742+ metrics .TotalApiCalls .Inc ()
719743 if err != nil && ! isNotFoundError (err ) {
744+ metrics .FailedApiCallsTotal .Inc ()
720745 err = fmt .Errorf ("could not fetch A record ['%s':'%s'] : %w" , * obj .Name , * obj .Ipv4Addr , err )
721746 return
722747 }
748+ metrics .ApiCallLatency .WithLabelValues ("GetObjectA" ).Observe (duration .Seconds ())
723749 } else {
724750 // If getObject is not set (action == create), we need to set the View for Infoblox to find the parent zone
725751 // If View is set for the other actions, Infoblox will complain that the view field is not allowed
@@ -741,9 +767,14 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
741767 if getObject {
742768 queryParams := ibclient .NewQueryParams (false , map [string ]string {"ptrdname" : * obj .PtrdName , "ipv4addr" : * obj .Ipv4Addr })
743769 err = p .client .GetObject (obj , "" , queryParams , & res )
770+ duration := time .Since (startTime )
771+ metrics .TotalApiCalls .Inc ()
744772 if err != nil && ! isNotFoundError (err ) {
773+ metrics .FailedApiCallsTotal .Inc ()
745774 return
746775 }
776+ metrics .ApiCallLatency .WithLabelValues ("GetObjectPTR" ).Observe (duration .Seconds ())
777+
747778 } else {
748779 // If getObject is not set (action == create), we need to set the View for Infoblox to find the parent zone
749780 // If View is set for the other actions, Infoblox will complain that the view field is not allowed
@@ -764,9 +795,13 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
764795 if getObject {
765796 queryParams := ibclient .NewQueryParams (false , map [string ]string {"name" : * obj .Name })
766797 err = p .client .GetObject (obj , "" , queryParams , & res )
798+ duration := time .Since (startTime )
799+ metrics .TotalApiCalls .Inc ()
767800 if err != nil && ! isNotFoundError (err ) {
801+ metrics .FailedApiCallsTotal .Inc ()
768802 return
769803 }
804+ metrics .ApiCallLatency .WithLabelValues ("GetObjectCNAME" ).Observe (duration .Seconds ())
770805 } else {
771806 // If getObject is not set (action == create), we need to set the View for Infoblox to find the parent zone
772807 // If View is set for the other actions, Infoblox will complain that the view field is not allowed
@@ -784,9 +819,13 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
784819 if getObject {
785820 queryParams := ibclient .NewQueryParams (false , map [string ]string {"name" : obj .Name })
786821 err = p .client .GetObject (obj , "" , queryParams , & res )
822+ duration := time .Since (startTime )
823+ metrics .TotalApiCalls .Inc ()
787824 if err != nil && ! isNotFoundError (err ) {
825+ metrics .FailedApiCallsTotal .Inc ()
788826 return
789827 }
828+ metrics .ApiCallLatency .WithLabelValues ("GetObjectNS" ).Observe (duration .Seconds ())
790829 } else {
791830 // If getObject is not set (action == create), we need to set the View for Infoblox to find the parent zone
792831 // If View is set for the other actions, Infoblox will complain that the view field is not allowed
@@ -813,9 +852,13 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
813852 if getObject {
814853 queryParams := ibclient .NewQueryParams (false , map [string ]string {"name" : * obj .Name })
815854 err = p .client .GetObject (obj , "" , queryParams , & res )
855+ duration := time .Since (startTime )
856+ metrics .TotalApiCalls .Inc ()
816857 if err != nil && ! isNotFoundError (err ) {
858+ metrics .FailedApiCallsTotal .Inc ()
817859 return
818860 }
861+ metrics .ApiCallLatency .WithLabelValues ("GetObjectTXT" ).Observe (duration .Seconds ())
819862 } else {
820863 // If getObject is not set (action == create), we need to set the View for Infoblox to find the parent zone
821864 // If View is set for the other actions, Infoblox will complain that the view field is not allowed
0 commit comments