Documentation
¶
Overview ¶
Package go-cs-bouncer implements a wrapper for the CrowdSec bouncer API.
It can be used to create 2 types of bouncer:
- A stream bouncer: in this mode, decisions are fetched in bulk at regular intervals. A `Stream` chan is exposed by the struct to allow you to read the decisions.
- A live bouncer: in this mode, you must call the Get() method to check if an IP has a decision associated with it.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var TotalLAPICalls prometheus.Counter = prometheus.NewCounter(prometheus.CounterOpts{
Name: "lapi_requests_total",
Help: "The total number of calls to CrowdSec LAPI",
},
)
var TotalLAPIError prometheus.Counter = prometheus.NewCounter(prometheus.CounterOpts{
Name: "lapi_requests_failures_total",
Help: "The total number of failed calls to CrowdSec LAPI",
},
)
Functions ¶
This section is empty.
Types ¶
type Client ¶ added in v0.0.14
type Client struct {
URL string
APIKey string
UserAgent string
// contains filtered or unexported fields
}
func (*Client) StreamDecisionConnect ¶ added in v0.0.14
type EventStreamReader ¶ added in v0.0.29
type EventStreamReader struct {
// contains filtered or unexported fields
}
EventStreamReader scans an io.Reader looking for EventStream messages.
func NewEventStreamReader ¶ added in v0.0.29
func NewEventStreamReader(eventStream io.Reader, maxBufferSize int) *EventStreamReader
NewEventStreamReader creates an instance of EventStreamReader.
func (*EventStreamReader) ReadEvent ¶ added in v0.0.29
func (e *EventStreamReader) ReadEvent() ([]byte, error)
ReadEvent scans the EventStream for events.
type LiveBouncer ¶
type LiveBouncer struct {
APIKey string `yaml:"api_key"`
APIUrl string `yaml:"api_url"`
InsecureSkipVerify *bool `yaml:"insecure_skip_verify"`
CertPath string `yaml:"cert_path"`
KeyPath string `yaml:"key_path"`
CAPath string `yaml:"ca_cert_path"`
APIClient *apiclient.ApiClient
UserAgent string
}
Example ¶
package main
import (
"fmt"
"log"
csbouncer "github.com/asians-cloud/go-cs-bouncer"
)
func main() {
bouncer := &csbouncer.LiveBouncer{
APIKey: "ebd4db481d51525fd0df924a69193921",
APIUrl: "http://localhost:8080/",
}
if err := bouncer.Init(); err != nil {
log.Fatalf(err.Error())
}
ipToQuery := "1.2.3.4"
response, err := bouncer.Get(ipToQuery)
if err != nil {
log.Fatalf("unable to get decision for ip '%s' : '%s'", ipToQuery, err)
}
if len(*response) == 0 {
log.Printf("no decision for '%s'", ipToQuery)
}
for _, decision := range *response {
fmt.Printf("decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
}
Output:
func (*LiveBouncer) Config ¶
func (b *LiveBouncer) Config(configPath string) error
Config() fills the struct with configuration values from a file. It is not aware of .yaml.local files so it is recommended to use ConfigReader() instead.
Example ¶
package main
import (
"fmt"
"log"
csbouncer "github.com/asians-cloud/go-cs-bouncer"
)
func main() {
bouncer := &csbouncer.LiveBouncer{}
err := bouncer.Config("./config.yaml")
if err != nil {
log.Fatal(err)
}
if err := bouncer.Init(); err != nil {
log.Fatalf(err.Error())
}
ipToQuery := "1.2.3.4"
response, err := bouncer.Get(ipToQuery)
if err != nil {
log.Fatalf("unable to get decision for ip '%s' : '%s'", ipToQuery, err)
}
if len(*response) == 0 {
log.Printf("no decision for '%s'", ipToQuery)
}
for _, decision := range *response {
fmt.Printf("decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
}
Output:
func (*LiveBouncer) ConfigReader ¶
func (b *LiveBouncer) ConfigReader(configReader io.Reader) error
func (*LiveBouncer) Get ¶
func (b *LiveBouncer) Get(value string) (*models.GetDecisionsResponse, error)
func (*LiveBouncer) Init ¶
func (b *LiveBouncer) Init() error
type SSEReader ¶ added in v0.0.38
type SSEReader struct {
// contains filtered or unexported fields
}
type StreamBouncer ¶
type StreamBouncer struct {
APIKey string `yaml:"api_key"`
APIUrl string `yaml:"api_url"`
InsecureSkipVerify *bool `yaml:"insecure_skip_verify"`
CertPath string `yaml:"cert_path"`
KeyPath string `yaml:"key_path"`
CAPath string `yaml:"ca_cert_path"`
TickerInterval string `yaml:"update_frequency"`
Scopes []string `yaml:"scopes"`
ScenariosContaining []string `yaml:"scenarios_containing"`
ScenariosNotContaining []string `yaml:"scenarios_not_containing"`
Origins []string `yaml:"origins"`
Startup bool `yaml:"startup"`
TickerIntervalDuration time.Duration
Stream chan *models.DecisionsStreamResponse
APIClient *apiclient.ApiClient
STREAMClient *Client
UserAgent string
Opts apiclient.DecisionsStreamOpts
// contains filtered or unexported fields
}
Example ¶
package main
import (
"context"
"fmt"
"log"
csbouncer "github.com/asians-cloud/go-cs-bouncer"
)
func main() {
bouncer := &csbouncer.StreamBouncer{
APIKey: "ebd4db481d51525fd0df924a69193921",
APIUrl: "http://localhost:8080/",
}
if err := bouncer.Init(); err != nil {
log.Fatalf(err.Error())
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
bouncer.Run(ctx)
cancel()
}()
for streamDecision := range bouncer.Stream {
for _, decision := range streamDecision.Deleted {
fmt.Printf("expired decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
for _, decision := range streamDecision.New {
fmt.Printf("new decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
}
}
Output:
func (*StreamBouncer) Config ¶
func (b *StreamBouncer) Config(configPath string) error
Config() fills the struct with configuration values from a file. It is not aware of .yaml.local files so it is recommended to use ConfigReader() instead.
Example ¶
package main
import (
"context"
"fmt"
"log"
csbouncer "github.com/asians-cloud/go-cs-bouncer"
)
func main() {
bouncer := &csbouncer.StreamBouncer{}
err := bouncer.Config("./config.yaml")
if err != nil {
log.Fatal(err)
}
if err := bouncer.Init(); err != nil {
log.Fatalf(err.Error())
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
bouncer.Run(ctx)
cancel()
}()
for streamDecision := range bouncer.Stream {
for _, decision := range streamDecision.Deleted {
fmt.Printf("expired decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
for _, decision := range streamDecision.New {
fmt.Printf("new decisions: IP: %s | Scenario: %s | Duration: %s | Scope : %v\n", *decision.Value, *decision.Scenario, *decision.Duration, *decision.Scope)
}
}
}
Output:
func (*StreamBouncer) ConfigReader ¶
func (b *StreamBouncer) ConfigReader(configReader io.Reader) error
func (*StreamBouncer) Init ¶
func (b *StreamBouncer) Init() error
func (*StreamBouncer) Run ¶
func (b *StreamBouncer) Run(ctx context.Context)
func (*StreamBouncer) RunStream ¶ added in v0.0.6
func (b *StreamBouncer) RunStream(ctx context.Context)