@@ -9,14 +9,13 @@ package netbox
9
9
10
10
import (
11
11
"fmt"
12
- "regexp"
13
- "strconv"
14
12
"strings"
15
13
"sync"
16
14
"sync/atomic"
17
15
"time"
18
16
19
17
dbModel "github.com/cloudflare/octopus/pkg/connector/netbox/model"
18
+ nbUtils "github.com/cloudflare/octopus/pkg/connector/netbox/utils"
20
19
"github.com/cloudflare/octopus/pkg/model"
21
20
"github.com/cloudflare/octopus/proto/octopus"
22
21
@@ -29,10 +28,6 @@ const (
29
28
updateInterval = time .Minute * 2
30
29
)
31
30
32
- var (
33
- ifNameTagsRegexp = regexp .MustCompile (`^(?P<intf_name>.+?)\.((?P<outer_tag>\d+)\.)?(?P<inner_tag>\d+)$` )
34
- )
35
-
36
31
type NetboxConnector struct {
37
32
connectorMu sync.RWMutex
38
33
client NetboxClientI
@@ -192,7 +187,7 @@ func (n *NetboxConnector) addDevices(t *model.Topology) error {
192
187
topoDev .Role = d .DeviceRole .Slug
193
188
topoDev .DeviceType = d .DeviceType .Slug
194
189
195
- md , err := metaDataFromTags (d .Tags )
190
+ md , err := nbUtils . GetMetaDataFromTags (d .Tags )
196
191
if err != nil {
197
192
return fmt .Errorf ("unable to get meta data: %v" , err )
198
193
}
@@ -218,7 +213,7 @@ func (n *NetboxConnector) addInterfaces(t *model.Topology) error {
218
213
t .DevicesByInterfaceID [nbIfa .ID ] = d
219
214
t .Interfaces [nbIfa .ID ] = ifa
220
215
221
- md , err := metaDataFromTags (nbIfa .Tags )
216
+ md , err := nbUtils . GetMetaDataFromTags (nbIfa .Tags )
222
217
if err != nil {
223
218
return fmt .Errorf ("unable to get meta data: %v" , err )
224
219
}
@@ -255,15 +250,15 @@ func (n *NetboxConnector) addInterfaceUnits(t *model.Topology) error {
255
250
return fmt .Errorf ("can not find interface %s:%s" , nbIfa .Device .Name , nbIfa .Parent .Name )
256
251
}
257
252
258
- vlanTag , err := parseUnitStr (unitStr )
253
+ vlanTag , err := nbUtils . ParseUnitStr (unitStr )
259
254
if err != nil {
260
- return fmt .Errorf ("Unable to convert unit %q (id=%d) (interface %q) to int for %s:%s. Ignoring logical interface. " , unitStr , nbIfa .ID , nbIfa .Name , nbIfa .Device .Name , nbIfa .Parent .Name )
255
+ return fmt .Errorf ("unable to convert unit %q (id=%d) (interface %q) to int for %s:%s. Ignoring logical interface" , unitStr , nbIfa .ID , nbIfa .Name , nbIfa .Device .Name , nbIfa .Parent .Name )
261
256
}
262
257
263
258
u := ifa .AddUnitIfNotExists (vlanTag )
264
259
t .DevicesByInterfaceID [nbIfa .ID ] = d
265
260
266
- md , err := metaDataFromTags (nbIfa .Tags )
261
+ md , err := nbUtils . GetMetaDataFromTags (nbIfa .Tags )
267
262
if err != nil {
268
263
return fmt .Errorf ("unable to get meta data: %v" , err )
269
264
}
@@ -274,34 +269,6 @@ func (n *NetboxConnector) addInterfaceUnits(t *model.Topology) error {
274
269
return nil
275
270
}
276
271
277
- func parseUnitStr (unitStr string ) (model.VLANTag , error ) {
278
- if strings .Contains (unitStr , "." ) {
279
- parts := strings .Split (unitStr , "." )
280
- if len (parts ) != 2 {
281
- return model.VLANTag {}, fmt .Errorf ("invalid unit string %q" , unitStr )
282
- }
283
-
284
- outerTag , err := strconv .Atoi (parts [0 ])
285
- if err != nil {
286
- return model.VLANTag {}, fmt .Errorf ("unable to convert %q to int: %v" , parts [0 ], err )
287
- }
288
-
289
- innerTag , err := strconv .Atoi (parts [1 ])
290
- if err != nil {
291
- return model.VLANTag {}, fmt .Errorf ("unable to convert %q to int: %v" , parts [1 ], err )
292
- }
293
-
294
- return model .NewVLANTag (uint16 (outerTag ), uint16 (innerTag )), nil
295
- }
296
-
297
- ctag , err := strconv .Atoi (unitStr )
298
- if err != nil {
299
- return model.VLANTag {}, fmt .Errorf ("unable to convert %q to int: %v" , unitStr , err )
300
- }
301
-
302
- return model .NewVLANTag (0 , uint16 (ctag )), nil
303
- }
304
-
305
272
func (n * NetboxConnector ) addIPAddresses (t * model.Topology ) error {
306
273
for _ , nbIP := range n .ipAddresses {
307
274
if nbIP .AssignedObjectID == 0 || nbIP .AssignedObjectTypeID != n .client .GetDcimInterfaceTypeID () {
@@ -323,18 +290,18 @@ func (n *NetboxConnector) addIPAddresses(t *model.Topology) error {
323
290
return fmt .Errorf ("interface with id %d not found" , ifaID )
324
291
}
325
292
326
- _ , vt , err := getInterfaceAndVLANTag (dcimIfa .Name )
293
+ _ , vt , err := nbUtils . GetInterfaceAndVLANTag (dcimIfa .Name )
327
294
if err != nil {
328
295
return fmt .Errorf ("unable to extract interface name and unit from %q: %v" , dcimIfa .Name , err )
329
296
}
330
297
331
- pfx , err := bnet .PrefixFromString (sanitizeIPAddress (nbIP .Address ))
298
+ pfx , err := bnet .PrefixFromString (nbUtils . SanitizeIPAddress (nbIP .Address ))
332
299
if err != nil {
333
300
return fmt .Errorf ("failed to parse IP %q: %v" , nbIP .Address , err )
334
301
}
335
302
336
303
ip := model .NewIP (* pfx )
337
- getCustomFieldData (ip .MetaData , nbIP .CustomFieldData )
304
+ nbUtils . GetCustomFieldData (ip .MetaData , nbIP .CustomFieldData )
338
305
339
306
u := ifa .AddUnitIfNotExists (vt )
340
307
if pfx .Addr ().IsIPv4 () {
@@ -347,26 +314,14 @@ func (n *NetboxConnector) addIPAddresses(t *model.Topology) error {
347
314
return nil
348
315
}
349
316
350
- func sanitizeIPAddress (addr string ) string {
351
- if strings .Contains (addr , "/" ) {
352
- return addr
353
- }
354
-
355
- if strings .Contains (addr , "." ) {
356
- return addr + "/32"
357
- }
358
-
359
- return addr + "/128"
360
- }
361
-
362
317
func (n * NetboxConnector ) addPrefixes (t * model.Topology ) error {
363
318
for _ , p := range n .prefixes {
364
319
pfx , err := bnet .PrefixFromString (p .Prefix )
365
320
if err != nil {
366
321
return fmt .Errorf ("failed to parse Prefix %q: %v" , p .Prefix , err )
367
322
}
368
323
369
- md , err := metaDataFromTags (p .Tags )
324
+ md , err := nbUtils . GetMetaDataFromTags (p .Tags )
370
325
if err != nil {
371
326
return fmt .Errorf ("failed to get Tags for Prefix %q: %v" , p .Prefix , err )
372
327
}
@@ -380,36 +335,6 @@ func (n *NetboxConnector) addPrefixes(t *model.Topology) error {
380
335
return nil
381
336
}
382
337
383
- func metaDataFromTags (tags []string ) (* model.MetaData , error ) {
384
- ret := model .NewMetaData ()
385
- for _ , tag := range tags {
386
- parts := strings .Split (tag , "=" )
387
-
388
- // Semantic Tag
389
- if len (parts ) == 2 {
390
- if _ , exists := ret .SemanticTags [parts [0 ]]; exists {
391
- return nil , fmt .Errorf ("Key %q exists already: %q vs. %q" , parts [0 ], ret .SemanticTags [parts [0 ]], parts [1 ])
392
- }
393
-
394
- ret .SemanticTags [parts [0 ]] = parts [1 ]
395
-
396
- } else {
397
- // Regular Tag
398
- ret .Tags = append (ret .Tags , tag )
399
- }
400
- }
401
-
402
- return ret , nil
403
- }
404
-
405
- func getCustomFieldData (md * model.MetaData , customFieldData string ) {
406
- if customFieldData == "" || customFieldData == "{}" {
407
- return
408
- }
409
-
410
- md .CustomFieldData = customFieldData
411
- }
412
-
413
338
func (n * NetboxConnector ) getCableEnd (terminationType int32 , terminationID int64 , t * model.Topology ) (* model.CableEnd , error ) {
414
339
ce := model.CableEnd {}
415
340
@@ -483,7 +408,7 @@ func (n *NetboxConnector) getCableEnd(terminationType int32, terminationID int64
483
408
484
409
default :
485
410
// consoleport, consoleserverport, powerport, or poweroutlet
486
- return nil , fmt .Errorf ("Don 't know what to do with cable termination ID %d (type %d)" , terminationID , terminationType )
411
+ return nil , fmt .Errorf ("don 't know what to do with cable termination ID %d (type %d)" , terminationID , terminationType )
487
412
}
488
413
489
414
return & ce , nil
@@ -528,7 +453,7 @@ func (n *NetboxConnector) addRearPorts(t *model.Topology) error {
528
453
for _ , rp := range n .rearPorts {
529
454
nbDev := n .devices [rp .DeviceID ]
530
455
if nbDev == nil {
531
- return fmt .Errorf ("Device %d not found" , rp .DeviceID )
456
+ return fmt .Errorf ("device %d not found" , rp .DeviceID )
532
457
}
533
458
534
459
d := t .GetDevice (nbDev .Name )
@@ -549,7 +474,7 @@ func (n *NetboxConnector) addFrontPorts(t *model.Topology) error {
549
474
for _ , fp := range n .frontPorts {
550
475
nbDev := n .devices [fp .DeviceID ]
551
476
if nbDev == nil {
552
- return fmt .Errorf ("Device %d not found" , fp .DeviceID )
477
+ return fmt .Errorf ("device %d not found" , fp .DeviceID )
553
478
}
554
479
555
480
d := t .GetDevice (nbDev .Name )
@@ -573,62 +498,6 @@ func (n *NetboxConnector) addFrontPorts(t *model.Topology) error {
573
498
return nil
574
499
}
575
500
576
- func getInterfaceAndVLANTag (name string ) (ifName string , vt model.VLANTag , err error ) {
577
- if isLogicalInterface (name ) {
578
- return extractInterfaceAndUnit (name )
579
- }
580
-
581
- return name , model.VLANTag {}, nil
582
- }
583
-
584
- func isLogicalInterface (name string ) bool {
585
- return strings .Contains (name , "." )
586
- }
587
-
588
- func extractInterfaceAndUnit (name string ) (string , model.VLANTag , error ) {
589
- extractedVars := reSubMatchMap (ifNameTagsRegexp , name )
590
- if _ , exists := extractedVars ["intf_name" ]; ! exists {
591
- return "" , model.VLANTag {}, fmt .Errorf ("unable to extract interface name from %q" , name )
592
- }
593
-
594
- if _ , exists := extractedVars ["inner_tag" ]; ! exists {
595
- return "" , model.VLANTag {}, fmt .Errorf ("unable to extract inner tag from %q" , name )
596
- }
597
-
598
- innerTag , err := strconv .Atoi (extractedVars ["inner_tag" ])
599
- if err != nil {
600
- return "" , model.VLANTag {}, fmt .Errorf ("unable to convert inner tag from string %q to int (%q)" , extractedVars ["inner_tag" ], name )
601
- }
602
-
603
- vt := model.VLANTag {
604
- InnerTag : uint16 (innerTag ),
605
- }
606
-
607
- outerTagStr := extractedVars ["outer_tag" ]
608
- if outerTagStr != "" {
609
- outerTag , err := strconv .Atoi (outerTagStr )
610
- if err != nil {
611
- return "" , model.VLANTag {}, fmt .Errorf ("unable to convert outer tag from string %q to int (%q)" , outerTagStr , name )
612
- }
613
-
614
- vt .OuterTag = uint16 (outerTag )
615
- }
616
-
617
- return extractedVars ["intf_name" ], vt , nil
618
- }
619
-
620
- func reSubMatchMap (r * regexp.Regexp , str string ) map [string ]string {
621
- match := r .FindStringSubmatch (str )
622
- subMatchMap := make (map [string ]string )
623
- for i , name := range r .SubexpNames () {
624
- if i != 0 && name != "" && i <= len (match ) {
625
- subMatchMap [name ] = match [i ]
626
- }
627
- }
628
-
629
- return subMatchMap
630
- }
631
-
632
501
func (n * NetboxConnector ) StartRefreshRoutine () {
633
502
go n .refreshRoutine ()
634
503
}
0 commit comments