@@ -24,6 +24,7 @@ import (
2424 "sync"
2525 "time"
2626
27+ "github.com/prometheus/client_golang/prometheus"
2728 "k8s.io/apimachinery/pkg/util/sets"
2829 "k8s.io/client-go/tools/cache"
2930 glog "k8s.io/klog"
@@ -59,9 +60,11 @@ type crdIpam struct {
5960 ipType Type
6061 //caches for FloatingIP crd, both stores allocated FloatingIPs and unallocated FloatingIPs
6162 cacheLock * sync.RWMutex
62- // key is FloatingIP name ( ip typed as uint32)
63+ // key is ip string
6364 allocatedFIPs map [string ]* FloatingIP
6465 unallocatedFIPs map [string ]* FloatingIP
66+
67+ ipCounterDesc * prometheus.Desc
6568}
6669
6770// NewCrdIPAM init IPAM struct.
@@ -72,6 +75,8 @@ func NewCrdIPAM(fipClient crd_clientset.Interface, ipType Type, informer crdInfo
7275 cacheLock : new (sync.RWMutex ),
7376 allocatedFIPs : make (map [string ]* FloatingIP ),
7477 unallocatedFIPs : make (map [string ]* FloatingIP ),
78+ ipCounterDesc : prometheus .NewDesc ("galaxy_ip_counter" , "Galaxy floating ip counter" ,
79+ []string {"type" , "subnet" , "first_ip" }, nil ),
7580 }
7681 // manually creating and fip to reserve it
7782 if informer != nil {
@@ -257,9 +262,13 @@ func (ci *crdIpam) Release(key string, ip net.IP) error {
257262
258263// First returns the first matched IP by key.
259264func (ci * crdIpam ) First (key string ) (* FloatingIPInfo , error ) {
260- fip , err := ci .findFloatingIPByKey (key )
261- if err != nil {
262- return nil , err
265+ ci .cacheLock .RLock ()
266+ defer ci .cacheLock .RUnlock ()
267+ var fip * FloatingIP
268+ for _ , spec := range ci .allocatedFIPs {
269+ if spec .Key == key {
270+ fip = spec
271+ }
263272 }
264273 if fip == nil {
265274 return nil , nil
@@ -317,6 +326,8 @@ func (ci *crdIpam) ByPrefix(prefix string) ([]FloatingIP, error) {
317326}
318327
319328func (ci * crdIpam ) NodeSubnet (nodeIP net.IP ) * net.IPNet {
329+ ci .cacheLock .RLock ()
330+ defer ci .cacheLock .RUnlock ()
320331 for j := range ci .FloatingIPs {
321332 nodeSubnets := ci .FloatingIPs [j ].NodeSubnets
322333 for k := range nodeSubnets {
@@ -463,17 +474,6 @@ func (ci *crdIpam) syncCacheAfterDel(released *FloatingIP) {
463474 return
464475}
465476
466- func (ci * crdIpam ) findFloatingIPByKey (key string ) (* FloatingIP , error ) {
467- ci .cacheLock .RLock ()
468- defer ci .cacheLock .RUnlock ()
469- for _ , spec := range ci .allocatedFIPs {
470- if spec .Key == key {
471- return spec , nil
472- }
473- }
474- return nil , nil
475- }
476-
477477func (ci * crdIpam ) filterAllocatedSubnet (key string ) sets.String {
478478 //key would not be empty
479479 subnetSet := sets .NewString ()
@@ -548,3 +548,45 @@ func (ci *crdIpam) ReleaseIPs(ipToKey map[string]string) (map[string]string, map
548548 }
549549 return deleted , undeleted , nil
550550}
551+
552+ // Describe sends metrics description to ch
553+ func (ci * crdIpam ) Describe (ch chan <- * prometheus.Desc ) {
554+ ch <- ci .ipCounterDesc
555+ }
556+
557+ // Collect sends metrics to ch
558+ func (ci * crdIpam ) Collect (ch chan <- prometheus.Metric ) {
559+ allocated , unallocated := map [string ]* FloatingIP {}, map [string ]* FloatingIP {}
560+ ci .cacheLock .RLock ()
561+ pools := make ([]* FloatingIPPool , len (ci .FloatingIPs ))
562+ for ipStr , fip := range ci .allocatedFIPs {
563+ allocated [ipStr ] = fip
564+ }
565+ for ipStr , fip := range ci .unallocatedFIPs {
566+ unallocated [ipStr ] = fip
567+ }
568+ for i := range ci .FloatingIPs {
569+ pools [i ] = ci .FloatingIPs [i ]
570+ }
571+ ci .cacheLock .RUnlock ()
572+ for _ , pool := range pools {
573+ subnetStr := pool .IPNet ().String ()
574+ var firstIP string
575+ var allocatedNum float64
576+ for _ , ipr := range pool .IPRanges {
577+ firstIP = ipr .First .String ()
578+ break
579+ }
580+ for _ , fip := range allocated {
581+ if ! pool .Contains (fip .IP ) {
582+ continue
583+ }
584+ allocatedNum += 1
585+ }
586+ // since subnetStr may be the same for different pools, add a first ip tag
587+ ch <- prometheus .MustNewConstMetric (ci .ipCounterDesc , prometheus .GaugeValue , allocatedNum ,
588+ "allocated" , subnetStr , firstIP )
589+ ch <- prometheus .MustNewConstMetric (ci .ipCounterDesc , prometheus .GaugeValue , float64 (pool .Size ()),
590+ "total" , subnetStr , firstIP )
591+ }
592+ }
0 commit comments