Compare commits
4 commits
Author | SHA1 | Date | |
---|---|---|---|
|
734c3d11fa | ||
|
978872c1e6 | ||
|
7c3d4488f6 | ||
|
79276bda95 |
83 changed files with 7279 additions and 580 deletions
|
@ -182,6 +182,9 @@ linters:
|
|||
|
||||
|
||||
issues:
|
||||
# “Look, that’s why there’s rules, understand? So that you think before you
|
||||
# break ‘em.” ― Terry Pratchett
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 10
|
||||
exclude-rules:
|
||||
|
|
|
@ -226,7 +226,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
|
|||
rootCmd.AddCommand(NewHubTestCmd())
|
||||
rootCmd.AddCommand(NewNotificationsCmd())
|
||||
rootCmd.AddCommand(NewSupportCmd())
|
||||
|
||||
rootCmd.AddCommand(NewSetupCmd())
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
if bincoverTesting != "" {
|
||||
log.Debug("coverage report is enabled")
|
||||
|
|
312
cmd/crowdsec-cli/setup.go
Normal file
312
cmd/crowdsec-cli/setup.go
Normal file
|
@ -0,0 +1,312 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v3"
|
||||
kyaml "sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/setup"
|
||||
)
|
||||
|
||||
// NewSetupCmd defines the "cscli setup" command.
|
||||
func NewSetupCmd() *cobra.Command {
|
||||
cmdSetup := &cobra.Command{
|
||||
Use: "setup",
|
||||
Short: "Tools to configure crowdsec",
|
||||
Long: "Manage hub configuration and service detection",
|
||||
Args: cobra.MinimumNArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
//
|
||||
// cscli setup detect
|
||||
//
|
||||
{
|
||||
cmdSetupDetect := &cobra.Command{
|
||||
Use: "detect",
|
||||
Short: "detect running services, generate a setup file",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runSetupDetect,
|
||||
}
|
||||
|
||||
defaultServiceDetect := csconfig.DefaultConfigPath("hub", "detect.yaml")
|
||||
|
||||
flags := cmdSetupDetect.Flags()
|
||||
flags.String("detect-config", defaultServiceDetect, "path to service detection configuration")
|
||||
flags.Bool("list-supported-services", false, "do not detect; only print supported services")
|
||||
flags.StringSlice("force-unit", nil, "force detection of a systemd unit (can be repeated)")
|
||||
flags.StringSlice("force-process", nil, "force detection of a running process (can be repeated)")
|
||||
flags.StringSlice("skip-service", nil, "ignore a service, don't recommend hub/datasources (can be repeated)")
|
||||
flags.String("force-os-family", "", "override OS.Family: one of linux, freebsd, windows or darwin")
|
||||
flags.String("force-os-id", "", "override OS.ID=[debian | ubuntu | , redhat...]")
|
||||
flags.String("force-os-version", "", "override OS.RawVersion (of OS or Linux distribution)")
|
||||
flags.Bool("snub-systemd", false, "don't use systemd, even if available")
|
||||
flags.Bool("yaml", false, "output yaml, not json")
|
||||
cmdSetup.AddCommand(cmdSetupDetect)
|
||||
}
|
||||
|
||||
//
|
||||
// cscli setup install-hub
|
||||
//
|
||||
{
|
||||
cmdSetupInstallHub := &cobra.Command{
|
||||
Use: "install-hub [setup_file] [flags]",
|
||||
Short: "install items from a setup file",
|
||||
Args: cobra.ExactArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runSetupInstallHub,
|
||||
}
|
||||
|
||||
flags := cmdSetupInstallHub.Flags()
|
||||
flags.Bool("dry-run", false, "don't install anything; print out what would have been")
|
||||
cmdSetup.AddCommand(cmdSetupInstallHub)
|
||||
}
|
||||
|
||||
//
|
||||
// cscli setup datasources
|
||||
//
|
||||
{
|
||||
cmdSetupDataSources := &cobra.Command{
|
||||
Use: "datasources [setup_file] [flags]",
|
||||
Short: "generate datasource (acquisition) configuration from a setup file",
|
||||
Args: cobra.ExactArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runSetupDataSources,
|
||||
}
|
||||
|
||||
flags := cmdSetupDataSources.Flags()
|
||||
flags.String("to-dir", "", "write the configuration to a directory, in multiple files")
|
||||
cmdSetup.AddCommand(cmdSetupDataSources)
|
||||
}
|
||||
|
||||
//
|
||||
// cscli setup validate
|
||||
//
|
||||
{
|
||||
cmdSetupValidate := &cobra.Command{
|
||||
Use: "validate [setup_file]",
|
||||
Short: "validate a setup file",
|
||||
Args: cobra.ExactArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runSetupValidate,
|
||||
}
|
||||
|
||||
cmdSetup.AddCommand(cmdSetupValidate)
|
||||
}
|
||||
|
||||
return cmdSetup
|
||||
}
|
||||
|
||||
func runSetupDetect(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
detectConfigFile, err := flags.GetString("detect-config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listSupportedServices, err := flags.GetBool("list-supported-services")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
forcedUnits, err := flags.GetStringSlice("force-unit")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
forcedProcesses, err := flags.GetStringSlice("force-process")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
forcedOSFamily, err := flags.GetString("force-os-family")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
forcedOSID, err := flags.GetString("force-os-id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
forcedOSVersion, err := flags.GetString("force-os-version")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
skipServices, err := flags.GetStringSlice("skip-service")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
snubSystemd, err := flags.GetBool("snub-systemd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !snubSystemd {
|
||||
_, err := exec.LookPath("systemctl")
|
||||
if err != nil {
|
||||
log.Debug("systemctl not available: snubbing systemd")
|
||||
snubSystemd = true
|
||||
}
|
||||
}
|
||||
|
||||
outYaml, err := flags.GetBool("yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if forcedOSFamily == "" && forcedOSID != "" {
|
||||
log.Debug("force-os-id is set: force-os-family defaults to 'linux'")
|
||||
forcedOSFamily = "linux"
|
||||
}
|
||||
|
||||
if listSupportedServices {
|
||||
supported, err := setup.ListSupported(detectConfigFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, svc := range supported {
|
||||
fmt.Println(svc)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
opts := setup.DetectOptions{
|
||||
ForcedUnits: forcedUnits,
|
||||
ForcedProcesses: forcedProcesses,
|
||||
ForcedOS: setup.ExprOS{
|
||||
Family: forcedOSFamily,
|
||||
ID: forcedOSID,
|
||||
RawVersion: forcedOSVersion,
|
||||
},
|
||||
SkipServices: skipServices,
|
||||
SnubSystemd: snubSystemd,
|
||||
}
|
||||
|
||||
hubSetup, err := setup.Detect(detectConfigFile, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("detecting services: %w", err)
|
||||
}
|
||||
|
||||
setup, err := setupAsString(hubSetup, outYaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(setup)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupAsString(cs setup.Setup, outYaml bool) (string, error) {
|
||||
var (
|
||||
ret []byte
|
||||
err error
|
||||
)
|
||||
|
||||
wrap := func(err error) error {
|
||||
return fmt.Errorf("while marshaling setup: %w", err)
|
||||
}
|
||||
|
||||
indentLevel := 2
|
||||
buf := &bytes.Buffer{}
|
||||
enc := yaml.NewEncoder(buf)
|
||||
enc.SetIndent(indentLevel)
|
||||
|
||||
if err = enc.Encode(cs); err != nil {
|
||||
return "", wrap(err)
|
||||
}
|
||||
|
||||
if err = enc.Close(); err != nil {
|
||||
return "", wrap(err)
|
||||
}
|
||||
|
||||
ret = buf.Bytes()
|
||||
|
||||
if !outYaml {
|
||||
// take a general approach to output json, so we avoid the
|
||||
// double tags in the structures and can use go-yaml features
|
||||
// missing from the json package
|
||||
ret, err = kyaml.YAMLToJSON(ret)
|
||||
if err != nil {
|
||||
return "", wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
func runSetupDataSources(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
fromFile := args[0]
|
||||
|
||||
toDir, err := flags.GetString("to-dir")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
input, err := os.ReadFile(fromFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while reading setup file: %w", err)
|
||||
}
|
||||
|
||||
output, err := setup.DataSources(input, toDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if toDir == "" {
|
||||
fmt.Println(output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runSetupInstallHub(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
fromFile := args[0]
|
||||
|
||||
dryRun, err := flags.GetBool("dry-run")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
input, err := os.ReadFile(fromFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while reading file %s: %w", fromFile, err)
|
||||
}
|
||||
|
||||
if err = setup.InstallHubItems(csConfig, input, dryRun); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runSetupValidate(cmd *cobra.Command, args []string) error {
|
||||
fromFile := args[0]
|
||||
input, err := os.ReadFile(fromFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while reading stdin: %w", err)
|
||||
}
|
||||
|
||||
if err = setup.Validate(input); err != nil {
|
||||
fmt.Printf("%v\n", err)
|
||||
return fmt.Errorf("invalid setup file")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
480
config/detect.yaml
Normal file
480
config/detect.yaml
Normal file
|
@ -0,0 +1,480 @@
|
|||
---
|
||||
version: 1.0
|
||||
|
||||
detect:
|
||||
|
||||
#
|
||||
# crowdsecurity/apache2
|
||||
#
|
||||
|
||||
# XXX some distro is using this path?
|
||||
# - /var/log/*http*/*.log
|
||||
|
||||
apache2-systemd-deb:
|
||||
when:
|
||||
- UnitFound("apache2.service")
|
||||
- PathExists("/etc/debian_version")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: file
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
labels:
|
||||
type: apache2
|
||||
|
||||
apache2-systemd-rpm:
|
||||
when:
|
||||
- UnitFound("httpd.service")
|
||||
- PathExists("/etc/redhat-release")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: file
|
||||
filenames:
|
||||
- /var/log/httpd/*.log
|
||||
# XXX /var/log/*http*/*.log
|
||||
labels:
|
||||
type: apache2
|
||||
|
||||
#
|
||||
# crowdsecurity/asterisk
|
||||
#
|
||||
|
||||
asterisk-systemd:
|
||||
when:
|
||||
- UnitFound("asterisk.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/asterisk
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: asterisk
|
||||
filenames:
|
||||
- /var/log/asterisk/*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/caddy
|
||||
#
|
||||
|
||||
caddy-systemd:
|
||||
when:
|
||||
- UnitFound("caddy.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/caddy
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: caddy
|
||||
filenames:
|
||||
- /var/log/caddy/*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/dovecot
|
||||
#
|
||||
|
||||
dovecot-systemd:
|
||||
when:
|
||||
- UnitFound("dovecot.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/dovecot
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/mail.log
|
||||
|
||||
#
|
||||
# LePresidente/emby
|
||||
#
|
||||
|
||||
emby-systemd:
|
||||
when:
|
||||
- UnitFound("emby-server.service")
|
||||
install:
|
||||
collections:
|
||||
- LePresidente/emby
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: emby
|
||||
filenames:
|
||||
- /var/log/embyserver.txt
|
||||
|
||||
#
|
||||
# crowdsecurity/endlessh
|
||||
#
|
||||
|
||||
endlessh-systemd:
|
||||
when:
|
||||
- UnitFound("endlessh.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/endlessh
|
||||
datasource:
|
||||
source: journalctl
|
||||
labels:
|
||||
type: syslog
|
||||
# XXX this? or /var/log/syslog?
|
||||
journalctl_filter:
|
||||
- "_SYSTEMD_UNIT=endlessh.service"
|
||||
|
||||
#
|
||||
# crowdsecurity/gitea
|
||||
#
|
||||
|
||||
# XXX untested
|
||||
|
||||
gitea-systemd:
|
||||
when:
|
||||
- UnitFound("gitea.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/gitea
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: gitea
|
||||
filenames:
|
||||
- /var/log/gitea.log
|
||||
|
||||
#
|
||||
# crowdsecurity/haproxy
|
||||
#
|
||||
|
||||
haproxy-systemd:
|
||||
when:
|
||||
- UnitFound("haproxy.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/haproxy
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: haproxy
|
||||
filenames:
|
||||
- /var/log/haproxy/*.log
|
||||
|
||||
#
|
||||
# firewallservices/lemonldap-ng
|
||||
#
|
||||
|
||||
lemonldap-ng-systemd:
|
||||
when:
|
||||
- UnitFound("lemonldap-ng-fastcgi-server.service")
|
||||
install:
|
||||
collections:
|
||||
- firewallservices/lemonldap-ng
|
||||
#datasource:
|
||||
# # XXX todo where are the logs?
|
||||
# labels:
|
||||
# type: syslog
|
||||
|
||||
#
|
||||
# crowdsecurity/mariadb
|
||||
#
|
||||
|
||||
mariadb-systemd:
|
||||
when:
|
||||
- UnitFound("mariadb.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/mariadb
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: mysql
|
||||
filenames:
|
||||
- /var/log/mysql/error.log
|
||||
|
||||
#
|
||||
# crowdsecurity/mysql
|
||||
#
|
||||
|
||||
mysql-systemd:
|
||||
when:
|
||||
- UnitFound("mysql.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/mysql
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: mysql
|
||||
filenames:
|
||||
- /var/log/mysql/error.log
|
||||
|
||||
#
|
||||
# crowdsecurity/nginx
|
||||
#
|
||||
|
||||
nginx-systemd:
|
||||
when:
|
||||
- UnitFound("nginx.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/nginx
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: nginx
|
||||
filenames:
|
||||
- /var/log/nginx/*.log
|
||||
|
||||
openresty-systemd:
|
||||
when:
|
||||
- UnitFound("openresty.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/nginx
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: nginx
|
||||
filenames:
|
||||
- /usr/local/openresty/nginx/logs/*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/odoo
|
||||
#
|
||||
|
||||
odoo-systemd:
|
||||
when:
|
||||
- UnitFound("odoo.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/odoo
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: odoo
|
||||
filenames:
|
||||
- /var/log/odoo/*.log
|
||||
|
||||
#
|
||||
# LePresidente/ombi
|
||||
#
|
||||
|
||||
# This only works on deb-based systems. On other distributions, the
|
||||
# application is run from the release tarball and the log location depends on
|
||||
# the location it's run from.
|
||||
|
||||
ombi-systemd:
|
||||
when:
|
||||
- UnitFound("ombi.service")
|
||||
- PathExists("/etc/debian_version")
|
||||
install:
|
||||
collections:
|
||||
- LePresidente/ombi
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: ombi
|
||||
filenames:
|
||||
- /var/log/ombi/log-*.txt
|
||||
|
||||
#
|
||||
# crowdsecurity/pgsql
|
||||
#
|
||||
|
||||
pgsql-systemd-deb:
|
||||
when:
|
||||
- UnitFound("postgresql.service")
|
||||
- PathExists("/etc/debian_version")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/pgsql
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: postgres
|
||||
filenames:
|
||||
- /var/log/postgresql/*.log
|
||||
|
||||
pgsql-systemd-rpm:
|
||||
when:
|
||||
- UnitFound("postgresql.service")
|
||||
- PathExists("/etc/redhat-release")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/pgsql
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: postgres
|
||||
filenames:
|
||||
- /var/lib/pgsql/data/log/*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/postfix
|
||||
#
|
||||
|
||||
postfix-systemd:
|
||||
when:
|
||||
- UnitFound("postfix.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/postfix
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/mail.log
|
||||
|
||||
#
|
||||
# crowdsecurity/proftpd
|
||||
#
|
||||
|
||||
proftpd-systemd:
|
||||
when:
|
||||
- UnitFound("proftpd.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/proftpd
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: proftpd
|
||||
filenames:
|
||||
- /var/log/proftpd/*.log
|
||||
|
||||
#
|
||||
# fulljackz/pureftpd
|
||||
#
|
||||
|
||||
pureftpd-systemd:
|
||||
when:
|
||||
- UnitFound("pure-ftpd.service")
|
||||
install:
|
||||
collections:
|
||||
- fulljackz/pureftpd
|
||||
# XXX ?
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/pure-ftpd/*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/smb
|
||||
#
|
||||
|
||||
smb-systemd:
|
||||
when:
|
||||
# deb -> smbd.service
|
||||
# rpm -> smb.service
|
||||
- UnitFound("smbd.service") or UnitFound("smb.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/smb
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: smb
|
||||
filenames:
|
||||
- /var/log/samba*.log
|
||||
|
||||
#
|
||||
# crowdsecurity/sshd
|
||||
#
|
||||
|
||||
sshd-systemd:
|
||||
when:
|
||||
# deb -> ssh.service
|
||||
# rpm -> sshd.service
|
||||
- UnitFound("ssh.service") or UnitFound("sshd.service") or UnitFound("ssh.socket") or UnitFound("sshd.socket")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/sshd
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/auth.log
|
||||
- /var/log/sshd.log
|
||||
- /var/log/secure
|
||||
|
||||
#
|
||||
# crowdsecurity/suricata
|
||||
#
|
||||
|
||||
suricata-systemd:
|
||||
when:
|
||||
- UnitFound("suricata.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/suricata
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: suricata-evelogs
|
||||
filenames:
|
||||
- /var/log/suricata/eve.json
|
||||
|
||||
#
|
||||
# crowdsecurity/vsftpd
|
||||
#
|
||||
|
||||
vsftpd-systemd:
|
||||
when:
|
||||
- UnitFound("vsftpd.service")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/vsftpd
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: vsftpd
|
||||
filenames:
|
||||
- /var/log/vsftpd/*.log
|
||||
|
||||
#
|
||||
# Operating Systems
|
||||
#
|
||||
|
||||
linux:
|
||||
when:
|
||||
- OS.Family == "linux"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/linux
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/syslog
|
||||
- /var/log/kern.log
|
||||
- /var/log/messages
|
||||
|
||||
freebsd:
|
||||
when:
|
||||
- OS.Family == "freebsd"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/freebsd
|
||||
|
||||
windows:
|
||||
when:
|
||||
- OS.Family == "windows"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/windows
|
||||
|
||||
#
|
||||
# anti-lockout
|
||||
#
|
||||
|
||||
whitelists:
|
||||
install:
|
||||
parsers:
|
||||
- crowdsecurity/whitelists
|
30
debian/postinst
vendored
30
debian/postinst
vendored
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
COLLECTIONS=false
|
||||
set -e
|
||||
|
@ -7,11 +7,11 @@ set -e
|
|||
. /usr/share/debconf/confmodule
|
||||
|
||||
if [ "$1" = configure ]; then
|
||||
if [[ ! -d /var/lib/crowdsec/data ]]; then
|
||||
if [ ! -d /var/lib/crowdsec/data ]; then
|
||||
mkdir -p /var/lib/crowdsec/data
|
||||
fi
|
||||
|
||||
if [[ -d /var/lib/crowdsec/backup ]]; then
|
||||
if [ -d /var/lib/crowdsec/backup ]; then
|
||||
cscli config restore /var/lib/crowdsec/backup/backup.config
|
||||
rm -rf /var/lib/crowdsec/backup
|
||||
/usr/bin/cscli hub update
|
||||
|
@ -19,29 +19,27 @@ if [ "$1" = configure ]; then
|
|||
systemctl start crowdsec
|
||||
fi
|
||||
|
||||
. /usr/share/crowdsec/wizard.sh -n
|
||||
if ! [[ -f /etc/crowdsec/acquis.yaml ]]; then
|
||||
echo Creating /etc/crowdsec/acquis.yaml
|
||||
set +e
|
||||
SILENT=true detect_services
|
||||
SILENT=true TMP_ACQUIS_FILE_SKIP=skip genacquisition
|
||||
set -e
|
||||
COLLECTIONS=true
|
||||
if ! find /etc/crowdsec/acquis.d -maxdepth 1 -type f -name '*' 2>/dev/null | grep -q '.'; then
|
||||
echo Creating /etc/crowdsec/acquis.d
|
||||
mkdir -p /etc/crowdsec/acquis.d
|
||||
cscli setup detect >/etc/crowdsec/.setup.yaml
|
||||
cscli setup install-hub /etc/crowdsec/.setup.yaml
|
||||
cscli setup datasources /etc/crowdsec/.setup.yaml --to-dir /etc/crowdsec/acquis.d
|
||||
fi
|
||||
|
||||
if [[ -f /etc/crowdsec/local_api_credentials.yaml ]] ; then
|
||||
if [ -f /etc/crowdsec/local_api_credentials.yaml ] ; then
|
||||
chmod 600 /etc/crowdsec/local_api_credentials.yaml
|
||||
fi
|
||||
|
||||
if [[ -f /etc/crowdsec/online_api_credentials.yaml ]]; then
|
||||
if [ -f /etc/crowdsec/online_api_credentials.yaml ]; then
|
||||
chmod 600 /etc/crowdsec/online_api_credentials.yaml
|
||||
fi
|
||||
|
||||
if [[ ! -f /etc/crowdsec/local_api_credentials.yaml ]] || [[ ! -f /etc/crowdsec/online_api_credentials.yaml ]]; then
|
||||
if [[ ! -f /etc/crowdsec/local_api_credentials.yaml ]] ; then
|
||||
if [ ! -f /etc/crowdsec/local_api_credentials.yaml ] || [ ! -f /etc/crowdsec/online_api_credentials.yaml ]; then
|
||||
if [ ! -f /etc/crowdsec/local_api_credentials.yaml ] ; then
|
||||
install -m 600 /dev/null /etc/crowdsec/local_api_credentials.yaml
|
||||
fi
|
||||
if [[ ! -f /etc/crowdsec/online_api_credentials.yaml ]] ; then
|
||||
if [ ! -f /etc/crowdsec/online_api_credentials.yaml ] ; then
|
||||
install -m 600 /dev/null /etc/crowdsec/online_api_credentials.yaml
|
||||
fi
|
||||
|
||||
|
|
20
go.mod
20
go.mod
|
@ -53,7 +53,7 @@ require (
|
|||
github.com/r3labs/diff/v2 v2.14.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
google.golang.org/grpc v1.46.0
|
||||
|
@ -65,18 +65,24 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/Masterminds/sprig/v3 v3.2.2
|
||||
github.com/aquasecurity/table v1.8.0
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/blackfireio/osinfo v1.0.3
|
||||
github.com/goccy/go-yaml v1.9.7
|
||||
github.com/google/winops v0.0.0-20211216095627-f0e86eb1453b
|
||||
github.com/ivanpirog/coloredcobra v1.0.1
|
||||
github.com/lithammer/dedent v1.1.0
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
|
||||
github.com/segmentio/kafka-go v0.4.34
|
||||
github.com/shirou/gopsutil/v3 v3.22.11
|
||||
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
||||
golang.org/x/sys v0.2.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apiserver v0.22.5
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -97,6 +103,7 @@ require (
|
|||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/analysis v0.19.16 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
|
@ -112,7 +119,7 @@ require (
|
|||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/gorilla/mux v1.7.3 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
|
@ -133,6 +140,7 @@ require (
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.15.7 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
|
@ -151,6 +159,7 @@ require (
|
|||
github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
|
@ -160,20 +169,23 @@ require (
|
|||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tidwall/gjson v1.13.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
github.com/vjeantet/grok v1.0.1 // indirect
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.9.0 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.25.2 // indirect
|
||||
k8s.io/apimachinery v0.25.2 // indirect
|
||||
k8s.io/klog/v2 v2.70.1 // indirect
|
||||
|
|
41
go.sum
41
go.sum
|
@ -57,6 +57,8 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
|
|||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||
|
@ -209,6 +211,7 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
|
|||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
|
@ -246,6 +249,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
|
|||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
|
@ -372,6 +377,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
|
|||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/goccy/go-yaml v1.9.7 h1:D/Vx+JITklB1ugSkncB4BNR67M3X6AKs9+rqVeo3ddw=
|
||||
github.com/goccy/go-yaml v1.9.7/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
|
||||
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
|
@ -431,8 +438,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
@ -634,8 +641,12 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -651,6 +662,7 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea
|
|||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
|
@ -664,7 +676,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
|
|||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
|
@ -762,6 +773,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
|
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
|
@ -827,6 +840,8 @@ github.com/segmentio/kafka-go v0.4.34 h1:Dm6YlLMiVSiwwav20KY0AoY63s661FXevwJ3CVH
|
|||
github.com/segmentio/kafka-go v0.4.34/go.mod h1:GAjxBQJdQMB5zfNA21AhpaqOB2Mu+w3De4ni3Gbm8y0=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.22.11 h1:kxsPKS+Eeo+VnEQ2XCaGJepeP6KY53QoRTETx3+1ndM=
|
||||
github.com/shirou/gopsutil/v3 v3.22.11/go.mod h1:xl0EeL4vXJ+hQMAGN8B9VFpxukEMA0XdevQOe5MZ1oY=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
|
@ -864,8 +879,9 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
|
@ -875,8 +891,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c h1:HelZ2kAFadG0La9d+4htN4HzQ68Bm2iM9qKMSMES6xg=
|
||||
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c/go.mod h1:JlzghshsemAMDGZLytTFY8C1JQxQPhnatWqNwUXjggo=
|
||||
|
@ -888,6 +905,10 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
|
|||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
|
@ -918,6 +939,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
|
||||
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
|
@ -1126,6 +1149,7 @@ golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1157,6 +1181,7 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1173,9 +1198,10 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
@ -1264,6 +1290,7 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
|
|
|
@ -134,6 +134,7 @@ func GetItemMap(itemType string) map[string]Item {
|
|||
var m map[string]Item
|
||||
var ok bool
|
||||
|
||||
log.Tracef("hubIdx: %v", hubIdx)
|
||||
if m, ok = hubIdx[itemType]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
@ -178,6 +179,7 @@ func GetItemByPath(itemType string, itemPath string) (*Item, error) {
|
|||
}
|
||||
|
||||
func GetItem(itemType string, itemName string) *Item {
|
||||
log.Tracef("getting hub item %s: %s", itemType, itemName)
|
||||
if m, ok := GetItemMap(itemType)[itemName]; ok {
|
||||
return &m
|
||||
}
|
||||
|
|
338
pkg/setup/README.md
Normal file
338
pkg/setup/README.md
Normal file
|
@ -0,0 +1,338 @@
|
|||
|
||||
---
|
||||
|
||||
# cscli setup
|
||||
|
||||
The "cscli setup" command can configure a crowdsec instance based on the services that are installed or running on the server.
|
||||
|
||||
There are three main subcommands:
|
||||
|
||||
- `cscli setup detect`: *detect* the services, the OS family, version or the Linux distribution
|
||||
- `cscli setup install-hub`: *install* the recommended collections, parsers, etc. based on the detection result
|
||||
- `cscli setup datasources`: *generate* the appropriate acquisition rules
|
||||
|
||||
The setup command is used in the `wizard.sh` script, but can also be invoked by hand or customized via a configuration file
|
||||
by adding new services, log locations and detection rules.
|
||||
|
||||
Detection and installation are performed as separate steps, as you can see in the following diagram:
|
||||
|
||||
```
|
||||
+-------------+
|
||||
| |
|
||||
| detect.yaml |
|
||||
| |
|
||||
+-------------+
|
||||
|
|
||||
v
|
||||
setup detect
|
||||
|
|
||||
v
|
||||
+--------------+
|
||||
| +---> setup install-hub +-----------------------+
|
||||
| setup.yaml | | |
|
||||
| +---> setup datasources --->| etc/crowdsec/acquis.d |
|
||||
+--------------+ | |
|
||||
+-----------------------+
|
||||
```
|
||||
|
||||
You can inspect and customize the intermediary file (`setup.yaml`), which is useful
|
||||
in case of many instances, deployment automation or unusual setups.
|
||||
|
||||
A subcommand can be used to check your changes in this case:
|
||||
|
||||
- `cscli setup validate`: *validate* or report errors on a setup file
|
||||
|
||||
## Basic usage
|
||||
|
||||
Identify the existing services and write out what was detected:
|
||||
|
||||
```console
|
||||
# cscli setup detect > setup.yaml
|
||||
```
|
||||
|
||||
See what was found.
|
||||
|
||||
```console
|
||||
# cscli setup install-hub setup.yaml --dry-run
|
||||
dry-run: would install collection crowdsecurity/apache2
|
||||
dry-run: would install collection crowdsecurity/linux
|
||||
dry-run: would install collection crowdsecurity/pgsql
|
||||
dry-run: would install parser crowdsecurity/whitelists
|
||||
```
|
||||
|
||||
Install the objects (parsers, scenarios...) required to support the detected services:
|
||||
|
||||
```console
|
||||
# cscli setup install-hub setup.yaml
|
||||
INFO[29-06-2022 03:16:14 PM] crowdsecurity/apache2-logs : OK
|
||||
INFO[29-06-2022 03:16:14 PM] Enabled parsers : crowdsecurity/apache2-logs
|
||||
INFO[29-06-2022 03:16:14 PM] crowdsecurity/http-logs : OK
|
||||
[...]
|
||||
INFO[29-06-2022 03:16:18 PM] Enabled crowdsecurity/linux
|
||||
```
|
||||
|
||||
Generate the datasource configuration:
|
||||
|
||||
```console
|
||||
# cscli setup datasources setup.yaml --to-dir /etc/crowdsec/acquis.d
|
||||
```
|
||||
|
||||
With the above command, each detected service gets a corresponding file in the
|
||||
`acquis.d` directory. Running `cscli setup` again may add more services as they
|
||||
are detected, but datasource files or hub items are never removed
|
||||
automatically.
|
||||
|
||||
|
||||
## The detect.yaml file
|
||||
|
||||
A detect.yaml file is downloaded when you first install crowdsec, and is updated by the `cscli hub update`
|
||||
command.
|
||||
|
||||
> **_NOTE_**: XXX XXX - this is currently not the case, the file is distributed in the crowdsec repository, but it should change.
|
||||
|
||||
You can see the default location with `cscli setup detect --help | grep detect-config`
|
||||
|
||||
The YAML file contains a version number (always 1.0) and a list of sections, one per supported service.
|
||||
|
||||
Each service defines its detection rules, the recommended hub items and
|
||||
recommended datasources. The same software can be defined in multiple service
|
||||
sections: for example, apache on debian and fedora have different detection
|
||||
rules and different datasources so it requires two sections to support both platforms.
|
||||
|
||||
The following are minimal `detect.yaml` examples just to show a few concepts.
|
||||
|
||||
```yaml
|
||||
version: 1.0
|
||||
|
||||
services:
|
||||
|
||||
apache2:
|
||||
when:
|
||||
- ProcessRunning("apache2")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasources:
|
||||
source: file
|
||||
labels:
|
||||
type: apache2
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/httpd/*.log
|
||||
```
|
||||
|
||||
|
||||
- `ProcessRunning()` matches the process name of a running application. The
|
||||
`when:` clause can contain any number of expressions, they are all evaluated
|
||||
and must all return true for a service to be detected (implied *and* clause, no
|
||||
short-circuit). A missing or empty `when:` section is evaluated as true.
|
||||
The [expression
|
||||
engine](https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md)
|
||||
is the same one used by CrowdSec parser filters. You can force the detection of
|
||||
a process by using the `cscli setup detect... --force-process <processname>`
|
||||
flag. It will always behave as if `<processname>` was running.
|
||||
|
||||
The `install:` section can contain any number of collections, parsers, scenarios
|
||||
and postoverflows. In practices, it's most often a single collection.
|
||||
|
||||
The `datasource:` section is copied as-is in the acquisition file.
|
||||
|
||||
> **_NOTE_**: XXX TODO - the current version does not validate the `datasource:` mapping. Bad content is written to acquis.d until crowdsec chokes on it.
|
||||
|
||||
Detecting a running process may seem a good idea, but if a process manager like
|
||||
systemd is available it's better to ask it for the information we want.
|
||||
|
||||
|
||||
```yaml
|
||||
version: 1.0
|
||||
|
||||
services:
|
||||
|
||||
apache2-systemd:
|
||||
when:
|
||||
- UnitFound("apache2.service")
|
||||
- OS.ID != "centos"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
|
||||
apache2-systemd-centos:
|
||||
when:
|
||||
- UnitFound("httpd.service")
|
||||
- OS.ID == "centos"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/httpd/*.log
|
||||
```
|
||||
|
||||
Here we see two more detection methods:
|
||||
|
||||
- `UnitFound()` matches the name of systemd units, if the are in state enabled,
|
||||
generated or static. You can see here that CentOS is using a different unit
|
||||
name for Apache so it must have its own service section. You can force the
|
||||
detection of a unit by using the `cscli setup detect... --force-unit <unitname>` flag.
|
||||
|
||||
- OS.Family, OS.ID and OS.RawVersion are read from /etc/os-release in case of
|
||||
Linux, and detected by other methods for FreeBSD and Windows. Under FreeBSD
|
||||
and Windows, the value of OS.ID is the same as OS.Family. If OS detection
|
||||
fails, it can be overridden with the flags `--force-os-family`, `--force-os-id`
|
||||
and `--force-os-version`.
|
||||
|
||||
If you want to ignore one or more services (i.e. not install anything and not
|
||||
generate acquisition rules) you can specify it with `cscli setup detect...
|
||||
--skip-service <servicename>`. For example, `--skip-service apache2-systemd`.
|
||||
If you want to disable systemd unit detection, use `cscli setup detect... --snub-systemd`.
|
||||
|
||||
If you used the `--force-process` or `--force-unit` flags, but none of the
|
||||
defined services is looking for them, you'll have an error like "detecting
|
||||
services: process(es) forced but not supported".
|
||||
|
||||
> **_NOTE_**: XXX XXX - having an error for this is maybe too much, but can tell that a configuration is outdated. Could this be a warning with optional flag to make it an error?
|
||||
|
||||
We used the `OS.ID` value to check for the linux distribution, but since the same configuration
|
||||
is required for CentOS and the other RedHat derivatives, it's better to check for the existence
|
||||
of a file that is known to exist in all of them:
|
||||
|
||||
```yaml
|
||||
version: 1.0
|
||||
|
||||
services:
|
||||
|
||||
apache2-systemd-deb:
|
||||
when:
|
||||
- UnitFound("apache2.service")
|
||||
- PathExists("/etc/debian_version")
|
||||
install:
|
||||
# [...]
|
||||
|
||||
apache2-systemd-rpm:
|
||||
when:
|
||||
- UnitFound("httpd.service")
|
||||
- PathExists("/etc/redhat-release")
|
||||
install:
|
||||
# [...]
|
||||
```
|
||||
|
||||
- `PathExists()` evaluates to true if a file, directory or link exists at the
|
||||
given path. It does not check for broken links.
|
||||
|
||||
|
||||
|
||||
Rules can be used to detect operating systems and environments:
|
||||
|
||||
```yaml
|
||||
version: 1.0
|
||||
|
||||
services:
|
||||
|
||||
linux:
|
||||
when:
|
||||
- OS.Family == "linux"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/linux
|
||||
datasource:
|
||||
type: file
|
||||
labels:
|
||||
type: syslog
|
||||
log_files:
|
||||
- /var/log/syslog
|
||||
- /var/log/kern.log
|
||||
- /var/log/messages
|
||||
|
||||
freebsd:
|
||||
when:
|
||||
- OS.Family == "freebsd"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/freebsd
|
||||
|
||||
windows:
|
||||
when:
|
||||
- OS.Family == "windows"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/windows
|
||||
```
|
||||
|
||||
The OS object contains a methods to check for version numbers:
|
||||
`OS.VersionCheck("<constraint>")`. It uses the
|
||||
[Masterminds/semver](https://github.com/Masterminds/semver) package and accepts
|
||||
a variety of operators.
|
||||
|
||||
Instead of: OS.RawVersion == "1.2.3" you should use `OS.VersionCheck("~1")`,
|
||||
`OS.VersionCheck("~1.2")` depending if you want to match the major or the minor
|
||||
version. It's unlikely that you need to match the exact patch level.
|
||||
|
||||
Leading zeroes are permitted, to allow comparison of Ubuntu versions: strict semver rules would treat "22.04" as invalid.
|
||||
|
||||
|
||||
# The `setup.yaml` file
|
||||
|
||||
This file does not actually have a specific name, as it's usually written to standard output.
|
||||
|
||||
For example, on a Debian system running Apache under systemd you can execute:
|
||||
|
||||
```console
|
||||
$ cscli setup detect --yaml
|
||||
setup:
|
||||
- detected_service: apache2-systemd-deb
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
labels:
|
||||
type: apache2
|
||||
- detected_service: linux
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/linux
|
||||
datasource:
|
||||
filenames:
|
||||
- /var/log/syslog
|
||||
- /var/log/kern.log
|
||||
- /var/log/messages
|
||||
labels:
|
||||
type: syslog
|
||||
- detected_service: whitelists
|
||||
install:
|
||||
parsers:
|
||||
- crowdsecurity/whitelists
|
||||
```
|
||||
|
||||
The default output format is JSON, which is compatible with YAML but less readable to humans.
|
||||
|
||||
- `detected_service`: used to generate a name for the files written to `acquis.d`
|
||||
- `install`: can contain collections, parsers, scenarios, postoverflows
|
||||
- `datasource`: copied to `acquis.d`
|
||||
|
||||
|
||||
```console
|
||||
$ cscli setup datasources --help
|
||||
generate datasource (acquisition) configuration from a setup file
|
||||
|
||||
Usage:
|
||||
cscli setup datasources [setup_file] [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for datasources
|
||||
--to-dir string write the configuration to a directory, in multiple files
|
||||
[...]
|
||||
```
|
||||
|
||||
If the `--to-dir` option is not specified, a single monolithic `acquis.yaml` is printed to the standard output.
|
||||
|
581
pkg/setup/detect.go
Normal file
581
pkg/setup/detect.go
Normal file
|
@ -0,0 +1,581 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sort"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/antonmedv/expr"
|
||||
"github.com/blackfireio/osinfo"
|
||||
"github.com/shirou/gopsutil/v3/process"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
// goccyyaml "github.com/goccy/go-yaml"
|
||||
|
||||
// "github.com/k0kubun/pp"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
|
||||
)
|
||||
|
||||
// ExecCommand can be replaced with a mock during tests.
|
||||
var ExecCommand = exec.Command
|
||||
|
||||
// HubItems contains the objects that are recommended to support a service.
|
||||
type HubItems struct {
|
||||
Collections []string `yaml:"collections,omitempty"`
|
||||
Parsers []string `yaml:"parsers,omitempty"`
|
||||
Scenarios []string `yaml:"scenarios,omitempty"`
|
||||
PostOverflows []string `yaml:"postoverflows,omitempty"`
|
||||
}
|
||||
|
||||
type DataSourceItem map[string]interface{}
|
||||
|
||||
// ServiceSetup describes the recommendations (hub objects and datasources) for a detected service.
|
||||
type ServiceSetup struct {
|
||||
DetectedService string `yaml:"detected_service"`
|
||||
Install *HubItems `yaml:"install,omitempty"`
|
||||
DataSource DataSourceItem `yaml:"datasource,omitempty"`
|
||||
}
|
||||
|
||||
// Setup is a container for a list of ServiceSetup objects, allowing for future extensions.
|
||||
type Setup struct {
|
||||
Setup []ServiceSetup `yaml:"setup"`
|
||||
}
|
||||
|
||||
func validateDataSource(opaqueDS DataSourceItem) error {
|
||||
if len(opaqueDS) == 0 {
|
||||
// empty datasource is valid
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// formally validate YAML
|
||||
|
||||
commonDS := configuration.DataSourceCommonCfg{}
|
||||
body, err := yaml.Marshal(opaqueDS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(body, &commonDS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// source is mandatory // XXX unless it's not?
|
||||
|
||||
if commonDS.Source == "" {
|
||||
return fmt.Errorf("source is empty")
|
||||
}
|
||||
|
||||
|
||||
// source must be known
|
||||
|
||||
ds := acquisition.GetDataSourceIface(commonDS.Source)
|
||||
if ds == nil {
|
||||
return fmt.Errorf("unknown source '%s'", commonDS.Source)
|
||||
}
|
||||
|
||||
// unmarshal and validate the rest with the specific implementation
|
||||
|
||||
err = ds.UnmarshalConfig(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// pp.Println(ds)
|
||||
return nil
|
||||
}
|
||||
|
||||
func readDetectConfig(file string) (DetectConfig, error) {
|
||||
var dc DetectConfig
|
||||
|
||||
yamlBytes, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return DetectConfig{}, fmt.Errorf("while reading file: %w", err)
|
||||
}
|
||||
|
||||
dec := yaml.NewDecoder(bytes.NewBuffer(yamlBytes))
|
||||
dec.KnownFields(true)
|
||||
|
||||
if err = dec.Decode(&dc); err != nil {
|
||||
return DetectConfig{}, fmt.Errorf("while parsing %s: %w", file, err)
|
||||
}
|
||||
|
||||
switch dc.Version {
|
||||
case "":
|
||||
return DetectConfig{}, fmt.Errorf("missing version tag (must be 1.0)")
|
||||
case "1.0":
|
||||
// all is well
|
||||
default:
|
||||
return DetectConfig{}, fmt.Errorf("unsupported version tag '%s' (must be 1.0)", dc.Version)
|
||||
}
|
||||
|
||||
for name, svc := range dc.Detect {
|
||||
err = validateDataSource(svc.DataSource)
|
||||
if err != nil {
|
||||
return DetectConfig{}, fmt.Errorf("invalid datasource for %s: %w", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return dc, nil
|
||||
}
|
||||
|
||||
// Service describes the rules for detecting a service and its recommended items.
|
||||
type Service struct {
|
||||
When []string `yaml:"when"`
|
||||
Install *HubItems `yaml:"install,omitempty"`
|
||||
DataSource DataSourceItem `yaml:"datasource,omitempty"`
|
||||
// AcquisYAML []byte
|
||||
}
|
||||
|
||||
// DetectConfig is the container of all detection rules (detect.yaml).
|
||||
type DetectConfig struct {
|
||||
Version string `yaml:"version"`
|
||||
Detect map[string]Service `yaml:"detect"`
|
||||
}
|
||||
|
||||
// ExprState keeps a global state for the duration of the service detection (cache etc.)
|
||||
type ExprState struct {
|
||||
unitsSearched map[string]bool
|
||||
detectOptions DetectOptions
|
||||
|
||||
// cache
|
||||
installedUnits map[string]bool
|
||||
// true if the list of running processes has already been retrieved, we can
|
||||
// avoid getting it a second time.
|
||||
processesSearched map[string]bool
|
||||
// cache
|
||||
runningProcesses map[string]bool
|
||||
}
|
||||
|
||||
// ExprServiceState keep a local state during the detection of a single service. It is reset before each service rules' evaluation.
|
||||
type ExprServiceState struct {
|
||||
detectedUnits []string
|
||||
}
|
||||
|
||||
// ExprOS contains the detected (or forced) OS fields available to the rule engine.
|
||||
type ExprOS struct {
|
||||
Family string
|
||||
ID string
|
||||
RawVersion string
|
||||
}
|
||||
|
||||
// This is not required with Masterminds/semver
|
||||
/*
|
||||
// normalizeVersion strips leading zeroes from each part, to allow comparison of ubuntu-like versions.
|
||||
func normalizeVersion(version string) string {
|
||||
// if it doesn't match a version string, return unchanged
|
||||
if ok := regexp.MustCompile(`^(\d+)(\.\d+)?(\.\d+)?$`).MatchString(version); !ok {
|
||||
// definitely not an ubuntu-like version, return unchanged
|
||||
return version
|
||||
}
|
||||
|
||||
ret := []rune{}
|
||||
|
||||
var cur rune
|
||||
|
||||
trim := true
|
||||
for _, next := range version + "." {
|
||||
if trim && cur == '0' && next != '.' {
|
||||
cur = next
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if cur != 0 {
|
||||
ret = append(ret, cur)
|
||||
}
|
||||
|
||||
trim = (cur == '.' || cur == 0)
|
||||
cur = next
|
||||
}
|
||||
|
||||
return string(ret)
|
||||
}
|
||||
*/
|
||||
|
||||
// VersionCheck returns true if the version of the OS matches the given constraint
|
||||
func (os ExprOS) VersionCheck(constraint string) (bool, error) {
|
||||
v, err := semver.NewVersion(os.RawVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
c, err := semver.NewConstraint(constraint)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return c.Check(v), nil
|
||||
}
|
||||
|
||||
// VersionAtLeast returns true if the version of the OS is at least the given version.
|
||||
func (os ExprOS) VersionAtLeast(constraint string) (bool, error) {
|
||||
return os.VersionCheck(">=" + constraint)
|
||||
}
|
||||
|
||||
// VersionIsLower returns true if the version of the OS is lower than the given version.
|
||||
func (os ExprOS) VersionIsLower(version string) (bool, error) {
|
||||
result, err := os.VersionAtLeast(version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return !result, nil
|
||||
}
|
||||
|
||||
// ExprEnvironment is used to expose functions and values to the rule engine.
|
||||
// It can cache the results of service detection commands, like systemctl etc.
|
||||
type ExprEnvironment struct {
|
||||
OS ExprOS
|
||||
|
||||
_serviceState *ExprServiceState
|
||||
_state *ExprState
|
||||
}
|
||||
|
||||
// NewExprEnvironment creates an environment object for the rule engine.
|
||||
func NewExprEnvironment(opts DetectOptions, os ExprOS) ExprEnvironment {
|
||||
return ExprEnvironment{
|
||||
_state: &ExprState{
|
||||
detectOptions: opts,
|
||||
|
||||
unitsSearched: make(map[string]bool),
|
||||
installedUnits: make(map[string]bool),
|
||||
|
||||
processesSearched: make(map[string]bool),
|
||||
runningProcesses: make(map[string]bool),
|
||||
},
|
||||
_serviceState: &ExprServiceState{},
|
||||
OS: os,
|
||||
}
|
||||
}
|
||||
|
||||
// PathExists returns true if the given path exists.
|
||||
func (e ExprEnvironment) PathExists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// UnitFound returns true if the unit is listed in the systemctl output.
|
||||
// Whether a disabled or failed unit is considered found or not, depends on the
|
||||
// systemctl parameters used.
|
||||
func (e ExprEnvironment) UnitFound(unitName string) (bool, error) {
|
||||
// fill initial caches
|
||||
if len(e._state.unitsSearched) == 0 {
|
||||
if !e._state.detectOptions.SnubSystemd {
|
||||
units, err := systemdUnitList()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, name := range units {
|
||||
e._state.installedUnits[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range e._state.detectOptions.ForcedUnits {
|
||||
e._state.installedUnits[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
e._state.unitsSearched[unitName] = true
|
||||
if e._state.installedUnits[unitName] {
|
||||
e._serviceState.detectedUnits = append(e._serviceState.detectedUnits, unitName)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ProcessRunning returns true if there is a running process with the given name.
|
||||
func (e ExprEnvironment) ProcessRunning(processName string) (bool, error) {
|
||||
if len(e._state.processesSearched) == 0 {
|
||||
procs, err := process.Processes()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("while looking up running processes: %w", err)
|
||||
}
|
||||
|
||||
for _, p := range procs {
|
||||
name, err := p.Name()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("while looking up running processes: %w", err)
|
||||
}
|
||||
|
||||
e._state.runningProcesses[name] = true
|
||||
}
|
||||
|
||||
for _, name := range e._state.detectOptions.ForcedProcesses {
|
||||
e._state.runningProcesses[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
e._state.processesSearched[processName] = true
|
||||
|
||||
return e._state.runningProcesses[processName], nil
|
||||
}
|
||||
|
||||
// applyRules checks if the 'when' expressions are true and returns a Service struct,
|
||||
// augmented with default values and anything that might be useful later on
|
||||
//
|
||||
// All expressions are evaluated (no short-circuit) because we want to know if there are errors.
|
||||
func applyRules(svc Service, env ExprEnvironment) (Service, bool, error) {
|
||||
newsvc := svc
|
||||
svcok := true
|
||||
env._serviceState = &ExprServiceState{}
|
||||
|
||||
for _, rule := range svc.When {
|
||||
out, err := expr.Eval(rule, env)
|
||||
log.Tracef(" Rule '%s' -> %t, %v", rule, out, err)
|
||||
|
||||
if err != nil {
|
||||
return Service{}, false, fmt.Errorf("rule '%s': %w", rule, err)
|
||||
}
|
||||
|
||||
outbool, ok := out.(bool)
|
||||
if !ok {
|
||||
return Service{}, false, fmt.Errorf("rule '%s': type must be a boolean", rule)
|
||||
}
|
||||
|
||||
svcok = svcok && outbool
|
||||
}
|
||||
|
||||
// if newsvc.Acquis == nil || (newsvc.Acquis.LogFiles == nil && newsvc.Acquis.JournalCTLFilter == nil) {
|
||||
// for _, unitName := range env._serviceState.detectedUnits {
|
||||
// if newsvc.Acquis == nil {
|
||||
// newsvc.Acquis = &AcquisItem{}
|
||||
// }
|
||||
// // if there is reference to more than one unit in the rules, we use the first one
|
||||
// newsvc.Acquis.JournalCTLFilter = []string{fmt.Sprintf(`_SYSTEMD_UNIT=%s`, unitName)}
|
||||
// break //nolint // we want to exit after one iteration
|
||||
// }
|
||||
// }
|
||||
|
||||
return newsvc, svcok, nil
|
||||
}
|
||||
|
||||
// filterWithRules decorates a DetectConfig map by filtering according to the when: clauses,
|
||||
// and applying default values or whatever useful to the Service items.
|
||||
func filterWithRules(dc DetectConfig, env ExprEnvironment) (map[string]Service, error) {
|
||||
ret := make(map[string]Service)
|
||||
|
||||
for name := range dc.Detect {
|
||||
//
|
||||
// an empty list of when: clauses defaults to true, if we want
|
||||
// to change this behavior, the place is here.
|
||||
// if len(svc.When) == 0 {
|
||||
// log.Warningf("empty 'when' clause: %+v", svc)
|
||||
// }
|
||||
//
|
||||
log.Trace("Evaluating rules for: ", name)
|
||||
|
||||
svc, ok, err := applyRules(dc.Detect[name], env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while looking for service %s: %w", name, err)
|
||||
}
|
||||
|
||||
if !ok {
|
||||
log.Tracef(" Skipping %s", name)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
log.Tracef(" Detected %s", name)
|
||||
|
||||
ret[name] = svc
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// return units that have been forced but not searched yet.
|
||||
func (e ExprEnvironment) unsearchedUnits() []string {
|
||||
ret := []string{}
|
||||
|
||||
for _, unit := range e._state.detectOptions.ForcedUnits {
|
||||
if !e._state.unitsSearched[unit] {
|
||||
ret = append(ret, unit)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// return processes that have been forced but not searched yet.
|
||||
func (e ExprEnvironment) unsearchedProcesses() []string {
|
||||
ret := []string{}
|
||||
|
||||
for _, proc := range e._state.detectOptions.ForcedProcesses {
|
||||
if !e._state.processesSearched[proc] {
|
||||
ret = append(ret, proc)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// checkConsumedForcedItems checks if all the "forced" options (units or processes) have been evaluated during the service detection.
|
||||
func checkConsumedForcedItems(e ExprEnvironment) error {
|
||||
unconsumed := e.unsearchedUnits()
|
||||
|
||||
unitMsg := ""
|
||||
if len(unconsumed) > 0 {
|
||||
unitMsg = fmt.Sprintf("unit(s) forced but not supported: %v", unconsumed)
|
||||
}
|
||||
|
||||
unconsumed = e.unsearchedProcesses()
|
||||
|
||||
procsMsg := ""
|
||||
if len(unconsumed) > 0 {
|
||||
procsMsg = fmt.Sprintf("process(es) forced but not supported: %v", unconsumed)
|
||||
}
|
||||
|
||||
join := ""
|
||||
if unitMsg != "" && procsMsg != "" {
|
||||
join = "; "
|
||||
}
|
||||
|
||||
if unitMsg != "" || procsMsg != "" {
|
||||
return fmt.Errorf("%s%s%s", unitMsg, join, procsMsg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetectOptions contains parameters for the Detect function.
|
||||
type DetectOptions struct {
|
||||
// slice of unit names that we want to force-detect
|
||||
ForcedUnits []string
|
||||
// slice of process names that we want to force-detect
|
||||
ForcedProcesses []string
|
||||
ForcedOS ExprOS
|
||||
SkipServices []string
|
||||
SnubSystemd bool
|
||||
}
|
||||
|
||||
// Detect performs the service detection from a given configuration.
|
||||
// It outputs a setup file that can be used as input to "cscli setup install-hub"
|
||||
// or "cscli setup datasources".
|
||||
func Detect(serviceDetectionFile string, opts DetectOptions) (Setup, error) {
|
||||
ret := Setup{}
|
||||
|
||||
// explicitly initialize to avoid json mashaling an empty slice as "null"
|
||||
ret.Setup = make([]ServiceSetup, 0)
|
||||
|
||||
log.Tracef("Reading detection rules: %s", serviceDetectionFile)
|
||||
|
||||
sc, err := readDetectConfig(serviceDetectionFile)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// // generate acquis.yaml snippet for this service
|
||||
// for key := range sc.Detect {
|
||||
// svc := sc.Detect[key]
|
||||
// if svc.Acquis != nil {
|
||||
// svc.AcquisYAML, err = yaml.Marshal(svc.Acquis)
|
||||
// if err != nil {
|
||||
// return ret, err
|
||||
// }
|
||||
// sc.Detect[key] = svc
|
||||
// }
|
||||
// }
|
||||
|
||||
var osfull *osinfo.OSInfo
|
||||
|
||||
os := opts.ForcedOS
|
||||
if os == (ExprOS{}) {
|
||||
osfull, err = osinfo.GetOSInfo()
|
||||
if err != nil {
|
||||
return ret, fmt.Errorf("detecting OS: %w", err)
|
||||
}
|
||||
|
||||
log.Tracef("Detected OS - %+v", *osfull)
|
||||
|
||||
os = ExprOS{
|
||||
Family: osfull.Family,
|
||||
ID: osfull.ID,
|
||||
RawVersion: osfull.Version,
|
||||
}
|
||||
} else {
|
||||
log.Tracef("Forced OS - %+v", os)
|
||||
}
|
||||
|
||||
if len(opts.ForcedUnits) > 0 {
|
||||
log.Tracef("Forced units - %v", opts.ForcedUnits)
|
||||
}
|
||||
|
||||
if len(opts.ForcedProcesses) > 0 {
|
||||
log.Tracef("Forced processes - %v", opts.ForcedProcesses)
|
||||
}
|
||||
|
||||
env := NewExprEnvironment(opts, os)
|
||||
|
||||
detected, err := filterWithRules(sc, env)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
if err = checkConsumedForcedItems(env); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// remove services the user asked to ignore
|
||||
for _, name := range opts.SkipServices {
|
||||
delete(detected, name)
|
||||
}
|
||||
|
||||
// sort the keys (service names) to have them in a predictable
|
||||
// order in the final output
|
||||
|
||||
keys := make([]string, 0)
|
||||
for k := range detected {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, name := range keys {
|
||||
svc := detected[name]
|
||||
// if svc.DataSource != nil {
|
||||
// if svc.DataSource.Labels["type"] == "" {
|
||||
// return Setup{}, fmt.Errorf("missing type label for service %s", name)
|
||||
// }
|
||||
// err = yaml.Unmarshal(svc.AcquisYAML, svc.DataSource)
|
||||
// if err != nil {
|
||||
// return Setup{}, fmt.Errorf("while unmarshaling datasource for service %s: %w", name, err)
|
||||
// }
|
||||
// }
|
||||
|
||||
ret.Setup = append(ret.Setup, ServiceSetup{
|
||||
DetectedService: name,
|
||||
Install: svc.Install,
|
||||
DataSource: svc.DataSource,
|
||||
})
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ListSupported parses the configuration file and outputs a list of the supported services.
|
||||
func ListSupported(serviceDetectionFile string) ([]string, error) {
|
||||
dc, err := readDetectConfig(serviceDetectionFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keys := make([]string, 0)
|
||||
for k := range dc.Detect {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys, nil
|
||||
}
|
1012
pkg/setup/detect_test.go
Normal file
1012
pkg/setup/detect_test.go
Normal file
File diff suppressed because it is too large
Load diff
9
pkg/setup/export_test.go
Normal file
9
pkg/setup/export_test.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package setup
|
||||
|
||||
var (
|
||||
SystemdUnitList = systemdUnitList
|
||||
FilterWithRules = filterWithRules
|
||||
ApplyRules = applyRules
|
||||
|
||||
// NormalizeVersion = normalizeVersion
|
||||
)
|
255
pkg/setup/install.go
Normal file
255
pkg/setup/install.go
Normal file
|
@ -0,0 +1,255 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
goccyyaml "github.com/goccy/go-yaml"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
// AcquisDocument is created from a SetupItem. It represents a single YAML document, and can be part of a multi-document file.
|
||||
type AcquisDocument struct {
|
||||
AcquisFilename string
|
||||
DataSource map[string]interface{}
|
||||
}
|
||||
|
||||
func decodeSetup(input []byte, fancyErrors bool) (Setup, error) {
|
||||
ret := Setup{}
|
||||
|
||||
// parse with goccy to have better error messages in many cases
|
||||
dec := goccyyaml.NewDecoder(bytes.NewBuffer(input), goccyyaml.Strict())
|
||||
|
||||
if err := dec.Decode(&ret); err != nil {
|
||||
if fancyErrors {
|
||||
return ret, fmt.Errorf("%v", goccyyaml.FormatError(err, true, true))
|
||||
}
|
||||
// XXX errors here are multiline, should we just print them to stderr instead of logging?
|
||||
return ret, fmt.Errorf("%v", err)
|
||||
}
|
||||
|
||||
// parse again because goccy is not strict enough anyway
|
||||
dec2 := yaml.NewDecoder(bytes.NewBuffer(input))
|
||||
dec2.KnownFields(true)
|
||||
|
||||
if err := dec2.Decode(&ret); err != nil {
|
||||
return ret, fmt.Errorf("while unmarshaling setup file: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// InstallHubItems installs the objects recommended in a setup file.
|
||||
func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error {
|
||||
setupEnvelope, err := decodeSetup(input, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := csConfig.LoadHub(); err != nil {
|
||||
return fmt.Errorf("loading hub: %w", err)
|
||||
}
|
||||
|
||||
if err := cwhub.SetHubBranch(); err != nil {
|
||||
return fmt.Errorf("setting hub branch: %w", err)
|
||||
}
|
||||
|
||||
if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
|
||||
return fmt.Errorf("getting hub index: %w", err)
|
||||
}
|
||||
|
||||
for _, setupItem := range setupEnvelope.Setup {
|
||||
forceAction := false
|
||||
downloadOnly := false
|
||||
install := setupItem.Install
|
||||
|
||||
if install == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(install.Collections) > 0 {
|
||||
for _, collection := range setupItem.Install.Collections {
|
||||
if dryRun {
|
||||
fmt.Println("dry-run: would install collection", collection)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, collection, cwhub.COLLECTIONS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing collection %s: %w", collection, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(install.Parsers) > 0 {
|
||||
for _, parser := range setupItem.Install.Parsers {
|
||||
if dryRun {
|
||||
fmt.Println("dry-run: would install parser", parser)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, parser, cwhub.PARSERS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing parser %s: %w", parser, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(install.Scenarios) > 0 {
|
||||
for _, scenario := range setupItem.Install.Scenarios {
|
||||
if dryRun {
|
||||
fmt.Println("dry-run: would install scenario", scenario)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, scenario, cwhub.SCENARIOS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing scenario %s: %w", scenario, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(install.PostOverflows) > 0 {
|
||||
for _, postoverflow := range setupItem.Install.PostOverflows {
|
||||
if dryRun {
|
||||
fmt.Println("dry-run: would install postoverflow", postoverflow)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, postoverflow, cwhub.PARSERS_OVFLW, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing postoverflow %s: %w", postoverflow, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// marshalAcquisDocuments creates the monolithic file, or itemized files (if a directory is provided) with the acquisition documents.
|
||||
func marshalAcquisDocuments(ads []AcquisDocument, toDir string) (string, error) {
|
||||
var sb strings.Builder
|
||||
|
||||
dashTerminator := false
|
||||
|
||||
disclaimer := `
|
||||
#
|
||||
# This file was automatically generated by "cscli setup datasources".
|
||||
# You can modify it by hand, but will be responsible for its maintenance.
|
||||
# To add datasources or logfiles, you can instead write a new configuration
|
||||
# in the directory defined by acquisition_dir.
|
||||
#
|
||||
|
||||
`
|
||||
|
||||
if toDir == "" {
|
||||
sb.WriteString(disclaimer)
|
||||
} else {
|
||||
_, err := os.Stat(toDir)
|
||||
if os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("directory %s does not exist", toDir)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ad := range ads {
|
||||
out, err := goccyyaml.MarshalWithOptions(ad.DataSource, goccyyaml.IndentSequence(true))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("while encoding datasource: %w", err)
|
||||
}
|
||||
|
||||
if toDir != "" {
|
||||
if ad.AcquisFilename == "" {
|
||||
return "", fmt.Errorf("empty acquis filename")
|
||||
}
|
||||
|
||||
fname := filepath.Join(toDir, ad.AcquisFilename)
|
||||
fmt.Println("creating", fname)
|
||||
|
||||
f, err := os.Create(fname)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating acquisition file: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(disclaimer)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("while writing to %s: %w", ad.AcquisFilename, err)
|
||||
}
|
||||
|
||||
_, err = f.Write(out)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("while writing to %s: %w", ad.AcquisFilename, err)
|
||||
}
|
||||
|
||||
f.Sync()
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if dashTerminator {
|
||||
sb.WriteString("---\n")
|
||||
}
|
||||
|
||||
sb.Write(out)
|
||||
|
||||
dashTerminator = true
|
||||
}
|
||||
|
||||
return sb.String(), nil
|
||||
}
|
||||
|
||||
// Validate checks the validity of a setup file.
|
||||
func Validate(input []byte) error {
|
||||
_, err := decodeSetup(input, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DataSources generates the acquisition documents from a setup file.
|
||||
func DataSources(input []byte, toDir string) (string, error) {
|
||||
setupEnvelope, err := decodeSetup(input, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ads := make([]AcquisDocument, 0)
|
||||
|
||||
filename := func(basename string, ext string) string {
|
||||
if basename == "" {
|
||||
return basename
|
||||
}
|
||||
|
||||
return basename + ext
|
||||
}
|
||||
|
||||
for _, setupItem := range setupEnvelope.Setup {
|
||||
datasource := setupItem.DataSource
|
||||
|
||||
basename := ""
|
||||
if toDir != "" {
|
||||
basename = "setup." + setupItem.DetectedService
|
||||
}
|
||||
|
||||
if datasource == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ad := AcquisDocument{
|
||||
AcquisFilename: filename(basename, ".yaml"),
|
||||
DataSource: datasource,
|
||||
}
|
||||
ads = append(ads, ad)
|
||||
}
|
||||
|
||||
return marshalAcquisDocuments(ads, toDir)
|
||||
}
|
59
pkg/setup/units.go
Normal file
59
pkg/setup/units.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// systemdUnitList returns all enabled systemd units.
|
||||
// It needs to parse the table because -o json does not work everywhere.
|
||||
func systemdUnitList() ([]string, error) {
|
||||
wrap := func(err error) error {
|
||||
return fmt.Errorf("running systemctl: %w", err)
|
||||
}
|
||||
|
||||
ret := make([]string, 0)
|
||||
cmd := ExecCommand("systemctl", "list-unit-files", "--state=enabled,generated,static")
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return ret, wrap(err)
|
||||
}
|
||||
|
||||
log.Debugf("Running systemctl...")
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return ret, wrap(err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
header := true // skip the first line
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if len(line) == 0 {
|
||||
break // the rest of the output is footer
|
||||
}
|
||||
|
||||
if !header {
|
||||
spaceIdx := strings.IndexRune(line, ' ')
|
||||
if spaceIdx == -1 {
|
||||
return ret, fmt.Errorf("can't parse systemctl output")
|
||||
}
|
||||
|
||||
line = line[:spaceIdx]
|
||||
ret = append(ret, line)
|
||||
}
|
||||
|
||||
header = false
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return ret, wrap(err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
32
pkg/setup/units_test.go
Normal file
32
pkg/setup/units_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package setup_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/setup"
|
||||
)
|
||||
|
||||
func TestSystemdUnitList(t *testing.T) {
|
||||
require := require.New(t)
|
||||
setup.ExecCommand = fakeExecCommand
|
||||
|
||||
defer func() { setup.ExecCommand = exec.Command }()
|
||||
|
||||
units, err := setup.SystemdUnitList() //nolint:typecheck,nolintlint // exported only for tests
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal([]string{
|
||||
"crowdsec-setup-detect.service",
|
||||
"apache2.service",
|
||||
"apparmor.service",
|
||||
"apport.service",
|
||||
"atop.service",
|
||||
"atopacct.service",
|
||||
"finalrd.service",
|
||||
"fwupd-refresh.service",
|
||||
"fwupd.service",
|
||||
}, units)
|
||||
}
|
|
@ -1,22 +1,66 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# XXX this can't be a good place to make the tree
|
||||
BASE="./tests"
|
||||
|
||||
usage() {
|
||||
echo "Usage:"
|
||||
echo " ./wizard.sh -h Display this help message."
|
||||
echo " ./test_env.sh -d ./tests Create test environment in './tests' folder"
|
||||
echo " $0 -h Display this help message."
|
||||
echo " $0 -d ./tests Create test environment in './tests' folder"
|
||||
exit 0
|
||||
}
|
||||
|
||||
set_colors() {
|
||||
FG_BLACK=""
|
||||
FG_RED=""
|
||||
FG_GREEN=""
|
||||
FG_YELLOW=""
|
||||
FG_BLUE=""
|
||||
FG_MAGENTA=""
|
||||
FG_CYAN=""
|
||||
FG_WHITE=""
|
||||
BOLD=""
|
||||
RESET=""
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
#shellcheck disable=SC2034
|
||||
if tput sgr0 >/dev/null; then
|
||||
FG_BLACK=$(tput setaf 0)
|
||||
FG_RED=$(tput setaf 1)
|
||||
FG_GREEN=$(tput setaf 2)
|
||||
FG_YELLOW=$(tput setaf 3)
|
||||
FG_BLUE=$(tput setaf 4)
|
||||
FG_MAGENTA=$(tput setaf 5)
|
||||
FG_CYAN=$(tput setaf 6)
|
||||
FG_WHITE=$(tput setaf 7)
|
||||
BOLD=$(tput bold)
|
||||
RESET=$(tput sgr0)
|
||||
fi
|
||||
}
|
||||
|
||||
log_info() {
|
||||
msg=$1
|
||||
date=$(date +%x:%X)
|
||||
echo "{FG_BLUE}INFO${RESET}[${date}] $msg"
|
||||
}
|
||||
|
||||
log_err() {
|
||||
msg=$1
|
||||
date=$(date +%x:%X)
|
||||
echo "${FG_RED}ERR${RESET}[${date}] $msg" >&2
|
||||
}
|
||||
|
||||
|
||||
set_colors()
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
key="${1}"
|
||||
case ${key} in
|
||||
-d|--directory)
|
||||
BASE=${2}
|
||||
shift #past argument
|
||||
shift
|
||||
BASE=$1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
|
@ -31,7 +75,7 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
BASE=$(realpath $BASE)
|
||||
BASE=$(realpath "$BASE")
|
||||
|
||||
DATA_DIR="$BASE/data"
|
||||
|
||||
|
@ -51,13 +95,8 @@ PLUGINS="http slack splunk email"
|
|||
PLUGINS_DIR="plugins"
|
||||
NOTIF_DIR="notifications"
|
||||
|
||||
log_info() {
|
||||
msg=$1
|
||||
date=$(date +%x:%X)
|
||||
echo -e "[$date][INFO] $msg"
|
||||
}
|
||||
|
||||
create_arbo() {
|
||||
create_tree() {
|
||||
mkdir -p "$BASE"
|
||||
mkdir -p "$DATA_DIR"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
@ -83,38 +122,37 @@ copy_files() {
|
|||
cp "./config/acquis.yaml" "$CONFIG_DIR"
|
||||
touch "$CONFIG_DIR"/local_api_credentials.yaml
|
||||
touch "$CONFIG_DIR"/online_api_credentials.yaml
|
||||
envsubst < "./config/dev.yaml" > $BASE/dev.yaml
|
||||
for plugin in $PLUGINS
|
||||
do
|
||||
cp $PLUGINS_DIR/$NOTIF_DIR/$plugin/notification-$plugin $BASE/$PLUGINS_DIR/notification-$plugin
|
||||
cp $PLUGINS_DIR/$NOTIF_DIR/$plugin/$plugin.yaml $CONFIG_DIR/$NOTIF_DIR/$plugin.yaml
|
||||
envsubst < "./config/dev.yaml" > "$BASE/dev.yaml"
|
||||
for plugin in $PLUGINS; do
|
||||
cp "$PLUGINS_DIR/$NOTIF_DIR/$plugin/notification-$plugin" "$BASE/$PLUGINS_DIR/notification-$plugin"
|
||||
cp "$PLUGINS_DIR/$NOTIF_DIR/$plugin/$plugin.yaml" "$CONFIG_DIR/$NOTIF_DIR/$plugin.yaml"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
setup() {
|
||||
$BASE/cscli -c "$CONFIG_FILE" hub update
|
||||
$BASE/cscli -c "$CONFIG_FILE" collections install crowdsecurity/linux
|
||||
"$BASE/cscli" -c "$CONFIG_FILE" hub update
|
||||
"$BASE/cscli" -c "$CONFIG_FILE" collections install crowdsecurity/linux
|
||||
}
|
||||
|
||||
setup_api() {
|
||||
$BASE/cscli -c "$CONFIG_FILE" machines add test -p testpassword -f $CONFIG_DIR/local_api_credentials.yaml --force
|
||||
"$BASE/cscli" -c "$CONFIG_FILE" machines add test -p testpassword -f "$CONFIG_DIR/local_api_credentials.yaml" --force
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
log_info "Creating test arboresence in $BASE"
|
||||
create_arbo
|
||||
log_info "Arboresence created"
|
||||
log_info "Creating directory tree in $BASE"
|
||||
create_tree
|
||||
log_info "Directory tree created"
|
||||
log_info "Copying needed files for tests environment"
|
||||
copy_files
|
||||
log_info "Files copied"
|
||||
log_info "Setting up configurations"
|
||||
CURRENT_PWD=$(pwd)
|
||||
cd $BASE
|
||||
cd "$BASE"
|
||||
setup_api
|
||||
setup
|
||||
cd $CURRENT_PWD
|
||||
cd "$CURRENT_PWD"
|
||||
log_info "Environment is ready in $BASE"
|
||||
}
|
||||
|
||||
|
|
16
tests/ansible/env/source-wizard.sh
vendored
Executable file
16
tests/ansible/env/source-wizard.sh
vendored
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
DB_BACKEND=sqlite
|
||||
TEST_SUITE_GIT=https://github.com/crowdsecurity/crowdsec
|
||||
TEST_SUITE_VERSION=mm-wizard
|
||||
|
||||
export DB_BACKEND
|
||||
export PACKAGE_TESTING
|
||||
export TEST_SUITE_GIT
|
||||
export TEST_SUITE_VERSION
|
||||
export TEST_SUITE_ZIP
|
||||
export TEST_PACKAGE_VERSION_DEB
|
||||
export TEST_PACKAGE_VERSION_RPM
|
||||
export TEST_PACKAGE_FILE
|
||||
export TEST_PACKAGE_DIR
|
||||
export TEST_SKIP
|
|
@ -6,6 +6,9 @@ roles:
|
|||
- src: https://github.com/crowdsecurity/ansible-role-postgresql
|
||||
version: crowdsec
|
||||
name: geerlingguy.postgresql
|
||||
# these should be included as dependencies of crowdsecurity.testing, but sometime are not
|
||||
- src: geerlingguy.repo-epel
|
||||
- src: gantsign.golang
|
||||
|
||||
collections:
|
||||
- name: https://github.com/crowdsecurity/ansible-collection-crowdsecurity.testing.git
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
pattern: "*.bats"
|
||||
register: testfiles
|
||||
|
||||
- name: "Run BATS tests for source build"
|
||||
- name: "Run BATS: functional tests for source build"
|
||||
become: false
|
||||
block:
|
||||
- name: "Run test scripts"
|
||||
|
@ -74,7 +74,7 @@
|
|||
when:
|
||||
- (package_testing is not defined) or (package_testing in ['', 'false', 'False'])
|
||||
|
||||
- name: "Run BATS tests for binary package"
|
||||
- name: "Run BATS: functional tests for binary package"
|
||||
become: true
|
||||
block:
|
||||
- name: "Run test scripts"
|
||||
|
|
42
tests/ansible/vagrant/experimental/wizard-centos-8/Vagrantfile
vendored
Normal file
42
tests/ansible/vagrant/experimental/wizard-centos-8/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'centos/stream8'
|
||||
config.vm.define 'wizard'
|
||||
|
||||
config.vm.provision 'shell', path: 'bootstrap'
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 4
|
||||
libvirt.memory = 4096
|
||||
end
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
|
||||
# config.vm.provision 'ansible' do |ansible|
|
||||
# ansible.config_file = '../../ansible.cfg'
|
||||
# ansible.playbook = '../../run_all.yml'
|
||||
# end
|
||||
|
||||
# same as above, to run the steps separately
|
||||
|
||||
config.vm.provision 'ansible' do |provdep|
|
||||
provdep.config_file = '../../../ansible.cfg'
|
||||
provdep.playbook = '../../../provision_dependencies.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |provtest|
|
||||
provtest.config_file = '../../../ansible.cfg'
|
||||
provtest.playbook = '../../../provision_test_suite.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |preptest|
|
||||
preptest.config_file = '../../../ansible.cfg'
|
||||
preptest.playbook = '../../../prepare_tests.yml'
|
||||
end
|
||||
|
||||
# config.vm.provision 'ansible' do |runtests|
|
||||
# runtests.config_file = '../../../ansible.cfg'
|
||||
# runtests.playbook = '../../../run_tests.yml'
|
||||
# end
|
||||
end
|
5
tests/ansible/vagrant/experimental/wizard-centos-8/bootstrap
Executable file
5
tests/ansible/vagrant/experimental/wizard-centos-8/bootstrap
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
unset IFS
|
||||
set -euf
|
||||
|
||||
sudo dnf -y update
|
42
tests/ansible/vagrant/experimental/wizard-debian-bullseye/Vagrantfile
vendored
Normal file
42
tests/ansible/vagrant/experimental/wizard-debian-bullseye/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'debian/bullseye64'
|
||||
config.vm.define 'wizard'
|
||||
|
||||
config.vm.provision 'shell', path: 'bootstrap'
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 4
|
||||
libvirt.memory = 4096
|
||||
end
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
|
||||
# config.vm.provision 'ansible' do |ansible|
|
||||
# ansible.config_file = '../../ansible.cfg'
|
||||
# ansible.playbook = '../../run_all.yml'
|
||||
# end
|
||||
|
||||
# same as above, to run the steps separately
|
||||
|
||||
config.vm.provision 'ansible' do |provdep|
|
||||
provdep.config_file = '../../../ansible.cfg'
|
||||
provdep.playbook = '../../../provision_dependencies.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |provtest|
|
||||
provtest.config_file = '../../../ansible.cfg'
|
||||
provtest.playbook = '../../../provision_test_suite.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |preptest|
|
||||
preptest.config_file = '../../../ansible.cfg'
|
||||
preptest.playbook = '../../../prepare_tests.yml'
|
||||
end
|
||||
|
||||
# config.vm.provision 'ansible' do |runtests|
|
||||
# runtests.config_file = '../../../ansible.cfg'
|
||||
# runtests.playbook = '../../../run_tests.yml'
|
||||
# end
|
||||
end
|
5
tests/ansible/vagrant/experimental/wizard-debian-bullseye/bootstrap
Executable file
5
tests/ansible/vagrant/experimental/wizard-debian-bullseye/bootstrap
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
unset IFS
|
||||
set -euf
|
||||
|
||||
sudo apt install -y aptitude
|
42
tests/ansible/vagrant/experimental/wizard-debian-buster/Vagrantfile
vendored
Normal file
42
tests/ansible/vagrant/experimental/wizard-debian-buster/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'debian/buster64'
|
||||
config.vm.define 'wizard'
|
||||
|
||||
config.vm.provision 'shell', path: 'bootstrap'
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 4
|
||||
libvirt.memory = 4096
|
||||
end
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
|
||||
# config.vm.provision 'ansible' do |ansible|
|
||||
# ansible.config_file = '../../ansible.cfg'
|
||||
# ansible.playbook = '../../run_all.yml'
|
||||
# end
|
||||
|
||||
# same as above, to run the steps separately
|
||||
|
||||
config.vm.provision 'ansible' do |provdep|
|
||||
provdep.config_file = '../../../ansible.cfg'
|
||||
provdep.playbook = '../../../provision_dependencies.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |provtest|
|
||||
provtest.config_file = '../../../ansible.cfg'
|
||||
provtest.playbook = '../../../provision_test_suite.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |preptest|
|
||||
preptest.config_file = '../../../ansible.cfg'
|
||||
preptest.playbook = '../../../prepare_tests.yml'
|
||||
end
|
||||
|
||||
# config.vm.provision 'ansible' do |runtests|
|
||||
# runtests.config_file = '../../../ansible.cfg'
|
||||
# runtests.playbook = '../../../run_tests.yml'
|
||||
# end
|
||||
end
|
5
tests/ansible/vagrant/experimental/wizard-debian-buster/bootstrap
Executable file
5
tests/ansible/vagrant/experimental/wizard-debian-buster/bootstrap
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
unset IFS
|
||||
set -euf
|
||||
|
||||
sudo apt install -y aptitude
|
42
tests/ansible/vagrant/experimental/wizard-fedora-36/Vagrantfile
vendored
Normal file
42
tests/ansible/vagrant/experimental/wizard-fedora-36/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'fedora/36-cloud-base'
|
||||
config.vm.define 'wizard'
|
||||
|
||||
config.vm.provision 'shell', path: 'bootstrap'
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 4
|
||||
libvirt.memory = 4096
|
||||
end
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
|
||||
# config.vm.provision 'ansible' do |ansible|
|
||||
# ansible.config_file = '../../ansible.cfg'
|
||||
# ansible.playbook = '../../run_all.yml'
|
||||
# end
|
||||
|
||||
# same as above, to run the steps separately
|
||||
|
||||
config.vm.provision 'ansible' do |provdep|
|
||||
provdep.config_file = '../../../ansible.cfg'
|
||||
provdep.playbook = '../../../provision_dependencies.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |provtest|
|
||||
provtest.config_file = '../../../ansible.cfg'
|
||||
provtest.playbook = '../../../provision_test_suite.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |preptest|
|
||||
preptest.config_file = '../../../ansible.cfg'
|
||||
preptest.playbook = '../../../prepare_tests.yml'
|
||||
end
|
||||
|
||||
# config.vm.provision 'ansible' do |runtests|
|
||||
# runtests.config_file = '../../../ansible.cfg'
|
||||
# runtests.playbook = '../../../run_tests.yml'
|
||||
# end
|
||||
end
|
5
tests/ansible/vagrant/experimental/wizard-fedora-36/bootstrap
Executable file
5
tests/ansible/vagrant/experimental/wizard-fedora-36/bootstrap
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
unset IFS
|
||||
set -euf
|
||||
|
||||
sudo dnf -y update
|
42
tests/ansible/vagrant/experimental/wizard-ubuntu-22.04/Vagrantfile
vendored
Normal file
42
tests/ansible/vagrant/experimental/wizard-ubuntu-22.04/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'generic/ubuntu2204'
|
||||
config.vm.define 'wizard'
|
||||
|
||||
config.vm.provision 'shell', path: 'bootstrap'
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 4
|
||||
libvirt.memory = 4096
|
||||
end
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
|
||||
# config.vm.provision 'ansible' do |ansible|
|
||||
# ansible.config_file = '../../ansible.cfg'
|
||||
# ansible.playbook = '../../run_all.yml'
|
||||
# end
|
||||
|
||||
# same as above, to run the steps separately
|
||||
|
||||
config.vm.provision 'ansible' do |provdep|
|
||||
provdep.config_file = '../../../ansible.cfg'
|
||||
provdep.playbook = '../../../provision_dependencies.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |provtest|
|
||||
provtest.config_file = '../../../ansible.cfg'
|
||||
provtest.playbook = '../../../provision_test_suite.yml'
|
||||
end
|
||||
|
||||
config.vm.provision 'ansible' do |preptest|
|
||||
preptest.config_file = '../../../ansible.cfg'
|
||||
preptest.playbook = '../../../prepare_tests.yml'
|
||||
end
|
||||
|
||||
# config.vm.provision 'ansible' do |runtests|
|
||||
# runtests.config_file = '../../../ansible.cfg'
|
||||
# runtests.playbook = '../../../run_tests.yml'
|
||||
# end
|
||||
end
|
5
tests/ansible/vagrant/experimental/wizard-ubuntu-22.04/bootstrap
Executable file
5
tests/ansible/vagrant/experimental/wizard-ubuntu-22.04/bootstrap
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
unset IFS
|
||||
set -euf
|
||||
|
||||
sudo apt install -y aptitude
|
8
tests/bats-detect/WARNING.md
Normal file
8
tests/bats-detect/WARNING.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
Running the tests in this directory WILL change the system configuration in
|
||||
unpredictable ways, remove packages and data (with a peculiar appetite for
|
||||
databases) and possibly bring the system to an unusable state.
|
||||
|
||||
They are meant to be run, as root, on temporary VMs. They are only intended to
|
||||
ease the development of configurations for "cscli setup detect".
|
||||
|
49
tests/bats-detect/apache2-deb.bats
Normal file
49
tests/bats-detect/apache2-deb.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove apache2
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "apache2: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'apache2-systemd-deb'
|
||||
refute_line 'apache2-systemd-rpm'
|
||||
}
|
||||
|
||||
@test "apache2: install" {
|
||||
run -0 deb-install apache2
|
||||
run -0 sudo systemctl enable apache2.service
|
||||
}
|
||||
|
||||
@test "apache2: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'apache2-systemd-deb'
|
||||
refute_line 'apache2-systemd-rpm'
|
||||
}
|
||||
|
||||
@test "apache2: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/apache2-rpm.bats
Normal file
49
tests/bats-detect/apache2-rpm.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove httpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "apache2: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'apache2-systemd-rpm'
|
||||
refute_line 'apache2-systemd-deb'
|
||||
}
|
||||
|
||||
@test "apache2: install" {
|
||||
run -0 rpm-install httpd
|
||||
run -0 sudo systemctl enable httpd.service
|
||||
}
|
||||
|
||||
@test "apache2: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'apache2-systemd-rpm'
|
||||
refute_line 'apache2-systemd-deb'
|
||||
}
|
||||
|
||||
@test "apache2: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/asterisk-deb.bats
Normal file
47
tests/bats-detect/asterisk-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove asterisk
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "asterisk: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'asterisk-systemd'
|
||||
}
|
||||
|
||||
@test "asterisk: install" {
|
||||
run -0 deb-install asterisk
|
||||
run -0 sudo systemctl enable asterisk.service
|
||||
}
|
||||
|
||||
@test "asterisk: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'asterisk-systemd'
|
||||
}
|
||||
|
||||
@test "asterisk: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
50
tests/bats-detect/asterisk-rpm.bats
Normal file
50
tests/bats-detect/asterisk-rpm.bats
Normal file
|
@ -0,0 +1,50 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove asterisk
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
if ! dnf list | grep -q asterisk; then
|
||||
skip 'asterisk package not available'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "asterisk: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'asterisk-systemd'
|
||||
}
|
||||
|
||||
@test "asterisk: install" {
|
||||
run -0 rpm-install asterisk
|
||||
run -0 sudo systemctl enable asterisk.service
|
||||
}
|
||||
|
||||
@test "asterisk: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'asterisk-systemd'
|
||||
}
|
||||
|
||||
@test "asterisk: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
53
tests/bats-detect/caddy-deb.bats
Normal file
53
tests/bats-detect/caddy-deb.bats
Normal file
|
@ -0,0 +1,53 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove caddy
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "caddy: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'caddy-systemd'
|
||||
}
|
||||
|
||||
@test "caddy: install" {
|
||||
run -0 deb-install debian-keyring debian-archive-keyring apt-transport-https
|
||||
run -0 curl -1sSLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key'
|
||||
run -0 sudo gpg --yes --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg < <(output)
|
||||
run -0 curl -1sSLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt'
|
||||
run -0 sudo tee /etc/apt/sources.list.d/caddy-stable.list < <(output)
|
||||
run -0 deb-update
|
||||
run -0 deb-install caddy
|
||||
run -0 sudo systemctl enable caddy.service
|
||||
}
|
||||
|
||||
@test "caddy: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'caddy-systemd'
|
||||
}
|
||||
|
||||
@test "caddy: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/caddy-rpm.bats
Normal file
49
tests/bats-detect/caddy-rpm.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove caddy
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "caddy: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'caddy-systemd'
|
||||
}
|
||||
|
||||
@test "caddy: install" {
|
||||
run -0 rpm-install 'dnf-command(copr)'
|
||||
run -0 sudo dnf -q -y copr enable @caddy/caddy
|
||||
run -0 rpm-install caddy
|
||||
run -0 sudo systemctl enable caddy.service
|
||||
}
|
||||
|
||||
@test "caddy: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'caddy-systemd'
|
||||
}
|
||||
|
||||
@test "caddy: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/dovecot-deb.bats
Normal file
47
tests/bats-detect/dovecot-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove dovecot-core
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "dovecot: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'dovecot-systemd'
|
||||
}
|
||||
|
||||
@test "dovecot: install" {
|
||||
run -0 deb-install dovecot-core
|
||||
run -0 sudo systemctl enable dovecot.service
|
||||
}
|
||||
|
||||
@test "dovecot: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'dovecot-systemd'
|
||||
}
|
||||
|
||||
@test "dovecot: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/dovecot-rpm.bats
Normal file
47
tests/bats-detect/dovecot-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove dovecot
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "dovecot: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'dovecot-systemd'
|
||||
}
|
||||
|
||||
@test "dovecot: install" {
|
||||
run -0 rpm-install dovecot
|
||||
run -0 sudo systemctl enable dovecot.service
|
||||
}
|
||||
|
||||
@test "dovecot: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'dovecot-systemd'
|
||||
}
|
||||
|
||||
@test "dovecot: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
52
tests/bats-detect/emby-deb.bats
Normal file
52
tests/bats-detect/emby-deb.bats
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove emby-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "emby: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'emby-systemd'
|
||||
}
|
||||
|
||||
@test "emby: install" {
|
||||
# https://emby.media/linux-server.html
|
||||
version=4.7.6.0
|
||||
filename="emby-server-deb_${version}_amd64.deb"
|
||||
# don't download twice
|
||||
run -0 curl -1sSLf "https://github.com/MediaBrowser/Emby.Releases/releases/download/${version}/${filename}" -o "${CACHEDIR}/${filename}"
|
||||
run -0 sudo dpkg --install "${CACHEDIR}/${filename}"
|
||||
run -0 sudo systemctl enable emby-server.service
|
||||
}
|
||||
|
||||
@test "emby: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'emby-systemd'
|
||||
}
|
||||
|
||||
@test "emby: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
52
tests/bats-detect/emby-rpm.bats
Normal file
52
tests/bats-detect/emby-rpm.bats
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove emby-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "emby: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'emby-systemd'
|
||||
}
|
||||
|
||||
@test "emby: install" {
|
||||
# https://emby.media/linux-server.html
|
||||
version=4.7.6.0
|
||||
filename="emby-server-rpm_${version}_x86_64.rpm"
|
||||
# don't download twice
|
||||
run -0 curl -1sSLf "https://github.com/MediaBrowser/Emby.Releases/releases/download/${version}/${filename}" -o "${CACHEDIR}/${filename}"
|
||||
run -0 rpm-install "${CACHEDIR}/${filename}"
|
||||
run -0 sudo systemctl enable emby-server.service
|
||||
}
|
||||
|
||||
@test "emby: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'emby-systemd'
|
||||
}
|
||||
|
||||
@test "emby: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
48
tests/bats-detect/endlessh-deb.bats
Normal file
48
tests/bats-detect/endlessh-deb.bats
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove endlessh
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "endlessh: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'endlessh-systemd'
|
||||
}
|
||||
|
||||
@test "endlessh: install" {
|
||||
# https://github.com/skeeto/endlessh
|
||||
run -0 deb-install endlessh
|
||||
run -0 sudo systemctl enable endlessh.service
|
||||
}
|
||||
|
||||
@test "endlessh: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'endlessh-systemd'
|
||||
}
|
||||
|
||||
@test "endlessh: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
48
tests/bats-detect/endlessh-rpm.bats
Normal file
48
tests/bats-detect/endlessh-rpm.bats
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove endlessh
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "endlessh: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'endlessh-systemd'
|
||||
}
|
||||
|
||||
@test "endlessh: install" {
|
||||
# https://github.com/skeeto/endlessh
|
||||
run -0 rpm-install endlessh
|
||||
run -0 sudo systemctl enable endlessh.service
|
||||
}
|
||||
|
||||
@test "endlessh: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'endlessh-systemd'
|
||||
}
|
||||
|
||||
@test "endlessh: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
46
tests/bats-detect/gitea.bats
Normal file
46
tests/bats-detect/gitea.bats
Normal file
|
@ -0,0 +1,46 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
}
|
||||
|
||||
setup() {
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
skip 'WIP'
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "gitea: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'gitea-systemd'
|
||||
}
|
||||
|
||||
@test "gitea: install" {
|
||||
# https://docs.gitea.io/en-us/install-from-binary/#download
|
||||
version=1.16.9
|
||||
# don't download twice
|
||||
run -0 wget -nc --directory-prefix "$CACHEDIR" "https://dl.gitea.io/gitea/${version}/gitea-${version}-linux-amd64"
|
||||
}
|
||||
|
||||
@test "gitea: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'gitea-systemd'
|
||||
}
|
||||
|
||||
@test "gitea: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/haproxy-deb.bats
Normal file
47
tests/bats-detect/haproxy-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove haproxy
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "haproxy: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'haproxy-systemd'
|
||||
}
|
||||
|
||||
@test "haproxy: install" {
|
||||
run -0 deb-install haproxy
|
||||
run -0 sudo systemctl enable haproxy.service
|
||||
}
|
||||
|
||||
@test "haproxy: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'haproxy-systemd'
|
||||
}
|
||||
|
||||
@test "haproxy: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/haproxy-rpm.bats
Normal file
47
tests/bats-detect/haproxy-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove haproxy
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "haproxy: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'haproxy-systemd'
|
||||
}
|
||||
|
||||
@test "haproxy: install" {
|
||||
run -0 rpm-install haproxy
|
||||
run -0 sudo systemctl enable haproxy.service
|
||||
}
|
||||
|
||||
@test "haproxy: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'haproxy-systemd'
|
||||
}
|
||||
|
||||
@test "haproxy: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/lemonldap-deb.bats
Normal file
47
tests/bats-detect/lemonldap-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove lemonldap-ng
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "lemonldap: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'lemonldap-ng-systemd'
|
||||
}
|
||||
|
||||
@test "lemonldap: install" {
|
||||
run -0 deb-install lemonldap-ng
|
||||
run -0 sudo systemctl enable lemonldap-ng-fastcgi-server.service
|
||||
}
|
||||
|
||||
@test "lemonldap: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'lemonldap-ng-systemd'
|
||||
}
|
||||
|
||||
@test "lemonldap: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
50
tests/bats-detect/lemonldap-rpm.bats
Normal file
50
tests/bats-detect/lemonldap-rpm.bats
Normal file
|
@ -0,0 +1,50 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove lemonldap-ng
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
skip 'WIP'
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "lemonldap: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'lemonldap-ng-systemd'
|
||||
}
|
||||
|
||||
@test "lemonldap: install" {
|
||||
run -0 rpm-install 'dnf-command(copr)'
|
||||
run -0 sudo dnf -q -y copr enable xavierb/lemonldap-ng
|
||||
run -0 rpm-install lemonldap-ng
|
||||
run -0 sudo systemctl enable lemonldap-ng-fastcgi-server.service
|
||||
}
|
||||
|
||||
@test "lemonldap: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'lemonldap-ng-systemd'
|
||||
}
|
||||
|
||||
@test "lemonldap: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
55
tests/bats-detect/lib/setup_file_detect.sh
Executable file
55
tests/bats-detect/lib/setup_file_detect.sh
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
TESTDATA="${BATS_TEST_DIRNAME}/testdata"
|
||||
export TESTDATA
|
||||
|
||||
CACHEDIR="${TESTDATA}/.cache"
|
||||
export CACHEDIR
|
||||
|
||||
mkdir -p "${CACHEDIR}"
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
export DEBIAN_FRONTEND
|
||||
|
||||
# avoid warnings in stderr, especially from perl modules
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
deb-install() {
|
||||
# use aptitude to reliably purge dependencies too
|
||||
sudo aptitude install "$@" -yq >/dev/null
|
||||
# this does not work well enough
|
||||
# sudo apt-get -qq -y -o Dpkg:Use-Pty=0 install "$@" >/dev/null
|
||||
# sudo apt-mark auto "$@"
|
||||
}
|
||||
export -f deb-install
|
||||
|
||||
deb-update() {
|
||||
sudo apt-get -qq -y -o Dpkg:Use-Pty=0 update
|
||||
}
|
||||
export -f deb-update
|
||||
|
||||
deb-remove() {
|
||||
for pkg in "$@"; do
|
||||
if dpkg -s "${pkg}" >/dev/null 2>&1; then
|
||||
# use aptitude to reliably purge dependencies too
|
||||
sudo aptitude purge "${pkg}" -yq >/dev/null
|
||||
# this does not work well enough
|
||||
# sudo apt-get -qq -y purge --auto-remove "${pkg}" >/dev/null
|
||||
fi
|
||||
done
|
||||
}
|
||||
export -f deb-remove
|
||||
|
||||
rpm-install() {
|
||||
sudo dnf -q -y install "$@"
|
||||
}
|
||||
export -f rpm-install
|
||||
|
||||
rpm-remove() {
|
||||
# don't fail if dnf does not exist (teardown is called on deb distros too)
|
||||
if command -v dnf >/dev/null; then
|
||||
sudo dnf -q -y remove "$@" >/dev/null
|
||||
fi
|
||||
}
|
||||
export -f rpm-remove
|
47
tests/bats-detect/litespeed.bats
Normal file
47
tests/bats-detect/litespeed.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove openlitespeed
|
||||
}
|
||||
|
||||
setup() {
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
skip 'WIP'
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "openlitespeed: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'litespeed-systemd'
|
||||
}
|
||||
|
||||
@test "openlitespeed: install" {
|
||||
run -0 sudo "${TESTDATA}/enable_lst_debian_repo.sh"
|
||||
run -0 deb-update
|
||||
run -0 deb-install openlitespeed
|
||||
# run -0 sudo systemctl enable XXX TODO
|
||||
}
|
||||
|
||||
@test "litespeed: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'litespeed-systemd'
|
||||
}
|
||||
|
||||
@test "litespeed: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/mariadb-deb.bats
Normal file
47
tests/bats-detect/mariadb-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove mariadb-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "mariadb: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'mariadb-systemd'
|
||||
}
|
||||
|
||||
@test "mariadb: install" {
|
||||
run -0 deb-install mariadb-server
|
||||
run -0 sudo systemctl enable mariadb.service
|
||||
}
|
||||
|
||||
@test "mariadb: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'mariadb-systemd'
|
||||
}
|
||||
|
||||
@test "mariadb: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/mariadb-rpm.bats
Normal file
47
tests/bats-detect/mariadb-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove mariadb-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "mariadb: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'mariadb-systemd'
|
||||
}
|
||||
|
||||
@test "mariadb: install" {
|
||||
run -0 rpm-install mariadb-server
|
||||
run -0 sudo systemctl enable mariadb.service
|
||||
}
|
||||
|
||||
@test "mariadb: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'mariadb-systemd'
|
||||
}
|
||||
|
||||
@test "mariadb: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
64
tests/bats-detect/mysql-deb.bats
Normal file
64
tests/bats-detect/mysql-deb.bats
Normal file
|
@ -0,0 +1,64 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
# debian: mysql-community-server
|
||||
# ubuntu: mysql-server
|
||||
deb-remove mysql-server mysql-community-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
if apt-cache search --names-only "^mysql-server$"; then
|
||||
skip "mysql-server package not available"
|
||||
fi
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "mysql: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'mysql-systemd'
|
||||
}
|
||||
|
||||
@test "mysql: install" {
|
||||
# ubuntu comes with mysql, debian does not
|
||||
if apt-cache search --names-only "^mysql-server$"; then
|
||||
# package not available, install the repo
|
||||
filename="mysql-apt-config_0.8.23-1_all.deb"
|
||||
run -0 curl -1sSLf "https://dev.mysql.com/get/${filename}" -o "${CACHEDIR}/${filename}"
|
||||
# XXX md5 c2b410031867dc7c966ca5b1aa0c72aa
|
||||
run -0 sudo dpkg --install "${CACHEDIR}/${filename}"
|
||||
run -0 deb-update
|
||||
# XXX this hangs
|
||||
run -0 deb-install mysql-community-server
|
||||
else
|
||||
run -0 deb-install mysql-server
|
||||
fi
|
||||
run -0 sudo systemctl enable mysql.service
|
||||
}
|
||||
|
||||
@test "mysql: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'mysql-systemd'
|
||||
}
|
||||
|
||||
@test "mysql: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
48
tests/bats-detect/mysql-rpm.bats
Normal file
48
tests/bats-detect/mysql-rpm.bats
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove mysql-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
skip 'WIP'
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "mysql: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'mysql-systemd'
|
||||
}
|
||||
|
||||
@test "mysql: install" {
|
||||
run -0 rpm-install mysql-server
|
||||
run -0 sudo systemctl enable mysql.service
|
||||
}
|
||||
|
||||
@test "mysql: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'mysql-systemd'
|
||||
}
|
||||
|
||||
@test "mysql: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/nginx-deb.bats
Normal file
47
tests/bats-detect/nginx-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove nginx
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "nginx: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'nginx-systemd'
|
||||
}
|
||||
|
||||
@test "nginx: install" {
|
||||
run -0 deb-install nginx
|
||||
run -0 sudo systemctl enable nginx.service
|
||||
}
|
||||
|
||||
@test "nginx: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'nginx-systemd'
|
||||
}
|
||||
|
||||
@test "nginx: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/nginx-rpm.bats
Normal file
47
tests/bats-detect/nginx-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove nginx
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "nginx: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'nginx-systemd'
|
||||
}
|
||||
|
||||
@test "nginx: install" {
|
||||
run -0 rpm-install nginx
|
||||
run -0 sudo systemctl enable nginx.service
|
||||
}
|
||||
|
||||
@test "nginx: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'nginx-systemd'
|
||||
}
|
||||
|
||||
@test "nginx: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
52
tests/bats-detect/odoo-deb.bats
Normal file
52
tests/bats-detect/odoo-deb.bats
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove odoo
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "odoo: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'odoo-systemd'
|
||||
}
|
||||
|
||||
@test "odoo: install" {
|
||||
run -0 deb-install debian-keyring debian-archive-keyring apt-transport-https
|
||||
run -0 curl -1sSLf https://nightly.odoo.com/odoo.key
|
||||
run -0 sudo gpg --yes --dearmor -o /usr/share/keyrings/odoo-keyring.gpg < <(output)
|
||||
run -0 sudo tee <<< "deb [signed-by=/usr/share/keyrings/odoo-keyring.gpg] https://nightly.odoo.com/15.0/nightly/deb/ ./" /etc/apt/sources.list.d/odoo.list >/dev/null
|
||||
run -0 deb-update
|
||||
run -0 deb-install odoo
|
||||
# run -0 sudo systemctl enable caddy.service
|
||||
}
|
||||
|
||||
@test "odoo: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'odoo-systemd'
|
||||
}
|
||||
|
||||
@test "odoo: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/odoo-rpm.bats
Normal file
49
tests/bats-detect/odoo-rpm.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove odoo
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
skip 'WIP (https://bytemeta.vip/repo/odoo/odoo/issues/95168)'
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "odoo: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'odoo-systemd'
|
||||
}
|
||||
|
||||
@test "odoo: install" {
|
||||
run -0 sudo dnf config-manager --add-repo=https://nightly.odoo.com/15.0/nightly/rpm/odoo.repo
|
||||
run -0 rpm-install odoo
|
||||
run -0 sudo systemctl enable odoo
|
||||
}
|
||||
|
||||
@test "odoo: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'odoo-systemd'
|
||||
}
|
||||
|
||||
@test "odoo: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
52
tests/bats-detect/ombi-deb.bats
Normal file
52
tests/bats-detect/ombi-deb.bats
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove ombi
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "ombi: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'ombi-systemd'
|
||||
}
|
||||
|
||||
@test "ombi: install" {
|
||||
run -0 deb-install debian-keyring debian-archive-keyring apt-transport-https
|
||||
run -0 curl -1sSLf https://apt.ombi.app/pub.key
|
||||
run -0 sudo gpg --yes --dearmor -o /usr/share/keyrings/ombi-keyring.gpg < <(output)
|
||||
run -0 sudo tee <<< "deb [signed-by=/usr/share/keyrings/ombi-keyring.gpg] https://apt.ombi.app/develop jessie main" /etc/apt/sources.list.d/ombi.list >/dev/null
|
||||
run -0 deb-update
|
||||
run -0 deb-install ombi
|
||||
run -0 sudo systemctl enable ombi.service
|
||||
}
|
||||
|
||||
@test "ombi: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'ombi-systemd'
|
||||
}
|
||||
|
||||
@test "ombi: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
57
tests/bats-detect/openresty-deb.bats
Normal file
57
tests/bats-detect/openresty-deb.bats
Normal file
|
@ -0,0 +1,57 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove openresty
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "openresty: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'openresty-systemd'
|
||||
}
|
||||
|
||||
@test "openresty: install" {
|
||||
run -0 deb-install debian-keyring debian-archive-keyring apt-transport-https
|
||||
run -0 curl -1sSLf 'https://openresty.org/package/pubkey.gpg'
|
||||
if [[ "$(lsb_release -is)" == "Ubuntu" ]]; then
|
||||
run -0 sudo gpg --yes --dearmor -o /usr/share/keyrings/openresty.gpg < <(output)
|
||||
run -0 sudo tee <<< "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/openresty.gpg] http://openresty.org/package/ubuntu $(lsb_release -sc) main" /etc/apt/sources.list.d/openresty.list
|
||||
else
|
||||
run -0 sudo apt-key add - < <(output)
|
||||
run -0 sudo tee <<< "deb http://openresty.org/package/debian $(lsb_release -sc) openresty" /etc/apt/sources.list.d/openresty.list
|
||||
fi
|
||||
run -0 deb-update
|
||||
run -0 deb-install openresty
|
||||
run -0 sudo systemctl enable openresty.service
|
||||
}
|
||||
|
||||
@test "openresty: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'openresty-systemd'
|
||||
}
|
||||
|
||||
@test "openresty: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
54
tests/bats-detect/openresty-rpm.bats
Normal file
54
tests/bats-detect/openresty-rpm.bats
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove openresty
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "openresty: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'openresty-systemd'
|
||||
}
|
||||
|
||||
@test "openresty: install" {
|
||||
run -0 rpm-install redhat-lsb-core
|
||||
if [[ "$(lsb_release -is)" == "Fedora" ]]; then
|
||||
run -0 sudo curl -1sSLf "https://openresty.org/package/fedora/openresty.repo" -o "/etc/yum.repos.d/openresty.repo"
|
||||
elif [[ "$(lsb_release -is)" == "CentOS" ]]; then
|
||||
run -0 sudo curl -1sSLf "https://openresty.org/package/centos/openresty.repo" -o "/etc/yum.repos.d/openresty.repo"
|
||||
fi
|
||||
run -0 sudo dnf check-update
|
||||
run -0 rpm-install openresty
|
||||
run -0 sudo systemctl enable openresty.service
|
||||
}
|
||||
|
||||
@test "openresty: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'openresty-systemd'
|
||||
}
|
||||
|
||||
@test "openresty: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
61
tests/bats-detect/pgsql-deb.bats
Normal file
61
tests/bats-detect/pgsql-deb.bats
Normal file
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env bats
|
||||
# vim: ft=bats:list:ts=8:sts=4:sw=4:et:ai:si:
|
||||
|
||||
set -u
|
||||
|
||||
cleanup() {
|
||||
command -v dpkg >/dev/null || return 0
|
||||
# sudo systemctl stop postgresql.service || :
|
||||
# remove the DB to avoid a prompt from postrm
|
||||
if [[ -d /var/lib/postgresql ]]; then
|
||||
# shellcheck disable=SC2045
|
||||
for cluster in $(ls /var/lib/postgresql 2>/dev/null); do
|
||||
sudo pg_dropcluster --stop "${cluster}" main
|
||||
done
|
||||
fi
|
||||
deb-remove postgresql $(dpkg -l | grep postgres | awk '{print $2}')
|
||||
}
|
||||
|
||||
setup_file() {
|
||||
load "../lib/setup_file.sh"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
cleanup
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
cleanup
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "pgsql: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'pgsql-systemd-deb'
|
||||
}
|
||||
|
||||
@test "pgsql: install" {
|
||||
run -0 deb-install postgresql
|
||||
run -0 sudo systemctl enable postgresql.service
|
||||
}
|
||||
|
||||
@test "pgsql: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'pgsql-systemd-deb'
|
||||
}
|
||||
|
||||
@test "pgsql: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
51
tests/bats-detect/pgsql-rpm.bats
Normal file
51
tests/bats-detect/pgsql-rpm.bats
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove postgresql-server
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "pgsql: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'pgsql-systemd-rpm'
|
||||
}
|
||||
|
||||
@test "pgsql: install" {
|
||||
run -0 rpm-install postgresql-server
|
||||
# for centos 8, we need to create the cluster
|
||||
if ! sudo bash -c 'stat /var/lib/pgsql/data/*'; then
|
||||
sudo /usr/bin/postgresql-setup --initdb
|
||||
fi
|
||||
run -0 sudo systemctl enable postgresql.service
|
||||
}
|
||||
|
||||
@test "pgsql: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'pgsql-systemd-rpm'
|
||||
}
|
||||
|
||||
@test "pgsql: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/postfix-deb.bats
Normal file
49
tests/bats-detect/postfix-deb.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove postfix
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "postfix: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'postfix-systemd'
|
||||
}
|
||||
|
||||
@test "postfix: install" {
|
||||
run -0 sudo debconf-set-selections <<< "postfix postfix/mailname string hostname.example.com"
|
||||
run -0 sudo debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
|
||||
run -0 deb-install postfix
|
||||
run -0 sudo systemctl enable postfix.service
|
||||
}
|
||||
|
||||
@test "postfix: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'postfix-systemd'
|
||||
}
|
||||
|
||||
@test "postfix: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/postfix-rpm.bats
Normal file
47
tests/bats-detect/postfix-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove postfix
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "postfix: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'postfix-systemd'
|
||||
}
|
||||
|
||||
@test "postfix: install" {
|
||||
run -0 rpm-install postfix
|
||||
run -0 sudo systemctl enable postfix.service
|
||||
}
|
||||
|
||||
@test "postfix: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'postfix-systemd'
|
||||
}
|
||||
|
||||
@test "postfix: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/proftpd-deb.bats
Normal file
47
tests/bats-detect/proftpd-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove proftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "proftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'proftpd-systemd'
|
||||
}
|
||||
|
||||
@test "proftpd: install" {
|
||||
run -0 deb-install proftpd
|
||||
run -0 sudo systemctl enable proftpd.service
|
||||
}
|
||||
|
||||
@test "proftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'proftpd-systemd'
|
||||
}
|
||||
|
||||
@test "proftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/proftpd-rpm.bats
Normal file
47
tests/bats-detect/proftpd-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove proftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "proftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'proftpd-systemd'
|
||||
}
|
||||
|
||||
@test "proftpd: install" {
|
||||
run -0 rpm-install proftpd
|
||||
run -0 sudo systemctl enable proftpd.service
|
||||
}
|
||||
|
||||
@test "proftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'proftpd-systemd'
|
||||
}
|
||||
|
||||
@test "proftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
62
tests/bats-detect/proxmox-deb.bats
Normal file
62
tests/bats-detect/proxmox-deb.bats
Normal file
|
@ -0,0 +1,62 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove proxmox-ve
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
|
||||
. /etc/os-release
|
||||
case "$VERSION_CODENAME" in
|
||||
bullseye | buster | jessie | squeeze | stretch | wheezy)
|
||||
skip "the installation does not work"
|
||||
;;
|
||||
*)
|
||||
skip "unsupported distribution"
|
||||
;;
|
||||
esac
|
||||
export VERSION_CODENAME
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "proxmox: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'proxmox-systemd'
|
||||
}
|
||||
|
||||
@test "proxmox: install" {
|
||||
run -0 deb-install debian-keyring debian-archive-keyring apt-transport-https
|
||||
run -0 sudo curl -1sSLf http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg -o /etc/apt/trusted.gpg.d/proxmox-ve-release-6.x.gpg
|
||||
run -0 sudo tee <<<"deb http://download.proxmox.com/debian/pve ${VERSION_CODENAME} pve-no-subscription" /etc/apt/sources.list.d/proxmox.list >/dev/null
|
||||
run -0 deb-update
|
||||
run -0 deb-install proxmox-ve
|
||||
run -0 sudo systemctl enable proxmox.service
|
||||
}
|
||||
|
||||
@test "proxmox: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'proxmox-systemd'
|
||||
}
|
||||
|
||||
@test "proxmox: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/pureftpd-deb.bats
Normal file
47
tests/bats-detect/pureftpd-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove pure-ftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "pureftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'pureftpd-systemd'
|
||||
}
|
||||
|
||||
@test "pureftpd: install" {
|
||||
run -0 deb-install pure-ftpd
|
||||
run -0 sudo systemctl enable pure-ftpd.service
|
||||
}
|
||||
|
||||
@test "pureftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'pureftpd-systemd'
|
||||
}
|
||||
|
||||
@test "pureftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/pureftpd-rpm.bats
Normal file
47
tests/bats-detect/pureftpd-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove pure-ftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "pureftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'pureftpd-systemd'
|
||||
}
|
||||
|
||||
@test "pureftpd: install" {
|
||||
run -0 rpm-install pure-ftpd
|
||||
run -0 sudo systemctl enable pure-ftpd.service
|
||||
}
|
||||
|
||||
@test "pureftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'pureftpd-systemd'
|
||||
}
|
||||
|
||||
@test "pureftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
50
tests/bats-detect/smb-deb.bats
Normal file
50
tests/bats-detect/smb-deb.bats
Normal file
|
@ -0,0 +1,50 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove samba
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "smb: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'smb-systemd'
|
||||
}
|
||||
|
||||
@test "smb: install" {
|
||||
run -0 sudo debconf-set-selections <<< "samba-common samba-common/workgroup string WORKGROUP"
|
||||
run -0 sudo debconf-set-selections <<< "samba-common samba-common/dhcp boolean true"
|
||||
run -0 sudo debconf-set-selections <<< "samba-common samba-common/do_debconf boolean true"
|
||||
run -0 deb-install samba
|
||||
run -0 sudo systemctl enable smbd.service
|
||||
}
|
||||
|
||||
@test "smb: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'smb-systemd'
|
||||
}
|
||||
|
||||
@test "smb: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/smb-rpm.bats
Normal file
47
tests/bats-detect/smb-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove samba
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "smb: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'smb-systemd'
|
||||
}
|
||||
|
||||
@test "smb: install" {
|
||||
run -0 rpm-install samba
|
||||
run -0 sudo systemctl enable smb.service
|
||||
}
|
||||
|
||||
@test "smb: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'smb-systemd'
|
||||
}
|
||||
|
||||
@test "smb: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/sshd-deb.bats
Normal file
49
tests/bats-detect/sshd-deb.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
# don't remove ssh here, we assume it's needed
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "sshd: detect unit (fail)" {
|
||||
run -0 sudo systemctl mask ssh.service
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'sshd-systemd'
|
||||
}
|
||||
|
||||
@test "sshd: install" {
|
||||
# run -0 deb-install openssh-server
|
||||
run -0 sudo systemctl unmask ssh.service
|
||||
run -0 sudo systemctl enable ssh.service
|
||||
}
|
||||
|
||||
@test "sshd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'sshd-systemd'
|
||||
}
|
||||
|
||||
@test "sshd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
49
tests/bats-detect/sshd-rpm.bats
Normal file
49
tests/bats-detect/sshd-rpm.bats
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
# don't remove ssh here, we assume it's needed
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "sshd: detect unit (fail)" {
|
||||
run -0 sudo systemctl mask sshd.service
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'sshd-systemd'
|
||||
}
|
||||
|
||||
@test "sshd: install" {
|
||||
# run -0 rpm-install openssh-server
|
||||
run -0 sudo systemctl unmask sshd.service
|
||||
run -0 sudo systemctl enable sshd.service
|
||||
}
|
||||
|
||||
@test "sshd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'sshd-systemd'
|
||||
}
|
||||
|
||||
@test "sshd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/suricata-deb.bats
Normal file
47
tests/bats-detect/suricata-deb.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
deb-remove suricata
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "suricata: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'suricata-systemd'
|
||||
}
|
||||
|
||||
@test "suricata: install" {
|
||||
run -0 deb-install suricata
|
||||
run -0 sudo systemctl enable suricata.service
|
||||
}
|
||||
|
||||
@test "suricata: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'suricata-systemd'
|
||||
}
|
||||
|
||||
@test "suricata: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/suricata-rpm.bats
Normal file
47
tests/bats-detect/suricata-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove suricata
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "suricata: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'suricata-systemd'
|
||||
}
|
||||
|
||||
@test "suricata: install" {
|
||||
run -0 rpm-install suricata
|
||||
run -0 sudo systemctl enable suricata.service
|
||||
}
|
||||
|
||||
@test "suricata: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'suricata-systemd'
|
||||
}
|
||||
|
||||
@test "suricata: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
65
tests/bats-detect/testdata/enable_lst_debian_repo.sh
vendored
Executable file
65
tests/bats-detect/testdata/enable_lst_debian_repo.sh
vendored
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
if [ -r /etc/os-release ]; then
|
||||
|
||||
echo " detecting OS type : "
|
||||
|
||||
. /etc/os-release
|
||||
|
||||
if [ $ID == "debian" ]; then
|
||||
echo "detected OS: $ID - $VERSION_ID"
|
||||
echo " now enable the LiteSpeed Debian Repo "
|
||||
if [ $VERSION_ID == "11" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ bullseye main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ bullseye main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ $VERSION_ID == "10" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ buster main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ buster main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ $VERSION_ID == "9" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ stretch main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ stretch main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ $VERSION_ID == "8" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ jessie main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ jessie main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
fi
|
||||
elif [ $ID == "ubuntu" ]; then
|
||||
echo "detected OS: $ID - $VERSION_ID"
|
||||
echo " now enable the LiteSpeed Debian Repo "
|
||||
if [ `echo "$VERSION_ID" | cut -b-2 ` == "14" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ trusty main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ trusty main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ `echo "$VERSION_ID" | cut -b-2 ` == "12" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ precise main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ precise main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ `echo "$VERSION_ID" | cut -b-2 ` == "16" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ xenial main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ xenial main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ `echo "$VERSION_ID" | cut -b-2 ` == "18" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ bionic main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ bionic main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ `echo "$VERSION_ID" | cut -b-2 ` == "20" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ focal main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ focal main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
elif [ `echo "$VERSION_ID" | cut -b-2 ` == "22" ]; then
|
||||
echo "deb http://rpms.litespeedtech.com/debian/ focal main" > /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
echo "#deb http://rpms.litespeedtech.com/edge/debian/ focal main" >> /etc/apt/sources.list.d/lst_debian_repo.list
|
||||
fi
|
||||
else
|
||||
echo " This distribution is not currently supported by LST repo "
|
||||
echo " If you really have the needs please contact LiteSpeed for support "
|
||||
fi
|
||||
else
|
||||
echo " The /etc/os-release file doesn't exist "
|
||||
echo " This script couldn't determine which distribution of the repo should be enabled "
|
||||
echo " Please consult LiteSpeed Customer Support for further assistance "
|
||||
fi
|
||||
|
||||
echo " register LiteSpeed GPG key "
|
||||
wget -O /etc/apt/trusted.gpg.d/lst_debian_repo.gpg http://rpms.litespeedtech.com/debian/lst_debian_repo.gpg
|
||||
wget -O /etc/apt/trusted.gpg.d/lst_repo.gpg http://rpms.litespeedtech.com/debian/lst_repo.gpg
|
||||
|
||||
echo " update the repo "
|
||||
apt-get update
|
||||
|
||||
echo " All done, congratulations and enjoy ! "
|
48
tests/bats-detect/vsftpd-deb.bats
Normal file
48
tests/bats-detect/vsftpd-deb.bats
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
sudo systemctl stop vsftpd.service 2>/dev/null || :
|
||||
deb-remove vsftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dpkg >/dev/null; then
|
||||
skip 'not a debian-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "vsftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'vsftpd-systemd'
|
||||
}
|
||||
|
||||
@test "vsftpd: install" {
|
||||
run -0 deb-install vsftpd
|
||||
run -0 sudo systemctl enable vsftpd.service
|
||||
}
|
||||
|
||||
@test "vsftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'vsftpd-systemd'
|
||||
}
|
||||
|
||||
@test "vsftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
47
tests/bats-detect/vsftpd-rpm.bats
Normal file
47
tests/bats-detect/vsftpd-rpm.bats
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/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"
|
||||
load "${BATS_TEST_DIRNAME}/lib/setup_file_detect.sh"
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
rpm-remove vsftpd
|
||||
}
|
||||
|
||||
setup() {
|
||||
if ! command -v dnf >/dev/null; then
|
||||
skip 'not a redhat-like system'
|
||||
fi
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "vsftpd: detect unit (fail)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
refute_line 'vsftpd-systemd'
|
||||
}
|
||||
|
||||
@test "vsftpd: install" {
|
||||
run -0 rpm-install vsftpd
|
||||
run -0 sudo systemctl enable vsftpd.service
|
||||
}
|
||||
|
||||
@test "vsftpd: detect unit (succeed)" {
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -r '.setup | .[].detected_service' <(output)
|
||||
assert_line 'vsftpd-systemd'
|
||||
}
|
||||
|
||||
@test "vsftpd: install detected collection" {
|
||||
run -0 cscli setup detect
|
||||
run -0 cscli setup install-hub <(output)
|
||||
}
|
815
tests/bats/07_setup.bats
Normal file
815
tests/bats/07_setup.bats
Normal file
|
@ -0,0 +1,815 @@
|
|||
#!/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"
|
||||
./instance-data load
|
||||
HUB_DIR=$(config_get '.config_paths.hub_dir')
|
||||
export HUB_DIR
|
||||
DETECT_YAML="${HUB_DIR}/detect.yaml"
|
||||
export DETECT_YAML
|
||||
# shellcheck disable=SC2154
|
||||
TESTDATA="${BATS_TEST_DIRNAME}/testdata/07_setup"
|
||||
export TESTDATA
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
}
|
||||
|
||||
setup() {
|
||||
load "../lib/setup.sh"
|
||||
load "../lib/bats-file/load.bash"
|
||||
load "../lib/bats-mock/load.bash"
|
||||
./instance-data load
|
||||
}
|
||||
|
||||
teardown() {
|
||||
./instance-crowdsec stop
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
#shellcheck disable=SC2154
|
||||
@test "cscli setup" {
|
||||
run -0 cscli help
|
||||
assert_line --regexp '^ +setup +Tools to configure crowdsec$'
|
||||
|
||||
run -0 cscli setup --help
|
||||
assert_line 'Usage:'
|
||||
assert_line ' cscli setup [command]'
|
||||
assert_line 'Manage hub configuration and service detection'
|
||||
assert_line --partial "detect detect running services, generate a setup file"
|
||||
assert_line --partial "datasources generate datasource (acquisition) configuration from a setup file"
|
||||
assert_line --partial "install-hub install items from a setup file"
|
||||
assert_line --partial "validate validate a setup file"
|
||||
|
||||
# cobra should return error for non-existing sub-subcommands, but doesn't
|
||||
run -0 cscli setup blahblah
|
||||
assert_line 'Usage:'
|
||||
}
|
||||
|
||||
@test "cscli setup detect --help; --detect-config" {
|
||||
run -0 cscli setup detect --help
|
||||
assert_line --regexp "detect running services, generate a setup file"
|
||||
assert_line 'Usage:'
|
||||
assert_line ' cscli setup detect [flags]'
|
||||
assert_line --partial "--detect-config string path to service detection configuration (default \"${HUB_DIR}/detect.yaml\")"
|
||||
assert_line --partial "--force-process strings force detection of a running process (can be repeated)"
|
||||
assert_line --partial "--force-unit strings force detection of a systemd unit (can be repeated)"
|
||||
assert_line --partial "--list-supported-services do not detect; only print supported services"
|
||||
assert_line --partial "--force-os-family string override OS.Family: one of linux, freebsd, windows or darwin"
|
||||
assert_line --partial "--force-os-id string override OS.ID=[debian | ubuntu | , redhat...]"
|
||||
assert_line --partial "--force-os-version string override OS.RawVersion (of OS or Linux distribution)"
|
||||
assert_line --partial "--skip-service strings ignore a service, don't recommend hub/datasources (can be repeated)"
|
||||
|
||||
run -1 --separate-stderr cscli setup detect --detect-config /path/does/not/exist
|
||||
assert_stderr --partial "detecting services: while reading file: open /path/does/not/exist: no such file or directory"
|
||||
|
||||
# rm -f "${HUB_DIR}/detect.yaml"
|
||||
}
|
||||
|
||||
@test "cscli setup detect (linux), --skip-service" {
|
||||
[[ ${OSTYPE} =~ linux.* ]] || skip
|
||||
tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
|
||||
cat <<-EOT >"${tempfile}"
|
||||
version: 1.0
|
||||
detect:
|
||||
linux:
|
||||
when:
|
||||
- OS.Family == "linux"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/linux
|
||||
thewiz:
|
||||
when:
|
||||
- OS.Family != "linux"
|
||||
foobarbaz:
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --detect-config "$tempfile"
|
||||
assert_json '{setup:[{detected_service:"foobarbaz"},{detected_service:"linux",install:{collections:["crowdsecurity/linux"]}}]}'
|
||||
|
||||
run -0 cscli setup detect --detect-config "$tempfile" --skip-service linux
|
||||
assert_json '{setup:[{detected_service:"foobarbaz"}]}'
|
||||
}
|
||||
|
||||
@test "cscli setup detect --force-os-*" {
|
||||
run -0 cscli setup detect --force-os-family linux --detect-config "${TESTDATA}/detect.yaml"
|
||||
run -0 jq -cS '.setup[] | select(.detected_service=="linux")' <(output)
|
||||
assert_json '{detected_service:"linux",install:{collections:["crowdsecurity/linux"]},datasource:{source:"file",labels:{type:"syslog"},filenames:["/var/log/syslog","/var/log/kern.log","/var/log/messages"]}}'
|
||||
|
||||
run -0 cscli setup detect --force-os-family freebsd --detect-config "${TESTDATA}/detect.yaml"
|
||||
run -0 jq -cS '.setup[] | select(.detected_service=="freebsd")' <(output)
|
||||
assert_json '{detected_service:"freebsd",install:{collections:["crowdsecurity/freebsd"]}}'
|
||||
|
||||
run -0 cscli setup detect --force-os-family windows --detect-config "${TESTDATA}/detect.yaml"
|
||||
run -0 jq -cS '.setup[] | select(.detected_service=="windows")' <(output)
|
||||
assert_json '{detected_service:"windows",install:{collections:["crowdsecurity/windows"]}}'
|
||||
|
||||
run -0 --separate-stderr cscli setup detect --force-os-family darwin --detect-config "${TESTDATA}/detect.yaml"
|
||||
refute_stderr
|
||||
# XXX do we want do disallow unknown family?
|
||||
# assert_stderr --partial "detecting services: OS 'darwin' not supported"
|
||||
|
||||
# XXX TODO force-os-id, force-os-version
|
||||
}
|
||||
|
||||
@test "cscli setup detect --list-supported-services" {
|
||||
tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
|
||||
cat <<-EOT >"${tempfile}"
|
||||
version: 1.0
|
||||
detect:
|
||||
thewiz:
|
||||
foobarbaz:
|
||||
apache2:
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --list-supported-services --detect-config "$tempfile"
|
||||
# the service list is sorted
|
||||
assert_output - <<-EOT
|
||||
apache2
|
||||
foobarbaz
|
||||
thewiz
|
||||
EOT
|
||||
|
||||
cat <<-EOT >"${tempfile}"
|
||||
thisisajoke
|
||||
EOT
|
||||
|
||||
run -1 --separate-stderr cscli setup detect --list-supported-services --detect-config "$tempfile"
|
||||
assert_stderr --partial "while parsing ${tempfile}: yaml: unmarshal errors:"
|
||||
|
||||
rm -f "$tempfile"
|
||||
}
|
||||
|
||||
@test "cscli setup detect (systemctl)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- UnitFound("mock-apache2.service")
|
||||
datasource:
|
||||
source: file
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache2
|
||||
EOT
|
||||
|
||||
# transparently mock systemctl. It's easier if you can tell the application
|
||||
# under test which executable to call (in which case just call $mock) but
|
||||
# here we do the symlink and $PATH dance as an example
|
||||
mocked_command="systemctl"
|
||||
|
||||
# mock setup
|
||||
mock="$(mock_create)"
|
||||
mock_path="${mock%/*}"
|
||||
mock_file="${mock##*/}"
|
||||
ln -sf "${mock_path}/${mock_file}" "${mock_path}/${mocked_command}"
|
||||
|
||||
#shellcheck disable=SC2030
|
||||
PATH="${mock_path}:${PATH}"
|
||||
|
||||
mock_set_output "$mock" \
|
||||
'UNIT FILE STATE VENDOR PRESET
|
||||
snap-bare-5.mount enabled enabled
|
||||
snap-core-13308.mount enabled enabled
|
||||
snap-firefox-1635.mount enabled enabled
|
||||
snap-fx-158.mount enabled enabled
|
||||
snap-gimp-393.mount enabled enabled
|
||||
snap-gtk\x2dcommon\x2dthemes-1535.mount enabled enabled
|
||||
snap-kubectl-2537.mount enabled enabled
|
||||
snap-rustup-1027.mount enabled enabled
|
||||
cups.path enabled enabled
|
||||
console-setup.service enabled enabled
|
||||
dmesg.service enabled enabled
|
||||
getty@.service enabled enabled
|
||||
grub-initrd-fallback.service enabled enabled
|
||||
irqbalance.service enabled enabled
|
||||
keyboard-setup.service enabled enabled
|
||||
mock-apache2.service enabled enabled
|
||||
networkd-dispatcher.service enabled enabled
|
||||
ua-timer.timer enabled enabled
|
||||
update-notifier-download.timer enabled enabled
|
||||
update-notifier-motd.timer enabled enabled
|
||||
|
||||
20 unit files listed.'
|
||||
mock_set_status "$mock" 1 2
|
||||
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -c '.setup' <(output)
|
||||
|
||||
# If a call to UnitFoundwas part of the expression and it returned true,
|
||||
# there is a default journalctl_filter derived from the unit's name.
|
||||
assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"}]'
|
||||
|
||||
# the command was called exactly once
|
||||
[[ $(mock_get_call_num "$mock") -eq 1 ]]
|
||||
|
||||
# the command was called with the expected parameters
|
||||
[[ $(mock_get_call_args "$mock" 1) == "list-unit-files --state=enabled,generated,static" ]]
|
||||
|
||||
run -1 systemctl
|
||||
|
||||
# mock teardown
|
||||
unlink "${mock_path}/${mocked_command}"
|
||||
PATH="${PATH/${mock_path}:/}"
|
||||
}
|
||||
|
||||
# XXX this is the same boilerplate as the previous test, can be simplified
|
||||
@test "cscli setup detect (snub systemd)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- UnitFound("mock-apache2.service")
|
||||
datasource:
|
||||
source: file
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache2
|
||||
EOT
|
||||
|
||||
# transparently mock systemctl. It's easier if you can tell the application
|
||||
# under test which executable to call (in which case just call $mock) but
|
||||
# here we do the symlink and $PATH dance as an example
|
||||
mocked_command="systemctl"
|
||||
|
||||
# mock setup
|
||||
mock="$(mock_create)"
|
||||
mock_path="${mock%/*}"
|
||||
mock_file="${mock##*/}"
|
||||
ln -sf "${mock_path}/${mock_file}" "${mock_path}/${mocked_command}"
|
||||
|
||||
#shellcheck disable=SC2031
|
||||
PATH="${mock_path}:${PATH}"
|
||||
|
||||
# we don't really care about the output, it's not used anyway
|
||||
mock_set_output "$mock" ""
|
||||
mock_set_status "$mock" 1 2
|
||||
|
||||
run -0 cscli setup detect --snub-systemd
|
||||
|
||||
# setup must not be 'null', but an empty list
|
||||
assert_json '{setup:[]}'
|
||||
|
||||
# the command was never called
|
||||
[[ $(mock_get_call_num "$mock") -eq 0 ]]
|
||||
|
||||
run -0 systemctl
|
||||
|
||||
# mock teardown
|
||||
unlink "${mock_path}/${mocked_command}"
|
||||
PATH="${PATH/${mock_path}:/}"
|
||||
}
|
||||
|
||||
@test "cscli setup detect --force-unit" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- UnitFound("force-apache2")
|
||||
datasource:
|
||||
source: file
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache2
|
||||
apache3:
|
||||
when:
|
||||
- UnitFound("force-apache3")
|
||||
datasource:
|
||||
source: file
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache3
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --force-unit force-apache2
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{"type":"apache2"}},detected_service:"apache2"}]'
|
||||
|
||||
run -0 cscli setup detect --force-unit force-apache2,force-apache3
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"},{datasource:{source:"file",filename:"dummy.log",labels:{"type":"apache3"}},detected_service:"apache3"}]'
|
||||
|
||||
# force-unit can be specified multiple times, the order does not matter
|
||||
run -0 cscli setup detect --force-unit force-apache3 --force-unit force-apache2
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"},{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache3"}},detected_service:"apache3"}]'
|
||||
|
||||
run -1 --separate-stderr cscli setup detect --force-unit mock-doesnotexist
|
||||
assert_stderr --partial "detecting services: unit(s) forced but not supported: [mock-doesnotexist]"
|
||||
}
|
||||
|
||||
@test "cscli setup detect (process)" {
|
||||
# This is harder to mock, because gopsutil requires proc/ to be a mount
|
||||
# point. So we pick a process that exists for sure.
|
||||
expected_process=$(basename "$SHELL")
|
||||
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- ProcessRunning("${expected_process}")
|
||||
apache3:
|
||||
when:
|
||||
- ProcessRunning("this-does-not-exist")
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{detected_service:"apache2"}]'
|
||||
}
|
||||
|
||||
@test "cscli setup detect --force-process" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- ProcessRunning("force-apache2")
|
||||
apache3:
|
||||
when:
|
||||
- ProcessRunning("this-does-not-exist")
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --force-process force-apache2
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{detected_service:"apache2"}]'
|
||||
}
|
||||
|
||||
@test "cscli setup detect (acquisition only, no hub items)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- UnitFound("force-apache2")
|
||||
datasource:
|
||||
source: file
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache2
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --force-unit force-apache2
|
||||
run -0 jq -cS '.setup' <(output)
|
||||
assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"}]'
|
||||
|
||||
run -0 cscli setup detect --force-unit force-apache2 --yaml
|
||||
assert_output - <<-EOT
|
||||
setup:
|
||||
- detected_service: apache2
|
||||
datasource:
|
||||
filename: dummy.log
|
||||
labels:
|
||||
type: apache2
|
||||
source: file
|
||||
EOT
|
||||
}
|
||||
|
||||
@test "cscli setup detect (full acquisition section)" {
|
||||
skip "not supported yet"
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
foobar:
|
||||
datasource:
|
||||
filenames:
|
||||
- /path/to/log/*.log
|
||||
exclude_regexps:
|
||||
- ^/path/to/log/excludeme\.log$
|
||||
force_inotify: true
|
||||
mode: tail
|
||||
labels:
|
||||
type: foolog
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --yaml
|
||||
assert_output - <<-EOT
|
||||
setup:
|
||||
- detected_service: foobar
|
||||
datasource:
|
||||
filenames:
|
||||
- /path/to/log/*.log
|
||||
exclude_regexps:
|
||||
- ^/path/to/log/excludeme.log$
|
||||
force_inotify: true
|
||||
mode: tail
|
||||
labels:
|
||||
type: foolog
|
||||
EOT
|
||||
}
|
||||
|
||||
@test "cscli setup detect + acquis + install (no acquisition, no hub items)" {
|
||||
# no-op edge case, to make sure we don't crash
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
always:
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect
|
||||
assert_json '{setup:[{detected_service:"always"}]}'
|
||||
setup=$output
|
||||
run -0 cscli setup datasources /dev/stdin <<<"$setup"
|
||||
run -0 cscli setup install-hub /dev/stdin <<<"$setup"
|
||||
}
|
||||
|
||||
@test "cscli setup detect (with collections)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
foobar:
|
||||
when:
|
||||
- ProcessRunning("force-foobar")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/foobar
|
||||
qox:
|
||||
when:
|
||||
- ProcessRunning("test-qox")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/foobar
|
||||
apache2:
|
||||
when:
|
||||
- ProcessRunning("force-apache2")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --force-process force-apache2,force-foobar
|
||||
run -0 jq -Sc '.setup | sort' <(output)
|
||||
assert_json '[{install:{collections:["crowdsecurity/apache2"]},detected_service:"apache2"},{install:{collections:["crowdsecurity/foobar"]},detected_service:"foobar"}]'
|
||||
}
|
||||
|
||||
@test "cscli setup detect (with acquisition)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
foobar:
|
||||
when:
|
||||
- ProcessRunning("force-foobar")
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: foobar
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --force-process force-foobar
|
||||
run -0 yq -op '.setup | sort_keys(..)' <(output)
|
||||
assert_output - <<-EOT
|
||||
0.datasource.filenames.0 = /var/log/apache2/*.log
|
||||
0.datasource.filenames.1 = /var/log/*http*/*.log
|
||||
0.datasource.labels.type = foobar
|
||||
0.datasource.source = file
|
||||
0.detected_service = foobar
|
||||
EOT
|
||||
|
||||
run -1 --separate-stderr cscli setup detect --force-process mock-doesnotexist
|
||||
assert_stderr --partial "detecting services: process(es) forced but not supported: [mock-doesnotexist]"
|
||||
}
|
||||
|
||||
@test "cscli setup detect (datasource validation)" {
|
||||
cat <<-EOT >"${DETECT_YAML}"
|
||||
version: 1.0
|
||||
detect:
|
||||
foobar:
|
||||
datasource:
|
||||
labels:
|
||||
type: something
|
||||
EOT
|
||||
|
||||
run -1 --separate-stderr cscli setup detect
|
||||
assert_stderr --partial "detecting services: invalid datasource for foobar: source is empty"
|
||||
|
||||
# more datasource-specific tests are in detect_test.go
|
||||
}
|
||||
|
||||
@test "cscli setup install-hub (dry run)" {
|
||||
# it's not installed
|
||||
run -0 cscli collections list -o json
|
||||
run -0 jq -r '.collections[].name' <(output)
|
||||
refute_line "crowdsecurity/apache2"
|
||||
|
||||
# we install it
|
||||
run -0 --separate-stderr cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/apache2"]}}]}'
|
||||
assert_output 'dry-run: would install collection crowdsecurity/apache2'
|
||||
|
||||
# still not installed
|
||||
run -0 cscli collections list -o json
|
||||
run -0 jq -r '.collections[].name' <(output)
|
||||
refute_line "crowdsecurity/apache2"
|
||||
}
|
||||
|
||||
@test "cscli setup install-hub (dry run: install multiple collections)" {
|
||||
# it's not installed
|
||||
run -0 cscli collections list -o json
|
||||
run -0 jq -r '.collections[].name' <(output)
|
||||
refute_line "crowdsecurity/apache2"
|
||||
|
||||
# we install it
|
||||
run -0 --separate-stderr cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/apache2"]}}]}'
|
||||
assert_output 'dry-run: would install collection crowdsecurity/apache2'
|
||||
|
||||
# still not installed
|
||||
run -0 cscli collections list -o json
|
||||
run -0 jq -r '.collections[].name' <(output)
|
||||
refute_line "crowdsecurity/apache2"
|
||||
}
|
||||
|
||||
@test "cscli setup install-hub (dry run: install multiple collections, parsers, scenarios, postoverflows)" {
|
||||
run -0 --separate-stderr cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/foo","johndoe/bar"],"parsers":["crowdsecurity/fooparser","johndoe/barparser"],"scenarios":["crowdsecurity/fooscenario","johndoe/barscenario"],"postoverflows":["crowdsecurity/foopo","johndoe/barpo"]}}]}'
|
||||
assert_line 'dry-run: would install collection crowdsecurity/foo'
|
||||
assert_line 'dry-run: would install collection johndoe/bar'
|
||||
assert_line 'dry-run: would install parser crowdsecurity/fooparser'
|
||||
assert_line 'dry-run: would install parser johndoe/barparser'
|
||||
assert_line 'dry-run: would install scenario crowdsecurity/fooscenario'
|
||||
assert_line 'dry-run: would install scenario johndoe/barscenario'
|
||||
assert_line 'dry-run: would install postoverflow crowdsecurity/foopo'
|
||||
assert_line 'dry-run: would install postoverflow johndoe/barpo'
|
||||
}
|
||||
|
||||
@test "cscli setup datasources" {
|
||||
run -0 cscli setup datasources --help
|
||||
assert_line --partial "--to-dir string write the configuration to a directory, in multiple files"
|
||||
|
||||
# single item
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin <<-EOT
|
||||
setup:
|
||||
- datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
EOT
|
||||
|
||||
# remove diclaimer
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
labels:
|
||||
type: syslog
|
||||
source: file
|
||||
EOT
|
||||
|
||||
# multiple items
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin <<-EOT
|
||||
setup:
|
||||
- datasource:
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
- datasource:
|
||||
labels:
|
||||
type: foobar
|
||||
filenames:
|
||||
- /var/log/foobar/*.log
|
||||
- datasource:
|
||||
labels:
|
||||
type: barbaz
|
||||
filenames:
|
||||
- /path/to/barbaz.log
|
||||
EOT
|
||||
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
labels:
|
||||
type: syslog
|
||||
---
|
||||
filenames:
|
||||
- /var/log/foobar/*.log
|
||||
labels:
|
||||
type: foobar
|
||||
---
|
||||
filenames:
|
||||
- /path/to/barbaz.log
|
||||
labels:
|
||||
type: barbaz
|
||||
EOT
|
||||
|
||||
# multiple items, to a directory
|
||||
|
||||
# avoid the BATS_TEST_TMPDIR variable, it can have a double //
|
||||
acquisdir=$(TMPDIR="$BATS_FILE_TMPDIR" mktemp -u)
|
||||
mkdir "$acquisdir"
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin --to-dir "$acquisdir" <<-EOT
|
||||
setup:
|
||||
- detected_service: apache2
|
||||
datasource:
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
- detected_service: foobar
|
||||
datasource:
|
||||
labels:
|
||||
type: foobar
|
||||
filenames:
|
||||
- /var/log/foobar/*.log
|
||||
- detected_service: barbaz
|
||||
datasource:
|
||||
labels:
|
||||
type: barbaz
|
||||
filenames:
|
||||
- /path/to/barbaz.log
|
||||
EOT
|
||||
|
||||
# XXX what if detected_service is missing?
|
||||
|
||||
run -0 cat "${acquisdir}/setup.apache2.yaml"
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
labels:
|
||||
type: syslog
|
||||
EOT
|
||||
|
||||
run -0 cat "${acquisdir}/setup.foobar.yaml"
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /var/log/foobar/*.log
|
||||
labels:
|
||||
type: foobar
|
||||
EOT
|
||||
|
||||
run -0 cat "${acquisdir}/setup.barbaz.yaml"
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /path/to/barbaz.log
|
||||
labels:
|
||||
type: barbaz
|
||||
EOT
|
||||
|
||||
rm -rf -- "${acquisdir:?}"
|
||||
mkdir "$acquisdir"
|
||||
|
||||
# having both filenames and journalctl does not generate two files: the datasource is copied as-is, even if incorrect
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin --to-dir "$acquisdir" <<-EOT
|
||||
setup:
|
||||
- detected_service: apache2
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
labels:
|
||||
type: apache2
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
journalctl_filter:
|
||||
- _SYSTEMD_UNIT=apache2.service
|
||||
EOT
|
||||
|
||||
run -0 cat "${acquisdir}/setup.apache2.yaml"
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
journalctl_filter:
|
||||
- _SYSTEMD_UNIT=apache2.service
|
||||
labels:
|
||||
type: apache2
|
||||
EOT
|
||||
|
||||
# the directory must exist
|
||||
run -1 --separate-stderr cscli setup datasources /dev/stdin --to-dir /path/does/not/exist <<< '{}'
|
||||
assert_stderr --partial "directory /path/does/not/exist does not exist"
|
||||
|
||||
# of course it must be a directory
|
||||
|
||||
touch "${acquisdir}/notadir"
|
||||
|
||||
run -1 --separate-stderr cscli setup datasources /dev/stdin --to-dir "${acquisdir}/notadir" <<-EOT
|
||||
setup:
|
||||
- detected_service: apache2
|
||||
datasource:
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
EOT
|
||||
assert_stderr --partial "open ${acquisdir}/notadir/setup.apache2.yaml: not a directory"
|
||||
|
||||
rm -rf -- "${acquisdir:?}"
|
||||
}
|
||||
|
||||
@test "cscli setup datasources (disclaimer)" {
|
||||
disclaimer="This file was automatically generated"
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin <<<"setup:"
|
||||
run -0 yq 'head_comment' <(output)
|
||||
assert_output --partial "$disclaimer"
|
||||
|
||||
run -0 cscli setup datasources /dev/stdin <<-EOT
|
||||
setup:
|
||||
- detected_service: something
|
||||
datasource:
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/something.log
|
||||
EOT
|
||||
run -0 yq 'head_comment' <(output)
|
||||
assert_output --partial "$disclaimer"
|
||||
}
|
||||
|
||||
@test "cscli setup (custom journalctl filter)" {
|
||||
tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
|
||||
cat <<-EOT >"${tempfile}"
|
||||
version: 1.0
|
||||
detect:
|
||||
thewiz:
|
||||
when:
|
||||
- UnitFound("thewiz.service")
|
||||
datasource:
|
||||
source: journalctl
|
||||
labels:
|
||||
type: thewiz
|
||||
journalctl_filter:
|
||||
- "SYSLOG_IDENTIFIER=TheWiz"
|
||||
EOT
|
||||
|
||||
run -0 cscli setup detect --detect-config "$tempfile" --force-unit thewiz.service
|
||||
run -0 jq -cS '.' <(output)
|
||||
assert_json '{setup:[{datasource:{source:"journalctl",journalctl_filter:["SYSLOG_IDENTIFIER=TheWiz"],labels:{type:"thewiz"}},detected_service:"thewiz"}]}'
|
||||
run -0 cscli setup datasources <(output)
|
||||
run -0 yq '. head_comment=""' <(output)
|
||||
assert_output - <<-EOT
|
||||
journalctl_filter:
|
||||
- SYSLOG_IDENTIFIER=TheWiz
|
||||
labels:
|
||||
type: thewiz
|
||||
source: journalctl
|
||||
EOT
|
||||
|
||||
rm -f "$tempfile"
|
||||
}
|
||||
|
||||
@test "cscli setup validate" {
|
||||
# an empty file is not enough
|
||||
run -1 --separate-stderr cscli setup validate /dev/null
|
||||
assert_output "EOF"
|
||||
assert_stderr --partial "invalid setup file"
|
||||
|
||||
# this is ok; install nothing
|
||||
run -0 --separate-stderr cscli setup validate /dev/stdin <<-EOT
|
||||
setup:
|
||||
EOT
|
||||
refute_output
|
||||
refute_stderr
|
||||
|
||||
run -1 --separate-stderr cscli setup validate /dev/stdin <<-EOT
|
||||
se tup:
|
||||
EOT
|
||||
assert_output - <<-EOT
|
||||
[1:1] unknown field "se tup"
|
||||
> 1 | se tup:
|
||||
^
|
||||
EOT
|
||||
assert_stderr --partial "invalid setup file"
|
||||
|
||||
run -1 --separate-stderr cscli setup validate /dev/stdin <<-EOT
|
||||
setup:
|
||||
alsdk al; sdf
|
||||
EOT
|
||||
assert_output "while unmarshaling setup file: yaml: line 2: could not find expected ':'"
|
||||
assert_stderr --partial "invalid setup file"
|
||||
}
|
||||
|
88
tests/bats/testdata/07_setup/detect.yaml
vendored
Normal file
88
tests/bats/testdata/07_setup/detect.yaml
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
# TODO: windows, use_time_machine, event support (see https://hub.crowdsec.net/author/crowdsecurity/collections/iis)
|
||||
|
||||
---
|
||||
version: 1.0
|
||||
|
||||
detect:
|
||||
apache2:
|
||||
when:
|
||||
- ProcessRunning("apache2")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: apache2
|
||||
filenames:
|
||||
- /var/log/apache2/*.log
|
||||
- /var/log/*http*/*.log
|
||||
- /var/log/httpd/*.log
|
||||
|
||||
apache2-systemd:
|
||||
when:
|
||||
- UnitFound("apache2.service")
|
||||
- OS.ID != "centos"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: journalctl
|
||||
journalctl_filter:
|
||||
- "_SYSTEMD_UNIT=mock-apache2.service"
|
||||
labels:
|
||||
type: apache2
|
||||
|
||||
apache2-systemd-centos:
|
||||
when:
|
||||
- UnitFound("httpd.service")
|
||||
- OS.ID == "centos"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: journalctl
|
||||
journalctl_filter:
|
||||
- "_SYSTEMD_UNIT=httpd.service"
|
||||
|
||||
ssh-systemd:
|
||||
when:
|
||||
- UnitFound("ssh.service") or UnitFound("ssh.socket")
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/apache2
|
||||
datasource:
|
||||
source: journalctl
|
||||
journalctl_filter:
|
||||
- "_SYSTEMD_UNIT=ssh.service"
|
||||
labels:
|
||||
type: syslog
|
||||
|
||||
linux:
|
||||
when:
|
||||
- OS.Family == "linux"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/linux
|
||||
datasource:
|
||||
source: file
|
||||
labels:
|
||||
type: syslog
|
||||
filenames:
|
||||
- /var/log/syslog
|
||||
- /var/log/kern.log
|
||||
- /var/log/messages
|
||||
|
||||
freebsd:
|
||||
when:
|
||||
- OS.Family == "freebsd"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/freebsd
|
||||
|
||||
windows:
|
||||
when:
|
||||
- OS.Family == "windows"
|
||||
install:
|
||||
collections:
|
||||
- crowdsecurity/windows
|
|
@ -61,6 +61,9 @@ config_generate() {
|
|||
../config/online_api_credentials.yaml \
|
||||
"${CONFIG_DIR}/"
|
||||
|
||||
cp ../config/detect.yaml \
|
||||
"${HUB_DIR}"
|
||||
|
||||
# the default acquis file contains files that are not readable by everyone
|
||||
touch "$LOG_DIR/empty.log"
|
||||
cat <<-EOT >"$CONFIG_DIR/acquis.yaml"
|
||||
|
|
Loading…
Reference in a new issue