Refact cwhub / sort cscli output, case insensitive (#2593)
* dead code: unknown localVersion now defaults to "?" * skip type declaration; whitespace * sync: next item if invalid cpath * func tests for install --force and --ignore * shorter test names * sort cscli <itemtype> output, with tests * cscli: refact hub sort code
This commit is contained in:
parent
4a6fd338e0
commit
79d019f9a2
11 changed files with 205 additions and 76 deletions
|
@ -289,7 +289,7 @@ func itemsRemoveRunner(it hubItemType) func(cmd *cobra.Command, args []string) e
|
|||
|
||||
if all {
|
||||
getter := hub.GetInstalledItems
|
||||
if (purge) {
|
||||
if purge {
|
||||
getter = hub.GetAllItems
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
@ -15,7 +14,8 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]string, error) {
|
||||
// selectItems returns a slice of items of a given type, selected by name and sorted by case-insensitive name
|
||||
func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]*cwhub.Item, error) {
|
||||
itemNames := hub.GetItemNames(itemType)
|
||||
|
||||
notExist := []string{}
|
||||
|
@ -37,26 +37,32 @@ func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly b
|
|||
installedOnly = false
|
||||
}
|
||||
|
||||
if installedOnly {
|
||||
installed := []string{}
|
||||
for _, item := range itemNames {
|
||||
if hub.GetItem(itemType, item).Installed {
|
||||
installed = append(installed, item)
|
||||
}
|
||||
items := make([]*cwhub.Item, 0, len(itemNames))
|
||||
|
||||
for _, itemName := range itemNames {
|
||||
item := hub.GetItem(itemType, itemName)
|
||||
if installedOnly && !item.Installed {
|
||||
continue
|
||||
}
|
||||
return installed, nil
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
return itemNames, nil
|
||||
|
||||
cwhub.SortItemSlice(items)
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// XXX: too complex, should be two functions (itemtypes array and args are not used together)
|
||||
func ListItems(hub *cwhub.Hub, out io.Writer, itemTypes []string, args []string, showType bool, showHeader bool, all bool) error {
|
||||
items := make(map[string][]string)
|
||||
items := make(map[string][]*cwhub.Item)
|
||||
|
||||
for _, itemType := range itemTypes {
|
||||
selected, err := selectItems(hub, itemType, args, !all)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Strings(selected)
|
||||
|
||||
items[itemType] = selected
|
||||
}
|
||||
|
||||
|
@ -79,8 +85,8 @@ func ListItems(hub *cwhub.Hub, out io.Writer, itemTypes []string, args []string,
|
|||
for _, itemType := range itemTypes {
|
||||
// empty slice in case there are no items of this type
|
||||
hubStatus[itemType] = make([]itemHubStatus, len(items[itemType]))
|
||||
for i, itemName := range items[itemType] {
|
||||
item := hub.GetItem(itemType, itemName)
|
||||
|
||||
for i, item := range items[itemType] {
|
||||
status, emo := item.Status()
|
||||
hubStatus[itemType][i] = itemHubStatus{
|
||||
Name: item.Name,
|
||||
|
@ -110,13 +116,10 @@ func ListItems(hub *cwhub.Hub, out io.Writer, itemTypes []string, args []string,
|
|||
return fmt.Errorf("failed to write header: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, itemType := range itemTypes {
|
||||
for _, itemName := range items[itemType] {
|
||||
item := hub.GetItem(itemType, itemName)
|
||||
for _, item := range items[itemType] {
|
||||
status, _ := item.Status()
|
||||
if item.LocalVersion == "" {
|
||||
item.LocalVersion = "n/a"
|
||||
}
|
||||
row := []string{
|
||||
item.Name,
|
||||
status,
|
||||
|
|
|
@ -11,14 +11,13 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
func listHubItemTable(hub *cwhub.Hub, out io.Writer, title string, itemType string, itemNames []string) {
|
||||
func listHubItemTable(hub *cwhub.Hub, out io.Writer, title string, itemType string, items []*cwhub.Item) {
|
||||
t := newLightTable(out)
|
||||
t.SetHeaders("Name", fmt.Sprintf("%v Status", emoji.Package), "Version", "Local Path")
|
||||
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
|
||||
for itemName := range itemNames {
|
||||
item := hub.GetItem(itemType, itemNames[itemName])
|
||||
for _, item := range items {
|
||||
status, emo := item.Status()
|
||||
t.AddRow(item.Name, fmt.Sprintf("%v %s", emo, status), item.LocalVersion, item.LocalPath)
|
||||
}
|
||||
|
|
|
@ -60,15 +60,13 @@ func testHub(t *testing.T, update bool) *Hub {
|
|||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
var hub *Hub
|
||||
|
||||
remote := &RemoteHubCfg{
|
||||
Branch: "master",
|
||||
URLTemplate: mockURLTemplate,
|
||||
IndexPath: ".index.json",
|
||||
}
|
||||
|
||||
hub, err = NewHub(local, remote, update)
|
||||
hub, err := NewHub(local, remote, update)
|
||||
require.NoError(t, err)
|
||||
|
||||
return hub
|
||||
|
|
|
@ -89,6 +89,7 @@ func (i *Item) purge() error {
|
|||
log.Debugf("%s doesn't exist, no need to remove", itempath)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("while removing file: %w", err)
|
||||
}
|
||||
|
||||
|
@ -101,8 +102,6 @@ func (i *Item) purge() error {
|
|||
// disable removes the symlink to the downloaded content, also removes the content if purge is true
|
||||
func (i *Item) disable(purge bool, force bool) error {
|
||||
// XXX: should return the number of disabled/purged items to inform the upper layer whether to reload or not
|
||||
var err error
|
||||
|
||||
if i.IsLocal() {
|
||||
return fmt.Errorf("%s isn't managed by hub. Please delete manually", i.Name)
|
||||
}
|
||||
|
@ -124,7 +123,7 @@ func (i *Item) disable(purge bool, force bool) error {
|
|||
}
|
||||
|
||||
if removeSub {
|
||||
if err = sub.disable(purge, force); err != nil {
|
||||
if err := sub.disable(purge, force); err != nil {
|
||||
return fmt.Errorf("while disabling %s: %w", sub.Name, err)
|
||||
}
|
||||
} else {
|
||||
|
@ -170,7 +169,7 @@ func (i *Item) disable(purge bool, force bool) error {
|
|||
return fmt.Errorf("%s isn't managed by hub", i.Name)
|
||||
}
|
||||
|
||||
if err = os.Remove(syml); err != nil {
|
||||
if err := os.Remove(syml); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Debugf("%s doesn't exist, no need to remove", syml)
|
||||
return nil
|
||||
|
@ -184,7 +183,7 @@ func (i *Item) disable(purge bool, force bool) error {
|
|||
i.Installed = false
|
||||
|
||||
if purge {
|
||||
if err = i.purge(); err != nil {
|
||||
if err := i.purge(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package cwhub
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/enescakir/emoji"
|
||||
|
@ -291,6 +293,7 @@ func (h *Hub) GetAllItems(itemType string) ([]*Item, error) {
|
|||
ret := make([]*Item, len(items))
|
||||
|
||||
idx := 0
|
||||
|
||||
for _, item := range items {
|
||||
ret[idx] = item
|
||||
idx++
|
||||
|
@ -332,3 +335,10 @@ func (h *Hub) GetInstalledItemsAsString(itemType string) ([]string, error) {
|
|||
|
||||
return retStr, nil
|
||||
}
|
||||
|
||||
// SortItemSlice sorts a slice of items by name, case insensitive
|
||||
func SortItemSlice(items []*Item) {
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return strings.ToLower(items[i].Name) < strings.ToLower(items[j].Name)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -150,10 +150,8 @@ func sortedVersions(raw []string) ([]string, error) {
|
|||
}
|
||||
|
||||
func (h *Hub) itemVisit(path string, f os.DirEntry, err error) error {
|
||||
var (
|
||||
local bool
|
||||
hubpath string
|
||||
)
|
||||
local := false
|
||||
hubpath := ""
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("while syncing hub dir: %s", err)
|
||||
|
@ -398,6 +396,7 @@ func (h *Hub) syncDir(dir string) ([]string, error) {
|
|||
cpath, err := filepath.Abs(fmt.Sprintf("%s/%s", dir, scan))
|
||||
if err != nil {
|
||||
log.Errorf("failed %s: %s", cpath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// explicit check for non existing directory, avoid spamming log.Debug
|
||||
|
|
|
@ -79,7 +79,17 @@ teardown() {
|
|||
rune -0 grep -vc 'name,status,version,description' <(output)
|
||||
assert_output "$expected"
|
||||
|
||||
# XXX: check alphabetical order in human, json, raw
|
||||
# the list should be the same in all formats, and sorted (not case sensitive)
|
||||
|
||||
list_raw=$(cscli collections list -o raw -a | tail -n +2 | cut -d, -f1)
|
||||
list_human=$(cscli collections list -o human -a | tail -n +6 | head -n -1 | cut -d' ' -f2)
|
||||
list_json=$(cscli collections list -o json -a | jq -r '.collections[].name')
|
||||
|
||||
rune -0 sort -f <<<"$list_raw"
|
||||
assert_output "$list_raw"
|
||||
|
||||
assert_equal "$list_raw" "$list_json"
|
||||
assert_equal "$list_raw" "$list_human"
|
||||
}
|
||||
|
||||
@test "cscli collections list [collection]..." {
|
||||
|
@ -120,7 +130,7 @@ teardown() {
|
|||
assert_output "2"
|
||||
}
|
||||
|
||||
@test "cscli collections install [collection]..." {
|
||||
@test "cscli collections install" {
|
||||
rune -1 cscli collections install
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
|
||||
|
@ -148,8 +158,7 @@ teardown() {
|
|||
assert_output --partial 'installed: true'
|
||||
}
|
||||
|
||||
@test "cscli collections install [collection]... (file location and download-only)" {
|
||||
# simple install
|
||||
@test "cscli collections install (file location and download-only)" {
|
||||
rune -0 cscli collections install crowdsecurity/linux --download-only
|
||||
rune -0 cscli collections inspect crowdsecurity/linux --no-metrics
|
||||
assert_output --partial 'crowdsecurity/linux'
|
||||
|
@ -158,11 +167,34 @@ teardown() {
|
|||
assert_file_not_exists "$CONFIG_DIR/collections/linux.yaml"
|
||||
|
||||
rune -0 cscli collections install crowdsecurity/linux
|
||||
rune -0 cscli collections inspect crowdsecurity/linux --no-metrics
|
||||
assert_output --partial 'installed: true'
|
||||
assert_file_exists "$CONFIG_DIR/collections/linux.yaml"
|
||||
}
|
||||
|
||||
@test "cscli collections install --force (tainted)" {
|
||||
rune -0 cscli collections install crowdsecurity/sshd
|
||||
echo "dirty" >"$CONFIG_DIR/collections/sshd.yaml"
|
||||
|
||||
@test "cscli collections inspect [collection]..." {
|
||||
rune -1 cscli collections install crowdsecurity/sshd
|
||||
assert_stderr --partial "error while installing 'crowdsecurity/sshd': while enabling crowdsecurity/sshd: crowdsecurity/sshd is tainted, won't enable unless --force"
|
||||
|
||||
rune -0 cscli collections install crowdsecurity/sshd --force
|
||||
assert_stderr --partial "crowdsecurity/sshd: overwrite"
|
||||
assert_stderr --partial "Enabled crowdsecurity/sshd"
|
||||
}
|
||||
|
||||
@test "cscli collections install --ignore (skip on errors)" {
|
||||
rune -1 cscli collections install foo/bar crowdsecurity/sshd
|
||||
assert_stderr --partial "can't find 'foo/bar' in collections"
|
||||
refute_stderr --partial "Enabled collections: crowdsecurity/sshd"
|
||||
|
||||
rune -0 cscli collections install foo/bar crowdsecurity/sshd --ignore
|
||||
assert_stderr --partial "can't find 'foo/bar' in collections"
|
||||
assert_stderr --partial "Enabled collections: crowdsecurity/sshd"
|
||||
}
|
||||
|
||||
@test "cscli collections inspect" {
|
||||
rune -1 cscli collections inspect
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
# required for metrics
|
||||
|
@ -223,7 +255,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli collections remove [collection]..." {
|
||||
@test "cscli collections remove" {
|
||||
rune -1 cscli collections remove
|
||||
assert_stderr --partial "specify at least one collection to remove or '--all'"
|
||||
rune -1 cscli collections remove blahblah/blahblah
|
||||
|
@ -277,7 +309,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli collections remove [collections]... --force" {
|
||||
@test "cscli collections remove --force" {
|
||||
# remove a collections that belongs to a collection
|
||||
rune -0 cscli collections install crowdsecurity/linux
|
||||
rune -0 cscli collections remove crowdsecurity/sshd
|
||||
|
@ -285,7 +317,7 @@ teardown() {
|
|||
assert_stderr --partial "Run 'sudo cscli collections remove crowdsecurity/sshd --force' if you want to force remove this collection"
|
||||
}
|
||||
|
||||
@test "cscli collections upgrade [collection]..." {
|
||||
@test "cscli collections upgrade" {
|
||||
rune -1 cscli collections upgrade
|
||||
assert_stderr --partial "specify at least one collection to upgrade or '--all'"
|
||||
rune -1 cscli collections upgrade blahblah/blahblah
|
||||
|
|
|
@ -79,7 +79,17 @@ teardown() {
|
|||
rune -0 grep -vc 'name,status,version,description' <(output)
|
||||
assert_output "$expected"
|
||||
|
||||
# XXX: check alphabetical order in human, json, raw
|
||||
# the list should be the same in all formats, and sorted (not case sensitive)
|
||||
|
||||
list_raw=$(cscli parsers list -o raw -a | tail -n +2 | cut -d, -f1)
|
||||
list_human=$(cscli parsers list -o human -a | tail -n +6 | head -n -1 | cut -d' ' -f2)
|
||||
list_json=$(cscli parsers list -o json -a | jq -r '.parsers[].name')
|
||||
|
||||
rune -0 sort -f <<<"$list_raw"
|
||||
assert_output "$list_raw"
|
||||
|
||||
assert_equal "$list_raw" "$list_json"
|
||||
assert_equal "$list_raw" "$list_human"
|
||||
}
|
||||
|
||||
@test "cscli parsers list [parser]..." {
|
||||
|
@ -120,7 +130,7 @@ teardown() {
|
|||
assert_output "3"
|
||||
}
|
||||
|
||||
@test "cscli parsers install [parser]..." {
|
||||
@test "cscli parsers install" {
|
||||
rune -1 cscli parsers install
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
|
||||
|
@ -148,8 +158,7 @@ teardown() {
|
|||
assert_output --partial 'installed: true'
|
||||
}
|
||||
|
||||
@test "cscli parsers install [parser]... (file location and download-only)" {
|
||||
# simple install
|
||||
@test "cscli parsers install (file location and download-only)" {
|
||||
rune -0 cscli parsers install crowdsecurity/whitelists --download-only
|
||||
rune -0 cscli parsers inspect crowdsecurity/whitelists --no-metrics
|
||||
assert_output --partial 'crowdsecurity/whitelists'
|
||||
|
@ -158,13 +167,34 @@ teardown() {
|
|||
assert_file_not_exists "$CONFIG_DIR/parsers/s02-enrich/whitelists.yaml"
|
||||
|
||||
rune -0 cscli parsers install crowdsecurity/whitelists
|
||||
rune -0 cscli parsers inspect crowdsecurity/whitelists --no-metrics
|
||||
assert_output --partial 'installed: true'
|
||||
assert_file_exists "$CONFIG_DIR/parsers/s02-enrich/whitelists.yaml"
|
||||
}
|
||||
|
||||
# XXX: test install with --force
|
||||
# XXX: test install with --ignore
|
||||
@test "cscli parsers install --force (tainted)" {
|
||||
rune -0 cscli parsers install crowdsecurity/whitelists
|
||||
echo "dirty" >"$CONFIG_DIR/parsers/s02-enrich/whitelists.yaml"
|
||||
|
||||
@test "cscli parsers inspect [parser]..." {
|
||||
rune -1 cscli parsers install crowdsecurity/whitelists
|
||||
assert_stderr --partial "error while installing 'crowdsecurity/whitelists': while enabling crowdsecurity/whitelists: crowdsecurity/whitelists is tainted, won't enable unless --force"
|
||||
|
||||
rune -0 cscli parsers install crowdsecurity/whitelists --force
|
||||
assert_stderr --partial "crowdsecurity/whitelists: overwrite"
|
||||
assert_stderr --partial "Enabled crowdsecurity/whitelists"
|
||||
}
|
||||
|
||||
@test "cscli parsers install --ignore (skip on errors)" {
|
||||
rune -1 cscli parsers install foo/bar crowdsecurity/whitelists
|
||||
assert_stderr --partial "can't find 'foo/bar' in parsers"
|
||||
refute_stderr --partial "Enabled parsers: crowdsecurity/whitelists"
|
||||
|
||||
rune -0 cscli parsers install foo/bar crowdsecurity/whitelists --ignore
|
||||
assert_stderr --partial "can't find 'foo/bar' in parsers"
|
||||
assert_stderr --partial "Enabled parsers: crowdsecurity/whitelists"
|
||||
}
|
||||
|
||||
@test "cscli parsers inspect" {
|
||||
rune -1 cscli parsers inspect
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
# required for metrics
|
||||
|
@ -195,8 +225,8 @@ teardown() {
|
|||
# one item, raw
|
||||
rune -0 cscli parsers inspect crowdsecurity/sshd-logs -o raw
|
||||
assert_line 'type: parsers'
|
||||
assert_line 'stage: s01-parse'
|
||||
assert_line 'name: crowdsecurity/sshd-logs'
|
||||
assert_line 'stage: s01-parse'
|
||||
assert_line 'author: crowdsecurity'
|
||||
assert_line 'remote_path: parsers/s01-parse/crowdsecurity/sshd-logs.yaml'
|
||||
assert_line 'installed: false'
|
||||
|
@ -227,7 +257,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli parsers remove [parser]..." {
|
||||
@test "cscli parsers remove" {
|
||||
rune -1 cscli parsers remove
|
||||
assert_stderr --partial "specify at least one parser to remove or '--all'"
|
||||
rune -1 cscli parsers remove blahblah/blahblah
|
||||
|
@ -281,7 +311,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli parsers remove [parser]... --force" {
|
||||
@test "cscli parsers remove --force" {
|
||||
# remove a parser that belongs to a collection
|
||||
rune -0 cscli collections install crowdsecurity/sshd
|
||||
rune -0 cscli parsers remove crowdsecurity/sshd-logs
|
||||
|
@ -289,7 +319,7 @@ teardown() {
|
|||
assert_stderr --partial "Run 'sudo cscli parsers remove crowdsecurity/sshd-logs --force' if you want to force remove this parser"
|
||||
}
|
||||
|
||||
@test "cscli parsers upgrade [parser]..." {
|
||||
@test "cscli parsers upgrade" {
|
||||
rune -1 cscli parsers upgrade
|
||||
assert_stderr --partial "specify at least one parser to upgrade or '--all'"
|
||||
rune -1 cscli parsers upgrade blahblah/blahblah
|
||||
|
|
|
@ -79,15 +79,24 @@ teardown() {
|
|||
rune -0 grep -vc 'name,status,version,description' <(output)
|
||||
assert_output "$expected"
|
||||
|
||||
# XXX: check alphabetical order in human, json, raw
|
||||
# the list should be the same in all formats, and sorted (not case sensitive)
|
||||
|
||||
list_raw=$(cscli postoverflows list -o raw -a | tail -n +2 | cut -d, -f1)
|
||||
list_human=$(cscli postoverflows list -o human -a | tail -n +6 | head -n -1 | cut -d' ' -f2)
|
||||
list_json=$(cscli postoverflows list -o json -a | jq -r '.postoverflows[].name')
|
||||
|
||||
rune -0 sort -f <<<"$list_raw"
|
||||
assert_output "$list_raw"
|
||||
|
||||
assert_equal "$list_raw" "$list_json"
|
||||
assert_equal "$list_raw" "$list_human"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows list [scenario]..." {
|
||||
@test "cscli postoverflows list [postoverflow]..." {
|
||||
# non-existent
|
||||
rune -1 cscli postoverflows install foo/bar
|
||||
assert_stderr --partial "can't find 'foo/bar' in postoverflows"
|
||||
|
||||
|
||||
# not installed
|
||||
rune -0 cscli postoverflows list crowdsecurity/rdns
|
||||
assert_output --regexp 'crowdsecurity/rdns.*disabled'
|
||||
|
@ -121,7 +130,7 @@ teardown() {
|
|||
assert_output "3"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows install [scenario]..." {
|
||||
@test "cscli postoverflows install" {
|
||||
rune -1 cscli postoverflows install
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
|
||||
|
@ -149,8 +158,7 @@ teardown() {
|
|||
assert_output --partial 'installed: true'
|
||||
}
|
||||
|
||||
@test "cscli postoverflows install [postoverflow]... (file location and download-only)" {
|
||||
# simple install
|
||||
@test "cscli postoverflows install (file location and download-only)" {
|
||||
rune -0 cscli postoverflows install crowdsecurity/rdns --download-only
|
||||
rune -0 cscli postoverflows inspect crowdsecurity/rdns --no-metrics
|
||||
assert_output --partial 'crowdsecurity/rdns'
|
||||
|
@ -159,13 +167,34 @@ teardown() {
|
|||
assert_file_not_exists "$CONFIG_DIR/postoverflows/s00-enrich/rdns.yaml"
|
||||
|
||||
rune -0 cscli postoverflows install crowdsecurity/rdns
|
||||
rune -0 cscli postoverflows inspect crowdsecurity/rdns --no-metrics
|
||||
assert_output --partial 'installed: true'
|
||||
assert_file_exists "$CONFIG_DIR/postoverflows/s00-enrich/rdns.yaml"
|
||||
}
|
||||
|
||||
# XXX: test install with --force
|
||||
# XXX: test install with --ignore
|
||||
@test "cscli postoverflows install --force (tainted)" {
|
||||
rune -0 cscli postoverflows install crowdsecurity/rdns
|
||||
echo "dirty" >"$CONFIG_DIR/postoverflows/s00-enrich/rdns.yaml"
|
||||
|
||||
@test "cscli postoverflows inspect [scenario]..." {
|
||||
rune -1 cscli postoverflows install crowdsecurity/rdns
|
||||
assert_stderr --partial "error while installing 'crowdsecurity/rdns': while enabling crowdsecurity/rdns: crowdsecurity/rdns is tainted, won't enable unless --force"
|
||||
|
||||
rune -0 cscli postoverflows install crowdsecurity/rdns --force
|
||||
assert_stderr --partial "crowdsecurity/rdns: overwrite"
|
||||
assert_stderr --partial "Enabled crowdsecurity/rdns"
|
||||
}
|
||||
|
||||
@test "cscli postoverflow install --ignore (skip on errors)" {
|
||||
rune -1 cscli postoverflows install foo/bar crowdsecurity/rdns
|
||||
assert_stderr --partial "can't find 'foo/bar' in postoverflows"
|
||||
refute_stderr --partial "Enabled postoverflows: crowdsecurity/rdns"
|
||||
|
||||
rune -0 cscli postoverflows install foo/bar crowdsecurity/rdns --ignore
|
||||
assert_stderr --partial "can't find 'foo/bar' in postoverflows"
|
||||
assert_stderr --partial "Enabled postoverflows: crowdsecurity/rdns"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows inspect" {
|
||||
rune -1 cscli postoverflows inspect
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
# required for metrics
|
||||
|
@ -196,8 +225,8 @@ teardown() {
|
|||
# one item, raw
|
||||
rune -0 cscli postoverflows inspect crowdsecurity/rdns -o raw
|
||||
assert_line 'type: postoverflows'
|
||||
assert_line 'stage: s00-enrich'
|
||||
assert_line 'name: crowdsecurity/rdns'
|
||||
assert_line 'stage: s00-enrich'
|
||||
assert_line 'author: crowdsecurity'
|
||||
assert_line 'remote_path: postoverflows/s00-enrich/crowdsecurity/rdns.yaml'
|
||||
assert_line 'installed: false'
|
||||
|
@ -228,7 +257,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows remove [postoverflow]..." {
|
||||
@test "cscli postoverflows remove" {
|
||||
rune -1 cscli postoverflows remove
|
||||
assert_stderr --partial "specify at least one postoverflow to remove or '--all'"
|
||||
rune -1 cscli postoverflows remove blahblah/blahblah
|
||||
|
@ -282,7 +311,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows remove [postoverflow]... --force" {
|
||||
@test "cscli postoverflows remove --force" {
|
||||
# remove a postoverflow that belongs to a collection
|
||||
rune -0 cscli collections install crowdsecurity/auditd
|
||||
rune -0 cscli postoverflows remove crowdsecurity/auditd-whitelisted-process
|
||||
|
@ -290,7 +319,7 @@ teardown() {
|
|||
assert_stderr --partial "Run 'sudo cscli postoverflows remove crowdsecurity/auditd-whitelisted-process --force' if you want to force remove this postoverflow"
|
||||
}
|
||||
|
||||
@test "cscli postoverflows upgrade [postoverflow]..." {
|
||||
@test "cscli postoverflows upgrade" {
|
||||
rune -1 cscli postoverflows upgrade
|
||||
assert_stderr --partial "specify at least one postoverflow to upgrade or '--all'"
|
||||
rune -1 cscli postoverflows upgrade blahblah/blahblah
|
||||
|
|
|
@ -79,7 +79,17 @@ teardown() {
|
|||
rune -0 grep -vc 'name,status,version,description' <(output)
|
||||
assert_output "$expected"
|
||||
|
||||
# XXX: check alphabetical order in human, json, raw
|
||||
# the list should be the same in all formats, and sorted (not case sensitive)
|
||||
|
||||
list_raw=$(cscli scenarios list -o raw -a | tail -n +2 | cut -d, -f1)
|
||||
list_human=$(cscli scenarios list -o human -a | tail -n +6 | head -n -1 | cut -d' ' -f2)
|
||||
list_json=$(cscli scenarios list -o json -a | jq -r '.scenarios[].name')
|
||||
|
||||
rune -0 sort -f <<<"$list_raw"
|
||||
assert_output "$list_raw"
|
||||
|
||||
assert_equal "$list_raw" "$list_json"
|
||||
assert_equal "$list_raw" "$list_human"
|
||||
}
|
||||
|
||||
@test "cscli scenarios list [scenario]..." {
|
||||
|
@ -120,7 +130,7 @@ teardown() {
|
|||
assert_output "3"
|
||||
}
|
||||
|
||||
@test "cscli scenarios install [scenario]..." {
|
||||
@test "cscli scenarios install" {
|
||||
rune -1 cscli scenarios install
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
|
||||
|
@ -148,7 +158,7 @@ teardown() {
|
|||
assert_output --partial 'installed: true'
|
||||
}
|
||||
|
||||
@test "cscli scenarios install [scenario]... (file location and download-only)" {
|
||||
@test "cscli scenarios install (file location and download-only)" {
|
||||
# simple install
|
||||
rune -0 cscli scenarios install crowdsecurity/ssh-bf --download-only
|
||||
rune -0 cscli scenarios inspect crowdsecurity/ssh-bf --no-metrics
|
||||
|
@ -158,14 +168,34 @@ teardown() {
|
|||
assert_file_not_exists "$CONFIG_DIR/scenarios/ssh-bf.yaml"
|
||||
|
||||
rune -0 cscli scenarios install crowdsecurity/ssh-bf
|
||||
rune -0 cscli scenarios inspect crowdsecurity/ssh-bf --no-metrics
|
||||
assert_output --partial 'installed: true'
|
||||
assert_file_exists "$CONFIG_DIR/scenarios/ssh-bf.yaml"
|
||||
}
|
||||
|
||||
# XXX: test install with --force
|
||||
# XXX: test install with --ignore
|
||||
@test "cscli scenarios install --force (tainted)" {
|
||||
rune -0 cscli scenarios install crowdsecurity/ssh-bf
|
||||
echo "dirty" >"$CONFIG_DIR/scenarios/ssh-bf.yaml"
|
||||
|
||||
rune -1 cscli scenarios install crowdsecurity/ssh-bf
|
||||
assert_stderr --partial "error while installing 'crowdsecurity/ssh-bf': while enabling crowdsecurity/ssh-bf: crowdsecurity/ssh-bf is tainted, won't enable unless --force"
|
||||
|
||||
@test "cscli scenarios inspect [scenario]..." {
|
||||
rune -0 cscli scenarios install crowdsecurity/ssh-bf --force
|
||||
assert_stderr --partial "crowdsecurity/ssh-bf: overwrite"
|
||||
assert_stderr --partial "Enabled crowdsecurity/ssh-bf"
|
||||
}
|
||||
|
||||
@test "cscli scenarios install --ignore (skip on errors)" {
|
||||
rune -1 cscli scenarios install foo/bar crowdsecurity/ssh-bf
|
||||
assert_stderr --partial "can't find 'foo/bar' in scenarios"
|
||||
refute_stderr --partial "Enabled scenarios: crowdsecurity/ssh-bf"
|
||||
|
||||
rune -0 cscli scenarios install foo/bar crowdsecurity/ssh-bf --ignore
|
||||
assert_stderr --partial "can't find 'foo/bar' in scenarios"
|
||||
assert_stderr --partial "Enabled scenarios: crowdsecurity/ssh-bf"
|
||||
}
|
||||
|
||||
@test "cscli scenarios inspect" {
|
||||
rune -1 cscli scenarios inspect
|
||||
assert_stderr --partial 'requires at least 1 arg(s), only received 0'
|
||||
# required for metrics
|
||||
|
@ -226,7 +256,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli scenarios remove [scenario]..." {
|
||||
@test "cscli scenarios remove" {
|
||||
rune -1 cscli scenarios remove
|
||||
assert_stderr --partial "specify at least one scenario to remove or '--all'"
|
||||
rune -1 cscli scenarios remove blahblah/blahblah
|
||||
|
@ -280,7 +310,7 @@ teardown() {
|
|||
assert_output "0"
|
||||
}
|
||||
|
||||
@test "cscli scenarios remove [scenario]... --force" {
|
||||
@test "cscli scenarios remove --force" {
|
||||
# remove a scenario that belongs to a collection
|
||||
rune -0 cscli collections install crowdsecurity/sshd
|
||||
rune -0 cscli scenarios remove crowdsecurity/ssh-bf
|
||||
|
@ -288,7 +318,7 @@ teardown() {
|
|||
assert_stderr --partial "Run 'sudo cscli scenarios remove crowdsecurity/ssh-bf --force' if you want to force remove this scenario"
|
||||
}
|
||||
|
||||
@test "cscli scenarios upgrade [scenario]..." {
|
||||
@test "cscli scenarios upgrade" {
|
||||
rune -1 cscli scenarios upgrade
|
||||
assert_stderr --partial "specify at least one scenario to upgrade or '--all'"
|
||||
rune -1 cscli scenarios upgrade blahblah/blahblah
|
||||
|
|
Loading…
Reference in a new issue