cscli setup
This commit is contained in:
parent
409721414b
commit
79276bda95
|
@ -182,6 +182,9 @@ linters:
|
||||||
|
|
||||||
|
|
||||||
issues:
|
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-issues-per-linter: 0
|
||||||
max-same-issues: 10
|
max-same-issues: 10
|
||||||
exclude-rules:
|
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(NewHubTestCmd())
|
||||||
rootCmd.AddCommand(NewNotificationsCmd())
|
rootCmd.AddCommand(NewNotificationsCmd())
|
||||||
rootCmd.AddCommand(NewSupportCmd())
|
rootCmd.AddCommand(NewSupportCmd())
|
||||||
|
rootCmd.AddCommand(NewSetupCmd())
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
if bincoverTesting != "" {
|
if bincoverTesting != "" {
|
||||||
log.Debug("coverage report is enabled")
|
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
|
COLLECTIONS=false
|
||||||
set -e
|
set -e
|
||||||
|
@ -7,11 +7,11 @@ set -e
|
||||||
. /usr/share/debconf/confmodule
|
. /usr/share/debconf/confmodule
|
||||||
|
|
||||||
if [ "$1" = configure ]; then
|
if [ "$1" = configure ]; then
|
||||||
if [[ ! -d /var/lib/crowdsec/data ]]; then
|
if [ ! -d /var/lib/crowdsec/data ]; then
|
||||||
mkdir -p /var/lib/crowdsec/data
|
mkdir -p /var/lib/crowdsec/data
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -d /var/lib/crowdsec/backup ]]; then
|
if [ -d /var/lib/crowdsec/backup ]; then
|
||||||
cscli config restore /var/lib/crowdsec/backup/backup.config
|
cscli config restore /var/lib/crowdsec/backup/backup.config
|
||||||
rm -rf /var/lib/crowdsec/backup
|
rm -rf /var/lib/crowdsec/backup
|
||||||
/usr/bin/cscli hub update
|
/usr/bin/cscli hub update
|
||||||
|
@ -19,29 +19,27 @@ if [ "$1" = configure ]; then
|
||||||
systemctl start crowdsec
|
systemctl start crowdsec
|
||||||
fi
|
fi
|
||||||
|
|
||||||
. /usr/share/crowdsec/wizard.sh -n
|
if ! find /etc/crowdsec/acquis.d -maxdepth 1 -type f -name '*' 2>/dev/null | grep -q '.'; then
|
||||||
if ! [[ -f /etc/crowdsec/acquis.yaml ]]; then
|
echo Creating /etc/crowdsec/acquis.d
|
||||||
echo Creating /etc/crowdsec/acquis.yaml
|
mkdir -p /etc/crowdsec/acquis.d
|
||||||
set +e
|
cscli setup detect >/etc/crowdsec/.setup.yaml
|
||||||
SILENT=true detect_services
|
cscli setup install-hub /etc/crowdsec/.setup.yaml
|
||||||
SILENT=true TMP_ACQUIS_FILE_SKIP=skip genacquisition
|
cscli setup datasources /etc/crowdsec/.setup.yaml --to-dir /etc/crowdsec/acquis.d
|
||||||
set -e
|
|
||||||
COLLECTIONS=true
|
|
||||||
fi
|
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
|
chmod 600 /etc/crowdsec/local_api_credentials.yaml
|
||||||
fi
|
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
|
chmod 600 /etc/crowdsec/online_api_credentials.yaml
|
||||||
fi
|
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 ] || [ ! -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 ] ; then
|
||||||
install -m 600 /dev/null /etc/crowdsec/local_api_credentials.yaml
|
install -m 600 /dev/null /etc/crowdsec/local_api_credentials.yaml
|
||||||
fi
|
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
|
install -m 600 /dev/null /etc/crowdsec/online_api_credentials.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -130,6 +130,7 @@ require (
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/k0kubun/pp v3.0.1+incompatible // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/klauspost/compress v1.15.7 // indirect
|
github.com/klauspost/compress v1.15.7 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -595,6 +595,8 @@ github.com/jszwec/csvutil v1.5.1/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4Yc
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
|
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
|
||||||
|
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
|
||||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
|
|
|
@ -134,6 +134,7 @@ func GetItemMap(itemType string) map[string]Item {
|
||||||
var m map[string]Item
|
var m map[string]Item
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
|
log.Tracef("hubIdx: %v", hubIdx)
|
||||||
if m, ok = hubIdx[itemType]; !ok {
|
if m, ok = hubIdx[itemType]; !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -178,6 +179,7 @@ func GetItemByPath(itemType string, itemPath string) (*Item, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetItem(itemType string, itemName string) *Item {
|
func GetItem(itemType string, itemName string) *Item {
|
||||||
|
log.Tracef("getting hub item %s: %s", itemType, itemName)
|
||||||
if m, ok := GetItemMap(itemType)[itemName]; ok {
|
if m, ok := GetItemMap(itemType)[itemName]; ok {
|
||||||
return &m
|
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"
|
BASE="./tests"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage:"
|
echo "Usage:"
|
||||||
echo " ./wizard.sh -h Display this help message."
|
echo " $0 -h Display this help message."
|
||||||
echo " ./test_env.sh -d ./tests Create test environment in './tests' folder"
|
echo " $0 -d ./tests Create test environment in './tests' folder"
|
||||||
exit 0
|
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
|
do
|
||||||
key="${1}"
|
key="${1}"
|
||||||
case ${key} in
|
case ${key} in
|
||||||
-d|--directory)
|
-d|--directory)
|
||||||
BASE=${2}
|
shift
|
||||||
shift #past argument
|
BASE=$1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
|
@ -31,7 +75,7 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
BASE=$(realpath $BASE)
|
BASE=$(realpath "$BASE")
|
||||||
|
|
||||||
DATA_DIR="$BASE/data"
|
DATA_DIR="$BASE/data"
|
||||||
|
|
||||||
|
@ -51,13 +95,8 @@ PLUGINS="http slack splunk email"
|
||||||
PLUGINS_DIR="plugins"
|
PLUGINS_DIR="plugins"
|
||||||
NOTIF_DIR="notifications"
|
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 "$BASE"
|
||||||
mkdir -p "$DATA_DIR"
|
mkdir -p "$DATA_DIR"
|
||||||
mkdir -p "$LOG_DIR"
|
mkdir -p "$LOG_DIR"
|
||||||
|
@ -83,38 +122,37 @@ copy_files() {
|
||||||
cp "./config/acquis.yaml" "$CONFIG_DIR"
|
cp "./config/acquis.yaml" "$CONFIG_DIR"
|
||||||
touch "$CONFIG_DIR"/local_api_credentials.yaml
|
touch "$CONFIG_DIR"/local_api_credentials.yaml
|
||||||
touch "$CONFIG_DIR"/online_api_credentials.yaml
|
touch "$CONFIG_DIR"/online_api_credentials.yaml
|
||||||
envsubst < "./config/dev.yaml" > $BASE/dev.yaml
|
envsubst < "./config/dev.yaml" > "$BASE/dev.yaml"
|
||||||
for plugin in $PLUGINS
|
for plugin in $PLUGINS; do
|
||||||
do
|
cp "$PLUGINS_DIR/$NOTIF_DIR/$plugin/notification-$plugin" "$BASE/$PLUGINS_DIR/notification-$plugin"
|
||||||
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"
|
||||||
cp $PLUGINS_DIR/$NOTIF_DIR/$plugin/$plugin.yaml $CONFIG_DIR/$NOTIF_DIR/$plugin.yaml
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
$BASE/cscli -c "$CONFIG_FILE" hub update
|
"$BASE/cscli" -c "$CONFIG_FILE" hub update
|
||||||
$BASE/cscli -c "$CONFIG_FILE" collections install crowdsecurity/linux
|
"$BASE/cscli" -c "$CONFIG_FILE" collections install crowdsecurity/linux
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_api() {
|
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() {
|
main() {
|
||||||
log_info "Creating test arboresence in $BASE"
|
log_info "Creating directory tree in $BASE"
|
||||||
create_arbo
|
create_tree
|
||||||
log_info "Arboresence created"
|
log_info "Directory tree created"
|
||||||
log_info "Copying needed files for tests environment"
|
log_info "Copying needed files for tests environment"
|
||||||
copy_files
|
copy_files
|
||||||
log_info "Files copied"
|
log_info "Files copied"
|
||||||
log_info "Setting up configurations"
|
log_info "Setting up configurations"
|
||||||
CURRENT_PWD=$(pwd)
|
CURRENT_PWD=$(pwd)
|
||||||
cd $BASE
|
cd "$BASE"
|
||||||
setup_api
|
setup_api
|
||||||
setup
|
setup
|
||||||
cd $CURRENT_PWD
|
cd "$CURRENT_PWD"
|
||||||
log_info "Environment is ready in $BASE"
|
log_info "Environment is ready in $BASE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ roles:
|
||||||
- src: https://github.com/crowdsecurity/ansible-role-postgresql
|
- src: https://github.com/crowdsecurity/ansible-role-postgresql
|
||||||
version: crowdsec
|
version: crowdsec
|
||||||
name: geerlingguy.postgresql
|
name: geerlingguy.postgresql
|
||||||
|
# these should be included as dependencies of crowdsecurity.testing, but sometime are not
|
||||||
|
- src: geerlingguy.repo-epel
|
||||||
|
- src: gantsign.golang
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- name: https://github.com/crowdsecurity/ansible-collection-crowdsecurity.testing.git
|
- name: https://github.com/crowdsecurity/ansible-collection-crowdsecurity.testing.git
|
||||||
|
|
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/online_api_credentials.yaml \
|
||||||
"${CONFIG_DIR}/"
|
"${CONFIG_DIR}/"
|
||||||
|
|
||||||
|
cp ../config/detect.yaml \
|
||||||
|
"${HUB_DIR}"
|
||||||
|
|
||||||
# the default acquis file contains files that are not readable by everyone
|
# the default acquis file contains files that are not readable by everyone
|
||||||
touch "$LOG_DIR/empty.log"
|
touch "$LOG_DIR/empty.log"
|
||||||
cat <<-EOT >"$CONFIG_DIR/acquis.yaml"
|
cat <<-EOT >"$CONFIG_DIR/acquis.yaml"
|
||||||
|
|
Loading…
Reference in a new issue