AliceLG - Configurable timeout for GoBGP gRPC calls
This commit is contained in:
parent
afc7baf79c
commit
faae66f275
25
README.md
25
README.md
@ -19,7 +19,9 @@ Alice-LG is a BGP looking glass which gets its data from external APIs.
|
||||
|
||||
Currently Alice-LG supports the following APIs:
|
||||
- [birdwatcher API](https://github.com/alice-lg/birdwatcher) for [BIRD](http://bird.network.cz/)
|
||||
- [GoBGP](https://osrg.github.io/gobgp/)
|
||||
|
||||
### Birdwatcher
|
||||
Normally you would first install the [birdwatcher API](https://github.com/alice-lg/birdwatcher) directly on the machine(s) where you run [BIRD](http://bird.network.cz/) on
|
||||
and then install Alice-LG on a seperate public facing server and point her to the afore mentioned [birdwatcher API](https://github.com/alice-lg/birdwatcher).
|
||||
|
||||
@ -28,6 +30,9 @@ just prior to [RIPE73](https://ripe73.ripe.net/) in Madrid, Spain.
|
||||
|
||||
Major thanks to Barry O'Donovan who built the original [INEX Bird's Eye](https://github.com/inex/birdseye) BIRD API of which Alice-LG is a spinnoff
|
||||
|
||||
### GoBGP
|
||||
Alice-LG supports direct integration with GoBGP instances using gRPC. See the configuration section for more detail.
|
||||
|
||||
## Building Alice-LG from scratch
|
||||
__These examples include setting up your Go environment, if you already have set that up then you can obviously skip that__
|
||||
|
||||
@ -74,8 +79,9 @@ You can copy it to any of the following locations:
|
||||
/etc/alice-lg/alice.conf # global
|
||||
|
||||
|
||||
You will have to edit the configuration file as you need to point Alice-LG to the correct [APIs](https://github.com/alice-lg/birdwatcher):
|
||||
You will have to edit the configuration file as you need to point Alice-LG to the correct backend source. Multiple sources can be configured.
|
||||
|
||||
[Birdwatcher](https://github.com/alice-lg/birdwatcher):
|
||||
```ini
|
||||
[source.rs1-example-v4]
|
||||
name = rs1.example.com (IPv4)
|
||||
@ -95,6 +101,23 @@ name = rs1.example.com (IPv6)
|
||||
api = http://rs1.example.com:29186/
|
||||
```
|
||||
|
||||
[GoBGP](https://osrg.github.io/gobgp/):
|
||||
```ini
|
||||
[source.rs2-example]
|
||||
name = rs2.example.com
|
||||
group = AMS
|
||||
|
||||
[source.rs2-example.gobgp]
|
||||
# Host is the IP (or DNS name) and port for the remote GoBGP daemon
|
||||
host = rs2.example.com:50051
|
||||
# ProcessingTimeout is a timeout in seconds configured per gRPC call to a given GoBGP daemon
|
||||
processing_timeout = 300
|
||||
type = multi_table
|
||||
peer_table_prefix = T
|
||||
pipe_protocol_prefix = M
|
||||
neighbors_refresh_timeout = 2
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
Launch the server by running
|
||||
|
@ -2,6 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/alice-lg/alice-lg/backend/sources/birdwatcher"
|
||||
"github.com/alice-lg/alice-lg/backend/sources/gobgp"
|
||||
)
|
||||
|
||||
// Test configuration loading and parsing
|
||||
@ -37,6 +40,42 @@ func TestLoadConfigs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestSourceConfig checks that the proper backend type was identified for each
|
||||
// example routeserver
|
||||
func TestSourceConfig(t *testing.T) {
|
||||
|
||||
config, err := loadConfig("../etc/alice-lg/alice.example.conf")
|
||||
if err != nil {
|
||||
t.Error("Could not load test config:", err)
|
||||
}
|
||||
|
||||
// Get sources
|
||||
rs1 := config.Sources[0] // Birdwatcher v4
|
||||
rs2 := config.Sources[1] // Birdwatcher v6
|
||||
rs3 := config.Sources[2] // GoBGP
|
||||
|
||||
nilBirdwatcherConfig := birdwatcher.Config{}
|
||||
if rs1.Birdwatcher == nilBirdwatcherConfig {
|
||||
t.Errorf(
|
||||
"Example routeserver %s should have been identified as a birdwatcher source but was not",
|
||||
rs1.Name,
|
||||
)
|
||||
}
|
||||
if rs2.Birdwatcher == nilBirdwatcherConfig {
|
||||
t.Errorf(
|
||||
"Example routeserver %s should have been identified as a birdwatcher source but was not",
|
||||
rs2.Name,
|
||||
)
|
||||
}
|
||||
nilGoBGPConfig := gobgp.Config{}
|
||||
if rs3.GoBGP == nilGoBGPConfig {
|
||||
t.Errorf(
|
||||
"Example routeserver %s should have been identified as a gobgp source but was not",
|
||||
rs3.Name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceConfigDefaultsOverride(t *testing.T) {
|
||||
|
||||
config, err := loadConfig("../etc/alice-lg/alice.example.conf")
|
||||
@ -45,8 +84,9 @@ func TestSourceConfigDefaultsOverride(t *testing.T) {
|
||||
}
|
||||
|
||||
// Get sources
|
||||
rs1 := config.Sources[0]
|
||||
rs2 := config.Sources[1]
|
||||
rs1 := config.Sources[0] // Birdwatcher v4
|
||||
rs2 := config.Sources[1] // Birdwatcher v6
|
||||
rs3 := config.Sources[2] // GoBGP
|
||||
|
||||
// Source 1 should be on default time
|
||||
// Source 2 should have an override
|
||||
@ -67,6 +107,13 @@ func TestSourceConfigDefaultsOverride(t *testing.T) {
|
||||
if rs2.Birdwatcher.Timezone != "Europe/Brussels" {
|
||||
t.Error("Expected 'Europe/Brussels', got", rs2.Birdwatcher.Timezone)
|
||||
}
|
||||
|
||||
if rs3.GoBGP.ProcessingTimeout != 300 {
|
||||
t.Error(
|
||||
"Expected GoBGP example to set 300s 'processing_timeout', got",
|
||||
rs3.GoBGP.ProcessingTimeout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectAndNoexportReasons(t *testing.T) {
|
||||
|
@ -4,8 +4,10 @@ type Config struct {
|
||||
Id string
|
||||
Name string
|
||||
|
||||
Host string `ini:"host"`
|
||||
Insecure bool `ini:"insecure"`
|
||||
TLSCert string `ini:"tls_crt"`
|
||||
TLSCommonName string `ini:"tls_common_name"`
|
||||
Host string `ini:"host"`
|
||||
Insecure bool `ini:"insecure"`
|
||||
// ProcessingTimeout is a timeout in seconds configured per gRPC call to a given GoBGP daemon
|
||||
ProcessingTimeout int `ini:"processing_timeout"`
|
||||
TLSCert string `ini:"tls_crt"`
|
||||
TLSCommonName string `ini:"tls_common_name"`
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func (gobgp *GoBGP) lookupNeighbour(neighborId string) (*gobgpapi.Peer, error) {
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) GetNeighbours() ([]*gobgpapi.Peer, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(gobgp.config.ProcessingTimeout))
|
||||
defer cancel()
|
||||
|
||||
peerStream, err := gobgp.client.ListPeer(ctx, &gobgpapi.ListPeerRequest{EnableAdvertised: true})
|
||||
@ -144,7 +144,7 @@ func (gobgp *GoBGP) parsePathIntoRoute(path *gobgpapi.Path, prefix string) (erro
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) GetRoutes(peer *gobgpapi.Peer, tableType gobgpapi.TableType, response *api.RoutesResponse) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(gobgp.config.ProcessingTimeout))
|
||||
defer cancel()
|
||||
|
||||
for _, family := range families {
|
||||
|
@ -88,7 +88,7 @@ func (gobgp *GoBGP) ExpireCaches() int {
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) NeighboursStatus() (*api.NeighboursStatusResponse, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(gobgp.config.ProcessingTimeout))
|
||||
defer cancel()
|
||||
|
||||
response := api.NeighboursStatusResponse{}
|
||||
@ -123,7 +123,7 @@ func (gobgp *GoBGP) NeighboursStatus() (*api.NeighboursStatusResponse, error) {
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) Status() (*api.StatusResponse, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(gobgp.config.ProcessingTimeout))
|
||||
defer cancel()
|
||||
|
||||
resp, err := gobgp.client.GetBgp(ctx, &gobgpapi.GetBgpRequest{})
|
||||
@ -138,7 +138,7 @@ func (gobgp *GoBGP) Status() (*api.StatusResponse, error) {
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) Neighbours() (*api.NeighboursResponse, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(gobgp.config.ProcessingTimeout))
|
||||
defer cancel()
|
||||
|
||||
response := api.NeighboursResponse{}
|
||||
|
@ -139,7 +139,7 @@ routeserver.name = RS
|
||||
|
||||
|
||||
# Routeservers
|
||||
|
||||
# Birdwatcher Example
|
||||
[source.rs0-example-v4]
|
||||
name = rs1.example.com (IPv4)
|
||||
# Optional: a group for the routeservers list
|
||||
@ -158,7 +158,6 @@ neighbors_refresh_timeout = 2
|
||||
# Optional:
|
||||
show_last_reboot = true
|
||||
|
||||
|
||||
[source.rs1-example-v6]
|
||||
name = rs1.example.com (IPv6)
|
||||
[source.rs1-example-v6.birdwatcher]
|
||||
@ -177,3 +176,20 @@ neighbors_refresh_timeout = 2
|
||||
servertime = 2006-01-02T15:04:05Z07:00
|
||||
servertime_short = 02.01.2006
|
||||
servertime_ext = Mon, 02 Jan 2006 15:04:05 -0700
|
||||
|
||||
|
||||
# Routeservers
|
||||
# GoBGP Example
|
||||
[source.rs2-example]
|
||||
name = rs2.example.com
|
||||
group = AMS
|
||||
|
||||
[source.rs2-example.gobgp]
|
||||
# host is the IP (or DNS name) and port for the remote GoBGP daemon
|
||||
host = rs2.example.com:50051
|
||||
# processing_timeout is a timeout in seconds configured per gRPC call to a given GoBGP daemon
|
||||
processing_timeout = 300
|
||||
type = multi_table
|
||||
peer_table_prefix = T
|
||||
pipe_protocol_prefix = M
|
||||
neighbors_refresh_timeout = 2
|
Loading…
x
Reference in New Issue
Block a user