mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-10-17 21:01:06 +02:00
gobgp client in kube-router docker image does not show peer information
Gobgp 1.21 seems to have problem, so setting the version used to 1.20 Fixes #58
This commit is contained in:
parent
dec6bfa5f5
commit
2bdf657cfa
10
glide.lock
generated
10
glide.lock
generated
@ -1,5 +1,5 @@
|
||||
hash: aa4807befbaa3fa5d489feed6ecaca17a92edb6761f7a3aebfbb053f1c636754
|
||||
updated: 2017-07-12T21:49:20.87386587-05:00
|
||||
hash: ec07230b29cc1473d02179ae0a62534d03e5b4b7683e4227174a9296e7661081
|
||||
updated: 2017-07-14T02:08:26.222807645+05:30
|
||||
imports:
|
||||
- name: github.com/armon/go-radix
|
||||
version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2
|
||||
@ -125,7 +125,7 @@ imports:
|
||||
- name: github.com/opencontainers/go-digest
|
||||
version: 279bed98673dd5bef374d3b6e4b09e2af76183bf
|
||||
- name: github.com/osrg/gobgp
|
||||
version: 9f9a71eab2bc9f2fed0d7c32a05f74d4c42b12ae
|
||||
version: 3d01f04c8cb10ad91fb53e432d82ad9c4d8efff2
|
||||
subpackages:
|
||||
- api
|
||||
- config
|
||||
@ -147,7 +147,9 @@ imports:
|
||||
- name: github.com/satori/go.uuid
|
||||
version: 5bf94b69c6b68ee1b541973bb8e1144db23a194b
|
||||
- name: github.com/sirupsen/logrus
|
||||
version: 1fe8319fcaef78ef9220c9b05178df0f871dbc5d
|
||||
version: 51dc0fc64317a2861273909081f9c315786533eb
|
||||
- name: github.com/Sirupsen/logrus
|
||||
version: 51dc0fc64317a2861273909081f9c315786533eb
|
||||
- name: github.com/spf13/afero
|
||||
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
|
||||
subpackages:
|
||||
|
@ -15,7 +15,7 @@ import:
|
||||
- package: github.com/mqliang/libipvs
|
||||
version: master
|
||||
- package: github.com/osrg/gobgp
|
||||
version: ^1.17.0
|
||||
version: ~1.20
|
||||
subpackages:
|
||||
- api
|
||||
- config
|
||||
|
1
vendor/github.com/Sirupsen/logrus/.gitignore
generated
vendored
Normal file
1
vendor/github.com/Sirupsen/logrus/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
logrus
|
12
vendor/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
Normal file
12
vendor/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- tip
|
||||
env:
|
||||
- GOMAXPROCS=4 GORACE=halt_on_error=1
|
||||
install:
|
||||
- go get github.com/stretchr/testify/assert
|
||||
script:
|
||||
- go test -race -v .
|
109
vendor/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
Normal file
109
vendor/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
# 1.0.2
|
||||
|
||||
* bug: quote non-string values in text formatter (#583)
|
||||
* Make (*Logger) SetLevel a public method
|
||||
|
||||
# 1.0.1
|
||||
|
||||
* bug: fix escaping in text formatter (#575)
|
||||
|
||||
# 1.0.0
|
||||
|
||||
* Officially changed name to lower-case
|
||||
* bug: colors on Windows 10 (#541)
|
||||
* bug: fix race in accessing level (#512)
|
||||
|
||||
# 0.11.5
|
||||
|
||||
* feature: add writer and writerlevel to entry (#372)
|
||||
|
||||
# 0.11.4
|
||||
|
||||
* bug: fix undefined variable on solaris (#493)
|
||||
|
||||
# 0.11.3
|
||||
|
||||
* formatter: configure quoting of empty values (#484)
|
||||
* formatter: configure quoting character (default is `"`) (#484)
|
||||
* bug: fix not importing io correctly in non-linux environments (#481)
|
||||
|
||||
# 0.11.2
|
||||
|
||||
* bug: fix windows terminal detection (#476)
|
||||
|
||||
# 0.11.1
|
||||
|
||||
* bug: fix tty detection with custom out (#471)
|
||||
|
||||
# 0.11.0
|
||||
|
||||
* performance: Use bufferpool to allocate (#370)
|
||||
* terminal: terminal detection for app-engine (#343)
|
||||
* feature: exit handler (#375)
|
||||
|
||||
# 0.10.0
|
||||
|
||||
* feature: Add a test hook (#180)
|
||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
||||
* performance: avoid re-allocations on `WithFields` (#335)
|
||||
|
||||
# 0.9.0
|
||||
|
||||
* logrus/text_formatter: don't emit empty msg
|
||||
* logrus/hooks/airbrake: move out of main repository
|
||||
* logrus/hooks/sentry: move out of main repository
|
||||
* logrus/hooks/papertrail: move out of main repository
|
||||
* logrus/hooks/bugsnag: move out of main repository
|
||||
* logrus/core: run tests with `-race`
|
||||
* logrus/core: detect TTY based on `stderr`
|
||||
* logrus/core: support `WithError` on logger
|
||||
* logrus/core: Solaris support
|
||||
|
||||
# 0.8.7
|
||||
|
||||
* logrus/core: fix possible race (#216)
|
||||
* logrus/doc: small typo fixes and doc improvements
|
||||
|
||||
|
||||
# 0.8.6
|
||||
|
||||
* hooks/raven: allow passing an initialized client
|
||||
|
||||
# 0.8.5
|
||||
|
||||
* logrus/core: revert #208
|
||||
|
||||
# 0.8.4
|
||||
|
||||
* formatter/text: fix data race (#218)
|
||||
|
||||
# 0.8.3
|
||||
|
||||
* logrus/core: fix entry log level (#208)
|
||||
* logrus/core: improve performance of text formatter by 40%
|
||||
* logrus/core: expose `LevelHooks` type
|
||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
||||
* formatter/text: print structs more verbosely
|
||||
|
||||
# 0.8.2
|
||||
|
||||
* logrus: fix more Fatal family functions
|
||||
|
||||
# 0.8.1
|
||||
|
||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
||||
|
||||
# 0.8.0
|
||||
|
||||
* logrus: defaults to stderr instead of stdout
|
||||
* hooks/sentry: add special field for `*http.Request`
|
||||
* formatter/text: ignore Windows for colors
|
||||
|
||||
# 0.7.3
|
||||
|
||||
* formatter/\*: allow configuration of timestamp layout
|
||||
|
||||
# 0.7.2
|
||||
|
||||
* formatter/text: Add configuration option for time format (#158)
|
21
vendor/github.com/Sirupsen/logrus/LICENSE
generated
vendored
Normal file
21
vendor/github.com/Sirupsen/logrus/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
504
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
Normal file
504
vendor/github.com/Sirupsen/logrus/README.md
generated
vendored
Normal file
@ -0,0 +1,504 @@
|
||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
|
||||
|
||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||
the standard library logger. [Godoc][godoc].
|
||||
|
||||
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
||||
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
||||
this caused issues in the community and we needed a standard. Some environments
|
||||
experienced problems with the upper-case variant, so the lower-case was decided.
|
||||
Everything using `logrus` will need to use the lower-case:
|
||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
||||
|
||||
To fix Glide, see [these
|
||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
||||
For an in-depth explanation of the casing issue, see [this
|
||||
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
||||
|
||||
**Are you interested in assisting in maintaining Logrus?** Currently I have a
|
||||
lot of obligations, and I am unable to provide Logrus with the maintainership it
|
||||
needs. If you'd like to help, please reach out to me at `simon at author's
|
||||
username dot com`.
|
||||
|
||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||
plain text):
|
||||
|
||||

|
||||
|
||||
With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
|
||||
or Splunk:
|
||||
|
||||
```json
|
||||
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
|
||||
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
||||
|
||||
{"level":"warning","msg":"The group's number increased tremendously!",
|
||||
"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
|
||||
"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
|
||||
"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
||||
|
||||
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
|
||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
||||
```
|
||||
|
||||
With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
|
||||
attached, the output is compatible with the
|
||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
||||
|
||||
```text
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
||||
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
||||
exit status 1
|
||||
```
|
||||
|
||||
#### Case-sensitivity
|
||||
|
||||
The organization's name was changed to lower-case--and this will not be changed
|
||||
back. If you are getting import conflicts due to case sensitivity, please use
|
||||
the lower-case import: `github.com/sirupsen/logrus`.
|
||||
|
||||
#### Example
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
```
|
||||
|
||||
Note that it's completely api-compatible with the stdlib logger, so you can
|
||||
replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
|
||||
and you'll now have the flexibility of Logrus. You can customize it all you
|
||||
want:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Log as JSON instead of the default ASCII formatter.
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
|
||||
// Output to stdout instead of the default stderr
|
||||
// Can be any io.Writer, see below for File example
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
// Only log the warning severity or above.
|
||||
log.SetLevel(log.WarnLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
|
||||
// A common pattern is to re-use fields between logging statements by re-using
|
||||
// the logrus.Entry returned from WithFields()
|
||||
contextLogger := log.WithFields(log.Fields{
|
||||
"common": "this is a common field",
|
||||
"other": "I also should be logged always",
|
||||
})
|
||||
|
||||
contextLogger.Info("I'll be logged with common and other field")
|
||||
contextLogger.Info("Me too")
|
||||
}
|
||||
```
|
||||
|
||||
For more advanced usage such as logging to multiple locations from the same
|
||||
application, you can also create an instance of the `logrus` Logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Create a new instance of the logger. You can have any number of instances.
|
||||
var log = logrus.New()
|
||||
|
||||
func main() {
|
||||
// The API for setting attributes is a little different than the package level
|
||||
// exported logger. See Godoc.
|
||||
log.Out = os.Stdout
|
||||
|
||||
// You could set this to any `io.Writer` such as a file
|
||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||
// if err == nil {
|
||||
// log.Out = file
|
||||
// } else {
|
||||
// log.Info("Failed to log to file, using default stderr")
|
||||
// }
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
}
|
||||
```
|
||||
|
||||
#### Fields
|
||||
|
||||
Logrus encourages careful, structured logging through logging fields instead of
|
||||
long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
|
||||
to send event %s to topic %s with key %d")`, you should log the much more
|
||||
discoverable:
|
||||
|
||||
```go
|
||||
log.WithFields(log.Fields{
|
||||
"event": event,
|
||||
"topic": topic,
|
||||
"key": key,
|
||||
}).Fatal("Failed to send event")
|
||||
```
|
||||
|
||||
We've found this API forces you to think about logging in a way that produces
|
||||
much more useful logging messages. We've been in countless situations where just
|
||||
a single added field to a log statement that was already there would've saved us
|
||||
hours. The `WithFields` call is optional.
|
||||
|
||||
In general, with Logrus using any of the `printf`-family functions should be
|
||||
seen as a hint you should add a field, however, you can still use the
|
||||
`printf`-family functions with Logrus.
|
||||
|
||||
#### Default Fields
|
||||
|
||||
Often it's helpful to have fields _always_ attached to log statements in an
|
||||
application or parts of one. For example, you may want to always log the
|
||||
`request_id` and `user_ip` in the context of a request. Instead of writing
|
||||
`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
|
||||
every line, you can create a `logrus.Entry` to pass around instead:
|
||||
|
||||
```go
|
||||
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
|
||||
requestLogger.Info("something happened on that request") # will log request_id and user_ip
|
||||
requestLogger.Warn("something not great happened")
|
||||
```
|
||||
|
||||
#### Hooks
|
||||
|
||||
You can add hooks for logging levels. For example to send errors to an exception
|
||||
tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
|
||||
multiple places simultaneously, e.g. syslog.
|
||||
|
||||
Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
|
||||
`init`:
|
||||
|
||||
```go
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
|
||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"log/syslog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
// Use the Airbrake hook to report errors that have Error severity or above to
|
||||
// an exception tracker. You can create custom hooks, see the Hooks section.
|
||||
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
|
||||
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
if err != nil {
|
||||
log.Error("Unable to connect to local syslog daemon")
|
||||
} else {
|
||||
log.AddHook(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
||||
|
||||
| Hook | Description |
|
||||
| ----- | ----------- |
|
||||
| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
|
||||
| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
|
||||
| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) |
|
||||
| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
|
||||
| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
||||
| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
|
||||
| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) |
|
||||
| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
|
||||
| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/)
|
||||
| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
|
||||
| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
|
||||
| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
|
||||
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
||||
| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
|
||||
| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
|
||||
| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) |
|
||||
| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
|
||||
| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
|
||||
| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
|
||||
| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) |
|
||||
| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
|
||||
| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
|
||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
||||
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||
| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
|
||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
||||
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||
| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
|
||||
| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
|
||||
| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
|
||||
| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
|
||||
| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
|
||||
| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
|
||||
| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
|
||||
| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
|
||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
||||
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
||||
| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
||||
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
||||
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||
| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
|
||||
| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) |
|
||||
|
||||
#### Level logging
|
||||
|
||||
Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
|
||||
|
||||
```go
|
||||
log.Debug("Useful debugging information.")
|
||||
log.Info("Something noteworthy happened!")
|
||||
log.Warn("You should probably take a look at this.")
|
||||
log.Error("Something failed but I'm not quitting.")
|
||||
// Calls os.Exit(1) after logging
|
||||
log.Fatal("Bye.")
|
||||
// Calls panic() after logging
|
||||
log.Panic("I'm bailing.")
|
||||
```
|
||||
|
||||
You can set the logging level on a `Logger`, then it will only log entries with
|
||||
that severity or anything above it:
|
||||
|
||||
```go
|
||||
// Will log anything that is info or above (warn, error, fatal, panic). Default.
|
||||
log.SetLevel(log.InfoLevel)
|
||||
```
|
||||
|
||||
It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
|
||||
environment if your application has that.
|
||||
|
||||
#### Entries
|
||||
|
||||
Besides the fields added with `WithField` or `WithFields` some fields are
|
||||
automatically added to all logging events:
|
||||
|
||||
1. `time`. The timestamp when the entry was created.
|
||||
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
|
||||
the `AddFields` call. E.g. `Failed to send event.`
|
||||
3. `level`. The logging level. E.g. `info`.
|
||||
|
||||
#### Environments
|
||||
|
||||
Logrus has no notion of environment.
|
||||
|
||||
If you wish for hooks and formatters to only be used in specific environments,
|
||||
you should handle that yourself. For example, if your application has a global
|
||||
variable `Environment`, which is a string representation of the environment you
|
||||
could do:
|
||||
|
||||
```go
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
init() {
|
||||
// do something here to set environment depending on an environment variable
|
||||
// or command-line flag
|
||||
if Environment == "production" {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
} else {
|
||||
// The TextFormatter is default, you don't actually have to do this.
|
||||
log.SetFormatter(&log.TextFormatter{})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This configuration is how `logrus` was intended to be used, but JSON in
|
||||
production is mostly only useful if you do log aggregation with tools like
|
||||
Splunk or Logstash.
|
||||
|
||||
#### Formatters
|
||||
|
||||
The built-in logging formatters are:
|
||||
|
||||
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
||||
without colors.
|
||||
* *Note:* to force colored output when there is no TTY, set the `ForceColors`
|
||||
field to `true`. To force no colored output even if there is a TTY set the
|
||||
`DisableColors` field to `true`. For Windows, see
|
||||
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
|
||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
|
||||
|
||||
Third party logging formatters:
|
||||
|
||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||
|
||||
You can define your formatter by implementing the `Formatter` interface,
|
||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
||||
`Fields` type (`map[string]interface{}`) with all your fields as well as the
|
||||
default ones (see Entries section above):
|
||||
|
||||
```go
|
||||
type MyJSONFormatter struct {
|
||||
}
|
||||
|
||||
log.SetFormatter(new(MyJSONFormatter))
|
||||
|
||||
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
// Note this doesn't include Time, Level and Message which are available on
|
||||
// the Entry. Consult `godoc` on information about those fields or read the
|
||||
// source of the official loggers.
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
```
|
||||
|
||||
#### Logger as an `io.Writer`
|
||||
|
||||
Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
||||
|
||||
```go
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
|
||||
srv := http.Server{
|
||||
// create a stdlib log.Logger that writes to
|
||||
// logrus.Logger.
|
||||
ErrorLog: log.New(w, "", 0),
|
||||
}
|
||||
```
|
||||
|
||||
Each line written to that writer will be printed the usual way, using formatters
|
||||
and hooks. The level for those entries is `info`.
|
||||
|
||||
This means that we can override the standard library logger easily:
|
||||
|
||||
```go
|
||||
logger := logrus.New()
|
||||
logger.Formatter = &logrus.JSONFormatter{}
|
||||
|
||||
// Use logrus for standard log output
|
||||
// Note that `log` here references stdlib's log
|
||||
// Not logrus imported under the name `log`.
|
||||
log.SetOutput(logger.Writer())
|
||||
```
|
||||
|
||||
#### Rotation
|
||||
|
||||
Log rotation is not provided with Logrus. Log rotation should be done by an
|
||||
external program (like `logrotate(8)`) that can compress and delete old log
|
||||
entries. It should not be a feature of the application-level logger.
|
||||
|
||||
#### Tools
|
||||
|
||||
| Tool | Description |
|
||||
| ---- | ----------- |
|
||||
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
|
||||
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
|
||||
|
||||
#### Testing
|
||||
|
||||
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
|
||||
|
||||
* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
|
||||
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
|
||||
|
||||
```go
|
||||
import(
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSomething(t*testing.T){
|
||||
logger, hook := test.NewNullLogger()
|
||||
logger.Error("Helloerror")
|
||||
|
||||
assert.Equal(t, 1, len(hook.Entries))
|
||||
assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
|
||||
assert.Equal(t, "Helloerror", hook.LastEntry().Message)
|
||||
|
||||
hook.Reset()
|
||||
assert.Nil(t, hook.LastEntry())
|
||||
}
|
||||
```
|
||||
|
||||
#### Fatal handlers
|
||||
|
||||
Logrus can register one or more functions that will be called when any `fatal`
|
||||
level message is logged. The registered handlers will be executed before
|
||||
logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
|
||||
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
|
||||
|
||||
```
|
||||
...
|
||||
handler := func() {
|
||||
// gracefully shutdown something...
|
||||
}
|
||||
logrus.RegisterExitHandler(handler)
|
||||
...
|
||||
```
|
||||
|
||||
#### Thread safety
|
||||
|
||||
By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
|
||||
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
|
||||
|
||||
Situation when locking is not needed includes:
|
||||
|
||||
* You have no hooks registered, or hooks calling is already thread-safe.
|
||||
|
||||
* Writing to logger.Out is already thread-safe, for example:
|
||||
|
||||
1) logger.Out is protected by locks.
|
||||
|
||||
2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
|
||||
|
||||
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
|
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package logrus
|
||||
|
||||
// The following code was sourced and modified from the
|
||||
// https://github.com/tebeka/atexit package governed by the following license:
|
||||
//
|
||||
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var handlers = []func(){}
|
||||
|
||||
func runHandler(handler func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
handler()
|
||||
}
|
||||
|
||||
func runHandlers() {
|
||||
for _, handler := range handlers {
|
||||
runHandler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
||||
func Exit(code int) {
|
||||
runHandlers()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
|
||||
// all handlers. The handlers will also be invoked when any Fatal log entry is
|
||||
// made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func RegisterExitHandler(handler func()) {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
74
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
Normal file
74
vendor/github.com/Sirupsen/logrus/alt_exit_test.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
current := len(handlers)
|
||||
RegisterExitHandler(func() {})
|
||||
if len(handlers) != current+1 {
|
||||
t.Fatalf("can't add handler")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
gofile := "/tmp/testprog.go"
|
||||
if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
|
||||
t.Fatalf("can't create go file")
|
||||
}
|
||||
|
||||
outfile := "/tmp/testprog.out"
|
||||
arg := time.Now().UTC().String()
|
||||
err := exec.Command("go", "run", gofile, outfile, arg).Run()
|
||||
if err == nil {
|
||||
t.Fatalf("completed normally, should have failed")
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(outfile)
|
||||
if err != nil {
|
||||
t.Fatalf("can't read output file %s", outfile)
|
||||
}
|
||||
|
||||
if string(data) != arg {
|
||||
t.Fatalf("bad data")
|
||||
}
|
||||
}
|
||||
|
||||
var testprog = []byte(`
|
||||
// Test program for atexit, gets output file and data as arguments and writes
|
||||
// data to output file in atexit handler.
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var outfile = ""
|
||||
var data = ""
|
||||
|
||||
func handler() {
|
||||
ioutil.WriteFile(outfile, []byte(data), 0666)
|
||||
}
|
||||
|
||||
func badHandler() {
|
||||
n := 0
|
||||
fmt.Println(1/n)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
outfile = flag.Arg(0)
|
||||
data = flag.Arg(1)
|
||||
|
||||
logrus.RegisterExitHandler(handler)
|
||||
logrus.RegisterExitHandler(badHandler)
|
||||
logrus.Fatal("Bye bye")
|
||||
}
|
||||
`)
|
26
vendor/github.com/Sirupsen/logrus/doc.go
generated
vendored
Normal file
26
vendor/github.com/Sirupsen/logrus/doc.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
||||
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 1,
|
||||
"size": 10,
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
|
||||
Output:
|
||||
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
||||
|
||||
For a full guide visit https://github.com/sirupsen/logrus
|
||||
*/
|
||||
package logrus
|
275
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
Normal file
275
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var bufferPool *sync.Pool
|
||||
|
||||
func init() {
|
||||
bufferPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
||||
// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
|
||||
// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
|
||||
// passed around as much as you wish to avoid field duplication.
|
||||
type Entry struct {
|
||||
Logger *Logger
|
||||
|
||||
// Contains all the fields set by the user.
|
||||
Data Fields
|
||||
|
||||
// Time at which the log entry was created
|
||||
Time time.Time
|
||||
|
||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||
Level Level
|
||||
|
||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
|
||||
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||
Buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
return &Entry{
|
||||
Logger: logger,
|
||||
// Default is three fields, give a little extra room
|
||||
Data: make(Fields, 5),
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the string representation from the reader and ultimately the
|
||||
// formatter.
|
||||
func (entry *Entry) String() (string, error) {
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
str := string(serialized)
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||
func (entry *Entry) WithError(err error) *Entry {
|
||||
return entry.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// Add a single field to the Entry.
|
||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
return entry.WithFields(Fields{key: value})
|
||||
}
|
||||
|
||||
// Add a map of fields to the Entry.
|
||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
data := make(Fields, len(entry.Data)+len(fields))
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
for k, v := range fields {
|
||||
data[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data}
|
||||
}
|
||||
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
entry.Time = time.Now()
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
|
||||
if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||
buffer.Reset()
|
||||
defer bufferPool.Put(buffer)
|
||||
entry.Buffer = buffer
|
||||
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||
entry.Buffer = nil
|
||||
if err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
} else {
|
||||
entry.Logger.mu.Lock()
|
||||
_, err = entry.Logger.Out.Write(serialized)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
// directly here.
|
||||
if level <= PanicLevel {
|
||||
panic(&entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.log(DebugLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Print(args ...interface{}) {
|
||||
entry.Info(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Info(args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.log(InfoLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.log(WarnLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warning(args ...interface{}) {
|
||||
entry.Warn(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Error(args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.log(ErrorLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.log(PanicLevel, fmt.Sprint(args...))
|
||||
}
|
||||
panic(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.Debug(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.Info(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
entry.Infof(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.Warn(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
entry.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.Error(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.Panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Entry Println family functions
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.Debug(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Infoln(args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.Info(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Println(args ...interface{}) {
|
||||
entry.Infoln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnln(args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.Warn(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningln(args ...interface{}) {
|
||||
entry.Warnln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorln(args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.Error(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.Panic(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
||||
// fmt.Sprintln where spaces are always added between operands, regardless of
|
||||
// their type. Instead of vendoring the Sprintln implementation to spare a
|
||||
// string allocation, we do the simplest thing.
|
||||
func (entry *Entry) sprintlnn(args ...interface{}) string {
|
||||
msg := fmt.Sprintln(args...)
|
||||
return msg[:len(msg)-1]
|
||||
}
|
77
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
Normal file
77
vendor/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEntryWithError(t *testing.T) {
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
defer func() {
|
||||
ErrorKey = "error"
|
||||
}()
|
||||
|
||||
err := fmt.Errorf("kaboom at layer %d", 4711)
|
||||
|
||||
assert.Equal(err, WithError(err).Data["error"])
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
|
||||
assert.Equal(err, entry.WithError(err).Data["error"])
|
||||
|
||||
ErrorKey = "err"
|
||||
|
||||
assert.Equal(err, entry.WithError(err).Data["err"])
|
||||
|
||||
}
|
||||
|
||||
func TestEntryPanicln(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom time")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicln("kaboom")
|
||||
}
|
||||
|
||||
func TestEntryPanicf(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom again")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom true", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
|
||||
}
|
59
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
Normal file
59
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
// "os"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.JSONFormatter)
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
|
||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||
// if err == nil {
|
||||
// log.Out = file
|
||||
// } else {
|
||||
// log.Info("Failed to log to file, using default stderr")
|
||||
// }
|
||||
|
||||
log.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"err": err,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
||||
}()
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 8,
|
||||
}).Debug("Started observing beach")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"temperature": -4,
|
||||
}).Debug("Temperature changes")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "orca",
|
||||
"size": 9009,
|
||||
}).Panic("It's over 9000!")
|
||||
}
|
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
Normal file
30
vendor/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
193
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
Normal file
193
vendor/github.com/Sirupsen/logrus/exported.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// std is the name of the standard logger in stdlib `log`
|
||||
std = New()
|
||||
)
|
||||
|
||||
func StandardLogger() *Logger {
|
||||
return std
|
||||
}
|
||||
|
||||
// SetOutput sets the standard logger output.
|
||||
func SetOutput(out io.Writer) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Out = out
|
||||
}
|
||||
|
||||
// SetFormatter sets the standard logger formatter.
|
||||
func SetFormatter(formatter Formatter) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Formatter = formatter
|
||||
}
|
||||
|
||||
// SetLevel sets the standard logger level.
|
||||
func SetLevel(level Level) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.SetLevel(level)
|
||||
}
|
||||
|
||||
// GetLevel returns the standard logger level.
|
||||
func GetLevel() Level {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
return std.level()
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the standard logger hooks.
|
||||
func AddHook(hook Hook) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
||||
func WithError(err error) *Entry {
|
||||
return std.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// WithField creates an entry from the standard logger and adds a field to
|
||||
// it. If you want multiple fields, use `WithFields`.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithField(key string, value interface{}) *Entry {
|
||||
return std.WithField(key, value)
|
||||
}
|
||||
|
||||
// WithFields creates an entry from the standard logger and adds multiple
|
||||
// fields to it. This is simply a helper for `WithField`, invoking it
|
||||
// once for each field.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithFields(fields Fields) *Entry {
|
||||
return std.WithFields(fields)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func Debug(args ...interface{}) {
|
||||
std.Debug(args...)
|
||||
}
|
||||
|
||||
// Print logs a message at level Info on the standard logger.
|
||||
func Print(args ...interface{}) {
|
||||
std.Print(args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func Info(args ...interface{}) {
|
||||
std.Info(args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func Warn(args ...interface{}) {
|
||||
std.Warn(args...)
|
||||
}
|
||||
|
||||
// Warning logs a message at level Warn on the standard logger.
|
||||
func Warning(args ...interface{}) {
|
||||
std.Warning(args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func Error(args ...interface{}) {
|
||||
std.Error(args...)
|
||||
}
|
||||
|
||||
// Panic logs a message at level Panic on the standard logger.
|
||||
func Panic(args ...interface{}) {
|
||||
std.Panic(args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
func Fatal(args ...interface{}) {
|
||||
std.Fatal(args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
std.Debugf(format, args...)
|
||||
}
|
||||
|
||||
// Printf logs a message at level Info on the standard logger.
|
||||
func Printf(format string, args ...interface{}) {
|
||||
std.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Infof logs a message at level Info on the standard logger.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
std.Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warnf logs a message at level Warn on the standard logger.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
std.Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Warningf logs a message at level Warn on the standard logger.
|
||||
func Warningf(format string, args ...interface{}) {
|
||||
std.Warningf(format, args...)
|
||||
}
|
||||
|
||||
// Errorf logs a message at level Error on the standard logger.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
std.Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Panicf logs a message at level Panic on the standard logger.
|
||||
func Panicf(format string, args ...interface{}) {
|
||||
std.Panicf(format, args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
std.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
// Debugln logs a message at level Debug on the standard logger.
|
||||
func Debugln(args ...interface{}) {
|
||||
std.Debugln(args...)
|
||||
}
|
||||
|
||||
// Println logs a message at level Info on the standard logger.
|
||||
func Println(args ...interface{}) {
|
||||
std.Println(args...)
|
||||
}
|
||||
|
||||
// Infoln logs a message at level Info on the standard logger.
|
||||
func Infoln(args ...interface{}) {
|
||||
std.Infoln(args...)
|
||||
}
|
||||
|
||||
// Warnln logs a message at level Warn on the standard logger.
|
||||
func Warnln(args ...interface{}) {
|
||||
std.Warnln(args...)
|
||||
}
|
||||
|
||||
// Warningln logs a message at level Warn on the standard logger.
|
||||
func Warningln(args ...interface{}) {
|
||||
std.Warningln(args...)
|
||||
}
|
||||
|
||||
// Errorln logs a message at level Error on the standard logger.
|
||||
func Errorln(args ...interface{}) {
|
||||
std.Errorln(args...)
|
||||
}
|
||||
|
||||
// Panicln logs a message at level Panic on the standard logger.
|
||||
func Panicln(args ...interface{}) {
|
||||
std.Panicln(args...)
|
||||
}
|
||||
|
||||
// Fatalln logs a message at level Fatal on the standard logger.
|
||||
func Fatalln(args ...interface{}) {
|
||||
std.Fatalln(args...)
|
||||
}
|
45
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
Normal file
45
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package logrus
|
||||
|
||||
import "time"
|
||||
|
||||
const DefaultTimestampFormat = time.RFC3339
|
||||
|
||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||
// `Entry`. It exposes all the fields, including the default ones:
|
||||
//
|
||||
// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
||||
// * `entry.Data["time"]`. The timestamp.
|
||||
// * `entry.Data["level"]. The level the entry was logged at.
|
||||
//
|
||||
// Any additional fields added with `WithField` or `WithFields` are also in
|
||||
// `entry.Data`. Format is expected to return an array of bytes which are then
|
||||
// logged to `logger.Out`.
|
||||
type Formatter interface {
|
||||
Format(*Entry) ([]byte, error)
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
//
|
||||
// Would just silently drop the user provided level. Instead with this code
|
||||
// it'll logged as:
|
||||
//
|
||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||
//
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields) {
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
}
|
||||
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
}
|
||||
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
}
|
||||
}
|
101
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
Normal file
101
vendor/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// smallFields is a small size data set for benchmarking
|
||||
var smallFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
}
|
||||
|
||||
// largeFields is a large size data set for benchmarking
|
||||
var largeFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
"five": "six",
|
||||
"seven": "eight",
|
||||
"nine": "ten",
|
||||
"eleven": "twelve",
|
||||
"thirteen": "fourteen",
|
||||
"fifteen": "sixteen",
|
||||
"seventeen": "eighteen",
|
||||
"nineteen": "twenty",
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
"e": "f",
|
||||
"g": "h",
|
||||
"i": "j",
|
||||
"k": "l",
|
||||
"m": "n",
|
||||
"o": "p",
|
||||
"q": "r",
|
||||
"s": "t",
|
||||
"u": "v",
|
||||
"w": "x",
|
||||
"y": "z",
|
||||
"this": "will",
|
||||
"make": "thirty",
|
||||
"entries": "yeah",
|
||||
}
|
||||
|
||||
var errorFields = Fields{
|
||||
"foo": fmt.Errorf("bar"),
|
||||
"baz": fmt.Errorf("qux"),
|
||||
}
|
||||
|
||||
func BenchmarkErrorTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, largeFields)
|
||||
}
|
||||
|
||||
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
|
||||
logger := New()
|
||||
|
||||
entry := &Entry{
|
||||
Time: time.Time{},
|
||||
Level: InfoLevel,
|
||||
Message: "message",
|
||||
Data: fields,
|
||||
Logger: logger,
|
||||
}
|
||||
var d []byte
|
||||
var err error
|
||||
for i := 0; i < b.N; i++ {
|
||||
d, err = formatter.Format(entry)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(d)))
|
||||
}
|
||||
}
|
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
Normal file
122
vendor/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *TestHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *TestHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookFires(t *testing.T) {
|
||||
hook := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ModifyHook struct {
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Fire(entry *Entry) error {
|
||||
entry.Data["wow"] = "whale"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookCanModifyEntry(t *testing.T) {
|
||||
hook := new(ModifyHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
})
|
||||
}
|
||||
|
||||
func TestCanFireMultipleHooks(t *testing.T) {
|
||||
hook1 := new(ModifyHook)
|
||||
hook2 := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook1)
|
||||
log.Hooks.Add(hook2)
|
||||
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
assert.Equal(t, hook2.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ErrorHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Levels() []Level {
|
||||
return []Level{
|
||||
ErrorLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestErrorHookShouldFireOnError(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Error("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
34
vendor/github.com/Sirupsen/logrus/hooks.go
generated
vendored
Normal file
34
vendor/github.com/Sirupsen/logrus/hooks.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package logrus
|
||||
|
||||
// A hook to be fired when logging on the logging levels returned from
|
||||
// `Levels()` on your implementation of the interface. Note that this is not
|
||||
// fired in a goroutine or a channel with workers, you should handle such
|
||||
// functionality yourself if your call is non-blocking and you don't wish for
|
||||
// the logging calls for levels returned from `Levels()` to block.
|
||||
type Hook interface {
|
||||
Levels() []Level
|
||||
Fire(*Entry) error
|
||||
}
|
||||
|
||||
// Internal type for storing the hooks on a logger instance.
|
||||
type LevelHooks map[Level][]Hook
|
||||
|
||||
// Add a hook to an instance of logger. This is called with
|
||||
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
|
||||
func (hooks LevelHooks) Add(hook Hook) {
|
||||
for _, level := range hook.Levels() {
|
||||
hooks[level] = append(hooks[level], hook)
|
||||
}
|
||||
}
|
||||
|
||||
// Fire all the hooks for the passed level. Used by `entry.log` to fire
|
||||
// appropriate hooks for a log entry.
|
||||
func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
|
||||
for _, hook := range hooks[level] {
|
||||
if err := hook.Fire(entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
39
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
Normal file
39
vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/sirupsen/logrus"
|
||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/sirupsen/logrus"
|
||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
54
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
Normal file
54
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"os"
|
||||
)
|
||||
|
||||
// SyslogHook to send logs via syslog.
|
||||
type SyslogHook struct {
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
}
|
||||
|
||||
// Creates a hook to be added to an instance of logger. This is called with
|
||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
// `if err == nil { log.Hooks.Add(hook) }`
|
||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
return &SyslogHook{w, network, raddr}, err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
return hook.Writer.Debug(line)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
Normal file
26
vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalhostAddAndPrint(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Unable to connect to local syslog.")
|
||||
}
|
||||
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
for _, level := range hook.Levels() {
|
||||
if len(log.Hooks[level]) != 1 {
|
||||
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Congratulations!")
|
||||
}
|
95
vendor/github.com/Sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
95
vendor/github.com/Sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
// The Test package is used for testing logrus. It is here for backwards
|
||||
// compatibility from when logrus' organization was upper-case. Please use
|
||||
// lower-case logrus and the `null` package instead of this one.
|
||||
package test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Hook is a hook designed for dealing with logs in test scenarios.
|
||||
type Hook struct {
|
||||
// Entries is an array of all entries that have been received by this hook.
|
||||
// For safe access, use the AllEntries() method, rather than reading this
|
||||
// value directly.
|
||||
Entries []*logrus.Entry
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewGlobal installs a test hook for the global logger.
|
||||
func NewGlobal() *Hook {
|
||||
|
||||
hook := new(Hook)
|
||||
logrus.AddHook(hook)
|
||||
|
||||
return hook
|
||||
|
||||
}
|
||||
|
||||
// NewLocal installs a test hook for a given local logger.
|
||||
func NewLocal(logger *logrus.Logger) *Hook {
|
||||
|
||||
hook := new(Hook)
|
||||
logger.Hooks.Add(hook)
|
||||
|
||||
return hook
|
||||
|
||||
}
|
||||
|
||||
// NewNullLogger creates a discarding logger and installs the test hook.
|
||||
func NewNullLogger() (*logrus.Logger, *Hook) {
|
||||
|
||||
logger := logrus.New()
|
||||
logger.Out = ioutil.Discard
|
||||
|
||||
return logger, NewLocal(logger)
|
||||
|
||||
}
|
||||
|
||||
func (t *Hook) Fire(e *logrus.Entry) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.Entries = append(t.Entries, e)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Hook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
// LastEntry returns the last entry that was logged or nil.
|
||||
func (t *Hook) LastEntry() *logrus.Entry {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
i := len(t.Entries) - 1
|
||||
if i < 0 {
|
||||
return nil
|
||||
}
|
||||
// Make a copy, for safety
|
||||
e := *t.Entries[i]
|
||||
return &e
|
||||
}
|
||||
|
||||
// AllEntries returns all entries that were logged.
|
||||
func (t *Hook) AllEntries() []*logrus.Entry {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
// Make a copy so the returned value won't race with future log requests
|
||||
entries := make([]*logrus.Entry, len(t.Entries))
|
||||
for i, entry := range t.Entries {
|
||||
// Make a copy, for safety
|
||||
e := *entry
|
||||
entries[i] = &e
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
// Reset removes all Entries from this test hook.
|
||||
func (t *Hook) Reset() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.Entries = make([]*logrus.Entry, 0)
|
||||
}
|
39
vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
generated
vendored
Normal file
39
vendor/github.com/Sirupsen/logrus/hooks/test/test_test.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAllHooks(t *testing.T) {
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
logger, hook := NewNullLogger()
|
||||
assert.Nil(hook.LastEntry())
|
||||
assert.Equal(0, len(hook.Entries))
|
||||
|
||||
logger.Error("Hello error")
|
||||
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
||||
assert.Equal("Hello error", hook.LastEntry().Message)
|
||||
assert.Equal(1, len(hook.Entries))
|
||||
|
||||
logger.Warn("Hello warning")
|
||||
assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
|
||||
assert.Equal("Hello warning", hook.LastEntry().Message)
|
||||
assert.Equal(2, len(hook.Entries))
|
||||
|
||||
hook.Reset()
|
||||
assert.Nil(hook.LastEntry())
|
||||
assert.Equal(0, len(hook.Entries))
|
||||
|
||||
hook = NewGlobal()
|
||||
|
||||
logrus.Error("Hello error")
|
||||
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
||||
assert.Equal("Hello error", hook.LastEntry().Message)
|
||||
assert.Equal(1, len(hook.Entries))
|
||||
|
||||
}
|
74
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
Normal file
74
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type fieldKey string
|
||||
type FieldMap map[fieldKey]string
|
||||
|
||||
const (
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
)
|
||||
|
||||
func (f FieldMap) resolve(key fieldKey) string {
|
||||
if k, ok := f[key]; ok {
|
||||
return k
|
||||
}
|
||||
|
||||
return string(key)
|
||||
}
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
DisableTimestamp bool
|
||||
|
||||
// FieldMap allows users to customize the names of keys for various fields.
|
||||
// As an example:
|
||||
// formatter := &JSONFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyMsg: "@message",
|
||||
// },
|
||||
// }
|
||||
FieldMap FieldMap
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
if !f.DisableTimestamp {
|
||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||
}
|
||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
199
vendor/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
Normal file
199
vendor/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestErrorNotLost(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["error"] != "wild walrus" {
|
||||
t.Fatal("Error field not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["omg"] != "wild walrus" {
|
||||
t.Fatal("Error field not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithTime(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("time", "right now!"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.time"] != "right now!" {
|
||||
t.Fatal("fields.time not set to original time field")
|
||||
}
|
||||
|
||||
if entry["time"] != "0001-01-01T00:00:00Z" {
|
||||
t.Fatal("time field not set to current time, was: ", entry["time"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithMsg(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("msg", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.msg"] != "something" {
|
||||
t.Fatal("fields.msg not set to original msg field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithLevel(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.level"] != "something" {
|
||||
t.Fatal("fields.level not set to original level field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
if b[len(b)-1] != '\n' {
|
||||
t.Fatal("Expected JSON log entry to end with a newline")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONMessageKey(t *testing.T) {
|
||||
formatter := &JSONFormatter{
|
||||
FieldMap: FieldMap{
|
||||
FieldKeyMsg: "message",
|
||||
},
|
||||
}
|
||||
|
||||
b, err := formatter.Format(&Entry{Message: "oh hai"})
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
s := string(b)
|
||||
if !(strings.Contains(s, "message") && strings.Contains(s, "oh hai")) {
|
||||
t.Fatal("Expected JSON to format message key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONLevelKey(t *testing.T) {
|
||||
formatter := &JSONFormatter{
|
||||
FieldMap: FieldMap{
|
||||
FieldKeyLevel: "somelevel",
|
||||
},
|
||||
}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
s := string(b)
|
||||
if !strings.Contains(s, "somelevel") {
|
||||
t.Fatal("Expected JSON to format level key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONTimeKey(t *testing.T) {
|
||||
formatter := &JSONFormatter{
|
||||
FieldMap: FieldMap{
|
||||
FieldKeyTime: "timeywimey",
|
||||
},
|
||||
}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
s := string(b)
|
||||
if !strings.Contains(s, "timeywimey") {
|
||||
t.Fatal("Expected JSON to format time key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONDisableTimestamp(t *testing.T) {
|
||||
formatter := &JSONFormatter{
|
||||
DisableTimestamp: true,
|
||||
}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
s := string(b)
|
||||
if strings.Contains(s, FieldKeyTime) {
|
||||
t.Error("Did not prevent timestamp", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEnableTimestamp(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
s := string(b)
|
||||
if !strings.Contains(s, FieldKeyTime) {
|
||||
t.Error("Timestamp not present", s)
|
||||
}
|
||||
}
|
317
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
Normal file
317
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
||||
// something more adventorous, such as logging to Kafka.
|
||||
Out io.Writer
|
||||
// Hooks for the logger instance. These allow firing events based on logging
|
||||
// levels and log entries. For example, to send errors to an error tracking
|
||||
// service, log to StatsD or dump the core on fatal errors.
|
||||
Hooks LevelHooks
|
||||
// All log entries pass through the formatter before logged to Out. The
|
||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
||||
// logs with colors, but to a file it wouldn't. You can easily implement your
|
||||
// own that implements the `Formatter` interface, see the `README` or included
|
||||
// formatters for examples.
|
||||
Formatter Formatter
|
||||
// The logging level the logger should log at. This is typically (and defaults
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged. `logrus.Debug` is useful in
|
||||
Level Level
|
||||
// Used to sync writing to the log. Locking is enabled by Default
|
||||
mu MutexWrap
|
||||
// Reusable empty entry
|
||||
entryPool sync.Pool
|
||||
}
|
||||
|
||||
type MutexWrap struct {
|
||||
lock sync.Mutex
|
||||
disabled bool
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Lock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Unlock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Disable() {
|
||||
mw.disabled = true
|
||||
}
|
||||
|
||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||
// `Out` and `Hooks` directly on the default logger instance. You can also just
|
||||
// instantiate your own:
|
||||
//
|
||||
// var log = &Logger{
|
||||
// Out: os.Stderr,
|
||||
// Formatter: new(JSONFormatter),
|
||||
// Hooks: make(LevelHooks),
|
||||
// Level: logrus.DebugLevel,
|
||||
// }
|
||||
//
|
||||
// It's recommended to make this a global instance called `log`.
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
Out: os.Stderr,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(LevelHooks),
|
||||
Level: InfoLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) newEntry() *Entry {
|
||||
entry, ok := logger.entryPool.Get().(*Entry)
|
||||
if ok {
|
||||
return entry
|
||||
}
|
||||
return NewEntry(logger)
|
||||
}
|
||||
|
||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||
logger.entryPool.Put(entry)
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithField(key, value)
|
||||
}
|
||||
|
||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||
// each `Field`.
|
||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithFields(fields)
|
||||
}
|
||||
|
||||
// Add an error as single field to the log entry. All it does is call
|
||||
// `WithError` for the given `error`.
|
||||
func (logger *Logger) WithError(err error) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithError(err)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Infof(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Printf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Debug(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Error(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatal(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Panic(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Infoln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Println(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
//When file is opened with appending mode, it's safe to
|
||||
//write concurrently to a file (within 4k message on Linux).
|
||||
//In these cases user can choose to disable the lock.
|
||||
func (logger *Logger) SetNoLock() {
|
||||
logger.mu.Disable()
|
||||
}
|
||||
|
||||
func (logger *Logger) level() Level {
|
||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||
}
|
||||
|
||||
func (logger *Logger) SetLevel(level Level) {
|
||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||
}
|
61
vendor/github.com/Sirupsen/logrus/logger_bench_test.go
generated
vendored
Normal file
61
vendor/github.com/Sirupsen/logrus/logger_bench_test.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// smallFields is a small size data set for benchmarking
|
||||
var loggerFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
}
|
||||
|
||||
func BenchmarkDummyLogger(b *testing.B) {
|
||||
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
b.Fatalf("%v", err)
|
||||
}
|
||||
defer nullf.Close()
|
||||
doLoggerBenchmark(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkDummyLoggerNoLock(b *testing.B) {
|
||||
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
b.Fatalf("%v", err)
|
||||
}
|
||||
defer nullf.Close()
|
||||
doLoggerBenchmarkNoLock(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func doLoggerBenchmark(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
||||
logger := Logger{
|
||||
Out: out,
|
||||
Level: InfoLevel,
|
||||
Formatter: formatter,
|
||||
}
|
||||
entry := logger.WithFields(fields)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
entry.Info("aaa")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
||||
logger := Logger{
|
||||
Out: out,
|
||||
Level: InfoLevel,
|
||||
Formatter: formatter,
|
||||
}
|
||||
logger.SetNoLock()
|
||||
entry := logger.WithFields(fields)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
entry.Info("aaa")
|
||||
}
|
||||
})
|
||||
}
|
143
vendor/github.com/Sirupsen/logrus/logrus.go
generated
vendored
Normal file
143
vendor/github.com/Sirupsen/logrus/logrus.go
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Fields type, used to pass to `WithFields`.
|
||||
type Fields map[string]interface{}
|
||||
|
||||
// Level type
|
||||
type Level uint32
|
||||
|
||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
||||
func (level Level) String() string {
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case FatalLevel:
|
||||
return "fatal"
|
||||
case PanicLevel:
|
||||
return "panic"
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
func ParseLevel(lvl string) (Level, error) {
|
||||
switch strings.ToLower(lvl) {
|
||||
case "panic":
|
||||
return PanicLevel, nil
|
||||
case "fatal":
|
||||
return FatalLevel, nil
|
||||
case "error":
|
||||
return ErrorLevel, nil
|
||||
case "warn", "warning":
|
||||
return WarnLevel, nil
|
||||
case "info":
|
||||
return InfoLevel, nil
|
||||
case "debug":
|
||||
return DebugLevel, nil
|
||||
}
|
||||
|
||||
var l Level
|
||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
}
|
||||
|
||||
// A constant exposing all logging levels
|
||||
var AllLevels = []Level{
|
||||
PanicLevel,
|
||||
FatalLevel,
|
||||
ErrorLevel,
|
||||
WarnLevel,
|
||||
InfoLevel,
|
||||
DebugLevel,
|
||||
}
|
||||
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
// on your instance of logger, obtained with `logrus.New()`.
|
||||
const (
|
||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
||||
// message passed to Debug, Info, ...
|
||||
PanicLevel Level = iota
|
||||
// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
|
||||
// logging level is set to Panic.
|
||||
FatalLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
// Commonly used for hooks to send errors to an error tracking service.
|
||||
ErrorLevel
|
||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
||||
WarnLevel
|
||||
// InfoLevel level. General operational entries about what's going on inside the
|
||||
// application.
|
||||
InfoLevel
|
||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
||||
DebugLevel
|
||||
)
|
||||
|
||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
||||
var (
|
||||
_ StdLogger = &log.Logger{}
|
||||
_ StdLogger = &Entry{}
|
||||
_ StdLogger = &Logger{}
|
||||
)
|
||||
|
||||
// StdLogger is what your logrus-enabled library should take, that way
|
||||
// it'll accept a stdlib logger and a logrus logger. There's no standard
|
||||
// interface, this is the closest we get, unfortunately.
|
||||
type StdLogger interface {
|
||||
Print(...interface{})
|
||||
Printf(string, ...interface{})
|
||||
Println(...interface{})
|
||||
|
||||
Fatal(...interface{})
|
||||
Fatalf(string, ...interface{})
|
||||
Fatalln(...interface{})
|
||||
|
||||
Panic(...interface{})
|
||||
Panicf(string, ...interface{})
|
||||
Panicln(...interface{})
|
||||
}
|
||||
|
||||
// The FieldLogger interface generalizes the Entry and Logger types
|
||||
type FieldLogger interface {
|
||||
WithField(key string, value interface{}) *Entry
|
||||
WithFields(fields Fields) *Entry
|
||||
WithError(err error) *Entry
|
||||
|
||||
Debugf(format string, args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Printf(format string, args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Warningf(format string, args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Panicf(format string, args ...interface{})
|
||||
|
||||
Debug(args ...interface{})
|
||||
Info(args ...interface{})
|
||||
Print(args ...interface{})
|
||||
Warn(args ...interface{})
|
||||
Warning(args ...interface{})
|
||||
Error(args ...interface{})
|
||||
Fatal(args ...interface{})
|
||||
Panic(args ...interface{})
|
||||
|
||||
Debugln(args ...interface{})
|
||||
Infoln(args ...interface{})
|
||||
Println(args ...interface{})
|
||||
Warnln(args ...interface{})
|
||||
Warningln(args ...interface{})
|
||||
Errorln(args ...interface{})
|
||||
Fatalln(args ...interface{})
|
||||
Panicln(args ...interface{})
|
||||
}
|
386
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
Normal file
386
vendor/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
Normal file
@ -0,0 +1,386 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
log(logger)
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = &TextFormatter{
|
||||
DisableColors: true,
|
||||
}
|
||||
|
||||
log(logger)
|
||||
|
||||
fields := make(map[string]string)
|
||||
for _, kv := range strings.Split(buffer.String(), " ") {
|
||||
if !strings.Contains(kv, "=") {
|
||||
continue
|
||||
}
|
||||
kvArr := strings.Split(kv, "=")
|
||||
key := strings.TrimSpace(kvArr[0])
|
||||
val := kvArr[1]
|
||||
if kvArr[1][0] == '"' {
|
||||
var err error
|
||||
val, err = strconv.Unquote(val)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
fields[key] = val
|
||||
}
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWarn(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Warn("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "warning")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "testtest")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
localLog := logger.WithFields(Fields{
|
||||
"key1": "value1",
|
||||
})
|
||||
|
||||
localLog.WithField("key2", "value2").Info("test")
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "value2", fields["key2"])
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
|
||||
buffer = bytes.Buffer{}
|
||||
fields = Fields{}
|
||||
localLog.Info("test")
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, ok := fields["key2"]
|
||||
assert.Equal(t, false, ok)
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
}
|
||||
|
||||
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["fields.msg"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("time", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["fields.time"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("level", 1).Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
|
||||
})
|
||||
}
|
||||
|
||||
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
|
||||
LogAndAssertText(t, func(log *Logger) {
|
||||
ll := log.WithField("herp", "derp")
|
||||
ll.Info("hello")
|
||||
ll.Info("bye")
|
||||
}, func(fields map[string]string) {
|
||||
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
|
||||
if _, ok := fields[fieldName]; ok {
|
||||
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
|
||||
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
llog := logger.WithField("context", "eating raw fish")
|
||||
|
||||
llog.Info("looks delicious")
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded first message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "looks delicious")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
|
||||
buffer.Reset()
|
||||
|
||||
llog.Warn("omg it is!")
|
||||
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded second message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "omg it is!")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
|
||||
|
||||
}
|
||||
|
||||
func TestConvertLevelToString(t *testing.T) {
|
||||
assert.Equal(t, "debug", DebugLevel.String())
|
||||
assert.Equal(t, "info", InfoLevel.String())
|
||||
assert.Equal(t, "warning", WarnLevel.String())
|
||||
assert.Equal(t, "error", ErrorLevel.String())
|
||||
assert.Equal(t, "fatal", FatalLevel.String())
|
||||
assert.Equal(t, "panic", PanicLevel.String())
|
||||
}
|
||||
|
||||
func TestParseLevel(t *testing.T) {
|
||||
l, err := ParseLevel("panic")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, PanicLevel, l)
|
||||
|
||||
l, err = ParseLevel("PANIC")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, PanicLevel, l)
|
||||
|
||||
l, err = ParseLevel("fatal")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, FatalLevel, l)
|
||||
|
||||
l, err = ParseLevel("FATAL")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, FatalLevel, l)
|
||||
|
||||
l, err = ParseLevel("error")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ErrorLevel, l)
|
||||
|
||||
l, err = ParseLevel("ERROR")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ErrorLevel, l)
|
||||
|
||||
l, err = ParseLevel("warn")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("WARN")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("warning")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("WARNING")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("info")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, InfoLevel, l)
|
||||
|
||||
l, err = ParseLevel("INFO")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, InfoLevel, l)
|
||||
|
||||
l, err = ParseLevel("debug")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, DebugLevel, l)
|
||||
|
||||
l, err = ParseLevel("DEBUG")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, DebugLevel, l)
|
||||
|
||||
l, err = ParseLevel("invalid")
|
||||
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
|
||||
}
|
||||
|
||||
func TestGetSetLevelRace(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
if i%2 == 0 {
|
||||
SetLevel(InfoLevel)
|
||||
} else {
|
||||
GetLevel()
|
||||
}
|
||||
}(i)
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestLoggingRace(t *testing.T) {
|
||||
logger := New()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(100)
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
go func() {
|
||||
logger.Info("info")
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Compile test
|
||||
func TestLogrusInterface(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
fn := func(l FieldLogger) {
|
||||
b := l.WithField("key", "value")
|
||||
b.Debug("Test")
|
||||
}
|
||||
// test logger
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
fn(logger)
|
||||
|
||||
// test Entry
|
||||
e := logger.WithField("another", "value")
|
||||
fn(e)
|
||||
}
|
||||
|
||||
// Implements io.Writer using channels for synchronization, so we can wait on
|
||||
// the Entry.Writer goroutine to write in a non-racey way. This does assume that
|
||||
// there is a single call to Logger.Out for each message.
|
||||
type channelWriter chan []byte
|
||||
|
||||
func (cw channelWriter) Write(p []byte) (int, error) {
|
||||
cw <- p
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func TestEntryWriter(t *testing.T) {
|
||||
cw := channelWriter(make(chan []byte, 1))
|
||||
log := New()
|
||||
log.Out = cw
|
||||
log.Formatter = new(JSONFormatter)
|
||||
log.WithField("foo", "bar").WriterLevel(WarnLevel).Write([]byte("hello\n"))
|
||||
|
||||
bs := <-cw
|
||||
var fields Fields
|
||||
err := json.Unmarshal(bs, &fields)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, fields["foo"], "bar")
|
||||
assert.Equal(t, fields["level"], "warning")
|
||||
}
|
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// +build appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "io"
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
return true
|
||||
}
|
10
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
Normal file
10
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios syscall.Termios
|
14
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
Normal file
14
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TCGETS
|
||||
|
||||
type Termios syscall.Termios
|
28
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
Normal file
28
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
var termios Termios
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
21
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
Normal file
21
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// +build solaris,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
|
||||
return err == nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
82
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
Normal file
82
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
var (
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
)
|
||||
|
||||
const (
|
||||
enableProcessedOutput = 0x0001
|
||||
enableWrapAtEolOutput = 0x0002
|
||||
enableVirtualTerminalProcessing = 0x0004
|
||||
)
|
||||
|
||||
func getVersion() (float64, error) {
|
||||
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
||||
cmd := exec.Command("cmd", "ver")
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
|
||||
version := strings.Replace(stdout.String(), "\n", "", -1)
|
||||
version = strings.Replace(version, "\r\n", "", -1)
|
||||
|
||||
x1 := strings.Index(version, "[Version")
|
||||
|
||||
if x1 == -1 || strings.Index(version, "]") == -1 {
|
||||
return -1, errors.New("Can't determine Windows version")
|
||||
}
|
||||
|
||||
return strconv.ParseFloat(version[x1+9:x1+13], 64)
|
||||
}
|
||||
|
||||
func init() {
|
||||
ver, err := getVersion()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Activate Virtual Processing for Windows CMD
|
||||
// Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
||||
if ver >= 10 {
|
||||
handle := syscall.Handle(os.Stderr.Fd())
|
||||
procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
|
||||
}
|
||||
}
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
175
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
Normal file
175
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
nocolor = 0
|
||||
red = 31
|
||||
green = 32
|
||||
yellow = 33
|
||||
blue = 36
|
||||
gray = 37
|
||||
)
|
||||
|
||||
var (
|
||||
baseTimestamp time.Time
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseTimestamp = time.Now()
|
||||
}
|
||||
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
|
||||
// Force disabling colors.
|
||||
DisableColors bool
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
|
||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// TimestampFormat to use for display when a full timestamp is printed
|
||||
TimestampFormat string
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
|
||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||
QuoteEmptyFields bool
|
||||
|
||||
// Whether the logger's out is to a terminal
|
||||
isTerminal bool
|
||||
|
||||
sync.Once
|
||||
}
|
||||
|
||||
func (f *TextFormatter) init(entry *Entry) {
|
||||
if entry.Logger != nil {
|
||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
var b *bytes.Buffer
|
||||
keys := make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
f.Do(func() { f.init(entry) })
|
||||
|
||||
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
if isColored {
|
||||
f.printColored(b, entry, keys, timestampFormat)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
|
||||
}
|
||||
f.appendKeyValue(b, "level", entry.Level.String())
|
||||
if entry.Message != "" {
|
||||
f.appendKeyValue(b, "msg", entry.Message)
|
||||
}
|
||||
for _, key := range keys {
|
||||
f.appendKeyValue(b, key, entry.Data[key])
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteByte('\n')
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel:
|
||||
levelColor = gray
|
||||
case WarnLevel:
|
||||
levelColor = yellow
|
||||
case ErrorLevel, FatalLevel, PanicLevel:
|
||||
levelColor = red
|
||||
default:
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
|
||||
if f.DisableTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
|
||||
} else if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
||||
if f.QuoteEmptyFields && len(text) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
f.appendValue(b, value)
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||
stringVal, ok := value.(string)
|
||||
if !ok {
|
||||
stringVal = fmt.Sprint(value)
|
||||
}
|
||||
|
||||
if !f.needsQuoting(stringVal) {
|
||||
b.WriteString(stringVal)
|
||||
} else {
|
||||
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||
}
|
||||
}
|
122
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
Normal file
122
vendor/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestQuoting(t *testing.T) {
|
||||
tf := &TextFormatter{DisableColors: true}
|
||||
|
||||
checkQuoting := func(q bool, value interface{}) {
|
||||
b, _ := tf.Format(WithField("test", value))
|
||||
idx := bytes.Index(b, ([]byte)("test="))
|
||||
cont := bytes.Contains(b[idx+5:], []byte("\""))
|
||||
if cont != q {
|
||||
if q {
|
||||
t.Errorf("quoting expected for: %#v", value)
|
||||
} else {
|
||||
t.Errorf("quoting not expected for: %#v", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkQuoting(false, "")
|
||||
checkQuoting(false, "abcd")
|
||||
checkQuoting(false, "v1.0")
|
||||
checkQuoting(false, "1234567890")
|
||||
checkQuoting(false, "/foobar")
|
||||
checkQuoting(false, "foo_bar")
|
||||
checkQuoting(false, "foo@bar")
|
||||
checkQuoting(false, "foobar^")
|
||||
checkQuoting(false, "+/-_^@f.oobar")
|
||||
checkQuoting(true, "foobar$")
|
||||
checkQuoting(true, "&foobar")
|
||||
checkQuoting(true, "x y")
|
||||
checkQuoting(true, "x,y")
|
||||
checkQuoting(false, errors.New("invalid"))
|
||||
checkQuoting(true, errors.New("invalid argument"))
|
||||
|
||||
// Test for quoting empty fields.
|
||||
tf.QuoteEmptyFields = true
|
||||
checkQuoting(true, "")
|
||||
checkQuoting(false, "abcd")
|
||||
checkQuoting(true, errors.New("invalid argument"))
|
||||
}
|
||||
|
||||
func TestEscaping(t *testing.T) {
|
||||
tf := &TextFormatter{DisableColors: true}
|
||||
|
||||
testCases := []struct {
|
||||
value string
|
||||
expected string
|
||||
}{
|
||||
{`ba"r`, `ba\"r`},
|
||||
{`ba'r`, `ba'r`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
b, _ := tf.Format(WithField("test", tc.value))
|
||||
if !bytes.Contains(b, []byte(tc.expected)) {
|
||||
t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEscaping_Interface(t *testing.T) {
|
||||
tf := &TextFormatter{DisableColors: true}
|
||||
|
||||
ts := time.Now()
|
||||
|
||||
testCases := []struct {
|
||||
value interface{}
|
||||
expected string
|
||||
}{
|
||||
{ts, fmt.Sprintf("\"%s\"", ts.String())},
|
||||
{errors.New("error: something went wrong"), "\"error: something went wrong\""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
b, _ := tf.Format(WithField("test", tc.value))
|
||||
if !bytes.Contains(b, []byte(tc.expected)) {
|
||||
t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestampFormat(t *testing.T) {
|
||||
checkTimeStr := func(format string) {
|
||||
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
||||
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
||||
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
||||
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
||||
timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
|
||||
if format == "" {
|
||||
format = time.RFC3339
|
||||
}
|
||||
_, e := time.Parse(format, (string)(timeStr))
|
||||
if e != nil {
|
||||
t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
|
||||
}
|
||||
}
|
||||
|
||||
checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
|
||||
checkTimeStr("Mon Jan _2 15:04:05 2006")
|
||||
checkTimeStr("")
|
||||
}
|
||||
|
||||
func TestDisableTimestampWithColoredOutput(t *testing.T) {
|
||||
tf := &TextFormatter{DisableTimestamp: true, ForceColors: true}
|
||||
|
||||
b, _ := tf.Format(WithField("test", "test"))
|
||||
if strings.Contains(string(b), "[0000]") {
|
||||
t.Error("timestamp not expected when DisableTimestamp is true")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add tests for sorting etc., this requires a parser for the text
|
||||
// formatter output.
|
62
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
Normal file
62
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
return logger.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
||||
return NewEntry(logger).WriterLevel(level)
|
||||
}
|
||||
|
||||
func (entry *Entry) Writer() *io.PipeWriter {
|
||||
return entry.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
var printFunc func(args ...interface{})
|
||||
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
printFunc = entry.Debug
|
||||
case InfoLevel:
|
||||
printFunc = entry.Info
|
||||
case WarnLevel:
|
||||
printFunc = entry.Warn
|
||||
case ErrorLevel:
|
||||
printFunc = entry.Error
|
||||
case FatalLevel:
|
||||
printFunc = entry.Fatal
|
||||
case PanicLevel:
|
||||
printFunc = entry.Panic
|
||||
default:
|
||||
printFunc = entry.Print
|
||||
}
|
||||
|
||||
go entry.writerScanner(reader, printFunc)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
printFunc(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
entry.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
||||
func writerFinalizer(writer *io.PipeWriter) {
|
||||
writer.Close()
|
||||
}
|
2
vendor/github.com/osrg/gobgp/VERSION
generated
vendored
2
vendor/github.com/osrg/gobgp/VERSION
generated
vendored
@ -1 +1 @@
|
||||
1.21
|
||||
1.20
|
1743
vendor/github.com/osrg/gobgp/api/gobgp.pb.go
generated
vendored
1743
vendor/github.com/osrg/gobgp/api/gobgp.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
162
vendor/github.com/osrg/gobgp/api/gobgp.proto
generated
vendored
162
vendor/github.com/osrg/gobgp/api/gobgp.proto
generated
vendored
@ -553,8 +553,6 @@ message Peer {
|
||||
Timers timers = 7;
|
||||
Transport transport = 8;
|
||||
RouteServer route_server = 9;
|
||||
GracefulRestart graceful_restart = 10;
|
||||
repeated AfiSafi afi_safis = 11;
|
||||
}
|
||||
|
||||
message ApplyPolicy {
|
||||
@ -588,9 +586,6 @@ message PeerConf {
|
||||
repeated bytes remote_cap = 11;
|
||||
repeated bytes local_cap = 12;
|
||||
string id = 13;
|
||||
// Note: Regarding to the consistency with OpenConfig mode, list of
|
||||
// PrefixLimit should be removed from here, and list of PrefixLimit in
|
||||
// AfiSafi should be used instead.
|
||||
repeated PrefixLimit prefix_limits = 14;
|
||||
string local_address = 15;
|
||||
string neighbor_interface = 16;
|
||||
@ -694,163 +689,6 @@ message RouteServer {
|
||||
bool route_server_client = 1;
|
||||
}
|
||||
|
||||
message GracefulRestart {
|
||||
bool enabled = 1;
|
||||
uint32 restart_time = 2;
|
||||
bool helper_only = 3;
|
||||
uint32 deferral_time = 4;
|
||||
bool notification_enabled = 5;
|
||||
bool longlived_enabled = 6;
|
||||
}
|
||||
|
||||
message MpGracefulRestartConfig {
|
||||
bool enabled = 1;
|
||||
}
|
||||
|
||||
message MpGracefulRestartState {
|
||||
bool enabled = 1;
|
||||
bool received = 2;
|
||||
bool advertised = 3;
|
||||
bool end_of_rib_received = 4;
|
||||
bool end_of_rib_sent = 5;
|
||||
}
|
||||
message MpGracefulRestart {
|
||||
MpGracefulRestartConfig config = 1;
|
||||
MpGracefulRestartState state = 2;
|
||||
}
|
||||
|
||||
message AfiSafiConfig {
|
||||
uint32 family = 1;
|
||||
bool enabled = 2;
|
||||
}
|
||||
|
||||
message AfiSafiState {
|
||||
uint32 family = 1;
|
||||
bool enabled = 2;
|
||||
uint32 total_paths = 3;
|
||||
uint32 total_prefixes = 4;
|
||||
}
|
||||
|
||||
message RouteSelectionOptionsConfig {
|
||||
bool always_compare_med = 1;
|
||||
bool ignore_as_path_length = 2;
|
||||
bool external_compare_router_id = 3;
|
||||
bool advertise_inactive_routes = 4;
|
||||
bool enable_aigp = 5;
|
||||
bool ignore_next_hop_igp_metric = 6;
|
||||
}
|
||||
|
||||
message RouteSelectionOptionsState {
|
||||
bool always_compare_med = 1;
|
||||
bool ignore_as_path_length = 2;
|
||||
bool external_compare_router_id = 3;
|
||||
bool advertise_inactive_routes = 4;
|
||||
bool enable_aigp = 5;
|
||||
bool ignore_next_hop_igp_metric = 6;
|
||||
}
|
||||
|
||||
message RouteSelectionOptions {
|
||||
RouteSelectionOptionsConfig config = 1;
|
||||
RouteSelectionOptionsState state = 2;
|
||||
}
|
||||
|
||||
message UseMultiplePathsConfig {
|
||||
bool enabled = 1;
|
||||
}
|
||||
|
||||
message UseMultiplePathsState {
|
||||
bool enabled = 1;
|
||||
}
|
||||
|
||||
message EbgpConfig {
|
||||
bool allow_multiple_as = 1;
|
||||
uint32 maximum_paths = 2;
|
||||
}
|
||||
|
||||
message EbgpState {
|
||||
bool allow_multiple_as = 1;
|
||||
uint32 maximum_paths = 2;
|
||||
}
|
||||
|
||||
message Ebgp {
|
||||
EbgpConfig config = 1;
|
||||
EbgpState state = 2;
|
||||
}
|
||||
|
||||
message IbgpConfig {
|
||||
uint32 maximum_paths = 1;
|
||||
}
|
||||
|
||||
message IbgpState {
|
||||
uint32 maximum_paths = 1;
|
||||
}
|
||||
|
||||
message Ibgp {
|
||||
IbgpConfig config = 1;
|
||||
IbgpState state = 2;
|
||||
}
|
||||
|
||||
message UseMultiplePaths {
|
||||
UseMultiplePathsConfig config = 1;
|
||||
UseMultiplePathsState state = 2;
|
||||
Ebgp ebgp = 3;
|
||||
Ibgp ibgp = 4;
|
||||
}
|
||||
|
||||
message RouteTargetMembershipConfig {
|
||||
uint32 deferral_time = 1;
|
||||
}
|
||||
|
||||
message RouteTargetMembershipState {
|
||||
uint32 deferral_time = 1;
|
||||
}
|
||||
|
||||
message RouteTargetMembership {
|
||||
RouteTargetMembershipConfig config = 1;
|
||||
RouteTargetMembershipState state = 2;
|
||||
}
|
||||
|
||||
message LongLivedGracefulRestartConfig {
|
||||
bool enabled = 1;
|
||||
uint32 restart_time = 2;
|
||||
}
|
||||
|
||||
message LongLivedGracefulRestartState {
|
||||
bool enabled = 1;
|
||||
bool received = 2;
|
||||
bool advertised = 3;
|
||||
uint32 peer_restart_time = 4;
|
||||
bool peer_restart_timer_expired = 5;
|
||||
}
|
||||
|
||||
message LongLivedGracefulRestart {
|
||||
LongLivedGracefulRestartConfig config = 1;
|
||||
LongLivedGracefulRestartState state = 2;
|
||||
}
|
||||
|
||||
message AfiSafi {
|
||||
MpGracefulRestart mp_graceful_restart = 1;
|
||||
AfiSafiConfig config = 2;
|
||||
ApplyPolicy apply_policy = 3;
|
||||
// TODO:
|
||||
// Support the following structures:
|
||||
// - Ipv4Unicast
|
||||
// - Ipv6Unicast
|
||||
// - Ipv4LabelledUnicast
|
||||
// - Ipv6LabelledUnicast
|
||||
// - L3vpnIpv4Unicast
|
||||
// - L3vpnIpv6Unicast
|
||||
// - L3vpnIpv4Multicast
|
||||
// - L3vpnIpv6Multicast
|
||||
// - L2vpnVpls
|
||||
// - L2vpnEvpn
|
||||
RouteSelectionOptions route_selection_options = 4;
|
||||
UseMultiplePaths use_multiple_paths = 5;
|
||||
PrefixLimit prefix_limits = 6;
|
||||
RouteTargetMembership route_target_membership = 7;
|
||||
LongLivedGracefulRestart long_lived_graceful_restart = 8;
|
||||
}
|
||||
|
||||
message Prefix {
|
||||
string ip_prefix = 1;
|
||||
uint32 mask_length_min = 2;
|
||||
|
365
vendor/github.com/osrg/gobgp/api/grpc_server.go
generated
vendored
365
vendor/github.com/osrg/gobgp/api/grpc_server.go
generated
vendored
@ -26,11 +26,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/server"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@ -88,138 +88,44 @@ func (s *Server) Serve() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewMpGracefulRestartFromConfigStruct(c *config.MpGracefulRestart) *MpGracefulRestart {
|
||||
return &MpGracefulRestart{
|
||||
Config: &MpGracefulRestartConfig{
|
||||
Enabled: c.Config.Enabled,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewAfiSafiConfigFromConfigStruct(c *config.AfiSafiConfig) *AfiSafiConfig {
|
||||
return &AfiSafiConfig{
|
||||
Family: uint32(bgp.AddressFamilyValueMap[string(c.AfiSafiName)]),
|
||||
Enabled: c.Enabled,
|
||||
}
|
||||
}
|
||||
|
||||
func NewApplyPolicyFromConfigStruct(c *config.ApplyPolicy) *ApplyPolicy {
|
||||
applyPolicy := &ApplyPolicy{
|
||||
ImportPolicy: &PolicyAssignment{
|
||||
Type: PolicyType_IMPORT,
|
||||
Default: RouteAction(c.Config.DefaultImportPolicy.ToInt()),
|
||||
},
|
||||
ExportPolicy: &PolicyAssignment{
|
||||
Type: PolicyType_EXPORT,
|
||||
Default: RouteAction(c.Config.DefaultExportPolicy.ToInt()),
|
||||
},
|
||||
InPolicy: &PolicyAssignment{
|
||||
Type: PolicyType_IN,
|
||||
Default: RouteAction(c.Config.DefaultInPolicy.ToInt()),
|
||||
},
|
||||
}
|
||||
|
||||
for _, pname := range c.Config.ImportPolicyList {
|
||||
applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
for _, pname := range c.Config.ExportPolicyList {
|
||||
applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
for _, pname := range c.Config.InPolicyList {
|
||||
applyPolicy.InPolicy.Policies = append(applyPolicy.InPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
|
||||
return applyPolicy
|
||||
}
|
||||
|
||||
func NewRouteSelectionOptionsFromConfigStruct(c *config.RouteSelectionOptions) *RouteSelectionOptions {
|
||||
return &RouteSelectionOptions{
|
||||
Config: &RouteSelectionOptionsConfig{
|
||||
AlwaysCompareMed: c.Config.AlwaysCompareMed,
|
||||
IgnoreAsPathLength: c.Config.IgnoreAsPathLength,
|
||||
ExternalCompareRouterId: c.Config.ExternalCompareRouterId,
|
||||
AdvertiseInactiveRoutes: c.Config.AdvertiseInactiveRoutes,
|
||||
EnableAigp: c.Config.EnableAigp,
|
||||
IgnoreNextHopIgpMetric: c.Config.IgnoreNextHopIgpMetric,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewUseMultiplePathsFromConfigStruct(c *config.UseMultiplePaths) *UseMultiplePaths {
|
||||
return &UseMultiplePaths{
|
||||
Config: &UseMultiplePathsConfig{
|
||||
Enabled: c.Config.Enabled,
|
||||
},
|
||||
Ebgp: &Ebgp{
|
||||
Config: &EbgpConfig{
|
||||
AllowMultipleAs: c.Ebgp.Config.AllowMultipleAs,
|
||||
MaximumPaths: c.Ebgp.Config.MaximumPaths,
|
||||
},
|
||||
},
|
||||
Ibgp: &Ibgp{
|
||||
Config: &IbgpConfig{
|
||||
MaximumPaths: c.Ibgp.Config.MaximumPaths,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewPrefixLimitFromConfigStruct(c *config.AfiSafi) *PrefixLimit {
|
||||
family, err := bgp.GetRouteFamily(string(c.Config.AfiSafiName))
|
||||
if err != nil || c.PrefixLimit.Config.MaxPrefixes == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &PrefixLimit{
|
||||
Family: uint32(family),
|
||||
MaxPrefixes: c.PrefixLimit.Config.MaxPrefixes,
|
||||
ShutdownThresholdPct: uint32(c.PrefixLimit.Config.ShutdownThresholdPct),
|
||||
}
|
||||
}
|
||||
|
||||
func NewRouteTargetMembershipFromConfigStruct(c *config.RouteTargetMembership) *RouteTargetMembership {
|
||||
return &RouteTargetMembership{
|
||||
Config: &RouteTargetMembershipConfig{
|
||||
DeferralTime: uint32(c.Config.DeferralTime),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewLongLivedGracefulRestartFromConfigStruct(c *config.LongLivedGracefulRestart) *LongLivedGracefulRestart {
|
||||
return &LongLivedGracefulRestart{
|
||||
Config: &LongLivedGracefulRestartConfig{
|
||||
Enabled: c.Config.Enabled,
|
||||
RestartTime: c.Config.RestartTime,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewAfiSafiFromConfigStruct(c *config.AfiSafi) *AfiSafi {
|
||||
return &AfiSafi{
|
||||
MpGracefulRestart: NewMpGracefulRestartFromConfigStruct(&c.MpGracefulRestart),
|
||||
Config: NewAfiSafiConfigFromConfigStruct(&c.Config),
|
||||
ApplyPolicy: NewApplyPolicyFromConfigStruct(&c.ApplyPolicy),
|
||||
RouteSelectionOptions: NewRouteSelectionOptionsFromConfigStruct(&c.RouteSelectionOptions),
|
||||
UseMultiplePaths: NewUseMultiplePathsFromConfigStruct(&c.UseMultiplePaths),
|
||||
PrefixLimits: NewPrefixLimitFromConfigStruct(c),
|
||||
RouteTargetMembership: NewRouteTargetMembershipFromConfigStruct(&c.RouteTargetMembership),
|
||||
LongLivedGracefulRestart: NewLongLivedGracefulRestartFromConfigStruct(&c.LongLivedGracefulRestart),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
|
||||
families := make([]uint32, 0, len(pconf.AfiSafis))
|
||||
prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis))
|
||||
afiSafis := make([]*AfiSafi, 0, len(pconf.AfiSafis))
|
||||
var families []uint32
|
||||
for _, f := range pconf.AfiSafis {
|
||||
if family, ok := bgp.AddressFamilyValueMap[string(f.Config.AfiSafiName)]; ok {
|
||||
families = append(families, uint32(family))
|
||||
}
|
||||
if prefixLimit := NewPrefixLimitFromConfigStruct(&f); prefixLimit != nil {
|
||||
prefixLimits = append(prefixLimits, prefixLimit)
|
||||
}
|
||||
if afiSafi := NewAfiSafiFromConfigStruct(&f); afiSafi != nil {
|
||||
afiSafis = append(afiSafis, afiSafi)
|
||||
}
|
||||
applyPolicy := &ApplyPolicy{}
|
||||
applyPolicy.ImportPolicy = &PolicyAssignment{
|
||||
Type: PolicyType_IMPORT,
|
||||
Default: RouteAction(pconf.ApplyPolicy.Config.DefaultImportPolicy.ToInt()),
|
||||
}
|
||||
for _, pname := range pconf.ApplyPolicy.Config.ImportPolicyList {
|
||||
applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
applyPolicy.ExportPolicy = &PolicyAssignment{
|
||||
Type: PolicyType_EXPORT,
|
||||
Default: RouteAction(pconf.ApplyPolicy.Config.DefaultExportPolicy.ToInt()),
|
||||
}
|
||||
for _, pname := range pconf.ApplyPolicy.Config.ExportPolicyList {
|
||||
applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
applyPolicy.InPolicy = &PolicyAssignment{
|
||||
Type: PolicyType_IN,
|
||||
Default: RouteAction(pconf.ApplyPolicy.Config.DefaultInPolicy.ToInt()),
|
||||
}
|
||||
for _, pname := range pconf.ApplyPolicy.Config.InPolicyList {
|
||||
applyPolicy.InPolicy.Policies = append(applyPolicy.InPolicy.Policies, &Policy{Name: pname})
|
||||
}
|
||||
prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis))
|
||||
for _, family := range pconf.AfiSafis {
|
||||
if c := family.PrefixLimit.Config; c.MaxPrefixes > 0 {
|
||||
k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName))
|
||||
prefixLimits = append(prefixLimits, &PrefixLimit{
|
||||
Family: uint32(k),
|
||||
MaxPrefixes: c.MaxPrefixes,
|
||||
ShutdownThresholdPct: uint32(c.ShutdownThresholdPct),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,13 +136,13 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
|
||||
localAddress = pconf.Transport.State.LocalAddress
|
||||
}
|
||||
var remoteCap, localCap [][]byte
|
||||
for _, c := range pconf.State.RemoteCapabilityList {
|
||||
cBuf, _ := c.Serialize()
|
||||
remoteCap = append(remoteCap, cBuf)
|
||||
for _, cap := range pconf.State.RemoteCapabilityList {
|
||||
c, _ := cap.Serialize()
|
||||
remoteCap = append(remoteCap, c)
|
||||
}
|
||||
for _, c := range pconf.State.LocalCapabilityList {
|
||||
cBuf, _ := c.Serialize()
|
||||
localCap = append(localCap, cBuf)
|
||||
for _, cap := range pconf.State.LocalCapabilityList {
|
||||
c, _ := cap.Serialize()
|
||||
localCap = append(localCap, c)
|
||||
}
|
||||
var removePrivateAs PeerConf_RemovePrivateAs
|
||||
switch pconf.Config.RemovePrivateAs {
|
||||
@ -247,7 +153,7 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
|
||||
}
|
||||
return &Peer{
|
||||
Families: families,
|
||||
ApplyPolicy: NewApplyPolicyFromConfigStruct(&pconf.ApplyPolicy),
|
||||
ApplyPolicy: applyPolicy,
|
||||
Conf: &PeerConf{
|
||||
NeighborAddress: pconf.Config.NeighborAddress,
|
||||
Id: s.RemoteRouterId,
|
||||
@ -291,12 +197,11 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
|
||||
TOTAL: s.Messages.Sent.Total,
|
||||
},
|
||||
},
|
||||
Received: s.AdjTable.Received,
|
||||
Accepted: s.AdjTable.Accepted,
|
||||
Advertised: s.AdjTable.Advertised,
|
||||
PeerAs: s.PeerAs,
|
||||
PeerType: uint32(s.PeerType.ToInt()),
|
||||
NeighborAddress: pconf.State.NeighborAddress,
|
||||
Received: s.AdjTable.Received,
|
||||
Accepted: s.AdjTable.Accepted,
|
||||
Advertised: s.AdjTable.Advertised,
|
||||
PeerAs: s.PeerAs,
|
||||
PeerType: uint32(s.PeerType.ToInt()),
|
||||
},
|
||||
Timers: &Timers{
|
||||
Config: &TimersConfig{
|
||||
@ -318,19 +223,10 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer {
|
||||
RouteServer: &RouteServer{
|
||||
RouteServerClient: pconf.RouteServer.Config.RouteServerClient,
|
||||
},
|
||||
GracefulRestart: &GracefulRestart{
|
||||
Enabled: pconf.GracefulRestart.Config.Enabled,
|
||||
RestartTime: uint32(pconf.GracefulRestart.Config.RestartTime),
|
||||
HelperOnly: pconf.GracefulRestart.Config.HelperOnly,
|
||||
DeferralTime: uint32(pconf.GracefulRestart.Config.DeferralTime),
|
||||
NotificationEnabled: pconf.GracefulRestart.Config.NotificationEnabled,
|
||||
LonglivedEnabled: pconf.GracefulRestart.Config.LongLivedEnabled,
|
||||
},
|
||||
Transport: &Transport{
|
||||
RemotePort: uint32(pconf.Transport.Config.RemotePort),
|
||||
LocalAddress: pconf.Transport.Config.LocalAddress,
|
||||
},
|
||||
AfiSafis: afiSafis,
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,114 +851,10 @@ func (s *Server) DeleteVrf(ctx context.Context, arg *DeleteVrfRequest) (*DeleteV
|
||||
return &DeleteVrfResponse{}, s.bgpServer.DeleteVrf(arg.Vrf.Name)
|
||||
}
|
||||
|
||||
func ReadMpGracefulRestartFromAPIStruct(c *config.MpGracefulRestart, a *MpGracefulRestart) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.Config != nil {
|
||||
c.Config.Enabled = a.Config.Enabled
|
||||
}
|
||||
}
|
||||
|
||||
func ReadAfiSafiConfigFromAPIStruct(c *config.AfiSafiConfig, a *AfiSafiConfig) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
c.Enabled = a.Enabled
|
||||
}
|
||||
|
||||
func ReadPrefixLimitFromAPIStruct(c *config.PrefixLimit, a *PrefixLimit) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
c.Config.MaxPrefixes = a.MaxPrefixes
|
||||
c.Config.ShutdownThresholdPct = config.Percentage(a.ShutdownThresholdPct)
|
||||
}
|
||||
|
||||
func ReadApplyPolicyFromAPIStruct(c *config.ApplyPolicy, a *ApplyPolicy) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.ImportPolicy != nil {
|
||||
c.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ImportPolicy.Default)]
|
||||
for _, p := range a.ImportPolicy.Policies {
|
||||
c.Config.ImportPolicyList = append(c.Config.ImportPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
if a.ExportPolicy != nil {
|
||||
c.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ExportPolicy.Default)]
|
||||
for _, p := range a.ExportPolicy.Policies {
|
||||
c.Config.ExportPolicyList = append(c.Config.ExportPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
if a.InPolicy != nil {
|
||||
c.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.InPolicy.Default)]
|
||||
for _, p := range a.InPolicy.Policies {
|
||||
c.Config.InPolicyList = append(c.Config.InPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadRouteSelectionOptionsFromAPIStruct(c *config.RouteSelectionOptions, a *RouteSelectionOptions) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.Config != nil {
|
||||
c.Config.AlwaysCompareMed = a.Config.AlwaysCompareMed
|
||||
c.Config.IgnoreAsPathLength = a.Config.IgnoreAsPathLength
|
||||
c.Config.ExternalCompareRouterId = a.Config.ExternalCompareRouterId
|
||||
c.Config.AdvertiseInactiveRoutes = a.Config.AdvertiseInactiveRoutes
|
||||
c.Config.EnableAigp = a.Config.EnableAigp
|
||||
c.Config.IgnoreNextHopIgpMetric = a.Config.IgnoreNextHopIgpMetric
|
||||
}
|
||||
}
|
||||
|
||||
func ReadUseMultiplePathsFromAPIStruct(c *config.UseMultiplePaths, a *UseMultiplePaths) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.Config != nil {
|
||||
c.Config.Enabled = a.Config.Enabled
|
||||
}
|
||||
if a.Ebgp != nil && a.Ebgp.Config != nil {
|
||||
c.Ebgp = config.Ebgp{
|
||||
Config: config.EbgpConfig{
|
||||
AllowMultipleAs: a.Ebgp.Config.AllowMultipleAs,
|
||||
MaximumPaths: a.Ebgp.Config.MaximumPaths,
|
||||
},
|
||||
}
|
||||
}
|
||||
if a.Ibgp != nil && a.Ibgp.Config != nil {
|
||||
c.Ibgp = config.Ibgp{
|
||||
Config: config.IbgpConfig{
|
||||
MaximumPaths: a.Ibgp.Config.MaximumPaths,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ReadRouteTargetMembershipFromAPIStruct(c *config.RouteTargetMembership, a *RouteTargetMembership) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.Config != nil {
|
||||
c.Config.DeferralTime = uint16(a.Config.DeferralTime)
|
||||
}
|
||||
}
|
||||
|
||||
func ReadLongLivedGracefulRestartFromAPIStruct(c *config.LongLivedGracefulRestart, a *LongLivedGracefulRestart) {
|
||||
if c == nil || a == nil {
|
||||
return
|
||||
}
|
||||
if a.Config != nil {
|
||||
c.Config.Enabled = a.Config.Enabled
|
||||
c.Config.RestartTime = a.Config.RestartTime
|
||||
}
|
||||
}
|
||||
|
||||
func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
|
||||
pconf := &config.Neighbor{}
|
||||
if a.Conf != nil {
|
||||
pconf.Config.NeighborAddress = a.Conf.NeighborAddress
|
||||
pconf.Config.PeerAs = a.Conf.PeerAs
|
||||
pconf.Config.LocalAs = a.Conf.LocalAs
|
||||
pconf.Config.AuthPassword = a.Conf.AuthPassword
|
||||
@ -1085,11 +877,11 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
|
||||
f := func(bufs [][]byte) ([]bgp.ParameterCapabilityInterface, error) {
|
||||
var caps []bgp.ParameterCapabilityInterface
|
||||
for _, buf := range bufs {
|
||||
c, err := bgp.DecodeCapability(buf)
|
||||
cap, err := bgp.DecodeCapability(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
caps = append(caps, c)
|
||||
caps = append(caps, cap)
|
||||
}
|
||||
return caps, nil
|
||||
}
|
||||
@ -1107,31 +899,22 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
|
||||
|
||||
pconf.State.RemoteRouterId = a.Conf.Id
|
||||
|
||||
for _, family := range a.Families {
|
||||
afiSafi := config.AfiSafi{
|
||||
for _, f := range a.Families {
|
||||
family := bgp.RouteFamily(f)
|
||||
pconf.AfiSafis = append(pconf.AfiSafis, config.AfiSafi{
|
||||
Config: config.AfiSafiConfig{
|
||||
AfiSafiName: config.AfiSafiType(bgp.RouteFamily(family).String()),
|
||||
AfiSafiName: config.AfiSafiType(family.String()),
|
||||
Enabled: true,
|
||||
},
|
||||
}
|
||||
for _, pl := range a.Conf.PrefixLimits {
|
||||
if family == pl.Family {
|
||||
ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, pl)
|
||||
})
|
||||
}
|
||||
for _, pl := range a.Conf.PrefixLimits {
|
||||
for i, f := range pconf.AfiSafis {
|
||||
if f.Config.AfiSafiName == config.AfiSafiType(bgp.RouteFamily(pl.Family).String()) {
|
||||
pconf.AfiSafis[i].PrefixLimit.Config.MaxPrefixes = pl.MaxPrefixes
|
||||
pconf.AfiSafis[i].PrefixLimit.Config.ShutdownThresholdPct = config.Percentage(pl.ShutdownThresholdPct)
|
||||
}
|
||||
}
|
||||
for _, a := range a.AfiSafis {
|
||||
if a.Config != nil && family == a.Config.Family {
|
||||
ReadMpGracefulRestartFromAPIStruct(&afiSafi.MpGracefulRestart, a.MpGracefulRestart)
|
||||
ReadAfiSafiConfigFromAPIStruct(&afiSafi.Config, a.Config)
|
||||
ReadApplyPolicyFromAPIStruct(&afiSafi.ApplyPolicy, a.ApplyPolicy)
|
||||
ReadRouteSelectionOptionsFromAPIStruct(&afiSafi.RouteSelectionOptions, a.RouteSelectionOptions)
|
||||
ReadUseMultiplePathsFromAPIStruct(&afiSafi.UseMultiplePaths, a.UseMultiplePaths)
|
||||
ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, a.PrefixLimits)
|
||||
ReadRouteTargetMembershipFromAPIStruct(&afiSafi.RouteTargetMembership, a.RouteTargetMembership)
|
||||
ReadLongLivedGracefulRestartFromAPIStruct(&afiSafi.LongLivedGracefulRestart, a.LongLivedGracefulRestart)
|
||||
}
|
||||
}
|
||||
pconf.AfiSafis = append(pconf.AfiSafis, afiSafi)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1156,15 +939,26 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
|
||||
if a.RouteServer != nil {
|
||||
pconf.RouteServer.Config.RouteServerClient = a.RouteServer.RouteServerClient
|
||||
}
|
||||
if a.GracefulRestart != nil {
|
||||
pconf.GracefulRestart.Config.Enabled = a.GracefulRestart.Enabled
|
||||
pconf.GracefulRestart.Config.RestartTime = uint16(a.GracefulRestart.RestartTime)
|
||||
pconf.GracefulRestart.Config.HelperOnly = a.GracefulRestart.HelperOnly
|
||||
pconf.GracefulRestart.Config.DeferralTime = uint16(a.GracefulRestart.DeferralTime)
|
||||
pconf.GracefulRestart.Config.NotificationEnabled = a.GracefulRestart.NotificationEnabled
|
||||
pconf.GracefulRestart.Config.LongLivedEnabled = a.GracefulRestart.LonglivedEnabled
|
||||
if a.ApplyPolicy != nil {
|
||||
if a.ApplyPolicy.ImportPolicy != nil {
|
||||
pconf.ApplyPolicy.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.ImportPolicy.Default)]
|
||||
for _, p := range a.ApplyPolicy.ImportPolicy.Policies {
|
||||
pconf.ApplyPolicy.Config.ImportPolicyList = append(pconf.ApplyPolicy.Config.ImportPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
if a.ApplyPolicy.ExportPolicy != nil {
|
||||
pconf.ApplyPolicy.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.ExportPolicy.Default)]
|
||||
for _, p := range a.ApplyPolicy.ExportPolicy.Policies {
|
||||
pconf.ApplyPolicy.Config.ExportPolicyList = append(pconf.ApplyPolicy.Config.ExportPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
if a.ApplyPolicy.InPolicy != nil {
|
||||
pconf.ApplyPolicy.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.ApplyPolicy.InPolicy.Default)]
|
||||
for _, p := range a.ApplyPolicy.InPolicy.Policies {
|
||||
pconf.ApplyPolicy.Config.InPolicyList = append(pconf.ApplyPolicy.Config.InPolicyList, p.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
ReadApplyPolicyFromAPIStruct(&pconf.ApplyPolicy, a.ApplyPolicy)
|
||||
if a.Transport != nil {
|
||||
pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress
|
||||
pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode
|
||||
@ -1183,7 +977,6 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) {
|
||||
pconf.State.AdjTable.Advertised = a.Info.Advertised
|
||||
pconf.State.PeerAs = a.Info.PeerAs
|
||||
pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)]
|
||||
pconf.State.NeighborAddress = a.Info.NeighborAddress
|
||||
|
||||
if a.Info.Messages != nil {
|
||||
if a.Info.Messages.Sent != nil {
|
||||
|
4
vendor/github.com/osrg/gobgp/client/client.go
generated
vendored
4
vendor/github.com/osrg/gobgp/client/client.go
generated
vendored
@ -136,14 +136,14 @@ func (cli *Client) getNeighbor(name string, afi int, vrf string, enableAdvertise
|
||||
neighbors := make([]*config.Neighbor, 0, len(ret.Peers))
|
||||
|
||||
for _, p := range ret.Peers {
|
||||
if name != "" && name != p.Info.NeighborAddress && name != p.Conf.NeighborInterface {
|
||||
if name != "" && name != p.Conf.NeighborAddress && name != p.Conf.NeighborInterface {
|
||||
continue
|
||||
}
|
||||
if vrf != "" && name != p.Conf.Vrf {
|
||||
continue
|
||||
}
|
||||
if afi > 0 {
|
||||
v6 := net.ParseIP(p.Info.NeighborAddress).To4() == nil
|
||||
v6 := net.ParseIP(p.Conf.NeighborAddress).To4() == nil
|
||||
if afi == bgp.AFI_IP && v6 || afi == bgp.AFI_IP6 && !v6 {
|
||||
continue
|
||||
}
|
||||
|
156
vendor/github.com/osrg/gobgp/config/bgp_configs.go
generated
vendored
156
vendor/github.com/osrg/gobgp/config/bgp_configs.go
generated
vendored
@ -965,54 +965,6 @@ func (v RpkiValidationResultType) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//struct for container gobgp:state
|
||||
type DynamicNeighborState struct {
|
||||
// original -> gobgp:prefix
|
||||
Prefix string `mapstructure:"prefix" json:"prefix,omitempty"`
|
||||
// original -> gobgp:peer-group
|
||||
PeerGroup string `mapstructure:"peer-group" json:"peer-group,omitempty"`
|
||||
}
|
||||
|
||||
//struct for container gobgp:config
|
||||
type DynamicNeighborConfig struct {
|
||||
// original -> gobgp:prefix
|
||||
Prefix string `mapstructure:"prefix" json:"prefix,omitempty"`
|
||||
// original -> gobgp:peer-group
|
||||
PeerGroup string `mapstructure:"peer-group" json:"peer-group,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *DynamicNeighborConfig) Equal(rhs *DynamicNeighborConfig) bool {
|
||||
if lhs == nil || rhs == nil {
|
||||
return false
|
||||
}
|
||||
if lhs.Prefix != rhs.Prefix {
|
||||
return false
|
||||
}
|
||||
if lhs.PeerGroup != rhs.PeerGroup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//struct for container gobgp:dynamic-neighbor
|
||||
type DynamicNeighbor struct {
|
||||
// original -> gobgp:prefix
|
||||
// original -> gobgp:dynamic-neighbor-config
|
||||
Config DynamicNeighborConfig `mapstructure:"config" json:"config,omitempty"`
|
||||
// original -> gobgp:dynamic-neighbor-state
|
||||
State DynamicNeighborState `mapstructure:"state" json:"state,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *DynamicNeighbor) Equal(rhs *DynamicNeighbor) bool {
|
||||
if lhs == nil || rhs == nil {
|
||||
return false
|
||||
}
|
||||
if !lhs.Config.Equal(&(rhs.Config)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//struct for container gobgp:state
|
||||
type CollectorState struct {
|
||||
// original -> gobgp:url
|
||||
@ -1219,9 +1171,6 @@ type BmpServerConfig struct {
|
||||
RouteMonitoringPolicy BmpRouteMonitoringPolicyType `mapstructure:"route-monitoring-policy" json:"route-monitoring-policy,omitempty"`
|
||||
// original -> gobgp:statistics-timeout
|
||||
StatisticsTimeout uint16 `mapstructure:"statistics-timeout" json:"statistics-timeout,omitempty"`
|
||||
// original -> gobgp:route-mirroring-enabled
|
||||
//gobgp:route-mirroring-enabled's original type is boolean
|
||||
RouteMirroringEnabled bool `mapstructure:"route-mirroring-enabled" json:"route-mirroring-enabled,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *BmpServerConfig) Equal(rhs *BmpServerConfig) bool {
|
||||
@ -1240,9 +1189,6 @@ func (lhs *BmpServerConfig) Equal(rhs *BmpServerConfig) bool {
|
||||
if lhs.StatisticsTimeout != rhs.StatisticsTimeout {
|
||||
return false
|
||||
}
|
||||
if lhs.RouteMirroringEnabled != rhs.RouteMirroringEnabled {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1565,8 +1511,6 @@ type PeerGroup struct {
|
||||
UseMultiplePaths UseMultiplePaths `mapstructure:"use-multiple-paths" json:"use-multiple-paths,omitempty"`
|
||||
// original -> gobgp:route-server
|
||||
RouteServer RouteServer `mapstructure:"route-server" json:"route-server,omitempty"`
|
||||
// original -> gobgp:ttl-security
|
||||
TtlSecurity TtlSecurity `mapstructure:"ttl-security" json:"ttl-security,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *PeerGroup) Equal(rhs *PeerGroup) bool {
|
||||
@ -1628,58 +1572,6 @@ func (lhs *PeerGroup) Equal(rhs *PeerGroup) bool {
|
||||
if !lhs.RouteServer.Equal(&(rhs.RouteServer)) {
|
||||
return false
|
||||
}
|
||||
if !lhs.TtlSecurity.Equal(&(rhs.TtlSecurity)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//struct for container gobgp:state
|
||||
type TtlSecurityState struct {
|
||||
// original -> gobgp:enabled
|
||||
//gobgp:enabled's original type is boolean
|
||||
Enabled bool `mapstructure:"enabled" json:"enabled,omitempty"`
|
||||
// original -> gobgp:ttl-min
|
||||
TtlMin uint8 `mapstructure:"ttl-min" json:"ttl-min,omitempty"`
|
||||
}
|
||||
|
||||
//struct for container gobgp:config
|
||||
type TtlSecurityConfig struct {
|
||||
// original -> gobgp:enabled
|
||||
//gobgp:enabled's original type is boolean
|
||||
Enabled bool `mapstructure:"enabled" json:"enabled,omitempty"`
|
||||
// original -> gobgp:ttl-min
|
||||
TtlMin uint8 `mapstructure:"ttl-min" json:"ttl-min,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *TtlSecurityConfig) Equal(rhs *TtlSecurityConfig) bool {
|
||||
if lhs == nil || rhs == nil {
|
||||
return false
|
||||
}
|
||||
if lhs.Enabled != rhs.Enabled {
|
||||
return false
|
||||
}
|
||||
if lhs.TtlMin != rhs.TtlMin {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//struct for container gobgp:ttl-security
|
||||
type TtlSecurity struct {
|
||||
// original -> gobgp:ttl-security-config
|
||||
Config TtlSecurityConfig `mapstructure:"config" json:"config,omitempty"`
|
||||
// original -> gobgp:ttl-security-state
|
||||
State TtlSecurityState `mapstructure:"state" json:"state,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *TtlSecurity) Equal(rhs *TtlSecurity) bool {
|
||||
if lhs == nil || rhs == nil {
|
||||
return false
|
||||
}
|
||||
if !lhs.Config.Equal(&(rhs.Config)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -2073,8 +1965,6 @@ type TransportConfig struct {
|
||||
// original -> gobgp:remote-port
|
||||
//gobgp:remote-port's original type is inet:port-number
|
||||
RemotePort uint16 `mapstructure:"remote-port" json:"remote-port,omitempty"`
|
||||
// original -> gobgp:ttl
|
||||
Ttl uint8 `mapstructure:"ttl" json:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
|
||||
@ -2096,9 +1986,6 @@ func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
|
||||
if lhs.RemotePort != rhs.RemotePort {
|
||||
return false
|
||||
}
|
||||
if lhs.Ttl != rhs.Ttl {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -2275,10 +2162,6 @@ type Received struct {
|
||||
Keepalive uint64 `mapstructure:"keepalive" json:"keepalive,omitempty"`
|
||||
// original -> gobgp:DYNAMIC-CAP
|
||||
DynamicCap uint64 `mapstructure:"dynamic-cap" json:"dynamic-cap,omitempty"`
|
||||
// original -> gobgp:WITHDRAW-UPDATE
|
||||
WithdrawUpdate uint32 `mapstructure:"withdraw-update" json:"withdraw-update,omitempty"`
|
||||
// original -> gobgp:WITHDRAW-PREFIX
|
||||
WithdrawPrefix uint32 `mapstructure:"withdraw-prefix" json:"withdraw-prefix,omitempty"`
|
||||
// original -> gobgp:DISCARDED
|
||||
Discarded uint64 `mapstructure:"discarded" json:"discarded,omitempty"`
|
||||
// original -> gobgp:TOTAL
|
||||
@ -2307,12 +2190,6 @@ func (lhs *Received) Equal(rhs *Received) bool {
|
||||
if lhs.DynamicCap != rhs.DynamicCap {
|
||||
return false
|
||||
}
|
||||
if lhs.WithdrawUpdate != rhs.WithdrawUpdate {
|
||||
return false
|
||||
}
|
||||
if lhs.WithdrawPrefix != rhs.WithdrawPrefix {
|
||||
return false
|
||||
}
|
||||
if lhs.Discarded != rhs.Discarded {
|
||||
return false
|
||||
}
|
||||
@ -2336,10 +2213,6 @@ type Sent struct {
|
||||
Keepalive uint64 `mapstructure:"keepalive" json:"keepalive,omitempty"`
|
||||
// original -> gobgp:DYNAMIC-CAP
|
||||
DynamicCap uint64 `mapstructure:"dynamic-cap" json:"dynamic-cap,omitempty"`
|
||||
// original -> gobgp:WITHDRAW-UPDATE
|
||||
WithdrawUpdate uint32 `mapstructure:"withdraw-update" json:"withdraw-update,omitempty"`
|
||||
// original -> gobgp:WITHDRAW-PREFIX
|
||||
WithdrawPrefix uint32 `mapstructure:"withdraw-prefix" json:"withdraw-prefix,omitempty"`
|
||||
// original -> gobgp:DISCARDED
|
||||
Discarded uint64 `mapstructure:"discarded" json:"discarded,omitempty"`
|
||||
// original -> gobgp:TOTAL
|
||||
@ -2368,12 +2241,6 @@ func (lhs *Sent) Equal(rhs *Sent) bool {
|
||||
if lhs.DynamicCap != rhs.DynamicCap {
|
||||
return false
|
||||
}
|
||||
if lhs.WithdrawUpdate != rhs.WithdrawUpdate {
|
||||
return false
|
||||
}
|
||||
if lhs.WithdrawPrefix != rhs.WithdrawPrefix {
|
||||
return false
|
||||
}
|
||||
if lhs.Discarded != rhs.Discarded {
|
||||
return false
|
||||
}
|
||||
@ -2580,8 +2447,6 @@ type Neighbor struct {
|
||||
UseMultiplePaths UseMultiplePaths `mapstructure:"use-multiple-paths" json:"use-multiple-paths,omitempty"`
|
||||
// original -> gobgp:route-server
|
||||
RouteServer RouteServer `mapstructure:"route-server" json:"route-server,omitempty"`
|
||||
// original -> gobgp:ttl-security
|
||||
TtlSecurity TtlSecurity `mapstructure:"ttl-security" json:"ttl-security,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *Neighbor) Equal(rhs *Neighbor) bool {
|
||||
@ -2643,9 +2508,6 @@ func (lhs *Neighbor) Equal(rhs *Neighbor) bool {
|
||||
if !lhs.RouteServer.Equal(&(rhs.RouteServer)) {
|
||||
return false
|
||||
}
|
||||
if !lhs.TtlSecurity.Equal(&(rhs.TtlSecurity)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -3890,8 +3752,6 @@ type Bgp struct {
|
||||
Zebra Zebra `mapstructure:"zebra" json:"zebra,omitempty"`
|
||||
// original -> gobgp:collector
|
||||
Collector Collector `mapstructure:"collector" json:"collector,omitempty"`
|
||||
// original -> gobgp:dynamic-neighbors
|
||||
DynamicNeighbors []DynamicNeighbor `mapstructure:"dynamic-neighbors" json:"dynamic-neighbors,omitempty"`
|
||||
}
|
||||
|
||||
func (lhs *Bgp) Equal(rhs *Bgp) bool {
|
||||
@ -3987,22 +3847,6 @@ func (lhs *Bgp) Equal(rhs *Bgp) bool {
|
||||
if !lhs.Collector.Equal(&(rhs.Collector)) {
|
||||
return false
|
||||
}
|
||||
if len(lhs.DynamicNeighbors) != len(rhs.DynamicNeighbors) {
|
||||
return false
|
||||
}
|
||||
{
|
||||
lmap := make(map[string]*DynamicNeighbor)
|
||||
for i, l := range lhs.DynamicNeighbors {
|
||||
lmap[mapkey(i, string(l.Config.Prefix))] = &lhs.DynamicNeighbors[i]
|
||||
}
|
||||
for i, r := range rhs.DynamicNeighbors {
|
||||
if l, y := lmap[mapkey(i, string(r.Config.Prefix))]; !y {
|
||||
return false
|
||||
} else if !r.Equal(l) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
142
vendor/github.com/osrg/gobgp/config/default.go
generated
vendored
142
vendor/github.com/osrg/gobgp/config/default.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"github.com/osrg/gobgp/packet/rtr"
|
||||
"github.com/spf13/viper"
|
||||
"net"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -16,20 +15,6 @@ const (
|
||||
DEFAULT_CONNECT_RETRY = 120
|
||||
)
|
||||
|
||||
var forcedOverwrittenConfig = []string{
|
||||
"neighbor.config.peer-as",
|
||||
"neighbor.timers.config.minimum-advertisement-interval",
|
||||
}
|
||||
|
||||
var configuredFields map[string]interface{}
|
||||
|
||||
func RegisterConfiguredFields(addr string, n interface{}) {
|
||||
if configuredFields == nil {
|
||||
configuredFields = make(map[string]interface{}, 0)
|
||||
}
|
||||
configuredFields[addr] = n
|
||||
}
|
||||
|
||||
func defaultAfiSafi(typ AfiSafiType, enable bool) AfiSafi {
|
||||
return AfiSafi{
|
||||
Config: AfiSafiConfig{
|
||||
@ -130,10 +115,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
|
||||
}
|
||||
}
|
||||
|
||||
if n.State.NeighborAddress == "" {
|
||||
n.State.NeighborAddress = n.Config.NeighborAddress
|
||||
}
|
||||
|
||||
n.State.PeerAs = n.Config.PeerAs
|
||||
n.AsPathOptions.State.AllowOwnAs = n.AsPathOptions.Config.AllowOwnAs
|
||||
|
||||
@ -158,14 +139,14 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.State.NeighborAddress = addr
|
||||
n.Config.NeighborAddress = addr
|
||||
}
|
||||
|
||||
if n.Transport.Config.LocalAddress == "" {
|
||||
if n.State.NeighborAddress == "" {
|
||||
if n.Config.NeighborAddress == "" {
|
||||
return fmt.Errorf("no neighbor address/interface specified")
|
||||
}
|
||||
ipAddr, err := net.ResolveIPAddr("ip", n.State.NeighborAddress)
|
||||
ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -188,8 +169,8 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
|
||||
defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true),
|
||||
defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true),
|
||||
}
|
||||
} else if ipAddr, err := net.ResolveIPAddr("ip", n.State.NeighborAddress); err != nil {
|
||||
return fmt.Errorf("invalid neighbor address: %s", n.State.NeighborAddress)
|
||||
} else if ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress); err != nil {
|
||||
return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress)
|
||||
} else if ipAddr.IP.To4() != nil {
|
||||
n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true)}
|
||||
} else {
|
||||
@ -209,7 +190,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
|
||||
if !vv.IsSet("afi-safi.config") {
|
||||
af.Config.Enabled = true
|
||||
}
|
||||
af.MpGracefulRestart.State.Enabled = af.MpGracefulRestart.Config.Enabled
|
||||
n.AfiSafis[i] = af
|
||||
}
|
||||
}
|
||||
@ -232,11 +212,6 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
|
||||
n.GracefulRestart.Config.DeferralTime = uint16(360)
|
||||
}
|
||||
}
|
||||
|
||||
if n.EbgpMultihop.Config.Enabled && n.TtlSecurity.Config.Enabled {
|
||||
return fmt.Errorf("ebgp-multihop and ttl-security are mututally exclusive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -279,45 +254,6 @@ func setDefaultPolicyConfigValuesWithViper(v *viper.Viper, p *PolicyDefinition)
|
||||
return nil
|
||||
}
|
||||
|
||||
func validatePeerGroupConfig(n *Neighbor, b *BgpConfigSet) error {
|
||||
name := n.Config.PeerGroup
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
pg, err := getPeerGroup(name, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if pg.Config.PeerAs != 0 && n.Config.PeerAs != 0 {
|
||||
return fmt.Errorf("Cannot configure remote-as for members. PeerGroup AS %d.", pg.Config.PeerAs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPeerGroup(n string, b *BgpConfigSet) (*PeerGroup, error) {
|
||||
if n == "" {
|
||||
return nil, fmt.Errorf("peer-group name is not configured")
|
||||
}
|
||||
for _, pg := range b.PeerGroups {
|
||||
if n == pg.Config.PeerGroupName {
|
||||
return &pg, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("No such peer-group: %s", n)
|
||||
}
|
||||
|
||||
func validateDynamicNeighborConfig(d *DynamicNeighborConfig, b *BgpConfigSet) error {
|
||||
if _, err := getPeerGroup(d.PeerGroup, b); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, _, err := net.ParseCIDR(d.Prefix); err != nil {
|
||||
return fmt.Errorf("Invalid Dynamic Neighbor prefix %s", d.Prefix)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
|
||||
if v == nil {
|
||||
v = viper.New()
|
||||
@ -357,10 +293,6 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
|
||||
}
|
||||
|
||||
for idx, n := range b.Neighbors {
|
||||
if err := validatePeerGroupConfig(&n, b); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vv := viper.New()
|
||||
if len(list) > idx {
|
||||
vv.Set("neighbor", list[idx])
|
||||
@ -369,16 +301,6 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
|
||||
return err
|
||||
}
|
||||
b.Neighbors[idx] = n
|
||||
|
||||
if n.Config.PeerGroup != "" {
|
||||
RegisterConfiguredFields(vv.Get("neighbor.config.neighbor-address").(string), list[idx])
|
||||
}
|
||||
}
|
||||
|
||||
for _, d := range b.DynamicNeighbors {
|
||||
if err := validateDynamicNeighborConfig(&d.Config, b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for idx, r := range b.RpkiServers {
|
||||
@ -405,57 +327,3 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func OverwriteNeighborConfigWithPeerGroup(c *Neighbor, pg *PeerGroup) error {
|
||||
v := viper.New()
|
||||
|
||||
val, ok := configuredFields[c.State.NeighborAddress]
|
||||
if ok {
|
||||
v.Set("neighbor", val)
|
||||
} else {
|
||||
v.Set("neighbor.config.peer-group", c.Config.PeerGroup)
|
||||
}
|
||||
|
||||
overwriteConfig(&c.Config, &pg.Config, "neighbor.config", v)
|
||||
overwriteConfig(&c.Timers.Config, &pg.Timers.Config, "neighbor.timers.config", v)
|
||||
overwriteConfig(&c.Transport.Config, &pg.Transport.Config, "neighbor.transport.config", v)
|
||||
overwriteConfig(&c.ErrorHandling.Config, &pg.ErrorHandling.Config, "neighbor.error-handling.config", v)
|
||||
overwriteConfig(&c.LoggingOptions.Config, &pg.LoggingOptions.Config, "neighbor.logging-options.config", v)
|
||||
overwriteConfig(&c.EbgpMultihop.Config, &pg.EbgpMultihop.Config, "neighbor.ebgp-multihop.config", v)
|
||||
overwriteConfig(&c.RouteReflector.Config, &pg.RouteReflector.Config, "neighbor.route-reflector.config", v)
|
||||
overwriteConfig(&c.AsPathOptions.Config, &pg.AsPathOptions.Config, "neighbor.as-path-options.config", v)
|
||||
overwriteConfig(&c.AddPaths.Config, &pg.AddPaths.Config, "neighbor.add-paths.config", v)
|
||||
overwriteConfig(&c.GracefulRestart.Config, &pg.GracefulRestart.Config, "neighbor.gradeful-restart.config", v)
|
||||
overwriteConfig(&c.ApplyPolicy.Config, &pg.ApplyPolicy.Config, "neighbor.apply-policy.config", v)
|
||||
overwriteConfig(&c.UseMultiplePaths.Config, &pg.UseMultiplePaths.Config, "neighbor.use-multiple-paths.config", v)
|
||||
overwriteConfig(&c.RouteServer.Config, &pg.RouteServer.Config, "neighbor.route-server.config", v)
|
||||
overwriteConfig(&c.TtlSecurity.Config, &pg.TtlSecurity.Config, "neighbor.ttl-security.config", v)
|
||||
|
||||
if !v.IsSet("neighbor.afi-safis") {
|
||||
c.AfiSafis = pg.AfiSafis
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func overwriteConfig(c, pg interface{}, tagPrefix string, v *viper.Viper) {
|
||||
nValue := reflect.Indirect(reflect.ValueOf(c))
|
||||
nType := reflect.Indirect(nValue).Type()
|
||||
pgValue := reflect.Indirect(reflect.ValueOf(pg))
|
||||
pgType := reflect.Indirect(pgValue).Type()
|
||||
|
||||
for i := 0; i < pgType.NumField(); i++ {
|
||||
field := pgType.Field(i).Name
|
||||
tag := tagPrefix + "." + nType.Field(i).Tag.Get("mapstructure")
|
||||
if func() bool {
|
||||
for _, t := range forcedOverwrittenConfig {
|
||||
if t == tag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}() || !v.IsSet(tag) {
|
||||
nValue.FieldByName(field).Set(pgValue.FieldByName(field))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
vendor/github.com/osrg/gobgp/config/serve.go
generated
vendored
45
vendor/github.com/osrg/gobgp/config/serve.go
generated
vendored
@ -1,7 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"os"
|
||||
"os/signal"
|
||||
@ -19,7 +19,6 @@ type BgpConfigSet struct {
|
||||
Collector Collector `mapstructure:"collector"`
|
||||
DefinedSets DefinedSets `mapstructure:"defined-sets"`
|
||||
PolicyDefinitions []PolicyDefinition `mapstructure:"policy-definitions"`
|
||||
DynamicNeighbors []DynamicNeighbor `mapstructure:"dynamic-neighbors"`
|
||||
}
|
||||
|
||||
func ReadConfigfileServe(path, format string, configCh chan *BgpConfigSet) {
|
||||
@ -77,16 +76,7 @@ func ReadConfigfileServe(path, format string, configCh chan *BgpConfigSet) {
|
||||
|
||||
func inSlice(n Neighbor, b []Neighbor) int {
|
||||
for i, nb := range b {
|
||||
if nb.State.NeighborAddress == n.State.NeighborAddress {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func existPeerGroup(n string, b []PeerGroup) int {
|
||||
for i, nb := range b {
|
||||
if nb.Config.PeerGroupName == n {
|
||||
if nb.Config.NeighborAddress == n.Config.NeighborAddress {
|
||||
return i
|
||||
}
|
||||
}
|
||||
@ -100,34 +90,8 @@ func ConfigSetToRoutingPolicy(c *BgpConfigSet) *RoutingPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatePeerGroupConfig(curC, newC *BgpConfigSet) ([]PeerGroup, []PeerGroup, []PeerGroup) {
|
||||
addedPg := []PeerGroup{}
|
||||
deletedPg := []PeerGroup{}
|
||||
updatedPg := []PeerGroup{}
|
||||
func UpdateConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor, bool) {
|
||||
|
||||
for _, n := range newC.PeerGroups {
|
||||
if idx := existPeerGroup(n.Config.PeerGroupName, curC.PeerGroups); idx < 0 {
|
||||
addedPg = append(addedPg, n)
|
||||
} else if !n.Equal(&curC.PeerGroups[idx]) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Config",
|
||||
}).Debugf("Current peer-group config:%s", curC.PeerGroups[idx])
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Config",
|
||||
}).Debugf("New peer-group config:%s", n)
|
||||
updatedPg = append(updatedPg, n)
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range curC.PeerGroups {
|
||||
if existPeerGroup(n.Config.PeerGroupName, newC.PeerGroups) < 0 {
|
||||
deletedPg = append(deletedPg, n)
|
||||
}
|
||||
}
|
||||
return addedPg, deletedPg, updatedPg
|
||||
}
|
||||
|
||||
func UpdateNeighborConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor) {
|
||||
added := []Neighbor{}
|
||||
deleted := []Neighbor{}
|
||||
updated := []Neighbor{}
|
||||
@ -151,7 +115,8 @@ func UpdateNeighborConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []N
|
||||
deleted = append(deleted, n)
|
||||
}
|
||||
}
|
||||
return added, deleted, updated
|
||||
|
||||
return added, deleted, updated, CheckPolicyDifference(ConfigSetToRoutingPolicy(curC), ConfigSetToRoutingPolicy(newC))
|
||||
}
|
||||
|
||||
func CheckPolicyDifference(currentPolicy *RoutingPolicy, newPolicy *RoutingPolicy) bool {
|
||||
|
11
vendor/github.com/osrg/gobgp/config/util.go
generated
vendored
11
vendor/github.com/osrg/gobgp/config/util.go
generated
vendored
@ -140,14 +140,3 @@ func ParseMaskLength(prefix, mask string) (int, int, error) {
|
||||
}
|
||||
return min, max, nil
|
||||
}
|
||||
|
||||
func ExtractNeighborAddress(c *Neighbor) (string, error) {
|
||||
addr := c.State.NeighborAddress
|
||||
if addr == "" {
|
||||
addr = c.Config.NeighborAddress
|
||||
if addr == "" {
|
||||
return "", fmt.Errorf("NeighborAddress is not configured")
|
||||
}
|
||||
}
|
||||
return addr, nil
|
||||
}
|
||||
|
11
vendor/github.com/osrg/gobgp/docs/sources/bmp.md
generated
vendored
11
vendor/github.com/osrg/gobgp/docs/sources/bmp.md
generated
vendored
@ -64,17 +64,6 @@ Please note the range of this interval is 15 though 65535 seconds.
|
||||
statistics-timeout = 3600
|
||||
```
|
||||
|
||||
To enable route mirroring feature, specify `true` for `route-mirroring-enabled` option.
|
||||
Please note this option is mainly for debugging purpose.
|
||||
|
||||
```toml
|
||||
[[bmp-servers]]
|
||||
[bmp-servers.config]
|
||||
address = "127.0.0.1"
|
||||
port=11019
|
||||
route-mirroring-enabled = true
|
||||
```
|
||||
|
||||
## <a name="verify"> Verification
|
||||
|
||||
Let's check if BMP works with a bmp server. GoBGP also supports BMP server (currently, just shows received BMP messages in the json format).
|
||||
|
22
vendor/github.com/osrg/gobgp/docs/sources/configuration.md
generated
vendored
22
vendor/github.com/osrg/gobgp/docs/sources/configuration.md
generated
vendored
@ -52,8 +52,6 @@
|
||||
# override global.config.as value
|
||||
local-as = 1000
|
||||
remove-private-as = "all"
|
||||
# To enable peer group setting, uncomment the following
|
||||
#peer-group = "my-peer-group"
|
||||
[neighbors.as-path-options.config]
|
||||
allow-own-as = 1
|
||||
replace-peer-as = true
|
||||
@ -65,7 +63,6 @@
|
||||
passive-mode = true
|
||||
local-address = "192.168.10.1"
|
||||
remote-port = 2016
|
||||
ttl = 64 # default value on Linux
|
||||
[neighbors.ebgp-multihop.config]
|
||||
enabled = true
|
||||
multihop-ttl = 100
|
||||
@ -132,25 +129,6 @@
|
||||
default-in-policy = "reject-route"
|
||||
[neighbors.route-server.config]
|
||||
route-server-client = true
|
||||
# To enable TTL Security, uncomment the following.
|
||||
# Please note that this feature is mututally exclusive with
|
||||
# "neighbors.ebgp-multihop.config".
|
||||
#[neighbors.ttl-security.config]
|
||||
# enabled = true
|
||||
# ttl-min = 255 # 255 means directly connected
|
||||
|
||||
[[peer-groups]]
|
||||
[peer-groups.config]
|
||||
peer-group-name = "my-peer-group"
|
||||
peer-as = 65000
|
||||
[[peer-groups.afi-safis]]
|
||||
[peer-groups.afi-safis.config]
|
||||
afi-safi-name = "ipv4-unicast"
|
||||
|
||||
[[dynamic-neighbors]]
|
||||
[dynamic-neighbors.config]
|
||||
prefix = "20.0.0.0/24"
|
||||
peer-group = "my-peer-group"
|
||||
|
||||
[[defined-sets.prefix-sets]]
|
||||
prefix-set-name = "ps0"
|
||||
|
2
vendor/github.com/osrg/gobgp/docs/sources/getting-started.md
generated
vendored
2
vendor/github.com/osrg/gobgp/docs/sources/getting-started.md
generated
vendored
@ -86,7 +86,7 @@ neighbors:
|
||||
```
|
||||
|
||||
```bash
|
||||
$ sudo -E gobgpd -t yaml -f gobgpd.yml
|
||||
$ sudo -E gobgpd -t yaml gobgpd.yml
|
||||
{"level":"info","msg":"Peer 10.0.255.1 is added","time":"2015-04-06T20:32:28+09:00"}
|
||||
{"level":"info","msg":"Peer 10.0.255.2 is added","time":"2015-04-06T20:32:28+09:00"}
|
||||
```
|
||||
|
483
vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md
generated
vendored
483
vendor/github.com/osrg/gobgp/docs/sources/grpc-client.md
generated
vendored
@ -3,24 +3,72 @@
|
||||
This page explains how to managing GoBGP with your favorite Language.
|
||||
You can use any language supported by [gRPC](http://www.grpc.io/) (10
|
||||
languages are supported now). This page gives an example in Python,
|
||||
Ruby, C++, Node.js, and Java. It assumes that you use Ubuntu 16.04 (64bit).
|
||||
Ruby, C++, Node.js, and Java. It assumes that you use Ubuntu 14.04 (64bit).
|
||||
|
||||
## Contents
|
||||
|
||||
- [Prerequisite](#prerequisite)
|
||||
- [Python](#python)
|
||||
- [Ruby](#ruby)
|
||||
- [C++](#cpp)
|
||||
- [Node.js](#nodejs)
|
||||
- [Java](#java)
|
||||
|
||||
## <a name="prerequisite"> Prerequisite
|
||||
We assumes that you have finished installing `protoc` [protocol buffer](https://github.com/google/protobuf) compiler to generate stub server and client code and "protobuf runtime" for your favorite language.
|
||||
|
||||
Please refer to [the official docs of gRPC](http://www.grpc.io/docs/) for details.
|
||||
|
||||
## <a name="python"> Python
|
||||
|
||||
We need to install ProtocolBuffers and gRPC libraries.
|
||||
|
||||
### Install ProtocolBuffers:
|
||||
```bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install -y build-essential autoconf git libtool unzip
|
||||
$ mkdir ~/work
|
||||
$ cd ~/work
|
||||
$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-1.tar.gz
|
||||
$ tar xvzf v3.0.0-beta-1.tar.gz
|
||||
$ cd protobuf-3.0.0-beta-1
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ vi ~/.bashrc
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
```
|
||||
|
||||
please check the version.
|
||||
```bash
|
||||
$ protoc --version
|
||||
libprotoc 3.0.0
|
||||
```
|
||||
|
||||
### Install gRPC:
|
||||
```bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install -y python-all-dev python-virtualenv
|
||||
$ cd ~/work
|
||||
$ git clone https://github.com/grpc/grpc.git
|
||||
$ cd grpc
|
||||
$ git checkout -b release-0_11_1 release-0_11_1
|
||||
$ git submodule update --init
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
### Install Python Libraries:
|
||||
|
||||
Install python libraries for protobuf and gRPC.
|
||||
Please use virtualenv if you want to keep your environment clean.
|
||||
In this example we create venv directory at $HOME/venv.
|
||||
|
||||
```bash
|
||||
$ virtualenv ~/venv
|
||||
$ source ~/venv/bin/activate
|
||||
$ cd ~/work/protobuf-3.0.0-beta-1/python
|
||||
$ python setup.py install
|
||||
$ cd ~/work/grpc/src/python/grpcio/
|
||||
$ python setup.py install
|
||||
$ deactivate
|
||||
```
|
||||
|
||||
### Generating Stub Code
|
||||
|
||||
We need to generate stub code GoBGP at first.
|
||||
@ -32,23 +80,93 @@ $ protoc -I $GOBGP_API --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`wh
|
||||
|
||||
### Get Neighbor
|
||||
|
||||
['tools/grpc/python/get_neighbor.py'](https://github.com/osrg/gobgp/blob/master/tools/grpc/python/get_neighbor.py) shows an example for getting neighbor's information.
|
||||
Here is an example for getting neighbor's information and we assumed that it's created in 'get_neighbor.py' under '$GOPATH/src/github.com/osrg/gobgp/tools/grpc/python'.
|
||||
```python
|
||||
import gobgp_pb2
|
||||
import sys
|
||||
|
||||
from grpc.beta import implementations
|
||||
|
||||
_TIMEOUT_SECONDS = 10
|
||||
|
||||
|
||||
def run(gobgpd_addr, neighbor_addr):
|
||||
channel = implementations.insecure_channel(gobgpd_addr, 50051)
|
||||
with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:
|
||||
peer = stub.GetNeighbor(gobgp_pb2.Arguments(rf=4, name=neighbor_addr), _TIMEOUT_SECONDS)
|
||||
print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
|
||||
print(" BGP version 4, remote router ID %s" % (peer.conf.id))
|
||||
print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
|
||||
print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
|
||||
print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
|
||||
print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gobgp = sys.argv[1]
|
||||
neighbor = sys.argv[2]
|
||||
run(gobgp, neighbor)
|
||||
```
|
||||
|
||||
We need to import gobgp_pb2 and call 'beta_create_GobgpApi_stub' in your code.
|
||||
|
||||
Let's run this script.
|
||||
|
||||
```bash
|
||||
$ python get_neighbor.py 172.18.0.2
|
||||
BGP neighbor is 10.0.0.2, remote AS 65002
|
||||
BGP version 4, remote router ID
|
||||
BGP state = active, up for 0
|
||||
$ source ~/venv/bin/activate
|
||||
(venv)$ python get_neighbor.py 10.0.255.1 10.0.0.1
|
||||
BGP neighbor is 10.0.0.1, remote AS 65001
|
||||
BGP version 4, remote router ID 192.168.0.1
|
||||
BGP state = BGP_FSM_ESTABLISHED, up for 9042
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90, keepalive interval is 30 seconds
|
||||
Hold time is 30, keepalive interval is 10 seconds
|
||||
Configured hold time is 30, keepalive interval is 10 seconds
|
||||
|
||||
```
|
||||
|
||||
We got the neighbor information successfully.
|
||||
|
||||
## <a name="ruby"> Ruby
|
||||
|
||||
### Install ProtoBuffers:
|
||||
|
||||
```bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install -y build-essential curl git m4 ruby autoconf libtool unzip
|
||||
$ mkdir ~/work
|
||||
$ cd ~/work
|
||||
$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-1.tar.gz
|
||||
$ tar xvzf v3.0.0-beta-1.tar.gz
|
||||
$ cd protobuf-3.0.0-beta-1
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ vi ~/.bashrc
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
```
|
||||
|
||||
### Installing gRPC and Ruby Libraries
|
||||
|
||||
```bash
|
||||
$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
|
||||
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
|
||||
$ source $HOME/.rvm/scripts/rvm
|
||||
$ rvm install 2.1
|
||||
$ gem install bundler
|
||||
$ cd ~/work/
|
||||
$ git clone https://github.com/grpc/grpc.git
|
||||
$ cd grpc
|
||||
$ git checkout -b release-0_11_1 release-0_11_1
|
||||
$ git submodule update --init
|
||||
$ $ make
|
||||
$ $ sudo make install
|
||||
$ cd src/ruby/
|
||||
$ gem build grpc.gemspec
|
||||
$ bundle install
|
||||
$ gem install -l grpc-0.11.0.gem
|
||||
```
|
||||
|
||||
### Generating Stub Code
|
||||
|
||||
We need to generate stub code GoBGP at first.
|
||||
@ -60,67 +178,195 @@ $ protoc -I $GOBGP_API --ruby_out=. --grpc_out=. --plugin=protoc-gen-grpc=`whic
|
||||
|
||||
### Get Neighbor
|
||||
|
||||
['tools/grpc/ruby/get_neighbor.py'](https://github.com/osrg/gobgp/blob/master/tools/grpc/ruby/get_neighbor.rb) shows an example for getting neighbor's information.
|
||||
Here is an example for getting neighbor's information.
|
||||
```ruby
|
||||
require 'gobgp'
|
||||
require 'gobgp_services'
|
||||
|
||||
host = 'localhost'
|
||||
host = ARGV[0] if ARGV.length > 0
|
||||
|
||||
stub = Gobgpapi::GobgpApi::Stub.new("#{host}:50051")
|
||||
arg = Gobgpapi::Arguments.new()
|
||||
stub.get_neighbors(arg).each do |n|
|
||||
puts "BGP neighbor is #{n.conf.neighbor_address}, remote AS #{n.conf.peer_as}"
|
||||
puts "\tBGP version 4, remote route ID #{n.conf.id}"
|
||||
puts "\tBGP state = #{n.info.bgp_state}, up for #{n.timers.state.uptime}"
|
||||
puts "\tBGP OutQ = #{n.info.out_q}, Flops = #{n.info.flops}"
|
||||
puts "\tHold time is #{n.timers.state.hold_time}, keepalive interval is #{n.timers.state.keepalive_interval} seconds"
|
||||
puts "\tConfigured hold time is #{n.timers.config.hold_time}"
|
||||
end
|
||||
```
|
||||
|
||||
Let's run this script.
|
||||
|
||||
```bash
|
||||
$ ruby -I . ./get_neighbors.rb 172.18.0.2
|
||||
BGP neighbor is 10.0.0.2, remote AS 65002
|
||||
BGP version 4, remote route ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90
|
||||
$ruby -I . ./get_neighbors.rb
|
||||
BGP neighbor is 192.168.10.2, remote AS 65001
|
||||
BGP version 4, remote route ID <nil>
|
||||
BGP state = BGP_FSM_ACTIVE, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90
|
||||
BGP neighbor is 192.168.10.3, remote AS 65001
|
||||
BGP version 4, remote route ID <nil>
|
||||
BGP state = BGP_FSM_ACTIVE, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90
|
||||
```
|
||||
|
||||
## <a name="cpp"> C++
|
||||
|
||||
For gRPC we need so much dependencies, please make coffee and be ready!
|
||||
|
||||
### Install ProtoBuffers:
|
||||
```bash
|
||||
apt-get update
|
||||
apt-get install -y gcc make autoconf automake git libtool g++ curl
|
||||
|
||||
cd /usr/src
|
||||
wget https://github.com/google/protobuf/archive/v3.0.0-alpha-4.tar.gz
|
||||
tar -xf v3.0.0-alpha-4.tar.gz
|
||||
cd protobuf-3.0.0-alpha-4/
|
||||
./autogen.sh
|
||||
./configure --prefix=/opt/protobuf_3.0.0_alpha4
|
||||
make -j 4
|
||||
make install
|
||||
```
|
||||
|
||||
### Install gRPC:
|
||||
```bash
|
||||
apt-get update
|
||||
apt-get install -y gcc make autoconf automake git libtool g++ python-all-dev python-virtualenv
|
||||
|
||||
cd /usr/src/
|
||||
git clone https://github.com/grpc/grpc.git
|
||||
cd grpc
|
||||
# We are using specific commit because gRPC is under heavy development right now
|
||||
git checkout e5cdbea1530a99a95fd3d032e7d69a19c61a0d16
|
||||
git submodule update --init
|
||||
make -j 4
|
||||
make install prefix=/opt/grpc
|
||||
```
|
||||
|
||||
We use .so compilation with golang, please use only 1.5 or newer version of Go Lang.
|
||||
|
||||
['tools/grpc/cpp/gobgp_api_client.cc'](https://github.com/osrg/gobgp/blob/master/tools/grpc/cpp/gobgp_api_client.cc) shows an example for getting neighbor's information.
|
||||
|
||||
We provide ['tools/grpc/cpp/build.sh'](https://github.com/osrg/gobgp/blob/master/tools/grpc/cpp/build.sh) to build this sample code.
|
||||
This script also generates stub codes and builds GoBGP shared library.
|
||||
|
||||
Let's build the sample code:
|
||||
Clone this repository and build API example:
|
||||
```bash
|
||||
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/cpp
|
||||
$ bash build.sh
|
||||
export PATH="$PATH:/opt//grpc/bin:/opt/protobuf_3.0.0_alpha4/bin/"
|
||||
|
||||
cd /usr/src
|
||||
git clone https://github.com/osrg/gobgp.git
|
||||
cd gobgp/gobgp/lib
|
||||
go build -buildmode=c-shared -o libgobgp.so *.go
|
||||
cp libgobgp.h /usr/src/gobgp/tools/grpc/cpp
|
||||
cp libgobgp.so /usr/src/gobgp/tools/grpc/cpp
|
||||
cp /usr/src/gobgp/api/gobgp.proto /usr/src/gobgp/tools/grpc/cpp/gobgp_api_client.proto
|
||||
cd /usr/src/gobgp/tools/grpc/cpp
|
||||
make
|
||||
```
|
||||
|
||||
### Let's run it:
|
||||
```bash
|
||||
$ ./gobgp_api_client 172.18.0.2
|
||||
BGP neighbor is: 10.0.0.2, remote AS: 1
|
||||
BGP version: 4, remote route ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0seconds
|
||||
Configured hold time is 90
|
||||
BGP neighbor is: 10.0.0.3, remote AS: 1
|
||||
BGP version: 4, remote route ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0seconds
|
||||
Configured hold time is 90
|
||||
LD_LIBRARY_PATH=".:/opt/grpc/lib:/opt/protobuf_3.0.0_alpha4/lib" ./gobgp_api_client
|
||||
|
||||
List of announced prefixes for route family: 65537
|
||||
|
||||
Prefix: 10.10.20.0/22
|
||||
NLRI: {"nlri":{"prefix":"10.10.20.0/22"},"attrs":[{"type":1,"value":0},{"type":3,"nexthop":"0.0.0.0"}]}
|
||||
|
||||
|
||||
List of announced prefixes for route family: 65669
|
||||
|
||||
Prefix: [destination:10.0.0.0/24][protocol: tcp][source:20.0.0.0/24]
|
||||
NLRI: {"nlri":{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]},"attrs":[{"type":1,"value":0},{"type":14,"nexthop":"0.0.0.0","afi":1,"safi":133,"value":[{"value":[{"type":1,"value":{"prefix":"10.0.0.0/24"}},{"type":3,"value":[{"op":129,"value":6}]},{"type":2,"value":{"prefix":"20.0.0.0/24"}}]}]},{"type":16,"value":[{"type":128,"subtype":8,"value":"10:10"}]}]}
|
||||
```
|
||||
|
||||
## <a name="nodejs"> Node.js
|
||||
|
||||
Build from source code because there is no official gRPC package for Ubuntu 14.04.
|
||||
(Debian Linux and Mac OSX are much easier. See [the document](https://github.com/grpc/grpc/tree/release-0_11/src/node))
|
||||
|
||||
|
||||
### Install Protocol Buffers:
|
||||
|
||||
Install protobuf v3.0.0-beta before gRPC. gRPC installation process will try to do it automatically but fail. (Probably because it tries another version of protobuf)
|
||||
|
||||
See [installation document](https://github.com/grpc/grpc/blob/master/INSTALL).
|
||||
|
||||
```bash
|
||||
$ [sudo] apt-get install unzip autoconf libtool build-essential
|
||||
|
||||
$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-4.tar.gz
|
||||
$ tar zxvf v3.0.0-beta-4.tar.gz
|
||||
$ cd protobuf-3.0.0-beta-4/
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ [sudo] make install
|
||||
```
|
||||
|
||||
### Install gRPC:
|
||||
|
||||
```bash
|
||||
$ [sudo] apt-get install git
|
||||
|
||||
$ git clone https://github.com/grpc/grpc.git
|
||||
$ cd grpc
|
||||
$ git submodule update --init
|
||||
$ make
|
||||
$ [sudo] make install
|
||||
```
|
||||
|
||||
### Install Node.js gRPC library:
|
||||
|
||||
Let's say Node.js is already installed,
|
||||
|
||||
```bash
|
||||
npm install grpc
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
Copy protocol definition.
|
||||
|
||||
```bash
|
||||
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/nodejs
|
||||
$ ln -s $GOPATH/src/github.com/osrg/gobgp/api/gobgp.proto
|
||||
cp $GOPATH/src/github.com/osrg/gobgp/api/gobgp.proto .
|
||||
```
|
||||
|
||||
Here is an example to show neighbor information.
|
||||
|
||||
```javascript
|
||||
var grpc = require('grpc');
|
||||
var api = grpc.load('gobgp.proto').gobgpapi;
|
||||
var stub = new api.GobgpApi('localhost:50051', grpc.credentials.createInsecure());
|
||||
|
||||
stub.getNeighbor({}, function(err, neighbor) {
|
||||
neighbor.peers.forEach(function(peer) {
|
||||
if(peer.info.bgp_state == 'BGP_FSM_ESTABLISHED') {
|
||||
var date = new Date(Number(peer.timers.state.uptime)*1000);
|
||||
var holdtime = peer.timers.state.negotiated_hold_time;
|
||||
var keepalive = peer.timers.state.keepalive_interval;
|
||||
}
|
||||
|
||||
console.log('BGP neighbor:', peer.conf.neighbor_address,
|
||||
', remote AS:', peer.conf.peer_as);
|
||||
console.log("\tBGP version 4, remote router ID:", peer.conf.id);
|
||||
console.log("\tBGP state:", peer.info.bgp_state,
|
||||
', uptime:', date);
|
||||
console.log("\tBGP OutQ:", peer.info.out_q,
|
||||
', Flops:', peer.info.flops);
|
||||
console.log("\tHold time:", holdtime,
|
||||
', keepalive interval:', keepalive, 'seconds');
|
||||
console.log("\tConfigured hold time:", peer.timers.config.hold_time);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
['tools/grpc/nodejs/get_neighbor.js'](https://github.com/osrg/gobgp/blob/master/tools/grpc/nodejs/get_neighbors.js) shows an example to show neighbor information.
|
||||
Let's run this:
|
||||
|
||||
```
|
||||
$ node get_neighbors.js
|
||||
BGP neighbor: 10.0.255.1 , remote AS: 65001
|
||||
BGP version 4, remote router ID: 10.0.255.1
|
||||
BGP state: BGP_FSM_ESTABLISHED , uptime: Wed Jul 20 2016 05:37:22 GMT+0900 (JST)
|
||||
@ -136,13 +382,7 @@ BGP neighbor: 10.0.255.2 , remote AS: 65002
|
||||
```
|
||||
|
||||
## <a name="java"> Java
|
||||
|
||||
At the time of this writing, versions of each plugins and tools are as following:
|
||||
* ProtocolBuffer: 3.3.0
|
||||
* grpc-java: 1.4.0
|
||||
* java: 1.8.0_131
|
||||
|
||||
In proceeding with the following procedure, please substitute versions to the latest.
|
||||
We can make a client in Java using [grpc-java](https://github.com/grpc/grpc-java).
|
||||
|
||||
### Install JDK:
|
||||
We need to install JDK and we use Oracle JDK8 in this example.
|
||||
@ -151,18 +391,41 @@ $ sudo add-apt-repository ppa:webupd8team/java
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install oracle-java8-installer
|
||||
$ java -version
|
||||
java version "1.8.0_131"
|
||||
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
|
||||
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
|
||||
java version "1.8.0_72"
|
||||
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
|
||||
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
|
||||
$ echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
|
||||
### Install ProtocolBuffers:
|
||||
We use v3.0.0 beta2.
|
||||
```bash
|
||||
$ sudo apt-get install -y build-essential autoconf git libtool unzip
|
||||
$ mkdir ~/work
|
||||
$ cd ~/work
|
||||
$ wget https://github.com/google/protobuf/archive/v3.0.0-beta-2.tar.gz
|
||||
$ tar xvzf v3.0.0-beta-2.tar.gz
|
||||
$ cd protobuf-3.0.0-beta-2
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ echo "export LD_LIBRARY_PATH=/usr/local/lib" >> ~/.bashrc
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
Please check the version.
|
||||
```bash
|
||||
$ protoc --version
|
||||
libprotoc 3.0.0
|
||||
```
|
||||
|
||||
### Create protobuf library for Java:
|
||||
We assume you've cloned gRPC repository in your home directory.
|
||||
```bash
|
||||
$ sudo apt-get install maven
|
||||
$ cd ~/grpc/third_party/protobuf/java
|
||||
$ cd ~/work/protobuf-3.0.0-beta-2/java
|
||||
$ mvn package
|
||||
...
|
||||
[INFO]
|
||||
@ -174,20 +437,22 @@ $ mvn package
|
||||
[INFO] Finished at: Mon Feb 08 11:51:51 JST 2016
|
||||
[INFO] Final Memory: 31M/228M
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
$ ls ./core/target/proto*
|
||||
./core/target/protobuf-java-3.3.0.jar
|
||||
$ ls ./target/proto*
|
||||
./target/protobuf-java-3.0.0-beta-2.jar
|
||||
```
|
||||
|
||||
### Clone grpc-java and get plugins
|
||||
### Clone grpc-java and build protoc plugin and other dependencies:
|
||||
```bash
|
||||
$ cd ~/work
|
||||
$ git clone https://github.com/grpc/grpc-java.git
|
||||
$ cd ./grpc-java
|
||||
$ git checkout -b v1.4.0 v1.4.0
|
||||
$ git checkout -b v0.12.0 v0.12.0
|
||||
$ cd ./all
|
||||
$ ../gradlew build
|
||||
$ ls ../compiler/build/binaries/java_pluginExecutable/
|
||||
protoc-gen-grpc-java
|
||||
$ ls ./build/libs/grpc-all-0.12.0*
|
||||
./build/libs/grpc-all-0.12.0-javadoc.jar ./build/libs/grpc-all-0.12.0-sources.jar ./build/libs/grpc-all-0.12.0.jar
|
||||
```
|
||||
|
||||
### Generate stub classes:
|
||||
@ -197,50 +462,94 @@ $ mkdir -p java/src
|
||||
$ cd java
|
||||
$ GOBGP_API=$GOPATH/src/github.com/osrg/gobgp/api
|
||||
$ protoc --java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
|
||||
$ protoc --plugin=protoc-gen-grpc-java=$HOME/work/grpc-java/compiler/build/exe/java_plugin/protoc-gen-grpc-java --grpc-java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
|
||||
$ protoc --plugin=protoc-gen-grpc-java=$HOME/work/grpc-java/compiler/build/binaries/java_pluginExecutable/protoc-gen-grpc-java --grpc-java_out=./src --proto_path="$GOBGP_API" $GOBGP_API/gobgp.proto
|
||||
$ ls ./src/gobgpapi/
|
||||
Gobgp.java GobgpApiGrpc.java
|
||||
```
|
||||
|
||||
### Build sample client:
|
||||
### Create your own client and build it:
|
||||
```bash
|
||||
$ cd ~/go/src/github.com/osrg/gobgp/tools/grpc/java
|
||||
$ mkdir -p src/gobgp/example
|
||||
$ cd src/gobgp/example
|
||||
$ vi GobgpSampleClient.java
|
||||
```
|
||||
|
||||
['tools/grpc/java/src/gobgp/example/GobgpSampleClient.java'](https://github.com/osrg/gobgp/blob/master/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java) is an example to show neighbor information.
|
||||
```java
|
||||
package gobgp.example;
|
||||
|
||||
import gobgpapi.Gobgp;
|
||||
import gobgpapi.GobgpApiGrpc;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GobgpSampleClient {
|
||||
|
||||
private final GobgpApiGrpc.GobgpApiBlockingStub blockingStub;
|
||||
|
||||
public GobgpSampleClient(String host, int port) {
|
||||
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
|
||||
this.blockingStub = GobgpApiGrpc.newBlockingStub(channel);
|
||||
}
|
||||
|
||||
public void getNeighbors(){
|
||||
|
||||
Gobgp.Arguments request = Gobgp.Arguments.newBuilder().build();
|
||||
|
||||
for(Iterator<Gobgp.Peer> iterator = this.blockingStub.getNeighbors(request); iterator.hasNext(); ) {
|
||||
Gobgp.Peer p = iterator.next();
|
||||
Gobgp.PeerConf conf = p.getConf();
|
||||
Gobgp.PeerState state = p.getInfo();
|
||||
Gobgp.Timers timer = p.getTimers();
|
||||
|
||||
System.out.printf("BGP neighbor is %s, remote AS %d\n", conf.getNeighborAddress(), conf.getPeerAs());
|
||||
System.out.printf("\tBGP version 4, remote router ID %s\n", conf.getId());
|
||||
System.out.printf("\tBGP state = %s, up for %d\n", state.getBgpState(), timer.getState().getUptime());
|
||||
System.out.printf("\tBGP OutQ = %d, Flops = %d\n", state.getOutQ(), state.getFlops());
|
||||
System.out.printf("\tHold time is %d, keepalive interval is %d seconds\n",
|
||||
timer.getState().getHoldTime(), timer.getState().getKeepaliveInterval());
|
||||
System.out.printf("\tConfigured hold time is %d\n", timer.getConfig().getHoldTime());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
new GobgpSampleClient(args[0], 8080).getNeighbors();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Let's build and run it. However we need to download and copy some dependencies beforehand.
|
||||
```bash
|
||||
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/java
|
||||
$ mkdir lib
|
||||
$ cd lib
|
||||
$ wget http://central.maven.org/maven2/com/google/guava/guava/22.0/guava-22.0.jar
|
||||
$ wget http://central.maven.org/maven2/com/squareup/okhttp/okhttp/2.5.0/okhttp-2.7.5.jar
|
||||
$ wget http://central.maven.org/maven2/com/squareup/okio/okio/1.13.0/okio-1.13.0.jar
|
||||
$ wget http://central.maven.org/maven2/com/google/instrumentation/instrumentation-api/0.4.3/instrumentation-api-0.4.3.jar
|
||||
$ cp ~/grpc/third_party/protobuf/java/core/target/protobuf-java-3.3.0.jar ./
|
||||
$ cp ~/work/grpc-java/stub/build/libs/grpc-stub-1.4.0.jar ./
|
||||
$ cp ~/work/grpc-java/core/build/libs/grpc-core-1.4.0.jar ./
|
||||
$ cp ~/work/grpc-java/protobuf/build/libs/grpc-protobuf-1.4.0.jar ./
|
||||
$ cp ~/work/grpc-java/protobuf-lite/build/libs/grpc-protobuf-lite-1.4.0.jar ./
|
||||
$ cp ~/work/grpc-java/context/build/libs/grpc-context-1.4.0.jar ./
|
||||
$ cp ~/work/grpc-java/okhttp/build/libs/grpc-okhttp-1.4.0.jar ./
|
||||
$ wget http://central.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.jar
|
||||
$ wget http://central.maven.org/maven2/com/squareup/okhttp/okhttp/2.5.0/okhttp-2.5.0.jar
|
||||
$ wget http://central.maven.org/maven2/com/squareup/okio/okio/1.6.0/okio-1.6.0.jar
|
||||
$ cp ~/work/protobuf-3.0.0-beta-2/java/target/protobuf-java-3.0.0-beta-2.jar ./
|
||||
$ cp ~/work/grpc-java/all/build/libs/grpc-all-0.12.0.jar ./
|
||||
```
|
||||
|
||||
We are ready to build and run.
|
||||
```bash
|
||||
$ cd $GOPATH/src/github.com/osrg/gobgp/tools/grpc/java
|
||||
$ mkdir classes
|
||||
$ CLASSPATH=./lib/protobuf-java-3.3.0.jar:./lib/guava-22.0.jar:./lib/grpc-okhttp-1.4.0.jar:./lib/okio-1.13.0.jar:./lib/grpc-stub-1.4.0.jar:./lib/grpc-core-1.4.0.jar:./lib/grpc-protobuf-1.4.0.jar:./lib/okhttp-2.7.5.jar:./lib/instrumentation-api-0.4.3.jar:./lib/grpc-context-1.4.0.jar:./lib/grpc-protobuf-lite-1.4.0.jar:./classes/
|
||||
$ CLASSPATH=./lib/protobuf-java-3.0.0-beta-2.jar:./lib/grpc-all-0.12.0.jar:./lib/guava-18.0.jar:./lib/okhttp-2.5.0.jar:./lib/okio-1.6.0.jar:./classes
|
||||
$ javac -classpath $CLASSPATH -d ./classes ./src/gobgpapi/*.java
|
||||
$ javac -classpath $CLASSPATH -d ./classes ./src/gobgp/example/GobgpSampleClient.java
|
||||
$ java -cp $CLASSPATH gobgp.example.GobgpSampleClient localhost
|
||||
BGP neighbor is 10.0.0.2, remote AS 1
|
||||
BGP version 4, remote router ID
|
||||
BGP state = active, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90
|
||||
BGP neighbor is 10.0.0.3, remote AS 1
|
||||
BGP version 4, remote router ID
|
||||
BGP state = active, up for 0
|
||||
Feb 08, 2016 2:39:29 PM io.grpc.internal.TransportSet$1 run
|
||||
INFO: Created transport io.grpc.okhttp.OkHttpClientTransport@ba4d54(localhost/127.0.0.1:8080) for localhost/127.0.0.1:8080
|
||||
Feb 08, 2016 2:39:29 PM io.grpc.internal.TransportSet$TransportListener transportReady
|
||||
INFO: Transport io.grpc.okhttp.OkHttpClientTransport@ba4d54(localhost/127.0.0.1:8080) for localhost/127.0.0.1:8080 is ready
|
||||
BGP neighbor is 10.0.255.1, remote AS 65001
|
||||
BGP version 4, remote router ID <nil>
|
||||
BGP state = BGP_FSM_ACTIVE, up for 0
|
||||
BGP OutQ = 0, Flops = 0
|
||||
Hold time is 0, keepalive interval is 0 seconds
|
||||
Configured hold time is 90
|
||||
|
2
vendor/github.com/osrg/gobgp/docs/sources/lib.md
generated
vendored
2
vendor/github.com/osrg/gobgp/docs/sources/lib.md
generated
vendored
@ -12,7 +12,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
api "github.com/osrg/gobgp/api"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
|
4
vendor/github.com/osrg/gobgp/gobgp/cmd/common.go
generated
vendored
4
vendor/github.com/osrg/gobgp/gobgp/cmd/common.go
generated
vendored
@ -178,8 +178,8 @@ func (n neighbors) Swap(i, j int) {
|
||||
}
|
||||
|
||||
func (n neighbors) Less(i, j int) bool {
|
||||
p1 := n[i].State.NeighborAddress
|
||||
p2 := n[j].State.NeighborAddress
|
||||
p1 := n[i].Config.NeighborAddress
|
||||
p2 := n[j].Config.NeighborAddress
|
||||
p1Isv4 := !strings.Contains(p1, ":")
|
||||
p2Isv4 := !strings.Contains(p2, ":")
|
||||
if p1Isv4 != p2Isv4 {
|
||||
|
2
vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go
generated
vendored
2
vendor/github.com/osrg/gobgp/gobgp/cmd/monitor.go
generated
vendored
@ -89,7 +89,7 @@ func NewMonitorCmd() *cobra.Command {
|
||||
j, _ := json.Marshal(s)
|
||||
fmt.Println(string(j))
|
||||
} else {
|
||||
addr := s.State.NeighborAddress
|
||||
addr := s.Config.NeighborAddress
|
||||
if s.Config.NeighborInterface != "" {
|
||||
addr = fmt.Sprintf("%s(%s)", addr, s.Config.NeighborInterface)
|
||||
}
|
||||
|
2
vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go
generated
vendored
2
vendor/github.com/osrg/gobgp/gobgp/cmd/mrt.go
generated
vendored
@ -80,8 +80,6 @@ func injectMrt(filename string, count int, skip int, onlyBest bool) error {
|
||||
peers = msg.Body.(*mrt.PeerIndexTable).Peers
|
||||
continue
|
||||
case mrt.RIB_IPV4_UNICAST, mrt.RIB_IPV6_UNICAST:
|
||||
case mrt.GEO_PEER_TABLE:
|
||||
fmt.Printf("WARNING: Skipping GEO_PEER_TABLE: %s", msg.Body.(*mrt.GeoPeerTable))
|
||||
default:
|
||||
exitWithError(fmt.Errorf("unsupported subType: %v", subType))
|
||||
}
|
||||
|
17
vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go
generated
vendored
17
vendor/github.com/osrg/gobgp/gobgp/cmd/neighbor.go
generated
vendored
@ -77,7 +77,7 @@ func showNeighbors(vrf string) error {
|
||||
|
||||
if globalOpts.Quiet {
|
||||
for _, p := range m {
|
||||
fmt.Println(p.State.NeighborAddress)
|
||||
fmt.Println(p.Config.NeighborAddress)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -92,7 +92,7 @@ func showNeighbors(vrf string) error {
|
||||
for _, n := range m {
|
||||
if i := len(n.Config.NeighborInterface); i > maxaddrlen {
|
||||
maxaddrlen = i
|
||||
} else if j := len(n.State.NeighborAddress); j > maxaddrlen {
|
||||
} else if j := len(n.Config.NeighborAddress); j > maxaddrlen {
|
||||
maxaddrlen = j
|
||||
}
|
||||
if l := len(getASN(n)); l > maxaslen {
|
||||
@ -142,7 +142,7 @@ func showNeighbors(vrf string) error {
|
||||
}
|
||||
|
||||
for i, n := range m {
|
||||
neigh := n.State.NeighborAddress
|
||||
neigh := n.Config.NeighborAddress
|
||||
if n.Config.NeighborInterface != "" {
|
||||
neigh = n.Config.NeighborInterface
|
||||
}
|
||||
@ -163,7 +163,7 @@ func showNeighbor(args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("BGP neighbor is %s, remote AS %s", p.State.NeighborAddress, getASN(p))
|
||||
fmt.Printf("BGP neighbor is %s, remote AS %s", p.Config.NeighborAddress, getASN(p))
|
||||
|
||||
if p.RouteReflector.Config.RouteReflectorClient {
|
||||
fmt.Printf(", route-reflector-client\n")
|
||||
@ -854,7 +854,6 @@ func modNeighbor(cmdType string, args []string) error {
|
||||
peer.Config.NeighborInterface = m["interface"][0]
|
||||
} else {
|
||||
peer.Config.NeighborAddress = m[""][0]
|
||||
peer.State.NeighborAddress = m[""][0]
|
||||
}
|
||||
if len(m["vrf"]) == 1 {
|
||||
peer.Config.Vrf = m["vrf"][0]
|
||||
@ -953,7 +952,7 @@ func NewNeighborCmd() *cobra.Command {
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
addr = peer.State.NeighborAddress
|
||||
addr = peer.Config.NeighborAddress
|
||||
}
|
||||
err := f(cmd.Use, addr, args[:len(args)-1])
|
||||
if err != nil {
|
||||
@ -984,7 +983,7 @@ func NewNeighborCmd() *cobra.Command {
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
remoteIP := peer.State.NeighborAddress
|
||||
remoteIP := peer.Config.NeighborAddress
|
||||
for _, v := range []string{CMD_IN, CMD_IMPORT, CMD_EXPORT} {
|
||||
if err := showNeighborPolicy(remoteIP, v, 4); err != nil {
|
||||
exitWithError(err)
|
||||
@ -1001,7 +1000,7 @@ func NewNeighborCmd() *cobra.Command {
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
remoteIP := peer.State.NeighborAddress
|
||||
remoteIP := peer.Config.NeighborAddress
|
||||
err = showNeighborPolicy(remoteIP, cmd.Use, 0)
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
@ -1017,7 +1016,7 @@ func NewNeighborCmd() *cobra.Command {
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
remoteIP := peer.State.NeighborAddress
|
||||
remoteIP := peer.Config.NeighborAddress
|
||||
args = args[:len(args)-1]
|
||||
if err = modNeighborPolicy(remoteIP, cmd.Use, subcmd.Use, args); err != nil {
|
||||
exitWithError(err)
|
||||
|
42
vendor/github.com/osrg/gobgp/gobgpd/main.go
generated
vendored
42
vendor/github.com/osrg/gobgp/gobgpd/main.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/jessevdk/go-flags"
|
||||
p "github.com/kr/pretty"
|
||||
api "github.com/osrg/gobgp/api"
|
||||
@ -31,7 +32,6 @@ import (
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/server"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
@ -149,7 +149,6 @@ func main() {
|
||||
select {
|
||||
case newConfig := <-configCh:
|
||||
var added, deleted, updated []config.Neighbor
|
||||
var addedPg, deletedPg, updatedPg []config.PeerGroup
|
||||
var updatePolicy bool
|
||||
|
||||
if c == nil {
|
||||
@ -191,7 +190,6 @@ func main() {
|
||||
}
|
||||
|
||||
added = newConfig.Neighbors
|
||||
addedPg = newConfig.PeerGroups
|
||||
if opts.GracefulRestart {
|
||||
for i, n := range added {
|
||||
if n.GracefulRestart.Config.Enabled {
|
||||
@ -201,10 +199,7 @@ func main() {
|
||||
}
|
||||
|
||||
} else {
|
||||
addedPg, deletedPg, updatedPg = config.UpdatePeerGroupConfig(c, newConfig)
|
||||
added, deleted, updated = config.UpdateNeighborConfig(c, newConfig)
|
||||
updatePolicy = config.CheckPolicyDifference(config.ConfigSetToRoutingPolicy(c), config.ConfigSetToRoutingPolicy(newConfig))
|
||||
|
||||
added, deleted, updated, updatePolicy = config.UpdateConfig(c, newConfig)
|
||||
if updatePolicy {
|
||||
log.Info("Policy config is updated")
|
||||
p := config.ConfigSetToRoutingPolicy(newConfig)
|
||||
@ -246,46 +241,21 @@ func main() {
|
||||
}
|
||||
c = newConfig
|
||||
}
|
||||
for i, pg := range addedPg {
|
||||
log.Infof("PeerGroup %s is added", pg.Config.PeerGroupName)
|
||||
if err := bgpServer.AddPeerGroup(&addedPg[i]); err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
for i, pg := range deletedPg {
|
||||
log.Infof("PeerGroup %s is deleted", pg.Config.PeerGroupName)
|
||||
if err := bgpServer.DeletePeerGroup(&deletedPg[i]); err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
for i, pg := range updatedPg {
|
||||
log.Infof("PeerGroup %s is updated", pg.Config.PeerGroupName)
|
||||
u, err := bgpServer.UpdatePeerGroup(&updatedPg[i])
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
updatePolicy = updatePolicy || u
|
||||
}
|
||||
for _, dn := range newConfig.DynamicNeighbors {
|
||||
log.Infof("Dynamic Neighbor %s is added to PeerGroup %s", dn.Config.Prefix, dn.Config.PeerGroup)
|
||||
if err := bgpServer.AddDynamicNeighbor(&dn); err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, p := range added {
|
||||
log.Infof("Peer %v is added", p.State.NeighborAddress)
|
||||
log.Infof("Peer %v is added", p.Config.NeighborAddress)
|
||||
if err := bgpServer.AddNeighbor(&added[i]); err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
for i, p := range deleted {
|
||||
log.Infof("Peer %v is deleted", p.State.NeighborAddress)
|
||||
log.Infof("Peer %v is deleted", p.Config.NeighborAddress)
|
||||
if err := bgpServer.DeleteNeighbor(&deleted[i]); err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
for i, p := range updated {
|
||||
log.Infof("Peer %v is updated", p.State.NeighborAddress)
|
||||
log.Infof("Peer %v is updated", p.Config.NeighborAddress)
|
||||
u, err := bgpServer.UpdateNeighbor(&updated[i])
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
|
4
vendor/github.com/osrg/gobgp/gobgpd/util.go
generated
vendored
4
vendor/github.com/osrg/gobgp/gobgpd/util.go
generated
vendored
@ -26,8 +26,8 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus/hooks/syslog"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
2
vendor/github.com/osrg/gobgp/gobmpd/main.go
generated
vendored
2
vendor/github.com/osrg/gobgp/gobmpd/main.go
generated
vendored
@ -19,8 +19,8 @@ import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/packet/bmp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
63
vendor/github.com/osrg/gobgp/packet/bgp/bgp.go
generated
vendored
63
vendor/github.com/osrg/gobgp/packet/bgp/bgp.go
generated
vendored
@ -590,31 +590,10 @@ func (m BGPAddPathMode) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
type CapAddPathTuple struct {
|
||||
RouteFamily RouteFamily
|
||||
Mode BGPAddPathMode
|
||||
}
|
||||
|
||||
func (t *CapAddPathTuple) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
RouteFamily RouteFamily `json:"family"`
|
||||
Mode uint8 `json:"mode"`
|
||||
}{
|
||||
RouteFamily: t.RouteFamily,
|
||||
Mode: uint8(t.Mode),
|
||||
})
|
||||
}
|
||||
|
||||
func NewCapAddPathTuple(family RouteFamily, mode BGPAddPathMode) *CapAddPathTuple {
|
||||
return &CapAddPathTuple{
|
||||
RouteFamily: family,
|
||||
Mode: mode,
|
||||
}
|
||||
}
|
||||
|
||||
type CapAddPath struct {
|
||||
DefaultParameterCapability
|
||||
Tuples []*CapAddPathTuple
|
||||
RouteFamily RouteFamily
|
||||
Mode BGPAddPathMode
|
||||
}
|
||||
|
||||
func (c *CapAddPath) DecodeFromBytes(data []byte) error {
|
||||
@ -623,46 +602,40 @@ func (c *CapAddPath) DecodeFromBytes(data []byte) error {
|
||||
if len(data) < 4 {
|
||||
return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityAddPath bytes available")
|
||||
}
|
||||
c.Tuples = []*CapAddPathTuple{}
|
||||
for len(data) >= 4 {
|
||||
t := &CapAddPathTuple{
|
||||
RouteFamily: AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2]),
|
||||
Mode: BGPAddPathMode(data[3]),
|
||||
}
|
||||
c.Tuples = append(c.Tuples, t)
|
||||
data = data[4:]
|
||||
}
|
||||
c.RouteFamily = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2])
|
||||
c.Mode = BGPAddPathMode(data[3])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CapAddPath) Serialize() ([]byte, error) {
|
||||
buf := make([]byte, len(c.Tuples)*4)
|
||||
for i, t := range c.Tuples {
|
||||
afi, safi := RouteFamilyToAfiSafi(t.RouteFamily)
|
||||
binary.BigEndian.PutUint16(buf[i*4:i*4+2], afi)
|
||||
buf[i*4+2] = safi
|
||||
buf[i*4+3] = byte(t.Mode)
|
||||
}
|
||||
buf := make([]byte, 4)
|
||||
afi, safi := RouteFamilyToAfiSafi(c.RouteFamily)
|
||||
binary.BigEndian.PutUint16(buf, afi)
|
||||
buf[2] = safi
|
||||
buf[3] = byte(c.Mode)
|
||||
c.DefaultParameterCapability.CapValue = buf
|
||||
return c.DefaultParameterCapability.Serialize()
|
||||
}
|
||||
|
||||
func (c *CapAddPath) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
Code BGPCapabilityCode `json:"code"`
|
||||
Tuples []*CapAddPathTuple `json:"tuples"`
|
||||
Code BGPCapabilityCode `json:"code"`
|
||||
Value RouteFamily `json:"value"`
|
||||
Mode BGPAddPathMode `json:"mode"`
|
||||
}{
|
||||
Code: c.Code(),
|
||||
Tuples: c.Tuples,
|
||||
Code: c.Code(),
|
||||
Value: c.RouteFamily,
|
||||
Mode: c.Mode,
|
||||
})
|
||||
}
|
||||
|
||||
func NewCapAddPath(tuples []*CapAddPathTuple) *CapAddPath {
|
||||
func NewCapAddPath(rf RouteFamily, mode BGPAddPathMode) *CapAddPath {
|
||||
return &CapAddPath{
|
||||
DefaultParameterCapability: DefaultParameterCapability{
|
||||
CapCode: BGP_CAP_ADD_PATH,
|
||||
},
|
||||
Tuples: tuples,
|
||||
RouteFamily: rf,
|
||||
Mode: mode,
|
||||
}
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/osrg/gobgp/packet/bgp/helper.go
generated
vendored
2
vendor/github.com/osrg/gobgp/packet/bgp/helper.go
generated
vendored
@ -31,7 +31,7 @@ func NewTestBGPOpenMessage() *BGPMessage {
|
||||
p4 := NewOptionParameterCapability(
|
||||
[]ParameterCapabilityInterface{NewCapFourOctetASNumber(100000)})
|
||||
p5 := NewOptionParameterCapability(
|
||||
[]ParameterCapabilityInterface{NewCapAddPath([]*CapAddPathTuple{NewCapAddPathTuple(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})})
|
||||
[]ParameterCapabilityInterface{NewCapAddPath(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})
|
||||
return NewBGPOpenMessage(11033, 303, "100.4.10.3",
|
||||
[]OptionParameterInterface{p1, p2, p3, p4, p5})
|
||||
}
|
||||
|
157
vendor/github.com/osrg/gobgp/packet/bmp/bmp.go
generated
vendored
157
vendor/github.com/osrg/gobgp/packet/bmp/bmp.go
generated
vendored
@ -802,159 +802,6 @@ const (
|
||||
BMP_ROUTE_MIRRORING_INFO_MSG_LOST
|
||||
)
|
||||
|
||||
type BMPRouteMirrTLVInterface interface {
|
||||
ParseValue([]byte) error
|
||||
Serialize() ([]byte, error)
|
||||
}
|
||||
|
||||
type BMPRouteMirrTLV struct {
|
||||
Type uint16
|
||||
Length uint16
|
||||
}
|
||||
|
||||
type BMPRouteMirrTLVBGPMsg struct {
|
||||
BMPRouteMirrTLV
|
||||
Value *bgp.BGPMessage
|
||||
}
|
||||
|
||||
func NewBMPRouteMirrTLVBGPMsg(t uint16, v *bgp.BGPMessage) *BMPRouteMirrTLVBGPMsg {
|
||||
return &BMPRouteMirrTLVBGPMsg{
|
||||
BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLVBGPMsg) ParseValue(data []byte) error {
|
||||
v, err := bgp.ParseBGPMessage(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Value = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLVBGPMsg) Serialize() ([]byte, error) {
|
||||
m, err := s.Value.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.Length = uint16(len(m))
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint16(buf[0:2], s.Type)
|
||||
binary.BigEndian.PutUint16(buf[2:4], s.Length)
|
||||
buf = append(buf, m...)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type BMPRouteMirrTLV16 struct {
|
||||
BMPRouteMirrTLV
|
||||
Value uint16
|
||||
}
|
||||
|
||||
func NewBMPRouteMirrTLV16(t uint16, v uint16) *BMPRouteMirrTLV16 {
|
||||
return &BMPRouteMirrTLV16{
|
||||
BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLV16) ParseValue(data []byte) error {
|
||||
s.Value = binary.BigEndian.Uint16(data[:2])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLV16) Serialize() ([]byte, error) {
|
||||
s.Length = 2
|
||||
buf := make([]byte, 6)
|
||||
binary.BigEndian.PutUint16(buf[0:2], s.Type)
|
||||
binary.BigEndian.PutUint16(buf[2:4], s.Length)
|
||||
binary.BigEndian.PutUint16(buf[4:6], s.Value)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type BMPRouteMirrTLVUnknown struct {
|
||||
BMPRouteMirrTLV
|
||||
Value []byte
|
||||
}
|
||||
|
||||
func NewBMPRouteMirrTLVUnknown(t uint16, v []byte) *BMPRouteMirrTLVUnknown {
|
||||
return &BMPRouteMirrTLVUnknown{
|
||||
BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t},
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLVUnknown) ParseValue(data []byte) error {
|
||||
s.Value = data[:s.Length]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BMPRouteMirrTLVUnknown) Serialize() ([]byte, error) {
|
||||
s.Length = uint16(len([]byte(s.Value)))
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint16(buf[0:2], s.Type)
|
||||
binary.BigEndian.PutUint16(buf[2:4], s.Length)
|
||||
buf = append(buf, s.Value...)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type BMPRouteMirroring struct {
|
||||
Info []BMPRouteMirrTLVInterface
|
||||
}
|
||||
|
||||
func NewBMPRouteMirroring(p BMPPeerHeader, info []BMPRouteMirrTLVInterface) *BMPMessage {
|
||||
return &BMPMessage{
|
||||
Header: BMPHeader{
|
||||
Version: BMP_VERSION,
|
||||
Type: BMP_MSG_ROUTE_MIRRORING,
|
||||
},
|
||||
PeerHeader: p,
|
||||
Body: &BMPRouteMirroring{
|
||||
Info: info,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (body *BMPRouteMirroring) ParseBody(msg *BMPMessage, data []byte) error {
|
||||
for len(data) >= 4 {
|
||||
tl := BMPRouteMirrTLV{
|
||||
Type: binary.BigEndian.Uint16(data[0:2]),
|
||||
Length: binary.BigEndian.Uint16(data[2:4]),
|
||||
}
|
||||
data = data[4:]
|
||||
if len(data) < int(tl.Length) {
|
||||
return fmt.Errorf("value lengh is not enough: %d bytes (%d bytes expected)", len(data), tl.Length)
|
||||
}
|
||||
var tlv BMPRouteMirrTLVInterface
|
||||
switch tl.Type {
|
||||
case BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG:
|
||||
tlv = &BMPRouteMirrTLVBGPMsg{BMPRouteMirrTLV: tl}
|
||||
case BMP_ROUTE_MIRRORING_TLV_TYPE_INFO:
|
||||
tlv = &BMPRouteMirrTLV16{BMPRouteMirrTLV: tl}
|
||||
default:
|
||||
tlv = &BMPRouteMirrTLVUnknown{BMPRouteMirrTLV: tl}
|
||||
}
|
||||
if err := tlv.ParseValue(data); err != nil {
|
||||
return err
|
||||
}
|
||||
body.Info = append(body.Info, tlv)
|
||||
data = data[tl.Length:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (body *BMPRouteMirroring) Serialize() ([]byte, error) {
|
||||
buf := make([]byte, 0)
|
||||
for _, tlv := range body.Info {
|
||||
b, err := tlv.Serialize()
|
||||
if err != nil {
|
||||
return buf, err
|
||||
}
|
||||
buf = append(buf, b...)
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
type BMPBody interface {
|
||||
// Sigh, some body messages need a BMPHeader to parse the body
|
||||
// data so we need to pass BMPHeader (avoid DecodeFromBytes
|
||||
@ -1037,10 +884,6 @@ func ParseBMPMessage(data []byte) (msg *BMPMessage, err error) {
|
||||
msg.Body = &BMPInitiation{}
|
||||
case BMP_MSG_TERMINATION:
|
||||
msg.Body = &BMPTermination{}
|
||||
case BMP_MSG_ROUTE_MIRRORING:
|
||||
msg.Body = &BMPRouteMirroring{}
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported BMP message type: %d", msg.Header.Type)
|
||||
}
|
||||
|
||||
if msg.Header.Type != BMP_MSG_INITIATION && msg.Header.Type != BMP_MSG_TERMINATION {
|
||||
|
14
vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go
generated
vendored
14
vendor/github.com/osrg/gobgp/packet/bmp/bmp_test.go
generated
vendored
@ -92,20 +92,6 @@ func Test_StatisticsReport(t *testing.T) {
|
||||
verify(t, s0)
|
||||
}
|
||||
|
||||
func Test_RouteMirroring(t *testing.T) {
|
||||
p0 := NewBMPPeerHeader(0, 0, 1000, "10.0.0.1", 70000, "10.0.0.2", 1)
|
||||
s0 := NewBMPRouteMirroring(
|
||||
*p0,
|
||||
[]BMPRouteMirrTLVInterface{
|
||||
NewBMPRouteMirrTLV16(BMP_ROUTE_MIRRORING_TLV_TYPE_INFO, BMP_ROUTE_MIRRORING_INFO_MSG_LOST),
|
||||
NewBMPRouteMirrTLVUnknown(0xff, []byte{0x01, 0x02, 0x03, 0x04}),
|
||||
// RFC7854: BGP Message TLV MUST occur last in the list of TLVs
|
||||
NewBMPRouteMirrTLVBGPMsg(BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG, bgp.NewTestBGPOpenMessage()),
|
||||
},
|
||||
)
|
||||
verify(t, s0)
|
||||
}
|
||||
|
||||
func Test_BogusHeader(t *testing.T) {
|
||||
h, err := ParseBMPMessage(make([]byte, 10))
|
||||
assert.Nil(t, h)
|
||||
|
114
vendor/github.com/osrg/gobgp/packet/mrt/mrt.go
generated
vendored
114
vendor/github.com/osrg/gobgp/packet/mrt/mrt.go
generated
vendored
@ -67,7 +67,6 @@ const (
|
||||
RIB_IPV6_UNICAST MRTSubTypeTableDumpv2 = 4
|
||||
RIB_IPV6_MULTICAST MRTSubTypeTableDumpv2 = 5
|
||||
RIB_GENERIC MRTSubTypeTableDumpv2 = 6
|
||||
GEO_PEER_TABLE MRTSubTypeTableDumpv2 = 7 // RFC6397
|
||||
RIB_IPV4_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 8 // RFC8050
|
||||
RIB_IPV4_MULTICAST_ADDPATH MRTSubTypeTableDumpv2 = 9 // RFC8050
|
||||
RIB_IPV6_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 10 // RFC8050
|
||||
@ -543,115 +542,6 @@ func (u *Rib) String() string {
|
||||
return fmt.Sprintf("RIB: Seq [%d] Prefix [%s] Entries [%s]", u.SequenceNumber, u.Prefix, u.Entries)
|
||||
}
|
||||
|
||||
type GeoPeer struct {
|
||||
Type uint8
|
||||
BgpId net.IP
|
||||
Latitude float32
|
||||
Longitude float32
|
||||
}
|
||||
|
||||
func (p *GeoPeer) DecodeFromBytes(data []byte) ([]byte, error) {
|
||||
if len(data) < 13 {
|
||||
return nil, fmt.Errorf("not all GeoPeer bytes are available")
|
||||
}
|
||||
// Peer IP Address and Peer AS should not be included
|
||||
p.Type = uint8(data[0])
|
||||
if p.Type != uint8(0) {
|
||||
return nil, fmt.Errorf("unsupported peer type for GeoPeer: %d", p.Type)
|
||||
}
|
||||
p.BgpId = net.IP(data[1:5])
|
||||
p.Latitude = math.Float32frombits(binary.BigEndian.Uint32(data[5:9]))
|
||||
p.Longitude = math.Float32frombits(binary.BigEndian.Uint32(data[9:13]))
|
||||
return data[13:], nil
|
||||
}
|
||||
|
||||
func (p *GeoPeer) Serialize() ([]byte, error) {
|
||||
buf := make([]byte, 13)
|
||||
buf[0] = uint8(0) // Peer IP Address and Peer AS should not be included
|
||||
bgpId := p.BgpId.To4()
|
||||
if bgpId == nil {
|
||||
return nil, fmt.Errorf("invalid BgpId: %s", p.BgpId)
|
||||
}
|
||||
copy(buf[1:5], bgpId)
|
||||
binary.BigEndian.PutUint32(buf[5:9], math.Float32bits(p.Latitude))
|
||||
binary.BigEndian.PutUint32(buf[9:13], math.Float32bits(p.Longitude))
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func NewGeoPeer(bgpid string, latitude float32, longitude float32) *GeoPeer {
|
||||
return &GeoPeer{
|
||||
Type: 0, // Peer IP Address and Peer AS should not be included
|
||||
BgpId: net.ParseIP(bgpid).To4(),
|
||||
Latitude: latitude,
|
||||
Longitude: longitude,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *GeoPeer) String() string {
|
||||
return fmt.Sprintf("PEER ENTRY: ID [%s] Latitude [%f] Longitude [%f]", p.BgpId, p.Latitude, p.Longitude)
|
||||
}
|
||||
|
||||
type GeoPeerTable struct {
|
||||
CollectorBgpId net.IP
|
||||
CollectorLatitude float32
|
||||
CollectorLongitude float32
|
||||
Peers []*GeoPeer
|
||||
}
|
||||
|
||||
func (t *GeoPeerTable) DecodeFromBytes(data []byte) error {
|
||||
if len(data) < 14 {
|
||||
return fmt.Errorf("not all GeoPeerTable bytes are available")
|
||||
}
|
||||
t.CollectorBgpId = net.IP(data[0:4])
|
||||
t.CollectorLatitude = math.Float32frombits(binary.BigEndian.Uint32(data[4:8]))
|
||||
t.CollectorLongitude = math.Float32frombits(binary.BigEndian.Uint32(data[8:12]))
|
||||
peerCount := binary.BigEndian.Uint16(data[12:14])
|
||||
data = data[14:]
|
||||
t.Peers = make([]*GeoPeer, 0, peerCount)
|
||||
var err error
|
||||
for i := 0; i < int(peerCount); i++ {
|
||||
p := &GeoPeer{}
|
||||
if data, err = p.DecodeFromBytes(data); err != nil {
|
||||
return err
|
||||
}
|
||||
t.Peers = append(t.Peers, p)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *GeoPeerTable) Serialize() ([]byte, error) {
|
||||
buf := make([]byte, 14)
|
||||
collectorBgpId := t.CollectorBgpId.To4()
|
||||
if collectorBgpId == nil {
|
||||
return nil, fmt.Errorf("invalid CollectorBgpId: %s", t.CollectorBgpId)
|
||||
}
|
||||
copy(buf[0:4], collectorBgpId)
|
||||
binary.BigEndian.PutUint32(buf[4:8], math.Float32bits(t.CollectorLatitude))
|
||||
binary.BigEndian.PutUint32(buf[8:12], math.Float32bits(t.CollectorLongitude))
|
||||
binary.BigEndian.PutUint16(buf[12:14], uint16(len(t.Peers)))
|
||||
for _, peer := range t.Peers {
|
||||
pbuf, err := peer.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = append(buf, pbuf...)
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func NewGeoPeerTable(bgpid string, latitude float32, longitude float32, peers []*GeoPeer) *GeoPeerTable {
|
||||
return &GeoPeerTable{
|
||||
CollectorBgpId: net.ParseIP(bgpid).To4(),
|
||||
CollectorLatitude: latitude,
|
||||
CollectorLongitude: longitude,
|
||||
Peers: peers,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *GeoPeerTable) String() string {
|
||||
return fmt.Sprintf("GEO_PEER_TABLE: CollectorBgpId [%s] CollectorLatitude [%f] CollectorLongitude [%f] Peers [%s]", t.CollectorBgpId, t.CollectorLatitude, t.CollectorLongitude, t.Peers)
|
||||
}
|
||||
|
||||
type BGP4MPHeader struct {
|
||||
PeerAS uint32
|
||||
LocalAS uint32
|
||||
@ -922,8 +812,6 @@ func ParseMRTBody(h *MRTHeader, data []byte) (*MRTMessage, error) {
|
||||
case RIB_IPV6_MULTICAST:
|
||||
rf = bgp.RF_IPv6_MC
|
||||
case RIB_GENERIC:
|
||||
case GEO_PEER_TABLE:
|
||||
msg.Body = &GeoPeerTable{}
|
||||
case RIB_IPV4_UNICAST_ADDPATH:
|
||||
rf = bgp.RF_IPv4_UC
|
||||
isAddPath = true
|
||||
@ -942,7 +830,7 @@ func ParseMRTBody(h *MRTHeader, data []byte) (*MRTMessage, error) {
|
||||
return nil, fmt.Errorf("unsupported table dumpv2 subtype: %v\n", subType)
|
||||
}
|
||||
|
||||
if msg.Body == nil {
|
||||
if subType != PEER_INDEX_TABLE {
|
||||
msg.Body = &Rib{
|
||||
RouteFamily: rf,
|
||||
isAddPath: isAddPath,
|
||||
|
16
vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go
generated
vendored
16
vendor/github.com/osrg/gobgp/packet/mrt/mrt_test.go
generated
vendored
@ -227,22 +227,6 @@ func TestMrtRibWithAddPath(t *testing.T) {
|
||||
assert.Equal(t, reflect.DeepEqual(r1, r2), true)
|
||||
}
|
||||
|
||||
func TestMrtGeoPeerTable(t *testing.T) {
|
||||
p1 := NewGeoPeer("192.168.0.1", 28.031157, 86.899684)
|
||||
p2 := NewGeoPeer("192.168.0.1", 35.360556, 138.727778)
|
||||
pt1 := NewGeoPeerTable("192.168.0.1", 12.345678, 98.765432, []*GeoPeer{p1, p2})
|
||||
b1, err := pt1.Serialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pt2 := &GeoPeerTable{}
|
||||
err = pt2.DecodeFromBytes(b1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, reflect.DeepEqual(pt1, pt2), true)
|
||||
}
|
||||
|
||||
func TestMrtBgp4mpStateChange(t *testing.T) {
|
||||
c1 := NewBGP4MPStateChange(65000, 65001, 1, "192.168.0.1", "192.168.0.2", false, ACTIVE, ESTABLISHED)
|
||||
b1, err := c1.Serialize()
|
||||
|
30
vendor/github.com/osrg/gobgp/server/bmp.go
generated
vendored
30
vendor/github.com/osrg/gobgp/server/bmp.go
generated
vendored
@ -17,11 +17,11 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/packet/bmp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
@ -127,9 +127,6 @@ func (b *bmpClient) loop() {
|
||||
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_LOCAL_RIB || b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_ALL {
|
||||
ops = append(ops, WatchBestPath(true))
|
||||
}
|
||||
if b.c.RouteMirroringEnabled {
|
||||
ops = append(ops, WatchMessage(false))
|
||||
}
|
||||
w := b.s.Watch(ops...)
|
||||
defer w.Stop()
|
||||
|
||||
@ -212,15 +209,6 @@ func (b *bmpClient) loop() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case *WatchEventMessage:
|
||||
info := &table.PeerInfo{
|
||||
Address: msg.PeerAddress,
|
||||
AS: msg.PeerAS,
|
||||
ID: msg.PeerID,
|
||||
}
|
||||
if err := write(bmpPeerRouteMirroring(bmp.BMP_PEER_TYPE_GLOBAL, 0, info, msg.Timestamp.Unix(), msg.Message)); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case <-tickerCh:
|
||||
neighborList := b.s.GetNeighbor("", true)
|
||||
@ -289,26 +277,12 @@ func bmpPeerRoute(t uint8, policy bool, pd uint64, peeri *table.PeerInfo, timest
|
||||
|
||||
func bmpPeerStats(peerType uint8, peerDist uint64, timestamp int64, neighConf *config.Neighbor) *bmp.BMPMessage {
|
||||
var peerFlags uint8 = 0
|
||||
ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, neighConf.State.NeighborAddress, neighConf.State.PeerAs, neighConf.State.RemoteRouterId, float64(timestamp))
|
||||
ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, neighConf.Config.NeighborAddress, neighConf.State.PeerAs, neighConf.State.RemoteRouterId, float64(timestamp))
|
||||
return bmp.NewBMPStatisticsReport(
|
||||
*ph,
|
||||
[]bmp.BMPStatsTLVInterface{
|
||||
bmp.NewBMPStatsTLV64(bmp.BMP_STAT_TYPE_ADJ_RIB_IN, uint64(neighConf.State.AdjTable.Accepted)),
|
||||
bmp.NewBMPStatsTLV64(bmp.BMP_STAT_TYPE_LOC_RIB, uint64(neighConf.State.AdjTable.Advertised+neighConf.State.AdjTable.Filtered)),
|
||||
bmp.NewBMPStatsTLV32(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, neighConf.State.Messages.Received.WithdrawUpdate),
|
||||
bmp.NewBMPStatsTLV32(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, neighConf.State.Messages.Received.WithdrawPrefix),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func bmpPeerRouteMirroring(peerType uint8, peerDist uint64, peerInfo *table.PeerInfo, timestamp int64, msg *bgp.BGPMessage) *bmp.BMPMessage {
|
||||
var peerFlags uint8 = 0
|
||||
ph := bmp.NewBMPPeerHeader(peerType, peerFlags, peerDist, peerInfo.Address.String(), peerInfo.AS, peerInfo.ID.String(), float64(timestamp))
|
||||
return bmp.NewBMPRouteMirroring(
|
||||
*ph,
|
||||
[]bmp.BMPRouteMirrTLVInterface{
|
||||
// RFC7854: BGP Message TLV MUST occur last in the list of TLVs
|
||||
bmp.NewBMPRouteMirrTLVBGPMsg(bmp.BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG, msg),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
2
vendor/github.com/osrg/gobgp/server/collector.go
generated
vendored
2
vendor/github.com/osrg/gobgp/server/collector.go
generated
vendored
@ -17,10 +17,10 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/influxdata/influxdb/client/v2"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
161
vendor/github.com/osrg/gobgp/server/fsm.go
generated
vendored
161
vendor/github.com/osrg/gobgp/server/fsm.go
generated
vendored
@ -17,12 +17,11 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/packet/bmp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/tomb.v2"
|
||||
"io"
|
||||
"math/rand"
|
||||
@ -183,18 +182,6 @@ func (fsm *FSM) bgpMessageStateUpdate(MessageType uint8, isIn bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (fsm *FSM) bmpStatsUpdate(statType uint16, increment int) {
|
||||
stats := &fsm.pConf.State.Messages.Received
|
||||
switch statType {
|
||||
// TODO
|
||||
// Support other stat types.
|
||||
case bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE:
|
||||
stats.WithdrawUpdate += uint32(increment)
|
||||
case bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX:
|
||||
stats.WithdrawPrefix += uint32(increment)
|
||||
}
|
||||
}
|
||||
|
||||
func NewFSM(gConf *config.Global, pConf *config.Neighbor, policy *table.RoutingPolicy) *FSM {
|
||||
adminState := ADMIN_STATE_UP
|
||||
if pConf.Config.AdminDown {
|
||||
@ -227,7 +214,7 @@ func NewFSM(gConf *config.Global, pConf *config.Neighbor, policy *table.RoutingP
|
||||
func (fsm *FSM) StateChange(nextState bgp.FSMState) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"old": fsm.state.String(),
|
||||
"new": nextState.String(),
|
||||
"reason": fsm.reason,
|
||||
@ -298,12 +285,12 @@ func (fsm *FSM) sendNotificationFromErrorMsg(e *bgp.MessageError) error {
|
||||
fsm.h.conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"Data": e,
|
||||
}).Warn("sent notification")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("can't send notification to %s since TCP connection is not established", fsm.pConf.State.NeighborAddress)
|
||||
return fmt.Errorf("can't send notification to %s since TCP connection is not established", fsm.pConf.Config.NeighborAddress)
|
||||
}
|
||||
|
||||
func (fsm *FSM) sendNotification(code, subType uint8, data []byte, msg string) error {
|
||||
@ -323,7 +310,7 @@ func (fsm *FSM) connectLoop() error {
|
||||
timer.Stop()
|
||||
|
||||
connect := func() {
|
||||
addr := fsm.pConf.State.NeighborAddress
|
||||
addr := fsm.pConf.Config.NeighborAddress
|
||||
port := int(bgp.BGP_PORT)
|
||||
if fsm.pConf.Transport.Config.RemotePort != 0 {
|
||||
port = int(fsm.pConf.Transport.Config.RemotePort)
|
||||
@ -342,7 +329,7 @@ func (fsm *FSM) connectLoop() error {
|
||||
if e != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
}).Warnf("failed to resolve ltcpaddr: %s", e)
|
||||
return
|
||||
}
|
||||
@ -358,13 +345,13 @@ func (fsm *FSM) connectLoop() error {
|
||||
conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
}).Warn("active conn is closed to avoid being blocked")
|
||||
}
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
}).Debugf("failed to connect: %s", err)
|
||||
}
|
||||
|
||||
@ -378,7 +365,7 @@ func (fsm *FSM) connectLoop() error {
|
||||
case <-fsm.t.Dying():
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
}).Debug("stop connect loop")
|
||||
return nil
|
||||
case <-timer.C:
|
||||
@ -429,7 +416,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
|
||||
if fsm.pConf.GracefulRestart.State.PeerRestarting {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("graceful restart timer expired")
|
||||
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
|
||||
@ -441,7 +428,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
|
||||
conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("Closed an accepted connection")
|
||||
case <-idleHoldTimer.C:
|
||||
@ -449,7 +436,7 @@ func (h *FSMHandler) idle() (bgp.FSMState, FsmStateReason) {
|
||||
if fsm.adminState == ADMIN_STATE_UP {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"Duration": fsm.idleHoldTime,
|
||||
}).Debug("IdleHoldTimer expired")
|
||||
fsm.idleHoldTime = HOLDTIME_IDLE
|
||||
@ -487,38 +474,13 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
|
||||
break
|
||||
}
|
||||
fsm.conn = conn
|
||||
ttl := 0
|
||||
ttlMin := 0
|
||||
if fsm.pConf.TtlSecurity.Config.Enabled {
|
||||
ttl = 255
|
||||
ttlMin = int(fsm.pConf.TtlSecurity.Config.TtlMin)
|
||||
} else if fsm.pConf.Config.PeerAs != 0 && fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
|
||||
if fsm.pConf.Config.PeerAs != 0 && fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL {
|
||||
ttl := 1
|
||||
if fsm.pConf.EbgpMultihop.Config.Enabled {
|
||||
ttl = int(fsm.pConf.EbgpMultihop.Config.MultihopTtl)
|
||||
} else if fsm.pConf.Transport.Config.Ttl != 0 {
|
||||
ttl = int(fsm.pConf.Transport.Config.Ttl)
|
||||
} else {
|
||||
ttl = 1
|
||||
}
|
||||
} else if fsm.pConf.Transport.Config.Ttl != 0 {
|
||||
ttl = int(fsm.pConf.Transport.Config.Ttl)
|
||||
}
|
||||
if ttl != 0 {
|
||||
if err := SetTcpTTLSockopts(conn.(*net.TCPConn), ttl); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warnf("cannot set TTL(=%d) for peer: %s", ttl, err)
|
||||
}
|
||||
}
|
||||
if ttlMin != 0 {
|
||||
if err := SetTcpMinTTLSockopts(conn.(*net.TCPConn), ttlMin); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warnf("cannot set minimal TTL(=%d) for peer: %s", ttl, err)
|
||||
if ttl != 0 {
|
||||
SetTcpTTLSockopts(conn.(*net.TCPConn), ttl)
|
||||
}
|
||||
}
|
||||
// we don't implement delayed open timer so move to opensent right
|
||||
@ -528,7 +490,7 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
|
||||
if fsm.pConf.GracefulRestart.State.PeerRestarting {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("graceful restart timer expired")
|
||||
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
|
||||
@ -544,7 +506,7 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) {
|
||||
case ADMIN_STATE_UP:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"AdminState": stateOp.State.String(),
|
||||
}).Panic("code logic bug")
|
||||
@ -683,13 +645,13 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
h.fsm.bgpMessageStateUpdate(0, true)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": h.fsm.pConf.State.NeighborAddress,
|
||||
"Key": h.fsm.pConf.Config.NeighborAddress,
|
||||
"State": h.fsm.state.String(),
|
||||
"error": err,
|
||||
}).Warn("malformed BGP Header")
|
||||
fmsg := &FsmMsg{
|
||||
MsgType: FSM_MSG_BGP_MESSAGE,
|
||||
MsgSrc: h.fsm.pConf.State.NeighborAddress,
|
||||
MsgSrc: h.fsm.pConf.Config.NeighborAddress,
|
||||
MsgData: err,
|
||||
Version: h.fsm.version,
|
||||
}
|
||||
@ -712,14 +674,14 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
}
|
||||
fmsg := &FsmMsg{
|
||||
MsgType: FSM_MSG_BGP_MESSAGE,
|
||||
MsgSrc: h.fsm.pConf.State.NeighborAddress,
|
||||
MsgSrc: h.fsm.pConf.Config.NeighborAddress,
|
||||
timestamp: now,
|
||||
Version: h.fsm.version,
|
||||
}
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": h.fsm.pConf.State.NeighborAddress,
|
||||
"Key": h.fsm.pConf.Config.NeighborAddress,
|
||||
"State": h.fsm.state.String(),
|
||||
"error": err,
|
||||
}).Warn("malformed BGP message")
|
||||
@ -742,7 +704,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": h.fsm.pConf.State.NeighborAddress,
|
||||
"Key": h.fsm.pConf.Config.NeighborAddress,
|
||||
"State": h.fsm.state.String(),
|
||||
"error": err,
|
||||
}).Warn("malformed BGP update message")
|
||||
@ -750,17 +712,6 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
return fmsg, err
|
||||
}
|
||||
|
||||
if routes := len(body.WithdrawnRoutes); routes > 0 {
|
||||
h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, 1)
|
||||
h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, routes)
|
||||
} else if attr := getPathAttrFromBGPUpdate(body, bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI); attr != nil {
|
||||
mpUnreach := attr.(*bgp.PathAttributeMpUnreachNLRI)
|
||||
if routes = len(mpUnreach.Value); routes > 0 {
|
||||
h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_UPDATE, 1)
|
||||
h.fsm.bmpStatsUpdate(bmp.BMP_STAT_TYPE_WITHDRAW_PREFIX, routes)
|
||||
}
|
||||
}
|
||||
|
||||
table.UpdatePathAttrs4ByteAs(body)
|
||||
if err = table.UpdatePathAggregator4ByteAs(body); err != nil {
|
||||
fmsg.MsgData = err
|
||||
@ -777,7 +728,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
}
|
||||
|
||||
fmsg.PathList = table.ProcessMessage(m, h.fsm.peerInfo, fmsg.timestamp)
|
||||
id := h.fsm.pConf.State.NeighborAddress
|
||||
id := h.fsm.pConf.Config.NeighborAddress
|
||||
for _, path := range fmsg.PathList {
|
||||
if path.IsEOR() {
|
||||
continue
|
||||
@ -804,7 +755,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
communication, rest := decodeAdministrativeCommunication(body.Data)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": h.fsm.pConf.State.NeighborAddress,
|
||||
"Key": h.fsm.pConf.Config.NeighborAddress,
|
||||
"Code": body.ErrorCode,
|
||||
"Subcode": body.ErrorSubcode,
|
||||
"Communicated-Reason": communication,
|
||||
@ -813,7 +764,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": h.fsm.pConf.State.NeighborAddress,
|
||||
"Key": h.fsm.pConf.Config.NeighborAddress,
|
||||
"Code": body.ErrorCode,
|
||||
"Subcode": body.ErrorSubcode,
|
||||
"Data": body.Data,
|
||||
@ -905,17 +856,16 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
|
||||
conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("Closed an accepted connection")
|
||||
case <-fsm.gracefulRestartTimer.C:
|
||||
if fsm.pConf.GracefulRestart.State.PeerRestarting {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("graceful restart timer expired")
|
||||
h.conn.Close()
|
||||
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
|
||||
}
|
||||
case i, ok := <-h.msgCh.Out():
|
||||
@ -944,7 +894,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
|
||||
fsm.pConf.State.PeerType = typ
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Infof("skiped asn negotiation: peer-as: %d, peer-type: %s", peerAs, typ)
|
||||
} else {
|
||||
@ -999,7 +949,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
|
||||
if fsm.pConf.GracefulRestart.State.PeerRestarting && cap.Flags&0x08 == 0 {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("restart flag is not set")
|
||||
// send notification?
|
||||
@ -1043,7 +993,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
|
||||
default:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Data": e.MsgData,
|
||||
}).Panic("unknown msg type")
|
||||
@ -1065,7 +1015,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
|
||||
case ADMIN_STATE_UP:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"AdminState": stateOp.State.String(),
|
||||
}).Panic("code logic bug")
|
||||
@ -1116,17 +1066,16 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
|
||||
conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("Closed an accepted connection")
|
||||
case <-fsm.gracefulRestartTimer.C:
|
||||
if fsm.pConf.GracefulRestart.State.PeerRestarting {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("graceful restart timer expired")
|
||||
h.conn.Close()
|
||||
return bgp.BGP_FSM_IDLE, FSM_RESTART_TIMER_EXPIRED
|
||||
}
|
||||
case <-ticker.C:
|
||||
@ -1155,7 +1104,7 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
|
||||
default:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Data": e.MsgData,
|
||||
}).Panic("unknown msg type")
|
||||
@ -1177,7 +1126,7 @@ func (h *FSMHandler) openconfirm() (bgp.FSMState, FsmStateReason) {
|
||||
case ADMIN_STATE_UP:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"AdminState": stateOp.State.String(),
|
||||
}).Panic("code logic bug")
|
||||
@ -1195,7 +1144,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
if fsm.twoByteAsTrans && m.Header.Type == bgp.BGP_MSG_UPDATE {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Data": m,
|
||||
}).Debug("update for 2byte AS peer")
|
||||
@ -1206,7 +1155,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Data": err,
|
||||
}).Warn("failed to serialize")
|
||||
@ -1222,7 +1171,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Data": err,
|
||||
}).Warn("failed to send")
|
||||
@ -1239,7 +1188,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
communication, rest := decodeAdministrativeCommunication(body.Data)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Code": body.ErrorCode,
|
||||
"Subcode": body.ErrorSubcode,
|
||||
@ -1249,7 +1198,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Code": body.ErrorCode,
|
||||
"Subcode": body.ErrorSubcode,
|
||||
@ -1263,7 +1212,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
update := m.Body.(*bgp.BGPUpdate)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"nlri": update.NLRI,
|
||||
"withdrawals": update.WithdrawnRoutes,
|
||||
@ -1272,7 +1221,7 @@ func (h *FSMHandler) sendMessageloop() error {
|
||||
default:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"data": m,
|
||||
}).Debug("sent")
|
||||
@ -1348,7 +1297,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
|
||||
conn.Close()
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("Closed an accepted connection")
|
||||
case err := <-h.errorCh:
|
||||
@ -1358,7 +1307,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
|
||||
err = FSM_GRACEFUL_RESTART
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Info("peer graceful restart")
|
||||
fsm.gracefulRestartTimer.Reset(time.Duration(fsm.pConf.GracefulRestart.State.PeerRestartTime) * time.Second)
|
||||
@ -1367,7 +1316,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
|
||||
case <-holdTimer.C:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("hold timer expired")
|
||||
m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_HOLD_TIMER_EXPIRED, 0, nil)
|
||||
@ -1424,7 +1373,7 @@ func (h *FSMHandler) loop() error {
|
||||
if nextState == bgp.BGP_FSM_ESTABLISHED && oldState == bgp.BGP_FSM_OPENCONFIRM {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Info("Peer Up")
|
||||
}
|
||||
@ -1438,14 +1387,14 @@ func (h *FSMHandler) loop() error {
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"Reason": reason,
|
||||
}).Info("Peer Down")
|
||||
}
|
||||
|
||||
e := time.AfterFunc(time.Second*120, func() {
|
||||
log.WithFields(log.Fields{"Topic": "Peer"}).Fatalf("failed to free the fsm.h.t for %s %s %s", fsm.pConf.State.NeighborAddress, oldState, nextState)
|
||||
log.WithFields(log.Fields{"Topic": "Peer"}).Fatalf("failed to free the fsm.h.t for %s %s %s", fsm.pConf.Config.NeighborAddress, oldState, nextState)
|
||||
})
|
||||
h.t.Wait()
|
||||
e.Stop()
|
||||
@ -1454,7 +1403,7 @@ func (h *FSMHandler) loop() error {
|
||||
if nextState >= bgp.BGP_FSM_IDLE {
|
||||
e := &FsmMsg{
|
||||
MsgType: FSM_MSG_STATE_CHANGE,
|
||||
MsgSrc: fsm.pConf.State.NeighborAddress,
|
||||
MsgSrc: fsm.pConf.Config.NeighborAddress,
|
||||
MsgData: nextState,
|
||||
Version: h.fsm.version,
|
||||
}
|
||||
@ -1468,7 +1417,7 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
|
||||
if fsm.adminState != s {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
"AdminState": s.String(),
|
||||
}).Debug("admin state changed")
|
||||
@ -1480,19 +1429,19 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
|
||||
case ADMIN_STATE_UP:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Info("Administrative start")
|
||||
case ADMIN_STATE_DOWN:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Info("Administrative shutdown")
|
||||
case ADMIN_STATE_PFX_CT:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Info("Administrative shutdown(Prefix limit reached)")
|
||||
}
|
||||
@ -1500,7 +1449,7 @@ func (h *FSMHandler) changeAdminState(s AdminState) error {
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": fsm.pConf.State.NeighborAddress,
|
||||
"Key": fsm.pConf.Config.NeighborAddress,
|
||||
"State": fsm.state.String(),
|
||||
}).Warn("cannot change to the same state")
|
||||
|
||||
|
2
vendor/github.com/osrg/gobgp/server/fsm_test.go
generated
vendored
2
vendor/github.com/osrg/gobgp/server/fsm_test.go
generated
vendored
@ -23,11 +23,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
6
vendor/github.com/osrg/gobgp/server/mrt.go
generated
vendored
6
vendor/github.com/osrg/gobgp/server/mrt.go
generated
vendored
@ -21,11 +21,11 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/packet/mrt"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -109,7 +109,7 @@ func (m *mrtWriter) loop() error {
|
||||
t := uint32(time.Now().Unix())
|
||||
peers := make([]*mrt.Peer, 0, len(m.Neighbor))
|
||||
for _, pconf := range m.Neighbor {
|
||||
peers = append(peers, mrt.NewPeer(pconf.State.RemoteRouterId, pconf.State.NeighborAddress, pconf.Config.PeerAs, true))
|
||||
peers = append(peers, mrt.NewPeer(pconf.State.RemoteRouterId, pconf.Config.NeighborAddress, pconf.Config.PeerAs, true))
|
||||
}
|
||||
if bm, err := mrt.NewMRTMessage(t, mrt.TABLE_DUMPv2, mrt.PEER_INDEX_TABLE, mrt.NewPeerIndexTable(m.RouterId, "", peers)); err != nil {
|
||||
break
|
||||
@ -119,7 +119,7 @@ func (m *mrtWriter) loop() error {
|
||||
|
||||
idx := func(p *table.Path) uint16 {
|
||||
for i, pconf := range m.Neighbor {
|
||||
if p.GetSource().Address.String() == pconf.State.NeighborAddress {
|
||||
if p.GetSource().Address.String() == pconf.Config.NeighborAddress {
|
||||
return uint16(i)
|
||||
}
|
||||
}
|
||||
|
112
vendor/github.com/osrg/gobgp/server/peer.go
generated
vendored
112
vendor/github.com/osrg/gobgp/server/peer.go
generated
vendored
@ -17,11 +17,11 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
@ -31,65 +31,6 @@ const (
|
||||
MIN_CONNECT_RETRY = 10
|
||||
)
|
||||
|
||||
type PeerGroup struct {
|
||||
Conf *config.PeerGroup
|
||||
members map[string]config.Neighbor
|
||||
dynamicNeighbors map[string]*config.DynamicNeighbor
|
||||
}
|
||||
|
||||
func NewPeerGroup(c *config.PeerGroup) *PeerGroup {
|
||||
return &PeerGroup{
|
||||
Conf: c,
|
||||
members: make(map[string]config.Neighbor, 0),
|
||||
dynamicNeighbors: make(map[string]*config.DynamicNeighbor, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (pg *PeerGroup) AddMember(c config.Neighbor) {
|
||||
pg.members[c.State.NeighborAddress] = c
|
||||
}
|
||||
|
||||
func (pg *PeerGroup) DeleteMember(c config.Neighbor) {
|
||||
delete(pg.members, c.State.NeighborAddress)
|
||||
}
|
||||
|
||||
func (pg *PeerGroup) AddDynamicNeighbor(c *config.DynamicNeighbor) {
|
||||
pg.dynamicNeighbors[c.Config.Prefix] = c
|
||||
}
|
||||
|
||||
func newDynamicPeer(g *config.Global, neighborAddress string, pg *config.PeerGroup, loc *table.TableManager, policy *table.RoutingPolicy) *Peer {
|
||||
conf := config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
PeerGroup: pg.Config.PeerGroupName,
|
||||
},
|
||||
State: config.NeighborState{
|
||||
NeighborAddress: neighborAddress,
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
PassiveMode: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := config.OverwriteNeighborConfigWithPeerGroup(&conf, pg); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": neighborAddress,
|
||||
}).Debugf("Can't overwrite neighbor config: %s", err)
|
||||
return nil
|
||||
}
|
||||
if err := config.SetDefaultNeighborConfigValues(&conf, g.Config.As); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": neighborAddress,
|
||||
}).Debugf("Can't set default config: %s", err)
|
||||
return nil
|
||||
}
|
||||
peer := NewPeer(g, &conf, loc, policy)
|
||||
peer.fsm.state = bgp.BGP_FSM_ACTIVE
|
||||
return peer
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
tableId string
|
||||
fsm *FSM
|
||||
@ -110,7 +51,7 @@ func NewPeer(g *config.Global, conf *config.Neighbor, loc *table.TableManager, p
|
||||
prefixLimitWarned: make(map[bgp.RouteFamily]bool),
|
||||
}
|
||||
if peer.isRouteServerClient() {
|
||||
peer.tableId = conf.State.NeighborAddress
|
||||
peer.tableId = conf.Config.NeighborAddress
|
||||
} else {
|
||||
peer.tableId = table.GLOBAL_RIB_NAME
|
||||
}
|
||||
@ -120,7 +61,7 @@ func NewPeer(g *config.Global, conf *config.Neighbor, loc *table.TableManager, p
|
||||
}
|
||||
|
||||
func (peer *Peer) ID() string {
|
||||
return peer.fsm.pConf.State.NeighborAddress
|
||||
return peer.fsm.pConf.Config.NeighborAddress
|
||||
}
|
||||
|
||||
func (peer *Peer) TableID() string {
|
||||
@ -143,10 +84,6 @@ func (peer *Peer) isGracefulRestartEnabled() bool {
|
||||
return peer.fsm.pConf.GracefulRestart.State.Enabled
|
||||
}
|
||||
|
||||
func (peer *Peer) isDynamicNeighbor() bool {
|
||||
return peer.fsm.pConf.Config.NeighborAddress == "" && peer.fsm.pConf.Config.NeighborInterface == ""
|
||||
}
|
||||
|
||||
func (peer *Peer) recvedAllEOR() bool {
|
||||
for _, a := range peer.fsm.pConf.AfiSafis {
|
||||
if s := a.MpGracefulRestart.State; s.Enabled && !s.EndOfRibReceived {
|
||||
@ -403,7 +340,7 @@ func (peer *Peer) processOutgoingPaths(paths, olds []*table.Path) []*table.Path
|
||||
if peer.fsm.pConf.GracefulRestart.State.LocalRestarting {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
}).Debug("now syncing, suppress sending updates")
|
||||
return nil
|
||||
}
|
||||
@ -521,7 +458,7 @@ func (peer *Peer) handleUpdate(e *FsmMsg) ([]*table.Path, []bgp.RouteFamily, *bg
|
||||
update := m.Body.(*bgp.BGPUpdate)
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
"nlri": update.NLRI,
|
||||
"withdrawals": update.WithdrawnRoutes,
|
||||
"attributes": update.PathAttributes,
|
||||
@ -628,42 +565,3 @@ func (peer *Peer) ToConfig(getAdvertised bool) *config.Neighbor {
|
||||
func (peer *Peer) DropAll(rfList []bgp.RouteFamily) {
|
||||
peer.adjRibIn.Drop(rfList)
|
||||
}
|
||||
|
||||
func (peer *Peer) stopFSM() error {
|
||||
failed := false
|
||||
addr := peer.fsm.pConf.State.NeighborAddress
|
||||
t1 := time.AfterFunc(time.Minute*5, func() {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
}).Warnf("Failed to free the fsm.h.t for %s", addr)
|
||||
failed = true
|
||||
})
|
||||
peer.fsm.h.t.Kill(nil)
|
||||
peer.fsm.h.t.Wait()
|
||||
t1.Stop()
|
||||
if !failed {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Debug("freed fsm.h.t")
|
||||
cleanInfiniteChannel(peer.outgoing)
|
||||
}
|
||||
failed = false
|
||||
t2 := time.AfterFunc(time.Minute*5, func() {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
}).Warnf("Failed to free the fsm.t for %s", addr)
|
||||
failed = true
|
||||
})
|
||||
peer.fsm.t.Kill(nil)
|
||||
peer.fsm.t.Wait()
|
||||
t2.Stop()
|
||||
if !failed {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Debug("freed fsm.t")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Failed to free FSM for %s", addr)
|
||||
}
|
||||
|
2
vendor/github.com/osrg/gobgp/server/rpki.go
generated
vendored
2
vendor/github.com/osrg/gobgp/server/rpki.go
generated
vendored
@ -24,12 +24,12 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/armon/go-radix"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/packet/rtr"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
442
vendor/github.com/osrg/gobgp/server/server.go
generated
vendored
442
vendor/github.com/osrg/gobgp/server/server.go
generated
vendored
@ -23,11 +23,11 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type TCPListener struct {
|
||||
@ -92,29 +92,27 @@ type BgpServer struct {
|
||||
fsmStateCh chan *FsmMsg
|
||||
acceptCh chan *net.TCPConn
|
||||
|
||||
mgmtCh chan *mgmtOp
|
||||
policy *table.RoutingPolicy
|
||||
listeners []*TCPListener
|
||||
neighborMap map[string]*Peer
|
||||
peerGroupMap map[string]*PeerGroup
|
||||
globalRib *table.TableManager
|
||||
roaManager *roaManager
|
||||
shutdown bool
|
||||
watcherMap map[WatchEventType][]*Watcher
|
||||
zclient *zebraClient
|
||||
bmpManager *bmpClientManager
|
||||
mrtManager *mrtManager
|
||||
mgmtCh chan *mgmtOp
|
||||
policy *table.RoutingPolicy
|
||||
listeners []*TCPListener
|
||||
neighborMap map[string]*Peer
|
||||
globalRib *table.TableManager
|
||||
roaManager *roaManager
|
||||
shutdown bool
|
||||
watcherMap map[WatchEventType][]*Watcher
|
||||
zclient *zebraClient
|
||||
bmpManager *bmpClientManager
|
||||
mrtManager *mrtManager
|
||||
}
|
||||
|
||||
func NewBgpServer() *BgpServer {
|
||||
roaManager, _ := NewROAManager(0)
|
||||
s := &BgpServer{
|
||||
neighborMap: make(map[string]*Peer),
|
||||
peerGroupMap: make(map[string]*PeerGroup),
|
||||
policy: table.NewRoutingPolicy(),
|
||||
roaManager: roaManager,
|
||||
mgmtCh: make(chan *mgmtOp, 1),
|
||||
watcherMap: make(map[WatchEventType][]*Watcher),
|
||||
neighborMap: make(map[string]*Peer),
|
||||
policy: table.NewRoutingPolicy(),
|
||||
roaManager: roaManager,
|
||||
mgmtCh: make(chan *mgmtOp, 1),
|
||||
watcherMap: make(map[WatchEventType][]*Watcher),
|
||||
}
|
||||
s.bmpManager = newBmpClientManager(s)
|
||||
s.mrtManager = newMrtManager(s)
|
||||
@ -236,24 +234,6 @@ func (server *BgpServer) Serve() {
|
||||
"Topic": "Peer",
|
||||
}).Debugf("Accepted a new passive connection from:%s", remoteAddr)
|
||||
peer.PassConn(conn)
|
||||
} else if pg := server.matchLongestDynamicNeighborPrefix(remoteAddr); pg != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
}).Debugf("Accepted a new dynamic neighbor from:%s", remoteAddr)
|
||||
peer := newDynamicPeer(&server.bgpConfig.Global, remoteAddr, pg.Conf, server.globalRib, server.policy)
|
||||
if peer == nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": remoteAddr,
|
||||
}).Infof("Can't create new Dynamic Peer")
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
server.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): peer.fsm.pConf.ApplyPolicy})
|
||||
server.neighborMap[remoteAddr] = peer
|
||||
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
|
||||
server.broadcastPeerState(peer, bgp.BGP_FSM_ACTIVE)
|
||||
peer.PassConn(conn)
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
@ -298,24 +278,6 @@ func (server *BgpServer) Serve() {
|
||||
}
|
||||
}
|
||||
|
||||
func (server *BgpServer) matchLongestDynamicNeighborPrefix(a string) *PeerGroup {
|
||||
ipAddr := net.ParseIP(a)
|
||||
longestMask := net.CIDRMask(0, 32).String()
|
||||
var longestPG *PeerGroup
|
||||
for _, pg := range server.peerGroupMap {
|
||||
for _, d := range pg.dynamicNeighbors {
|
||||
_, netAddr, _ := net.ParseCIDR(d.Config.Prefix)
|
||||
if netAddr.Contains(ipAddr) {
|
||||
if netAddr.Mask.String() > longestMask {
|
||||
longestMask = netAddr.Mask.String()
|
||||
longestPG = pg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return longestPG
|
||||
}
|
||||
|
||||
func sendFsmOutgoingMsg(peer *Peer, paths []*table.Path, notification *bgp.BGPMessage, stayIdle bool) {
|
||||
peer.outgoing.In() <- &FsmOutgoingMsg{
|
||||
Paths: paths,
|
||||
@ -570,33 +532,6 @@ func (server *BgpServer) broadcastPeerState(peer *Peer, oldState bgp.FSMState) {
|
||||
}
|
||||
}
|
||||
|
||||
func (server *BgpServer) notifyMessageWatcher(peer *Peer, timestamp time.Time, msg *bgp.BGPMessage, isSent bool) {
|
||||
// validation should be done in the caller of this function
|
||||
_, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER]
|
||||
l, _ := peer.fsm.LocalHostPort()
|
||||
ev := &WatchEventMessage{
|
||||
Message: msg,
|
||||
PeerAS: peer.fsm.peerInfo.AS,
|
||||
LocalAS: peer.fsm.peerInfo.LocalAS,
|
||||
PeerAddress: peer.fsm.peerInfo.Address,
|
||||
LocalAddress: net.ParseIP(l),
|
||||
PeerID: peer.fsm.peerInfo.ID,
|
||||
FourBytesAs: y,
|
||||
Timestamp: timestamp,
|
||||
IsSent: isSent,
|
||||
}
|
||||
if !isSent {
|
||||
server.notifyWatcher(WATCH_EVENT_TYPE_RECV_MSG, ev)
|
||||
}
|
||||
}
|
||||
|
||||
func (server *BgpServer) notifyRecvMessageWatcher(peer *Peer, timestamp time.Time, msg *bgp.BGPMessage) {
|
||||
if peer == nil || !server.isWatched(WATCH_EVENT_TYPE_RECV_MSG) {
|
||||
return
|
||||
}
|
||||
server.notifyMessageWatcher(peer, timestamp, msg, false)
|
||||
}
|
||||
|
||||
func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*table.Path {
|
||||
moded := make([]*table.Path, 0, len(pathList)/2)
|
||||
for _, before := range pathList {
|
||||
@ -757,11 +692,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
peer.fsm.pConf.State.PeerAs = 0
|
||||
peer.fsm.peerInfo.AS = 0
|
||||
}
|
||||
if peer.isDynamicNeighbor() {
|
||||
peer.stopPeerRestarting()
|
||||
go peer.stopFSM()
|
||||
delete(server.neighborMap, peer.fsm.pConf.State.NeighborAddress)
|
||||
}
|
||||
} else if peer.fsm.pConf.GracefulRestart.State.PeerRestarting && nextState == bgp.BGP_FSM_IDLE {
|
||||
if peer.fsm.pConf.GracefulRestart.State.LongLivedEnabled {
|
||||
llgr, no_llgr := peer.llgrFamilies()
|
||||
@ -842,7 +772,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
deferralExpiredFunc := func(family bgp.RouteFamily) func() {
|
||||
return func() {
|
||||
server.mgmtOperation(func() error {
|
||||
server.softResetOut(peer.fsm.pConf.State.NeighborAddress, family, true)
|
||||
server.softResetOut(peer.fsm.pConf.Config.NeighborAddress, family, true)
|
||||
return nil
|
||||
}, false)
|
||||
}
|
||||
@ -905,7 +835,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
// clear counter
|
||||
if peer.fsm.adminState == ADMIN_STATE_DOWN {
|
||||
peer.fsm.pConf.State = config.NeighborState{}
|
||||
peer.fsm.pConf.State.NeighborAddress = peer.fsm.pConf.Config.NeighborAddress
|
||||
peer.fsm.pConf.Timers.State = config.TimersState{}
|
||||
}
|
||||
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
|
||||
@ -924,7 +853,6 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
sendFsmOutgoingMsg(peer, nil, bgp.NewBGPNotificationMessage(m.TypeCode, m.SubTypeCode, m.Data), false)
|
||||
return
|
||||
case *bgp.BGPMessage:
|
||||
server.notifyRecvMessageWatcher(peer, e.timestamp, m)
|
||||
if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED || e.timestamp.Unix() < peer.fsm.pConf.Timers.State.Uptime {
|
||||
return
|
||||
}
|
||||
@ -1012,7 +940,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
pathList := peer.adjRibIn.DropStale(peer.configuredRFlist())
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
}).Debugf("withdraw %d stale routes", len(pathList))
|
||||
server.propagateUpdate(peer, pathList)
|
||||
}
|
||||
@ -1042,7 +970,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
|
||||
default:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
"Data": e.MsgData,
|
||||
}).Panic("unknown msg type")
|
||||
}
|
||||
@ -1103,7 +1031,7 @@ func (s *BgpServer) UpdatePolicy(policy config.RoutingPolicy) error {
|
||||
for _, peer := range s.neighborMap {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
}).Info("call set policy")
|
||||
ap[peer.ID()] = peer.fsm.pConf.ApplyPolicy
|
||||
}
|
||||
@ -1647,42 +1575,17 @@ func (s *BgpServer) GetNeighbor(address string, getAdvertised bool) (l []*config
|
||||
return l
|
||||
}
|
||||
|
||||
func (server *BgpServer) addPeerGroup(c *config.PeerGroup) error {
|
||||
name := c.Config.PeerGroupName
|
||||
if _, y := server.peerGroupMap[name]; y {
|
||||
return fmt.Errorf("Can't overwrite the existing peer-group: %s", name)
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Name": name,
|
||||
}).Info("Add a peer group configuration")
|
||||
|
||||
server.peerGroupMap[c.Config.PeerGroupName] = NewPeerGroup(c)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *BgpServer) addNeighbor(c *config.Neighbor) error {
|
||||
addr, err := config.ExtractNeighborAddress(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, y := server.neighborMap[addr]; y {
|
||||
return fmt.Errorf("Can't overwrite the existing peer: %s", addr)
|
||||
}
|
||||
|
||||
if c.Config.PeerGroup != "" {
|
||||
if err := config.OverwriteNeighborConfigWithPeerGroup(c, server.peerGroupMap[c.Config.PeerGroup].Conf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := config.SetDefaultNeighborConfigValues(c, server.bgpConfig.Global.Config.As); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr := c.Config.NeighborAddress
|
||||
if _, y := server.neighborMap[addr]; y {
|
||||
return fmt.Errorf("Can't overwrite the existing peer: %s", addr)
|
||||
}
|
||||
|
||||
if vrf := c.Config.Vrf; vrf != "" {
|
||||
if c.RouteServer.Config.RouteServerClient {
|
||||
return fmt.Errorf("route server client can't be enslaved to VRF")
|
||||
@ -1737,62 +1640,19 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error {
|
||||
}
|
||||
}
|
||||
server.neighborMap[addr] = peer
|
||||
if name := c.Config.PeerGroup; name != "" {
|
||||
server.peerGroupMap[name].AddMember(*c)
|
||||
}
|
||||
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
|
||||
server.broadcastPeerState(peer, bgp.BGP_FSM_IDLE)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BgpServer) AddPeerGroup(c *config.PeerGroup) error {
|
||||
return s.mgmtOperation(func() error {
|
||||
return s.addPeerGroup(c)
|
||||
}, true)
|
||||
}
|
||||
|
||||
func (s *BgpServer) AddNeighbor(c *config.Neighbor) error {
|
||||
return s.mgmtOperation(func() error {
|
||||
return s.addNeighbor(c)
|
||||
}, true)
|
||||
}
|
||||
|
||||
func (s *BgpServer) AddDynamicNeighbor(c *config.DynamicNeighbor) error {
|
||||
return s.mgmtOperation(func() error {
|
||||
s.peerGroupMap[c.Config.PeerGroup].AddDynamicNeighbor(c)
|
||||
return nil
|
||||
}, true)
|
||||
}
|
||||
|
||||
func (server *BgpServer) deletePeerGroup(pg *config.PeerGroup) error {
|
||||
name := pg.Config.PeerGroupName
|
||||
|
||||
if _, y := server.peerGroupMap[name]; !y {
|
||||
return fmt.Errorf("Can't delete a peer-group %s which does not exist", name)
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Name": name,
|
||||
}).Info("Delete a peer group configuration")
|
||||
|
||||
delete(server.peerGroupMap, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) error {
|
||||
if c.Config.PeerGroup != "" {
|
||||
_, y := server.peerGroupMap[c.Config.PeerGroup]
|
||||
if y {
|
||||
server.peerGroupMap[c.Config.PeerGroup].DeleteMember(*c)
|
||||
}
|
||||
}
|
||||
|
||||
addr, err := config.ExtractNeighborAddress(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr := c.Config.NeighborAddress
|
||||
if intf := c.Config.NeighborInterface; intf != "" {
|
||||
var err error
|
||||
addr, err = config.GetIPv6LinkLocalNeighborAddress(intf)
|
||||
@ -1814,151 +1674,130 @@ func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8)
|
||||
n.fsm.sendNotification(code, subcode, nil, "")
|
||||
n.stopPeerRestarting()
|
||||
|
||||
go n.stopFSM()
|
||||
go func(addr string) {
|
||||
failed := false
|
||||
t1 := time.AfterFunc(time.Minute*5, func() {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
}).Warnf("Failed to free the fsm.h.t for %s", addr)
|
||||
failed = true
|
||||
})
|
||||
n.fsm.h.t.Kill(nil)
|
||||
n.fsm.h.t.Wait()
|
||||
t1.Stop()
|
||||
if !failed {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Debug("freed fsm.h.t")
|
||||
cleanInfiniteChannel(n.outgoing)
|
||||
}
|
||||
failed = false
|
||||
t2 := time.AfterFunc(time.Minute*5, func() {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
}).Warnf("Failed to free the fsm.t for %s", addr)
|
||||
failed = true
|
||||
})
|
||||
n.fsm.t.Kill(nil)
|
||||
n.fsm.t.Wait()
|
||||
t2.Stop()
|
||||
if !failed {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Debug("freed fsm.t")
|
||||
}
|
||||
}(addr)
|
||||
delete(server.neighborMap, addr)
|
||||
server.dropPeerAllRoutes(n, n.configuredRFlist())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BgpServer) DeletePeerGroup(c *config.PeerGroup) error {
|
||||
return s.mgmtOperation(func() error {
|
||||
name := c.Config.PeerGroupName
|
||||
for _, n := range s.neighborMap {
|
||||
if n.fsm.pConf.Config.PeerGroup == name {
|
||||
return fmt.Errorf("failed to delete peer-group %s: neighbor %s is in use", name, n.ID())
|
||||
}
|
||||
}
|
||||
return s.deletePeerGroup(c)
|
||||
}, true)
|
||||
}
|
||||
|
||||
func (s *BgpServer) DeleteNeighbor(c *config.Neighbor) error {
|
||||
return s.mgmtOperation(func() error {
|
||||
return s.deleteNeighbor(c, bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_PEER_DECONFIGURED)
|
||||
}, true)
|
||||
}
|
||||
|
||||
func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) {
|
||||
name := pg.Config.PeerGroupName
|
||||
|
||||
_, ok := s.peerGroupMap[name]
|
||||
if !ok {
|
||||
return false, fmt.Errorf("Peer-group %s doesn't exist.", name)
|
||||
}
|
||||
s.peerGroupMap[name].Conf = pg
|
||||
|
||||
for _, n := range s.peerGroupMap[name].members {
|
||||
c := n
|
||||
u, err := s.updateNeighbor(&c)
|
||||
if err != nil {
|
||||
return needsSoftResetIn, err
|
||||
}
|
||||
needsSoftResetIn = needsSoftResetIn || u
|
||||
}
|
||||
return needsSoftResetIn, nil
|
||||
}
|
||||
|
||||
func (s *BgpServer) UpdatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) {
|
||||
func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
|
||||
err = s.mgmtOperation(func() error {
|
||||
needsSoftResetIn, err = s.updatePeerGroup(pg)
|
||||
return err
|
||||
}, true)
|
||||
return needsSoftResetIn, err
|
||||
}
|
||||
|
||||
func (s *BgpServer) updateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
|
||||
if c.Config.PeerGroup != "" {
|
||||
if err := config.OverwriteNeighborConfigWithPeerGroup(c, s.peerGroupMap[c.Config.PeerGroup].Conf); err != nil {
|
||||
return needsSoftResetIn, err
|
||||
addr := c.Config.NeighborAddress
|
||||
peer, ok := s.neighborMap[addr]
|
||||
if !ok {
|
||||
return fmt.Errorf("Neighbor that has %v doesn't exist.", addr)
|
||||
}
|
||||
}
|
||||
|
||||
addr, err := config.ExtractNeighborAddress(c)
|
||||
if err != nil {
|
||||
return needsSoftResetIn, err
|
||||
}
|
||||
if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Info("Update ApplyPolicy")
|
||||
s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy})
|
||||
peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy
|
||||
needsSoftResetIn = true
|
||||
}
|
||||
original := peer.fsm.pConf
|
||||
|
||||
peer, ok := s.neighborMap[addr]
|
||||
if !ok {
|
||||
return needsSoftResetIn, fmt.Errorf("Neighbor that has %v doesn't exist.", addr)
|
||||
}
|
||||
|
||||
if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Info("Update ApplyPolicy")
|
||||
s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy})
|
||||
peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy
|
||||
needsSoftResetIn = true
|
||||
}
|
||||
original := peer.fsm.pConf
|
||||
|
||||
if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.ID(),
|
||||
}).Info("Update aspath options")
|
||||
peer.fsm.pConf.AsPathOptions = c.AsPathOptions
|
||||
needsSoftResetIn = true
|
||||
}
|
||||
|
||||
if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) {
|
||||
sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE)
|
||||
if original.Config.AdminDown != c.Config.AdminDown {
|
||||
sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN
|
||||
state := "Admin Down"
|
||||
if c.Config.AdminDown == false {
|
||||
state = "Admin Up"
|
||||
}
|
||||
if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.ID(),
|
||||
"State": state,
|
||||
}).Info("Update admin-state configuration")
|
||||
} else if original.Config.PeerAs != c.Config.PeerAs {
|
||||
sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED
|
||||
}).Info("Update aspath options")
|
||||
peer.fsm.pConf.AsPathOptions = c.AsPathOptions
|
||||
needsSoftResetIn = true
|
||||
}
|
||||
if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil {
|
||||
|
||||
if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) {
|
||||
sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE)
|
||||
if original.Config.AdminDown != c.Config.AdminDown {
|
||||
sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN
|
||||
state := "Admin Down"
|
||||
if c.Config.AdminDown == false {
|
||||
state = "Admin Up"
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.ID(),
|
||||
"State": state,
|
||||
}).Info("Update admin-state configuration")
|
||||
} else if original.Config.PeerAs != c.Config.PeerAs {
|
||||
sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED
|
||||
}
|
||||
if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Error(err)
|
||||
return err
|
||||
}
|
||||
err = s.addNeighbor(c)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Error(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if !original.Timers.Config.Equal(&c.Timers.Config) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Error(err)
|
||||
return needsSoftResetIn, err
|
||||
"Key": peer.ID(),
|
||||
}).Info("Update timer configuration")
|
||||
peer.fsm.pConf.Timers.Config = c.Timers.Config
|
||||
}
|
||||
err = s.addNeighbor(c)
|
||||
|
||||
err = peer.updatePrefixLimitConfig(c.AfiSafis)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Error(err)
|
||||
// rollback to original state
|
||||
peer.fsm.pConf = original
|
||||
}
|
||||
return needsSoftResetIn, err
|
||||
}
|
||||
|
||||
if !original.Timers.Config.Equal(&c.Timers.Config) {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.ID(),
|
||||
}).Info("Update timer configuration")
|
||||
peer.fsm.pConf.Timers.Config = c.Timers.Config
|
||||
}
|
||||
|
||||
err = peer.updatePrefixLimitConfig(c.AfiSafis)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": addr,
|
||||
}).Error(err)
|
||||
// rollback to original state
|
||||
peer.fsm.pConf = original
|
||||
}
|
||||
return needsSoftResetIn, err
|
||||
}
|
||||
|
||||
func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) {
|
||||
err = s.mgmtOperation(func() error {
|
||||
needsSoftResetIn, err = s.updateNeighbor(c)
|
||||
return err
|
||||
}, true)
|
||||
return needsSoftResetIn, err
|
||||
@ -2025,10 +1864,10 @@ func (s *BgpServer) setAdminState(addr, communication string, enable bool) error
|
||||
case peer.fsm.adminStateCh <- *stateOp:
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.fsm.pConf.State.NeighborAddress,
|
||||
"Key": peer.fsm.pConf.Config.NeighborAddress,
|
||||
}).Debug(message)
|
||||
default:
|
||||
log.Warning("previous request is still remaining. : ", peer.fsm.pConf.State.NeighborAddress)
|
||||
log.Warning("previous request is still remaining. : ", peer.fsm.pConf.Config.NeighborAddress)
|
||||
}
|
||||
}
|
||||
if enable {
|
||||
@ -2291,7 +2130,6 @@ const (
|
||||
WATCH_EVENT_TYPE_POST_UPDATE WatchEventType = "postupdate"
|
||||
WATCH_EVENT_TYPE_PEER_STATE WatchEventType = "peerstate"
|
||||
WATCH_EVENT_TYPE_TABLE WatchEventType = "table"
|
||||
WATCH_EVENT_TYPE_RECV_MSG WatchEventType = "receivedmessage"
|
||||
)
|
||||
|
||||
type WatchEvent interface {
|
||||
@ -2342,18 +2180,6 @@ type WatchEventBestPath struct {
|
||||
MultiPathList [][]*table.Path
|
||||
}
|
||||
|
||||
type WatchEventMessage struct {
|
||||
Message *bgp.BGPMessage
|
||||
PeerAS uint32
|
||||
LocalAS uint32
|
||||
PeerAddress net.IP
|
||||
LocalAddress net.IP
|
||||
PeerID net.IP
|
||||
FourBytesAs bool
|
||||
Timestamp time.Time
|
||||
IsSent bool
|
||||
}
|
||||
|
||||
type watchOptions struct {
|
||||
bestpath bool
|
||||
preUpdate bool
|
||||
@ -2364,8 +2190,6 @@ type watchOptions struct {
|
||||
initPostUpdate bool
|
||||
initPeerState bool
|
||||
tableName string
|
||||
recvMessage bool
|
||||
sentMessage bool
|
||||
}
|
||||
|
||||
type WatchOption func(*watchOptions)
|
||||
@ -2412,19 +2236,6 @@ func WatchTableName(name string) WatchOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WatchMessage(isSent bool) WatchOption {
|
||||
return func(o *watchOptions) {
|
||||
if isSent {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Server",
|
||||
}).Warn("watch event for sent messages is not implemented yet")
|
||||
// o.sentMessage = true
|
||||
} else {
|
||||
o.recvMessage = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Watcher struct {
|
||||
opts watchOptions
|
||||
realCh chan WatchEvent
|
||||
@ -2648,9 +2459,6 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if w.opts.recvMessage {
|
||||
register(WATCH_EVENT_TYPE_RECV_MSG, w)
|
||||
}
|
||||
|
||||
go w.loop()
|
||||
return nil
|
||||
|
293
vendor/github.com/osrg/gobgp/server/server_test.go
generated
vendored
293
vendor/github.com/osrg/gobgp/server/server_test.go
generated
vendored
@ -16,10 +16,10 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net"
|
||||
"runtime"
|
||||
@ -31,17 +31,13 @@ func TestModPolicyAssign(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
s := NewBgpServer()
|
||||
go s.Serve()
|
||||
err := s.Start(&config.Global{
|
||||
s.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 1,
|
||||
RouterId: "1.1.1.1",
|
||||
Port: -1,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s.Stop()
|
||||
|
||||
err = s.AddPolicy(&table.Policy{Name: "p1"}, false)
|
||||
err := s.AddPolicy(&table.Policy{Name: "p1"}, false)
|
||||
assert.Nil(err)
|
||||
|
||||
err = s.AddPolicy(&table.Policy{Name: "p2"}, false)
|
||||
@ -66,16 +62,13 @@ func TestMonitor(test *testing.T) {
|
||||
assert := assert.New(test)
|
||||
s := NewBgpServer()
|
||||
go s.Serve()
|
||||
err := s.Start(&config.Global{
|
||||
s.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 1,
|
||||
RouterId: "1.1.1.1",
|
||||
Port: 10179,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s.Stop()
|
||||
|
||||
n := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
@ -87,21 +80,18 @@ func TestMonitor(test *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err = s.AddNeighbor(n)
|
||||
assert.Nil(err)
|
||||
|
||||
if err := s.AddNeighbor(n); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
t := NewBgpServer()
|
||||
go t.Serve()
|
||||
err = t.Start(&config.Global{
|
||||
t.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 2,
|
||||
RouterId: "2.2.2.2",
|
||||
Port: -1,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer t.Stop()
|
||||
|
||||
m := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
@ -113,8 +103,9 @@ func TestMonitor(test *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err = t.AddNeighbor(m)
|
||||
assert.Nil(err)
|
||||
if err := t.AddNeighbor(m); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
@ -168,10 +159,6 @@ func TestNumGoroutineWithAddDeleteNeighbor(t *testing.T) {
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s.Stop()
|
||||
|
||||
// wait a few seconds to avoid taking effect from other test cases.
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
num := runtime.NumGoroutine()
|
||||
|
||||
@ -356,261 +343,3 @@ func TestFilterpathWithRejectPolicy(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPeerGroup(test *testing.T) {
|
||||
assert := assert.New(test)
|
||||
log.SetLevel(log.DebugLevel)
|
||||
s := NewBgpServer()
|
||||
go s.Serve()
|
||||
err := s.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 1,
|
||||
RouterId: "1.1.1.1",
|
||||
Port: 10179,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s.Stop()
|
||||
|
||||
g := &config.PeerGroup{
|
||||
Config: config.PeerGroupConfig{
|
||||
PeerAs: 2,
|
||||
PeerGroupName: "g",
|
||||
},
|
||||
}
|
||||
err = s.AddPeerGroup(g)
|
||||
assert.Nil(err)
|
||||
|
||||
n := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
PeerGroup: "g",
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
PassiveMode: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
configured := map[string]interface{}{
|
||||
"config": map[string]interface{}{
|
||||
"neigbor-address": "127.0.0.1",
|
||||
"peer-group": "g",
|
||||
},
|
||||
"transport": map[string]interface{}{
|
||||
"config": map[string]interface{}{
|
||||
"passive-mode": true,
|
||||
},
|
||||
},
|
||||
}
|
||||
config.RegisterConfiguredFields("127.0.0.1", configured)
|
||||
err = s.AddNeighbor(n)
|
||||
assert.Nil(err)
|
||||
|
||||
t := NewBgpServer()
|
||||
go t.Serve()
|
||||
err = t.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 2,
|
||||
RouterId: "2.2.2.2",
|
||||
Port: -1,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer t.Stop()
|
||||
|
||||
m := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
PeerAs: 1,
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
RemotePort: 10179,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = t.AddNeighbor(m)
|
||||
assert.Nil(err)
|
||||
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if t.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDynamicNeighbor(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
log.SetLevel(log.DebugLevel)
|
||||
s1 := NewBgpServer()
|
||||
go s1.Serve()
|
||||
err := s1.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 1,
|
||||
RouterId: "1.1.1.1",
|
||||
Port: 10179,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s1.Stop()
|
||||
|
||||
g := &config.PeerGroup{
|
||||
Config: config.PeerGroupConfig{
|
||||
PeerAs: 2,
|
||||
PeerGroupName: "g",
|
||||
},
|
||||
}
|
||||
err = s1.AddPeerGroup(g)
|
||||
assert.Nil(err)
|
||||
|
||||
d := &config.DynamicNeighbor{
|
||||
Config: config.DynamicNeighborConfig{
|
||||
Prefix: "127.0.0.0/24",
|
||||
PeerGroup: "g",
|
||||
},
|
||||
}
|
||||
err = s1.AddDynamicNeighbor(d)
|
||||
assert.Nil(err)
|
||||
|
||||
s2 := NewBgpServer()
|
||||
go s2.Serve()
|
||||
err = s2.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 2,
|
||||
RouterId: "2.2.2.2",
|
||||
Port: -1,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s2.Stop()
|
||||
|
||||
m := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
PeerAs: 1,
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
RemotePort: 10179,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = s2.AddNeighbor(m)
|
||||
|
||||
assert.Nil(err)
|
||||
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if s2.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGracefulRestartTimerExpired(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
s1 := NewBgpServer()
|
||||
go s1.Serve()
|
||||
err := s1.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 1,
|
||||
RouterId: "1.1.1.1",
|
||||
Port: 10179,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s1.Stop()
|
||||
|
||||
n := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
PeerAs: 2,
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
PassiveMode: true,
|
||||
},
|
||||
},
|
||||
GracefulRestart: config.GracefulRestart{
|
||||
Config: config.GracefulRestartConfig{
|
||||
Enabled: true,
|
||||
RestartTime: 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = s1.AddNeighbor(n)
|
||||
assert.Nil(err)
|
||||
|
||||
s2 := NewBgpServer()
|
||||
go s2.Serve()
|
||||
err = s2.Start(&config.Global{
|
||||
Config: config.GlobalConfig{
|
||||
As: 2,
|
||||
RouterId: "2.2.2.2",
|
||||
Port: -1,
|
||||
},
|
||||
})
|
||||
assert.Nil(err)
|
||||
defer s2.Stop()
|
||||
|
||||
m := &config.Neighbor{
|
||||
Config: config.NeighborConfig{
|
||||
NeighborAddress: "127.0.0.1",
|
||||
PeerAs: 1,
|
||||
},
|
||||
Transport: config.Transport{
|
||||
Config: config.TransportConfig{
|
||||
RemotePort: 10179,
|
||||
},
|
||||
},
|
||||
GracefulRestart: config.GracefulRestart{
|
||||
Config: config.GracefulRestartConfig{
|
||||
Enabled: true,
|
||||
RestartTime: 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = s2.AddNeighbor(m)
|
||||
assert.Nil(err)
|
||||
|
||||
// Waiting for BGP session established.
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if s2.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Force TCP session disconnected in order to cause Graceful Restart at s1
|
||||
// side.
|
||||
for _, n := range s2.neighborMap {
|
||||
n.fsm.conn.Close()
|
||||
}
|
||||
s2.Stop()
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
// Create dummy session which does NOT send BGP OPEN message in order to
|
||||
// cause Graceful Restart timer expired.
|
||||
var conn net.Conn
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
var err error
|
||||
conn, err = net.Dial("tcp", "127.0.0.1:10179")
|
||||
if err != nil {
|
||||
log.Warn("net.Dial:", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Waiting for Graceful Restart timer expired and moving on to IDLE state.
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if s1.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_IDLE {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/osrg/gobgp/server/sockopt.go
generated
vendored
4
vendor/github.com/osrg/gobgp/server/sockopt.go
generated
vendored
@ -29,10 +29,6 @@ func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
return fmt.Errorf("setting ttl is not supported")
|
||||
}
|
||||
|
||||
func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
return fmt.Errorf("setting min ttl is not supported")
|
||||
}
|
||||
|
||||
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
|
||||
return nil, fmt.Errorf("md5 active connection unsupported")
|
||||
}
|
||||
|
33
vendor/github.com/osrg/gobgp/server/sockopt_bsd.go
generated
vendored
33
vendor/github.com/osrg/gobgp/server/sockopt_bsd.go
generated
vendored
@ -25,8 +25,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TCP_MD5SIG = 0x10 // TCP MD5 Signature (RFC2385)
|
||||
IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
|
||||
TCP_MD5SIG = 0x10
|
||||
)
|
||||
|
||||
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
|
||||
@ -50,7 +49,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
fi, err := conn.File()
|
||||
defer fi.Close()
|
||||
if err != nil {
|
||||
@ -59,27 +64,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
if conn, err := net.FileConn(fi); err == nil {
|
||||
defer conn.Close()
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
|
||||
}
|
||||
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
}
|
||||
|
||||
func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_MINTTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = IPV6_MINHOPCOUNT
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
|
||||
}
|
||||
|
||||
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
|
||||
|
33
vendor/github.com/osrg/gobgp/server/sockopt_linux.go
generated
vendored
33
vendor/github.com/osrg/gobgp/server/sockopt_linux.go
generated
vendored
@ -26,8 +26,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TCP_MD5SIG = 14 // TCP MD5 Signature (RFC2385)
|
||||
IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
|
||||
TCP_MD5SIG = 14
|
||||
)
|
||||
|
||||
type tcpmd5sig struct {
|
||||
@ -75,7 +74,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
fi, err := conn.File()
|
||||
defer fi.Close()
|
||||
if err != nil {
|
||||
@ -84,27 +89,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
if conn, err := net.FileConn(fi); err == nil {
|
||||
defer conn.Close()
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
|
||||
}
|
||||
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
}
|
||||
|
||||
func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_MINTTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = IPV6_MINHOPCOUNT
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
|
||||
}
|
||||
|
||||
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
|
||||
|
35
vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go
generated
vendored
35
vendor/github.com/osrg/gobgp/server/sockopt_openbsd.go
generated
vendored
@ -19,7 +19,7 @@ package server
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
@ -348,8 +348,7 @@ func saDelete(address string) error {
|
||||
}
|
||||
|
||||
const (
|
||||
TCP_MD5SIG = 0x4 // TCP MD5 Signature (RFC2385)
|
||||
IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
|
||||
TCP_MD5SIG = 0x4
|
||||
)
|
||||
|
||||
func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error {
|
||||
@ -374,7 +373,13 @@ func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error
|
||||
return saDelete(address)
|
||||
}
|
||||
|
||||
func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
fi, err := conn.File()
|
||||
defer fi.Close()
|
||||
if err != nil {
|
||||
@ -383,27 +388,7 @@ func setTcpSockoptInt(conn *net.TCPConn, level int, name int, value int) error {
|
||||
if conn, err := net.FileConn(fi); err == nil {
|
||||
defer conn.Close()
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, value))
|
||||
}
|
||||
|
||||
func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_TTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = syscall.IPV6_UNICAST_HOPS
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
}
|
||||
|
||||
func SetTcpMinTTLSockopts(conn *net.TCPConn, ttl int) error {
|
||||
level := syscall.IPPROTO_IP
|
||||
name := syscall.IP_MINTTL
|
||||
if strings.Contains(conn.RemoteAddr().String(), "[") {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
name = IPV6_MINHOPCOUNT
|
||||
}
|
||||
return setTcpSockoptInt(conn, level, name, ttl)
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl))
|
||||
}
|
||||
|
||||
func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) {
|
||||
|
2
vendor/github.com/osrg/gobgp/server/zclient.go
generated
vendored
2
vendor/github.com/osrg/gobgp/server/zclient.go
generated
vendored
@ -17,10 +17,10 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
"github.com/osrg/gobgp/zebra"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
4
vendor/github.com/osrg/gobgp/table/destination.go
generated
vendored
4
vendor/github.com/osrg/gobgp/table/destination.go
generated
vendored
@ -23,9 +23,9 @@ import (
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var SelectionOptions config.RouteSelectionOptionsConfig
|
||||
@ -127,7 +127,7 @@ func (i *PeerInfo) String() string {
|
||||
func NewPeerInfo(g *config.Global, p *config.Neighbor) *PeerInfo {
|
||||
id := net.ParseIP(string(p.RouteReflector.Config.RouteReflectorClusterId)).To4()
|
||||
// exclude zone info
|
||||
naddr, _ := net.ResolveIPAddr("ip", p.State.NeighborAddress)
|
||||
naddr, _ := net.ResolveIPAddr("ip", p.Config.NeighborAddress)
|
||||
return &PeerInfo{
|
||||
AS: p.Config.PeerAs,
|
||||
LocalAS: g.Config.As,
|
||||
|
2
vendor/github.com/osrg/gobgp/table/message.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/message.go
generated
vendored
@ -17,8 +17,8 @@ package table
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"hash/fnv"
|
||||
"reflect"
|
||||
)
|
||||
|
4
vendor/github.com/osrg/gobgp/table/path.go
generated
vendored
4
vendor/github.com/osrg/gobgp/table/path.go
generated
vendored
@ -24,10 +24,10 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/satori/go.uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -258,7 +258,7 @@ func UpdatePathAttrs(global *config.Global, peer *config.Neighbor, info *PeerInf
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Peer",
|
||||
"Key": peer.State.NeighborAddress,
|
||||
"Key": peer.Config.NeighborAddress,
|
||||
}).Warnf("invalid peer type: %d", peer.State.PeerType)
|
||||
}
|
||||
return path
|
||||
|
2
vendor/github.com/osrg/gobgp/table/policy.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/policy.go
generated
vendored
@ -26,10 +26,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/armon/go-radix"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type PolicyOptions struct {
|
||||
|
2
vendor/github.com/osrg/gobgp/table/policy_test.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/policy_test.go
generated
vendored
@ -24,9 +24,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/config"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
2
vendor/github.com/osrg/gobgp/table/table.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/table.go
generated
vendored
@ -20,9 +20,9 @@ import (
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/armon/go-radix"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type LookupOption uint8
|
||||
|
2
vendor/github.com/osrg/gobgp/table/table_manager.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/table_manager.go
generated
vendored
@ -18,8 +18,8 @@ package table
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
2
vendor/github.com/osrg/gobgp/table/table_manager_test.go
generated
vendored
2
vendor/github.com/osrg/gobgp/table/table_manager_test.go
generated
vendored
@ -17,8 +17,8 @@ package table
|
||||
|
||||
import (
|
||||
_ "fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net"
|
||||
"os"
|
||||
|
2
vendor/github.com/osrg/gobgp/test/lib/base.py
generated
vendored
2
vendor/github.com/osrg/gobgp/test/lib/base.py
generated
vendored
@ -103,7 +103,7 @@ def make_gobgp_ctn(tag='gobgp', local_gobgp_path='', from_image='osrg/quagga'):
|
||||
|
||||
c = CmdBuffer()
|
||||
c << 'FROM {0}'.format(from_image)
|
||||
c << 'RUN go get -d github.com/osrg/gobgp/...; exit 0'
|
||||
c << 'RUN go get -d github.com/osrg/gobgp/...'
|
||||
c << 'RUN rm -rf /go/src/github.com/osrg/gobgp'
|
||||
c << 'ADD gobgp /go/src/github.com/osrg/gobgp/'
|
||||
c << 'RUN go get github.com/osrg/gobgp/...'
|
||||
|
42
vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py
generated
vendored
42
vendor/github.com/osrg/gobgp/test/scenario_test/graceful_restart_test.py
generated
vendored
@ -26,7 +26,6 @@ from lib.noseplugin import OptionParser, parser_option
|
||||
|
||||
from lib import base
|
||||
from lib.base import (
|
||||
BGP_FSM_IDLE,
|
||||
BGP_FSM_ACTIVE,
|
||||
BGP_FSM_ESTABLISHED,
|
||||
)
|
||||
@ -129,47 +128,6 @@ class GoBGPTestBase(unittest.TestCase):
|
||||
g2 = self.bgpds['g2']
|
||||
self.assertTrue(len(g2.get_global_rib()) == 0)
|
||||
|
||||
def test_07_multineighbor_established(self):
|
||||
g1 = self.bgpds['g1']
|
||||
g2 = self.bgpds['g2']
|
||||
g3 = self.bgpds['g3']
|
||||
|
||||
g1._start_gobgp()
|
||||
|
||||
g1.del_peer(g2)
|
||||
g1.del_peer(g3)
|
||||
g2.del_peer(g1)
|
||||
g3.del_peer(g1)
|
||||
g1.add_peer(g2, graceful_restart=True, llgr=True)
|
||||
g1.add_peer(g3, graceful_restart=True, llgr=True)
|
||||
g2.add_peer(g1, graceful_restart=True, llgr=True)
|
||||
g3.add_peer(g1, graceful_restart=True, llgr=True)
|
||||
|
||||
g2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
|
||||
g3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
|
||||
|
||||
def test_08_multineighbor_graceful_restart(self):
|
||||
g1 = self.bgpds['g1']
|
||||
g2 = self.bgpds['g2']
|
||||
g3 = self.bgpds['g3']
|
||||
|
||||
g1.graceful_restart()
|
||||
g2.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
|
||||
g3.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
|
||||
|
||||
g1._start_gobgp(graceful_restart=True)
|
||||
|
||||
count = 0
|
||||
while ((g1.get_neighbor_state(g2) != BGP_FSM_ESTABLISHED)
|
||||
or (g1.get_neighbor_state(g3) != BGP_FSM_ESTABLISHED)):
|
||||
count += 1
|
||||
# assert connections are not refused
|
||||
self.assertTrue(g1.get_neighbor_state(g2) != BGP_FSM_IDLE)
|
||||
self.assertTrue(g1.get_neighbor_state(g3) != BGP_FSM_IDLE)
|
||||
if count > 120:
|
||||
raise Exception('timeout')
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
|
||||
|
16
vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile
generated
vendored
16
vendor/github.com/osrg/gobgp/tools/grpc/cpp/Makefile
generated
vendored
@ -1,17 +1,7 @@
|
||||
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
|
||||
SYSTEM ?= $(HOST_SYSTEM)
|
||||
CXX = g++
|
||||
CPPFLAGS += -I/usr/local/include -pthread
|
||||
CPPFLAGS += -I/opt/protobuf_3.0.0_alpha4/include -I/opt/grpc/include -pthread
|
||||
CXXFLAGS += -std=c++11
|
||||
ifeq ($(SYSTEM),Darwin)
|
||||
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
|
||||
-lgrpc++_reflection \
|
||||
-lprotobuf -lpthread -ldl
|
||||
else
|
||||
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
|
||||
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
|
||||
-lprotobuf -lpthread -ldl
|
||||
endif
|
||||
LDFLAGS += -L/opt/grpc/lib -L/opt/protobuf_3.0.0_alpha4/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl
|
||||
PROTOC = protoc
|
||||
GRPC_CPP_PLUGIN = grpc_cpp_plugin
|
||||
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
|
||||
@ -23,7 +13,7 @@ vpath %.proto $(PROTOS_PATH)
|
||||
all: system-check gobgp_api_client
|
||||
|
||||
gobgp_api_client: gobgp_api_client.pb.o gobgp_api_client.grpc.pb.o gobgp_api_client.o
|
||||
$(CXX) $^ $(LDFLAGS) -L. -lgobgp -o $@
|
||||
$(CXX) $^ $(LDFLAGS) -L. -lgobgp -o $@
|
||||
|
||||
%.grpc.pb.cc: %.proto
|
||||
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
|
||||
|
11
vendor/github.com/osrg/gobgp/tools/grpc/cpp/build.sh
generated
vendored
11
vendor/github.com/osrg/gobgp/tools/grpc/cpp/build.sh
generated
vendored
@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
GOBGP_PATH=${GOPATH}/src/github.com/osrg/gobgp
|
||||
|
||||
cd ${GOBGP_PATH}/gobgp/lib
|
||||
go build -buildmode=c-shared -o libgobgp.so *.go
|
||||
cd ${GOBGP_PATH}/tools/grpc/cpp
|
||||
ln -s ${GOBGP_PATH}/gobgp/lib/libgobgp.h
|
||||
ln -s ${GOBGP_PATH}/gobgp/lib/libgobgp.so
|
||||
ln -s ${GOBGP_PATH}/api/gobgp.proto gobgp_api_client.proto
|
||||
make
|
255
vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc
generated
vendored
255
vendor/github.com/osrg/gobgp/tools/grpc/cpp/gobgp_api_client.cc
generated
vendored
@ -25,44 +25,218 @@ using gobgpapi::GobgpApi;
|
||||
class GrpcClient {
|
||||
public:
|
||||
GrpcClient(std::shared_ptr<Channel> channel) : stub_(GobgpApi::NewStub(channel)) {}
|
||||
void GetAllActiveAnnounces(unsigned int route_family) {
|
||||
ClientContext context;
|
||||
gobgpapi::Table table;
|
||||
|
||||
std::string GetNeighbor() {
|
||||
gobgpapi::GetNeighborRequest request;
|
||||
table.set_family(route_family);
|
||||
// We could specify certain neighbor here
|
||||
table.set_name("");
|
||||
table.set_type(gobgpapi::Resource::GLOBAL);
|
||||
|
||||
gobgpapi::Table response_table;
|
||||
|
||||
auto status = stub_->GetRib(&context, table, &response_table);
|
||||
|
||||
if (!status.ok()) {
|
||||
// error_message
|
||||
std::cout << "Problem with RPC: " << status.error_code() << " message " << status.error_message() << std::endl;
|
||||
return;
|
||||
} else {
|
||||
// std::cout << "RPC working well" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "List of announced prefixes for route family: " << route_family << std::endl << std::endl;
|
||||
|
||||
for (auto current_destination : response_table.destinations()) {
|
||||
std::cout << "Prefix: " << current_destination.prefix() << std::endl;
|
||||
|
||||
//std::cout << "Paths size: " << current_destination.paths_size() << std::endl;
|
||||
|
||||
gobgpapi::Path my_path = current_destination.paths(0);
|
||||
|
||||
// std::cout << "Pattrs size: " << my_path.pattrs_size() << std::endl;
|
||||
|
||||
buf my_nlri;
|
||||
my_nlri.value = (char*)my_path.nlri().c_str();
|
||||
my_nlri.len = my_path.nlri().size();
|
||||
|
||||
path_t gobgp_lib_path;
|
||||
gobgp_lib_path.nlri = my_nlri;
|
||||
// Not used in library code!
|
||||
gobgp_lib_path.path_attributes_cap = 0;
|
||||
gobgp_lib_path.path_attributes_len = my_path.pattrs_size();
|
||||
|
||||
buf* my_path_attributes[ my_path.pattrs_size() ];
|
||||
for (int i = 0; i < my_path.pattrs_size(); i++) {
|
||||
my_path_attributes[i] = (buf*)malloc(sizeof(buf));
|
||||
my_path_attributes[i]->len = my_path.pattrs(i).size();
|
||||
my_path_attributes[i]->value = (char*)my_path.pattrs(i).c_str();
|
||||
}
|
||||
|
||||
gobgp_lib_path.path_attributes = my_path_attributes;
|
||||
|
||||
std::cout << "NLRI: " << decode_path(&gobgp_lib_path) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceFlowSpecPrefix(bool withdraw) {
|
||||
const gobgpapi::ModPathArguments current_mod_path_arguments;
|
||||
|
||||
unsigned int AFI_IP = 1;
|
||||
unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
|
||||
unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
|
||||
|
||||
gobgpapi::Path* current_path = new gobgpapi::Path;
|
||||
current_path->set_is_withdraw(withdraw);
|
||||
|
||||
/*
|
||||
buf:
|
||||
char *value;
|
||||
int len;
|
||||
|
||||
path:
|
||||
buf nlri;
|
||||
buf** path_attributes;
|
||||
int path_attributes_len;
|
||||
int path_attributes_cap;
|
||||
*/
|
||||
|
||||
path* path_c_struct = serialize_path(ipv4_flow_spec_route_family, (char*)"match destination 10.0.0.0/24 protocol tcp source 20.0.0.0/24 then redirect 10:10");
|
||||
|
||||
// printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
|
||||
|
||||
for (int path_attribute_number = 0; path_attribute_number < path_c_struct->path_attributes_len; path_attribute_number++) {
|
||||
current_path->add_pattrs(path_c_struct->path_attributes[path_attribute_number]->value,
|
||||
path_c_struct->path_attributes[path_attribute_number]->len);
|
||||
}
|
||||
|
||||
current_path->set_nlri(path_c_struct->nlri.value, path_c_struct->nlri.len);
|
||||
|
||||
gobgpapi::ModPathsArguments request;
|
||||
request.set_resource(gobgpapi::Resource::GLOBAL);
|
||||
|
||||
google::protobuf::RepeatedPtrField< ::gobgpapi::Path >* current_path_list = request.mutable_paths();
|
||||
current_path_list->AddAllocated(current_path);
|
||||
request.set_name("");
|
||||
|
||||
ClientContext context;
|
||||
|
||||
gobgpapi::GetNeighborResponse response;
|
||||
grpc::Status status = stub_->GetNeighbor(&context, request, &response);
|
||||
gobgpapi::Error return_error;
|
||||
|
||||
// result is a std::unique_ptr<grpc::ClientWriter<gobgpapi::ModPathArguments> >
|
||||
auto send_stream = stub_->ModPaths(&context, &return_error);
|
||||
|
||||
bool write_result = send_stream->Write(request);
|
||||
|
||||
if (!write_result) {
|
||||
std::cout << "Write to API failed\n";
|
||||
}
|
||||
|
||||
// Finish all writes
|
||||
send_stream->WritesDone();
|
||||
|
||||
auto status = send_stream->Finish();
|
||||
|
||||
if (status.ok()) {
|
||||
//std::cout << "modpath executed correctly" << std::cout;
|
||||
} else {
|
||||
std::cout << "modpath failed with code: " << status.error_code()
|
||||
<< " message " << status.error_message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceUnicastPrefix(bool withdraw) {
|
||||
const gobgpapi::ModPathArguments current_mod_path_arguments;
|
||||
|
||||
unsigned int AFI_IP = 1;
|
||||
unsigned int SAFI_UNICAST = 1;
|
||||
unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
|
||||
|
||||
gobgpapi::Path* current_path = new gobgpapi::Path;
|
||||
current_path->set_is_withdraw(withdraw);
|
||||
|
||||
/*
|
||||
buf:
|
||||
char *value;
|
||||
int len;
|
||||
|
||||
path:
|
||||
buf nlri;
|
||||
buf** path_attributes;
|
||||
int path_attributes_len;
|
||||
int path_attributes_cap;
|
||||
*/
|
||||
|
||||
// 10.10.20.33/22 nexthop 10.10.1.99/32
|
||||
path* path_c_struct = serialize_path(ipv4_unicast_route_family, (char*)"10.10.20.33/22");
|
||||
|
||||
// printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
|
||||
|
||||
for (int path_attribute_number = 0; path_attribute_number < path_c_struct->path_attributes_len; path_attribute_number++) {
|
||||
current_path->add_pattrs(path_c_struct->path_attributes[path_attribute_number]->value,
|
||||
path_c_struct->path_attributes[path_attribute_number]->len);
|
||||
}
|
||||
|
||||
current_path->set_nlri(path_c_struct->nlri.value, path_c_struct->nlri.len);
|
||||
|
||||
gobgpapi::ModPathsArguments request;
|
||||
request.set_resource(gobgpapi::Resource::GLOBAL);
|
||||
google::protobuf::RepeatedPtrField< ::gobgpapi::Path >* current_path_list = request.mutable_paths();
|
||||
current_path_list->AddAllocated(current_path);
|
||||
request.set_name("");
|
||||
|
||||
ClientContext context;
|
||||
|
||||
gobgpapi::Error return_error;
|
||||
|
||||
// result is a std::unique_ptr<grpc::ClientWriter<api::ModPathArguments> >
|
||||
auto send_stream = stub_->ModPaths(&context, &return_error);
|
||||
|
||||
bool write_result = send_stream->Write(request);
|
||||
|
||||
if (!write_result) {
|
||||
std::cout << "Write to API failed\n";
|
||||
}
|
||||
|
||||
// Finish all writes
|
||||
send_stream->WritesDone();
|
||||
|
||||
auto status = send_stream->Finish();
|
||||
|
||||
if (status.ok()) {
|
||||
//std::cout << "modpath executed correctly" << std::cout;
|
||||
} else {
|
||||
std::cout << "modpath failed with code: " << status.error_code()
|
||||
<< " message " << status.error_message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetNeighbor(std::string neighbor_ip) {
|
||||
gobgpapi::Arguments request;
|
||||
request.set_family(4);
|
||||
request.set_name(neighbor_ip);
|
||||
|
||||
ClientContext context;
|
||||
|
||||
gobgpapi::Peer peer;
|
||||
grpc::Status status = stub_->GetNeighbor(&context, request, &peer);
|
||||
|
||||
if (status.ok()) {
|
||||
gobgpapi::PeerConf peer_conf = peer.conf();
|
||||
gobgpapi::PeerState peer_info = peer.info();
|
||||
|
||||
std::stringstream buffer;
|
||||
for (int i=0; i < response.peers_size(); i++) {
|
||||
|
||||
buffer
|
||||
<< "Peer AS: " << peer_conf.peer_as() << "\n"
|
||||
<< "Peer router id: " << peer_conf.id() << "\n"
|
||||
<< "Peer flops: " << peer_info.flops() << "\n"
|
||||
<< "BGP state: " << peer_info.bgp_state();
|
||||
|
||||
gobgpapi::PeerConf peer_conf = response.peers(i).conf();
|
||||
gobgpapi::PeerState peer_info = response.peers(i).info();
|
||||
gobgpapi::Timers peer_timers = response.peers(i).timers();
|
||||
|
||||
buffer
|
||||
<< "BGP neighbor is: " << peer_conf.neighbor_address()
|
||||
<< ", remote AS: " << peer_conf.peer_as() << "\n"
|
||||
<< "\tBGP version: 4, remote route ID " << peer_conf.id() << "\n"
|
||||
<< "\tBGP state = " << peer_info.bgp_state()
|
||||
<< ", up for " << peer_timers.state().uptime() << "\n"
|
||||
<< "\tBGP OutQ = " << peer_info.out_q()
|
||||
<< ", Flops = " << peer_info.flops() << "\n"
|
||||
<< "\tHold time is " << peer_timers.state().hold_time()
|
||||
<< ", keepalive interval is " << peer_timers.state().keepalive_interval() << "seconds\n"
|
||||
<< "\tConfigured hold time is " << peer_timers.config().hold_time() << "\n";
|
||||
|
||||
}
|
||||
return buffer.str();
|
||||
} else {
|
||||
std::stringstream buffer;
|
||||
buffer
|
||||
<< status.error_code() << "\n"
|
||||
<< status.error_message() << "\n"
|
||||
<< status.error_details() << "\n";
|
||||
return buffer.str();
|
||||
return "Something wrong";
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,16 +245,25 @@ class GrpcClient {
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc < 2) {
|
||||
std::cout << "Usage: ./gobgp_api_client [gobgp address]\n";
|
||||
return 1;
|
||||
}
|
||||
GrpcClient gobgp_client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
|
||||
|
||||
std::string reply = gobgp_client.GetNeighbor("213.133.111.200");
|
||||
std::cout << "Neighbor information: " << reply << std::endl;
|
||||
|
||||
std::string addr = argv[1];
|
||||
GrpcClient gobgp_client(grpc::CreateChannel(addr + ":50051", grpc::InsecureChannelCredentials()));
|
||||
gobgp_client.AnnounceUnicastPrefix(false);
|
||||
|
||||
std::string reply = gobgp_client.GetNeighbor();
|
||||
std::cout << reply;
|
||||
gobgp_client.AnnounceFlowSpecPrefix(false);
|
||||
|
||||
unsigned int AFI_IP = 1;
|
||||
unsigned int SAFI_UNICAST = 1;
|
||||
unsigned int SAFI_FLOW_SPEC_UNICAST = 133;
|
||||
|
||||
unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
|
||||
unsigned int ipv4_flow_spec_route_family = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST;
|
||||
|
||||
gobgp_client.GetAllActiveAnnounces(ipv4_unicast_route_family);
|
||||
std::cout << std::endl << std::endl;
|
||||
gobgp_client.GetAllActiveAnnounces(ipv4_flow_spec_route_family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
44
vendor/github.com/osrg/gobgp/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java
generated
vendored
44
vendor/github.com/osrg/gobgp/tools/grpc/java/src/gobgp/example/GobgpSampleClient.java
generated
vendored
@ -1,44 +0,0 @@
|
||||
package gobgp.example;
|
||||
|
||||
import gobgpapi.Gobgp;
|
||||
import gobgpapi.GobgpApiGrpc;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GobgpSampleClient {
|
||||
|
||||
private final GobgpApiGrpc.GobgpApiBlockingStub blockingStub;
|
||||
|
||||
public GobgpSampleClient(String host, int port) {
|
||||
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
|
||||
this.blockingStub = GobgpApiGrpc.newBlockingStub(channel);
|
||||
}
|
||||
|
||||
public void getNeighbors(){
|
||||
|
||||
Gobgp.GetNeighborRequest request = Gobgp.GetNeighborRequest.newBuilder().build();
|
||||
|
||||
for(Gobgp.Peer peer: this.blockingStub.getNeighbor(request).getPeersList()) {
|
||||
Gobgp.PeerConf conf = peer.getConf();
|
||||
Gobgp.PeerState state = peer.getInfo();
|
||||
Gobgp.Timers timer = peer.getTimers();
|
||||
|
||||
System.out.printf("BGP neighbor is %s, remote AS %d\n", conf.getNeighborAddress(), conf.getPeerAs());
|
||||
System.out.printf("\tBGP version 4, remote router ID %s\n", conf.getId());
|
||||
System.out.printf("\tBGP state = %s, up for %d\n", state.getBgpState(), timer.getState().getUptime());
|
||||
System.out.printf("\tBGP OutQ = %d, Flops = %d\n", state.getOutQ(), state.getFlops());
|
||||
System.out.printf("\tHold time is %d, keepalive interval is %d seconds\n",
|
||||
timer.getState().getHoldTime(), timer.getState().getKeepaliveInterval());
|
||||
System.out.printf("\tConfigured hold time is %d\n", timer.getConfig().getHoldTime());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
new GobgpSampleClient(args[0], 50051).getNeighbors();
|
||||
}
|
||||
|
||||
}
|
||||
|
31
vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py
generated
vendored
31
vendor/github.com/osrg/gobgp/tools/grpc/python/get_neighbor.py
generated
vendored
@ -1,28 +1,27 @@
|
||||
import gobgp_pb2_grpc
|
||||
import gobgp_pb2
|
||||
import sys
|
||||
|
||||
import grpc
|
||||
from grpc.beta import implementations
|
||||
from grpc.framework.interfaces.face.face import ExpirationError
|
||||
|
||||
_TIMEOUT_SECONDS = 1
|
||||
|
||||
|
||||
def run(gobgpd_addr):
|
||||
channel = grpc.insecure_channel(gobgpd_addr + ':50051')
|
||||
stub = gobgp_pb2_grpc.GobgpApiStub(channel)
|
||||
try:
|
||||
peers = stub.GetNeighbor(gobgp_pb2.GetNeighborRequest()).peers
|
||||
for peer in peers:
|
||||
print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
|
||||
print(" BGP version 4, remote router ID %s" % (peer.conf.id))
|
||||
print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
|
||||
print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
|
||||
print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
|
||||
print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
|
||||
except ExpirationError, e:
|
||||
print str(e)
|
||||
sys.exit(-1)
|
||||
channel = implementations.insecure_channel(gobgpd_addr, 50051)
|
||||
with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:
|
||||
try:
|
||||
peers = stub.GetNeighbor(gobgp_pb2.GetNeighborRequest(), _TIMEOUT_SECONDS).peers
|
||||
for peer in peers:
|
||||
print("BGP neighbor is %s, remote AS %d" % (peer.conf.neighbor_address, peer.conf.peer_as))
|
||||
print(" BGP version 4, remote router ID %s" % (peer.conf.id))
|
||||
print(" BGP state = %s, up for %s" % (peer.info.bgp_state, peer.timers.state.uptime))
|
||||
print(" BGP OutQ = %d, Flops = %d" % (peer.info.out_q, peer.info.flops))
|
||||
print(" Hold time is %d, keepalive interval is %d seconds" % (peer.timers.state.negotiated_hold_time, peer.timers.state.keepalive_interval))
|
||||
print(" Configured hold time is %d, keepalive interval is %d seconds" % (peer.timers.config.hold_time, peer.timers.config.keepalive_interval))
|
||||
except ExpirationError, e:
|
||||
print str(e)
|
||||
sys.exit(-1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
gobgp = sys.argv[1]
|
||||
|
11
vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb
generated
vendored
11
vendor/github.com/osrg/gobgp/tools/grpc/ruby/get_neighbors.rb
generated
vendored
@ -1,11 +1,12 @@
|
||||
require 'gobgp_pb'
|
||||
require 'gobgp_services_pb'
|
||||
require 'gobgp'
|
||||
require 'gobgp_services'
|
||||
|
||||
host = ARGV[0]
|
||||
host = 'localhost'
|
||||
host = ARGV[0] if ARGV.length > 0
|
||||
|
||||
stub = Gobgpapi::GobgpApi::Stub.new("#{host}:50051", :this_channel_is_insecure)
|
||||
arg = Gobgpapi::GetNeighborRequest.new()
|
||||
stub.get_neighbor(arg).peers.each do |n|
|
||||
arg = Gobgpapi::Arguments.new()
|
||||
stub.get_neighbors(arg).each do |n|
|
||||
puts "BGP neighbor is #{n.conf.neighbor_address}, remote AS #{n.conf.peer_as}"
|
||||
puts "\tBGP version 4, remote route ID #{n.conf.id}"
|
||||
puts "\tBGP state = #{n.info.bgp_state}, up for #{n.timers.state.uptime}"
|
||||
|
37
vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst
generated
vendored
37
vendor/github.com/osrg/gobgp/tools/pyang_plugins/README.rst
generated
vendored
@ -3,38 +3,21 @@ What's this ?
|
||||
This is a pyang plugin to generate config/bgp_configs.go from
|
||||
openconfig yang files (see https://github.com/openconfig/public).
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
Please confirm $GOPATH is configured before the following steps.
|
||||
|
||||
How to use
|
||||
==========
|
||||
Set the environment variables for this tool::
|
||||
::
|
||||
|
||||
$ GOBGP_PATH=$GOPATH/src/github.com/osrg/gobgp/
|
||||
|
||||
Clone the required resources by using Git::
|
||||
|
||||
$ cd $HOME
|
||||
$ git clone https://github.com/osrg/public
|
||||
$ git clone https://github.com/YangModels/yang
|
||||
$ git clone https://github.com/mbj4668/pyang
|
||||
|
||||
Setup environments for pyang::
|
||||
|
||||
$ cd $HOME/pyang
|
||||
$ YANG_DIR=`pwd`
|
||||
$ cd $PYANG_INSTALL_DIR
|
||||
$ source ./env.sh
|
||||
|
||||
Generate config/bgp_configs.go from yang files::
|
||||
|
||||
$ PYTHONPATH=. ./bin/pyang \
|
||||
--plugindir $GOBGP_PATH/tools/pyang_plugins \
|
||||
-p $HOME/yang/standard/ietf/RFC \
|
||||
-p $HOME/public/release/models \
|
||||
-p $HOME/public/release/models/bgp \
|
||||
-p $HOME/public/release/models/policy \
|
||||
-f golang \
|
||||
$HOME/public/release/models/bgp/openconfig-bgp.yang \
|
||||
$HOME/public/release/models/policy/openconfig-routing-policy.yang \
|
||||
$ PYTHONPATH=. ./bin/pyang --plugindir $GOBGP_PATH/tools/pyang_plugins \
|
||||
-p $YANG_DIR/yang/standard/ietf/RFC \
|
||||
-p $YANG_DIR/public/release/models \
|
||||
-p $YANG_DIR/public/release/models/bgp \
|
||||
-p $YANG_DIR/public/release/models/policy \
|
||||
-f golang $YANG_DIR/public/release/models/bgp/openconfig-bgp.yang \
|
||||
$YANG_DIR/public/release/models/policy/openconfig-routing-policy.yang \
|
||||
$GOBGP_PATH/tools/pyang_plugins/gobgp.yang \
|
||||
| gofmt > $GOBGP_PATH/config/bgp_configs.go
|
||||
|
118
vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang
generated
vendored
118
vendor/github.com/osrg/gobgp/tools/pyang_plugins/gobgp.yang
generated
vendored
@ -180,18 +180,6 @@ module gobgp {
|
||||
error condition has occurred exchanged.";
|
||||
}
|
||||
|
||||
leaf WITHDRAW-UPDATE {
|
||||
type uint32;
|
||||
description
|
||||
"Number of updates subjected to treat-as-withdraw treatment.";
|
||||
}
|
||||
|
||||
leaf WITHDRAW-PREFIX {
|
||||
type uint32;
|
||||
description
|
||||
"Number of prefixes subjected to treat-as-withdraw treatment.";
|
||||
}
|
||||
|
||||
leaf DISCARDED {
|
||||
type uint64;
|
||||
description
|
||||
@ -207,6 +195,7 @@ module gobgp {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
grouping gobgp-adjacent-table {
|
||||
container adj-table {
|
||||
leaf ADVERTISED {
|
||||
@ -559,30 +548,20 @@ module gobgp {
|
||||
"Reference to the address of the BMP server used as
|
||||
a key in the BMP server list";
|
||||
}
|
||||
|
||||
leaf port {
|
||||
type uint32;
|
||||
description
|
||||
"Reference to the port of the BMP server";
|
||||
}
|
||||
|
||||
leaf route-monitoring-policy {
|
||||
type bmp-route-monitoring-policy-type;
|
||||
default PRE-POLICY;
|
||||
}
|
||||
|
||||
leaf statistics-timeout {
|
||||
type uint16;
|
||||
description
|
||||
"Interval seconds of statistics messages sent to BMP server";
|
||||
}
|
||||
|
||||
leaf route-mirroring-enabled {
|
||||
type boolean;
|
||||
description
|
||||
"Enable feature for mirroring of received BGP messages
|
||||
mainly for debugging purpose";
|
||||
}
|
||||
}
|
||||
|
||||
grouping gobgp-bmp-server-state {
|
||||
@ -653,47 +632,6 @@ module gobgp {
|
||||
}
|
||||
}
|
||||
|
||||
grouping gobgp-ttl-security-config {
|
||||
description
|
||||
"Configuration parameters for TTL Security";
|
||||
|
||||
leaf enabled {
|
||||
type boolean;
|
||||
default "false";
|
||||
description
|
||||
"Enable features for TTL Security";
|
||||
}
|
||||
|
||||
leaf ttl-min {
|
||||
type uint8;
|
||||
description
|
||||
"Reference to the port of the BMP server";
|
||||
}
|
||||
}
|
||||
|
||||
grouping gobgp-ttl-security-config-set {
|
||||
description
|
||||
"set of configurations for Generalized TTL Security Mechanism (GTSM)";
|
||||
|
||||
container ttl-security {
|
||||
description
|
||||
"Configure TTL Security feature";
|
||||
|
||||
container config {
|
||||
description
|
||||
"Configuration parameters for TTL Security";
|
||||
uses gobgp-ttl-security-config;
|
||||
}
|
||||
|
||||
container state {
|
||||
config false;
|
||||
description
|
||||
"State information for TTL Security";
|
||||
uses gobgp-ttl-security-config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// augment statements
|
||||
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:state/bgp:messages/bgp:sent" {
|
||||
description "additional counters";
|
||||
@ -807,11 +745,6 @@ module gobgp {
|
||||
leaf remote-port {
|
||||
type inet:port-number;
|
||||
}
|
||||
|
||||
leaf ttl {
|
||||
description "TTL value for BGP packets";
|
||||
type uint8;
|
||||
}
|
||||
}
|
||||
|
||||
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:timers/bgp:config" {
|
||||
@ -871,16 +804,6 @@ module gobgp {
|
||||
uses gobgp-route-server-config-set;
|
||||
}
|
||||
|
||||
augment "/bgp:bgp/bgp:peer-groups/bgp:peer-group" {
|
||||
description "TTL Security configuration for peer-group";
|
||||
uses gobgp-ttl-security-config-set;
|
||||
}
|
||||
|
||||
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor" {
|
||||
description "TTL Security configuration for neighbor";
|
||||
uses gobgp-ttl-security-config-set;
|
||||
}
|
||||
|
||||
augment "/bgp:bgp/bgp:global/bgp:apply-policy/bgp:config" {
|
||||
description "addtional policy";
|
||||
uses gobgp-in-policy;
|
||||
@ -1182,45 +1105,6 @@ module gobgp {
|
||||
uses listen-config;
|
||||
}
|
||||
|
||||
grouping dynamic-neighbors {
|
||||
container dynamic-neighbors {
|
||||
list dynamic-neighbor {
|
||||
key "prefix";
|
||||
|
||||
leaf prefix {
|
||||
type leafref {
|
||||
path "../config/prefix";
|
||||
}
|
||||
}
|
||||
|
||||
container config {
|
||||
uses bgp-global-dynamic-neighbor-config;
|
||||
}
|
||||
|
||||
container state {
|
||||
config false;
|
||||
uses bgp-global-dynamic-neighbor-config;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grouping bgp-global-dynamic-neighbor-config {
|
||||
description "A dynamic neighbor belongs to a peer group.
|
||||
This configuration structure was taken from the latest openconfig.";
|
||||
|
||||
leaf prefix {
|
||||
type string;
|
||||
}
|
||||
leaf peer-group {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
|
||||
augment "/bgp:bgp" {
|
||||
uses dynamic-neighbors;
|
||||
}
|
||||
|
||||
augment "/bgp:bgp/bgp:global/bgp:afi-safis/bgp:afi-safi" {
|
||||
uses bgp-mp:all-afi-safi-common;
|
||||
}
|
||||
|
2
vendor/github.com/osrg/gobgp/zebra/zapi.go
generated
vendored
2
vendor/github.com/osrg/gobgp/zebra/zapi.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
1
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
1
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
@ -1,6 +1,7 @@
|
||||
# 1.0.2
|
||||
|
||||
* bug: quote non-string values in text formatter (#583)
|
||||
* Make (*Logger) SetLevel a public method
|
||||
|
||||
# 1.0.1
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user