Skip to content
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
12 changes: 10 additions & 2 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import (
"github.com/spf13/viper"
)

type Filter string

const (
defaultListenAddress = "0.0.0.0"
defaultListenPort = 8080
localPath = "."

SiteFilter Filter = "site"
SiteGroupFilter Filter = "site_group"
SiteRegionFilter Filter = "region"
)

var (
Expand All @@ -21,8 +27,9 @@ var (
type Config struct {
Authentication AuthConfig
NetBox struct {
URL string
APIKey string
URL string
APIKey string
DatacenterFilterKey Filter
}
Log struct {
Level string
Expand Down Expand Up @@ -61,6 +68,7 @@ func setDefaults() {

viper.SetDefault("NetBox.URL", "")
viper.SetDefault("NetBox.APIKey", "")
viper.SetDefault("NetBox.DatacenterFilterKey", SiteFilter)

viper.SetDefault("Build.Interval", time.Minute)
viper.SetDefault("Build.AllDevicesMustBuild", false)
Expand Down
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/bgp_global.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// GetBGPGlobal returns all BGP global configuration from the Network CMDB.
func GetBGPGlobal() ([]*bgp.BGPGlobal, error) {
response := netbox.NetboxResponse[bgp.BGPGlobal]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/bgp-global/", &response)
err := netbox.Get("/api/plugins/cmdb/bgp-global/", &response, params)
if err != nil {
return nil, fmt.Errorf("BGP Global fetching failure: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/bgp_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// GetBGPSessions returns all BGP sessions from the Network CMDB.
func GetBGPSessions() ([]*bgp.Session, error) {
response := netbox.NetboxResponse[bgp.Session]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/bgp-sessions/", &response)
err := netbox.Get("/api/plugins/cmdb/bgp-sessions/", &response, params)
if err != nil {
return nil, fmt.Errorf("BGP Sessions fetching failure: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/community_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// GetCommunityLists returns all community-lists from the Network CMDB.
func GetCommunityLists() ([]*routingpolicy.CommunityList, error) {
response := netbox.NetboxResponse[routingpolicy.CommunityList]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/bgp-community-lists/", &response)
err := netbox.Get("/api/plugins/cmdb/bgp-community-lists/", &response, params)
if err != nil {
return nil, fmt.Errorf("BGP Community Lists fetching failure: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/peer_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (
// You should migrate to configuration without using peer-groups.
func GetPeerGroups() ([]*bgp.PeerGroup, error) {
response := netbox.NetboxResponse[bgp.PeerGroup]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/peer-groups/", &response)
err := netbox.Get("/api/plugins/cmdb/peer-groups/", &response, params)
if err != nil {
return nil, fmt.Errorf("peer-groups fetching failure: %w", err)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/prefix_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// GetPrefixLists returns all prefix-lists from the Network CMDB.
func GetPrefixLists() ([]*routingpolicy.PrefixList, error) {
response := netbox.NetboxResponse[routingpolicy.PrefixList]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/prefix-lists/", &response)
err := netbox.Get("/api/plugins/cmdb/prefix-lists/", &response, params)
if err != nil {
return nil, fmt.Errorf("prefix-lists fetching failure: %w", err)
}
Expand Down
28 changes: 28 additions & 0 deletions internal/ingestor/cmdb/query_param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmdb

import (
"net/url"

"github.com/criteo/data-aggregation-api/internal/config"
"github.com/rs/zerolog/log"
)

func deviceDatacenterFilter() url.Values {
datacenterFilter := ""

switch string(config.Cfg.NetBox.DatacenterFilterKey) {
case "site":
datacenterFilter = "device__site__name"
case "site_group":
datacenterFilter = "device__site__group__name"
case "region":
datacenterFilter = "device__site__region__name"
default:
log.Fatal().Msgf("unknown datacenter filter: %s", config.Cfg.NetBox.DatacenterFilterKey)
}

params := url.Values{}
params.Set(datacenterFilter, config.Cfg.Datacenter)

return params
}
3 changes: 2 additions & 1 deletion internal/ingestor/cmdb/route_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// GetRoutePolicies returns all route-policies defined in the CDMB.
func GetRoutePolicies() ([]*routingpolicy.RoutePolicy, error) {
response := netbox.NetboxResponse[routingpolicy.RoutePolicy]{}
params := deviceDatacenterFilter()

err := netbox.Get("/api/plugins/cmdb/route-policies/", &response)
err := netbox.Get("/api/plugins/cmdb/route-policies/", &response, params)
if err != nil {
return nil, fmt.Errorf("route-policies fetching failure: %w", err)
}
Expand Down
10 changes: 8 additions & 2 deletions internal/ingestor/dcim/network_inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package dcim

import (
"fmt"
"net/url"

"github.com/rs/zerolog/log"

"github.com/criteo/data-aggregation-api/internal/config"
"github.com/criteo/data-aggregation-api/internal/ingestor/netbox"
"github.com/criteo/data-aggregation-api/internal/model/dcim"
)
Expand All @@ -15,8 +17,12 @@ import (
func GetNetworkInventory() ([]*dcim.NetworkDevice, error) {
response := netbox.NetboxResponse[dcim.NetworkDevice]{}

if err := netbox.Get("/api/dcim/devices/?role__n=server", &response); err != nil {
return nil, fmt.Errorf("network inventory fetching failure: %s", err)
params := url.Values{}
params.Set(string(config.Cfg.NetBox.DatacenterFilterKey), config.Cfg.Datacenter)
params.Set("role__n", "server")

if err := netbox.Get("/api/dcim/devices/", &response, params); err != nil {
return nil, fmt.Errorf("network inventory fetching failure: %w", err)
}

if response.Count != len(response.Results) {
Expand Down
27 changes: 11 additions & 16 deletions internal/ingestor/netbox/netbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"strings"
"net/url"
"time"

"github.com/go-playground/validator/v10"
Expand All @@ -31,35 +31,30 @@ func NewGetRequest(url string) (*http.Request, error) {
}

// Get fetches a Netbox endpoint.
func Get[R any](endpoint string, out *NetboxResponse[R]) error {
func Get[R any](endpoint string, out *NetboxResponse[R], params url.Values) error {
const endpointKey = "endpoint"
client := http.Client{Timeout: 10 * 60 * time.Second}
sep := "?"

// TODO: use url.Values and url.JoinPath instead
if strings.Contains(endpoint, sep) {
sep = "&"
}
params.Set("limit", "0")
params.Set("ordering", "id")

datacenterFilter := ""
// TODO: implement filter on CMDB side!
if config.Cfg.Datacenter != "" {
datacenterFilter = "&site_group=" + strings.ToUpper(config.Cfg.Datacenter)
baseURL, err := url.JoinPath(config.Cfg.NetBox.URL, endpoint)
if err != nil {
return fmt.Errorf("failed to assemble URL: %w", err)
}

url := config.Cfg.NetBox.URL + endpoint + sep + "limit=0&ordering=id" + datacenterFilter
url := baseURL + "?" + params.Encode()
log.Info().Str(endpointKey, endpoint).Msgf("Get %s", url)

// Get all pages
for url != "" {
req, err := NewGetRequest(url)
if err != nil {
return err
return fmt.Errorf("failed to create request: %w", err)
}

data, err := client.Do(req)
if err != nil {
return err
return fmt.Errorf("failed to query netbox: %w", err)
}
defer func() {
if err := data.Body.Close(); err != nil {
Expand All @@ -74,7 +69,7 @@ func Get[R any](endpoint string, out *NetboxResponse[R]) error {
var buffer NetboxResponse[R]
err = json.NewDecoder(data.Body).Decode(&buffer)
if err != nil {
return err
return fmt.Errorf("failed to decode netbox response: %w", err)
}

out.Results = append(out.Results, buffer.Results...)
Expand Down
1 change: 1 addition & 0 deletions settings.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Authentication:
NetBox:
URL: "https://netbox.local"
APIKey: "<some_key>"
DatacenterFilterKey: "site_group"

Build:
Interval: "30m"