dummy plugin (#1342)
This commit is contained in:
parent
76e97303a5
commit
81793fe8bf
15 changed files with 251 additions and 15 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -28,3 +28,4 @@ plugins/notifications/http/notification-http
|
|||
plugins/notifications/slack/notification-slack
|
||||
plugins/notifications/splunk/notification-splunk
|
||||
plugins/notifications/email/notification-email
|
||||
plugins/notifications/dummy/notification-dummy
|
||||
|
|
13
Makefile
13
Makefile
|
@ -13,11 +13,13 @@ HTTP_PLUGIN_FOLDER = "./plugins/notifications/http"
|
|||
SLACK_PLUGIN_FOLDER = "./plugins/notifications/slack"
|
||||
SPLUNK_PLUGIN_FOLDER = "./plugins/notifications/splunk"
|
||||
EMAIL_PLUGIN_FOLDER = "./plugins/notifications/email"
|
||||
DUMMY_PLUGIN_FOLDER = "./plugins/notifications/dummy"
|
||||
|
||||
HTTP_PLUGIN_BIN = "notification-http"
|
||||
SLACK_PLUGIN_BIN = "notification-slack"
|
||||
SPLUNK_PLUGIN_BIN = "notification-splunk"
|
||||
EMAIL_PLUGIN_BIN = "notification-email"
|
||||
DUMMY_PLUGIN_BIN= "notification-dummy"
|
||||
|
||||
HTTP_PLUGIN_CONFIG = "http.yaml"
|
||||
SLACK_PLUGIN_CONFIG = "slack.yaml"
|
||||
|
@ -73,9 +75,9 @@ all: clean test build
|
|||
static: crowdsec_static cscli_static plugins_static
|
||||
|
||||
.PHONY: plugins
|
||||
plugins: http-plugin slack-plugin splunk-plugin email-plugin
|
||||
plugins: http-plugin slack-plugin splunk-plugin email-plugin dummy-plugin
|
||||
|
||||
plugins_static: http-plugin_static slack-plugin_static splunk-plugin_static email-plugin_static
|
||||
plugins_static: http-plugin_static slack-plugin_static splunk-plugin_static email-plugin_static dummy-plugin_static
|
||||
|
||||
goversion:
|
||||
@if [ $(GO_MAJOR_VERSION) -gt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \
|
||||
|
@ -101,6 +103,7 @@ clean: testclean
|
|||
@$(RM) $(SLACK_PLUGIN_FOLDER)/$(SLACK_PLUGIN_BIN)
|
||||
@$(RM) $(SPLUNK_PLUGIN_FOLDER)/$(SPLUNK_PLUGIN_BIN)
|
||||
@$(RM) $(EMAIL_PLUGIN_FOLDER)/$(EMAIL_PLUGIN_BIN)
|
||||
@$(RM) $(DUMMY_PLUGIN_FOLDER)/$(DUMMY_PLUGIN_BIN)
|
||||
|
||||
|
||||
cscli: goversion
|
||||
|
@ -121,6 +124,9 @@ splunk-plugin: goversion
|
|||
email-plugin: goversion
|
||||
@GOARCH=$(GOARCH) GOOS=$(GOOS) $(MAKE) -C $(EMAIL_PLUGIN_FOLDER) build --no-print-directory
|
||||
|
||||
dummy-plugin: goversion
|
||||
@GOARCH=$(GOARCH) GOOS=$(GOOS) $(MAKE) -C $(DUMMY_PLUGIN_FOLDER) build --no-print-directory
|
||||
|
||||
cscli_static: goversion
|
||||
@GOARCH=$(GOARCH) GOOS=$(GOOS) $(MAKE) -C $(CSCLI_FOLDER) static --no-print-directory
|
||||
|
||||
|
@ -139,6 +145,9 @@ splunk-plugin_static:goversion
|
|||
email-plugin_static:goversion
|
||||
@GOARCH=$(GOARCH) GOOS=$(GOOS) $(MAKE) -C $(EMAIL_PLUGIN_FOLDER) static --no-print-directory
|
||||
|
||||
dummy-plugin_static:goversion
|
||||
@GOARCH=$(GOARCH) GOOS=$(GOOS) $(MAKE) -C $(DUMMY_PLUGIN_FOLDER) static --no-print-directory
|
||||
|
||||
.PHONY: testclean
|
||||
testclean: bats-clean
|
||||
@$(RM) pkg/apiserver/ent
|
||||
|
|
|
@ -7,7 +7,7 @@ decisions:
|
|||
duration: 4h
|
||||
# notifications:
|
||||
# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
|
||||
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||
# - email_default # Set the required http parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||
# - email_default # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||
on_success: break
|
||||
|
|
21
plugins/notifications/dummy/LICENSE
Normal file
21
plugins/notifications/dummy/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Crowdsec
|
||||
|
||||
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.
|
16
plugins/notifications/dummy/Makefile
Normal file
16
plugins/notifications/dummy/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Go parameters
|
||||
GOCMD=go
|
||||
GOBUILD=$(GOCMD) build
|
||||
GOCLEAN=$(GOCMD) clean
|
||||
GOTEST=$(GOCMD) test
|
||||
GOGET=$(GOCMD) get
|
||||
BINARY_NAME=notification-dummy
|
||||
|
||||
clean:
|
||||
@$(RM) "$(BINARY_NAME)"
|
||||
|
||||
build: clean
|
||||
@$(GOBUILD) $(LD_OPTS) -o $(BINARY_NAME) -v
|
||||
|
||||
static: clean
|
||||
$(GOBUILD) $(LD_OPTS_STATIC) -o $(BINARY_NAME) -v -a -tags netgo
|
22
plugins/notifications/dummy/dummy.yaml
Normal file
22
plugins/notifications/dummy/dummy.yaml
Normal file
|
@ -0,0 +1,22 @@
|
|||
type: dummy # Don't change
|
||||
name: dummy_default # Must match the registered plugin in the profile
|
||||
|
||||
# One of "trace", "debug", "info", "warn", "error", "off"
|
||||
log_level: info
|
||||
|
||||
# group_wait: # Time to wait collecting alerts before relaying a message to this plugin, eg "30s"
|
||||
# group_threshold: # Amount of alerts that triggers a message before <group_wait> has expired, eg "10"
|
||||
# max_retry: # Number of attempts to relay messages to plugins in case of error
|
||||
# timeout: # Time to wait for response from the plugin before considering the attempt a failure, eg "10s"
|
||||
|
||||
#-------------------------
|
||||
# plugin-specific options
|
||||
|
||||
# The following template receives a list of models.Alert objects
|
||||
# The output goes in the logs and to a text file, if defined
|
||||
format: |
|
||||
{{.|toJson}}
|
||||
|
||||
#
|
||||
# output_file: # notifications will be appended here. optional
|
||||
|
88
plugins/notifications/dummy/main.go
Normal file
88
plugins/notifications/dummy/main.go
Normal file
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type PluginConfig struct {
|
||||
Name string `yaml:"name"`
|
||||
LogLevel *string `yaml:"log_level"`
|
||||
OutputFile *string `yaml:"output_file"`
|
||||
}
|
||||
|
||||
type DummyPlugin struct {
|
||||
PluginConfigByName map[string]PluginConfig
|
||||
}
|
||||
|
||||
var logger hclog.Logger = hclog.New(&hclog.LoggerOptions{
|
||||
Name: "dummy-plugin",
|
||||
Level: hclog.LevelFromString("INFO"),
|
||||
Output: os.Stderr,
|
||||
JSONFormat: true,
|
||||
})
|
||||
|
||||
func (s *DummyPlugin) Notify(ctx context.Context, notification *protobufs.Notification) (*protobufs.Empty, error) {
|
||||
if _, ok := s.PluginConfigByName[notification.Name]; !ok {
|
||||
return nil, fmt.Errorf("invalid plugin config name %s", notification.Name)
|
||||
}
|
||||
cfg := s.PluginConfigByName[notification.Name]
|
||||
|
||||
if cfg.LogLevel != nil && *cfg.LogLevel != "" {
|
||||
logger.SetLevel(hclog.LevelFromString(*cfg.LogLevel))
|
||||
}
|
||||
|
||||
logger.Info(fmt.Sprintf("received signal for %s config", notification.Name))
|
||||
logger.Debug(notification.Text)
|
||||
|
||||
if cfg.OutputFile != nil && *cfg.OutputFile != "" {
|
||||
f, err := os.OpenFile(*cfg.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Cannot open notification file: %s", err))
|
||||
}
|
||||
if _, err := f.WriteString(notification.Text); err != nil {
|
||||
f.Close()
|
||||
logger.Error(fmt.Sprintf("Cannot write notification to file: %s", err))
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Cannot close notification file: %s", err))
|
||||
}
|
||||
}
|
||||
fmt.Print(notification.Text)
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *DummyPlugin) Configure(ctx context.Context, config *protobufs.Config) (*protobufs.Empty, error) {
|
||||
d := PluginConfig{}
|
||||
err := yaml.Unmarshal(config.Config, &d)
|
||||
s.PluginConfigByName[d.Name] = d
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
}
|
||||
|
||||
sp := &DummyPlugin{PluginConfigByName: make(map[string]PluginConfig)}
|
||||
plugin.Serve(&plugin.ServeConfig{
|
||||
HandshakeConfig: handshake,
|
||||
Plugins: map[string]plugin.Plugin{
|
||||
"dummy": &protobufs.NotifierPlugin{
|
||||
Impl: sp,
|
||||
},
|
||||
},
|
||||
GRPCServer: plugin.DefaultGRPCServer,
|
||||
Logger: logger,
|
||||
})
|
||||
}
|
|
@ -18,7 +18,7 @@ do
|
|||
BASE=${2}
|
||||
shift #past argument
|
||||
shift
|
||||
;;
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
|
@ -47,7 +47,7 @@ PARSER_S02="$PARSER_DIR/s02-enrich"
|
|||
SCENARIOS_DIR="$CONFIG_DIR/scenarios"
|
||||
POSTOVERFLOWS_DIR="$CONFIG_DIR/postoverflows"
|
||||
HUB_DIR="$CONFIG_DIR/hub"
|
||||
PLUGINS="http slack splunk"
|
||||
PLUGINS="http slack splunk email"
|
||||
PLUGINS_DIR="plugins"
|
||||
NOTIF_DIR="notifications"
|
||||
|
||||
|
@ -70,13 +70,13 @@ create_arbo() {
|
|||
mkdir -p "$POSTOVERFLOWS_DIR"
|
||||
mkdir -p "$CSCLI_DIR"
|
||||
mkdir -p "$HUB_DIR"
|
||||
mkdir -p $CONFIG_DIR/$NOTIF_DIR/$plugin
|
||||
mkdir -p $BASE/$PLUGINS_DIR
|
||||
mkdir -p "$CONFIG_DIR/$NOTIF_DIR/$plugin"
|
||||
mkdir -p "$BASE/$PLUGINS_DIR"
|
||||
}
|
||||
|
||||
copy_files() {
|
||||
cp "./config/profiles.yaml" "$CONFIG_DIR"
|
||||
cp "./config/simulation.yaml" "$CONFIG_DIR"
|
||||
cp "./config/simulation.yaml" "$CONFIG_DIR"
|
||||
cp "./cmd/crowdsec/crowdsec" "$BASE"
|
||||
cp "./cmd/crowdsec-cli/cscli" "$BASE"
|
||||
cp -r "./config/patterns" "$CONFIG_DIR"
|
||||
|
|
|
@ -41,6 +41,7 @@ bats-build: bats-environment bats-check-requirements
|
|||
@install -m 0755 plugins/notifications/http/notification-http $(PLUGIN_DIR)/
|
||||
@install -m 0755 plugins/notifications/slack/notification-slack $(PLUGIN_DIR)/
|
||||
@install -m 0755 plugins/notifications/splunk/notification-splunk $(PLUGIN_DIR)/
|
||||
@install -m 0755 plugins/notifications/dummy/notification-dummy $(PLUGIN_DIR)/
|
||||
# Create a reusable package with initial configuration + data
|
||||
@$(TEST_DIR)/instance-data make
|
||||
# Generate dynamic tests
|
||||
|
|
55
tests/bats/71_dummy_plugin.bats
Normal file
55
tests/bats/71_dummy_plugin.bats
Normal file
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env bats
|
||||
# vim: ft=bats:list:ts=8:sts=4:sw=4:et:ai:si:
|
||||
|
||||
set -u
|
||||
|
||||
setup_file() {
|
||||
load "../lib/setup_file.sh" >&3 2>&1
|
||||
./instance-data load
|
||||
|
||||
tempfile=$(TMPDIR="${BATS_FILE_TMPDIR}" mktemp)
|
||||
export tempfile
|
||||
|
||||
yq "
|
||||
.group_wait=\"5s\" |
|
||||
.group_threshold=2 |
|
||||
.output_file=\"${tempfile}\"
|
||||
" -i "${CONFIG_DIR}/notifications/dummy.yaml"
|
||||
|
||||
yq '
|
||||
.notifications=["dummy_default"] |
|
||||
.filters=["Alert.GetScope() == \"Ip\""]
|
||||
' -i "${CONFIG_DIR}/profiles.yaml"
|
||||
|
||||
yq '
|
||||
.plugin_config.user="" |
|
||||
.plugin_config.group=""
|
||||
' -i "${CONFIG_DIR}/config.yaml"
|
||||
|
||||
./instance-crowdsec start
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh" >&3 2>&1
|
||||
}
|
||||
|
||||
setup() {
|
||||
load "../lib/setup.sh"
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "$FILE add two bans" {
|
||||
run -0 cscli decisions add --ip 1.2.3.4 --duration 30s
|
||||
assert_output --partial 'Decision successfully added'
|
||||
|
||||
run -0 cscli decisions add --ip 1.2.3.5 --duration 30s
|
||||
assert_output --partial 'Decision successfully added'
|
||||
sleep 2
|
||||
}
|
||||
|
||||
@test "$FILE expected 1 notification" {
|
||||
run -0 cat "${tempfile}"
|
||||
assert_output --partial 1.2.3.4
|
||||
assert_output --partial 1.2.3.5
|
||||
}
|
22
tests/config-templates/notifications/dummy.yaml
Normal file
22
tests/config-templates/notifications/dummy.yaml
Normal file
|
@ -0,0 +1,22 @@
|
|||
type: dummy # Don't change
|
||||
name: dummy_default # Must match the registered plugin in the profile
|
||||
|
||||
# One of "trace", "debug", "info", "warn", "error", "off"
|
||||
log_level: info
|
||||
|
||||
# group_wait: # Time to wait collecting alerts before relaying a message to this plugin, eg "30s"
|
||||
# group_threshold: # Amount of alerts that triggers a message before <group_wait> has expired, eg "10"
|
||||
# max_retry: # Number of attempts to relay messages to plugins in case of error
|
||||
# timeout: # Time to wait for response from the plugin before considering the attempt a failure, eg "10s"
|
||||
|
||||
#-------------------------
|
||||
# plugin-specific options
|
||||
|
||||
# The following template receives a list of models.Alert objects
|
||||
# The output goes in the logs and to a text file, if defined
|
||||
format: |
|
||||
{{.|toJson}}
|
||||
|
||||
#
|
||||
# output_file: # notifications will be appended here. optional
|
||||
|
|
@ -7,7 +7,7 @@ decisions:
|
|||
duration: 4h
|
||||
# notifications:
|
||||
# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
|
||||
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||
# - email_default # Set the required http parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||
# - email_default # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||
on_success: break
|
||||
|
|
|
@ -57,6 +57,7 @@ make_init_data() {
|
|||
envsubst < "./config-templates/notifications/email.yaml" > "${CONFIG_DIR}/notifications/email.yaml"
|
||||
envsubst < "./config-templates/notifications/slack.yaml" > "${CONFIG_DIR}/notifications/slack.yaml"
|
||||
envsubst < "./config-templates/notifications/splunk.yaml" > "${CONFIG_DIR}/notifications/splunk.yaml"
|
||||
envsubst < "./config-templates/notifications/dummy.yaml" > "${CONFIG_DIR}/notifications/dummy.yaml"
|
||||
|
||||
mkdir -p "${CONFIG_DIR}/hub"
|
||||
"${BIN_DIR}/cscli" machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto
|
||||
|
|
|
@ -77,7 +77,7 @@ SPLUNK_PLUGIN_CONFIG="./plugins/notifications/splunk/splunk.yaml"
|
|||
EMAIL_PLUGIN_CONFIG="./plugins/notifications/email/email.yaml"
|
||||
|
||||
BACKUP_DIR=$(mktemp -d)
|
||||
rm -rf $BACKUP_DIR
|
||||
rm -rf -- "$BACKUP_DIR"
|
||||
|
||||
log_info() {
|
||||
msg=$1
|
||||
|
@ -502,7 +502,7 @@ install_plugins(){
|
|||
cp -n ${SLACK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||
cp -n ${SPLUNK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||
cp -n ${HTTP_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||
cp -n ${EMAIL_PLUGIN_CONFIG} /etc/crowdsec/notifications
|
||||
cp -n ${EMAIL_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue