merge hub-1.5.6
This commit is contained in:
commit
15120a6d8f
47 changed files with 713 additions and 559 deletions
|
@ -151,11 +151,12 @@ func NewCapiStatusCmd() *cobra.Command {
|
|||
return fmt.Errorf("parsing api url ('%s'): %w", csConfig.API.Server.OnlineClient.Credentials.URL, err)
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scenarios, err := cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
scenarios, err := hub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get scenarios: %w", err)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ cscli collections remove crowdsecurity/http-cve crowdsecurity/iptables
|
|||
Aliases: []string{"collection"},
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,13 @@ func runCollectionsInstall(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range args {
|
||||
t := cwhub.GetItem(cwhub.COLLECTIONS, name)
|
||||
t := hub.GetItem(cwhub.COLLECTIONS, name)
|
||||
if t == nil {
|
||||
nearestItem, score := GetDistance(cwhub.COLLECTIONS, name)
|
||||
Suggest(cwhub.COLLECTIONS, name, nearestItem.Name, score, ignoreError)
|
||||
|
@ -75,7 +80,7 @@ func runCollectionsInstall(cmd *cobra.Command, args []string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, name, cwhub.COLLECTIONS, force, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(name, cwhub.COLLECTIONS, force, downloadOnly); err != nil {
|
||||
if !ignoreError {
|
||||
return fmt.Errorf("error while installing '%s': %w", name, err)
|
||||
}
|
||||
|
@ -126,8 +131,13 @@ func runCollectionsRemove(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.COLLECTIONS, "", all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.COLLECTIONS, "", all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -141,7 +151,7 @@ func runCollectionsRemove(cmd *cobra.Command, args []string) error {
|
|||
|
||||
for _, name := range args {
|
||||
if !force {
|
||||
item := cwhub.GetItem(cwhub.COLLECTIONS, name)
|
||||
item := hub.GetItem(cwhub.COLLECTIONS, name)
|
||||
if item == nil {
|
||||
// XXX: this should be in GetItem?
|
||||
return fmt.Errorf("can't find '%s' in %s", name, cwhub.COLLECTIONS)
|
||||
|
@ -153,7 +163,7 @@ func runCollectionsRemove(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.COLLECTIONS, name, all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.COLLECTIONS, name, all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -197,8 +207,13 @@ func runCollectionsUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.COLLECTIONS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.COLLECTIONS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -209,7 +224,7 @@ func runCollectionsUpgrade(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.COLLECTIONS, name, force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.COLLECTIONS, name, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||
)
|
||||
|
||||
func backupHub(dirPath string) error {
|
||||
func backupHub(hub *cwhub.Hub, dirPath string) error {
|
||||
var err error
|
||||
var itemDirectory string
|
||||
var upstreamParsers []string
|
||||
|
@ -22,7 +22,7 @@ func backupHub(dirPath string) error {
|
|||
clog := log.WithFields(log.Fields{
|
||||
"type": itemType,
|
||||
})
|
||||
itemMap := cwhub.GetItemMap(itemType)
|
||||
itemMap := hub.GetItemMap(itemType)
|
||||
if itemMap == nil {
|
||||
clog.Infof("No %s to backup.", itemType)
|
||||
continue
|
||||
|
@ -189,7 +189,12 @@ func backupConfigToDirectory(dirPath string) error {
|
|||
log.Infof("Saved profiles to %s", backupProfiles)
|
||||
}
|
||||
|
||||
if err = backupHub(dirPath); err != nil {
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = backupHub(hub, dirPath); err != nil {
|
||||
return fmt.Errorf("failed to backup hub config: %s", err)
|
||||
}
|
||||
|
||||
|
@ -197,7 +202,7 @@ func backupConfigToDirectory(dirPath string) error {
|
|||
}
|
||||
|
||||
func runConfigBackup(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -23,23 +23,28 @@ type OldAPICfg struct {
|
|||
|
||||
// it's a rip of the cli version, but in silent-mode
|
||||
func silentInstallItem(name string, obtype string) (string, error) {
|
||||
var item = cwhub.GetItem(obtype, name)
|
||||
if item == nil {
|
||||
return "", fmt.Errorf("error retrieving item")
|
||||
}
|
||||
err := cwhub.DownloadLatest(csConfig.Hub, item, false, false)
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error while downloading %s : %v", item.Name, err)
|
||||
}
|
||||
if err := cwhub.AddItem(obtype, *item); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = cwhub.EnableItem(csConfig.Hub, item)
|
||||
var item = hub.GetItem(obtype, name)
|
||||
if item == nil {
|
||||
return "", fmt.Errorf("error retrieving item")
|
||||
}
|
||||
err = hub.DownloadLatest(item, false, false)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error while downloading %s : %v", item.Name, err)
|
||||
}
|
||||
if err := hub.AddItem(obtype, *item); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = hub.EnableItem(item)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error while enabling %s : %v", item.Name, err)
|
||||
}
|
||||
if err := cwhub.AddItem(obtype, *item); err != nil {
|
||||
if err := hub.AddItem(obtype, *item); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("Enabled %s", item.Name), nil
|
||||
|
@ -292,7 +297,7 @@ func runConfigRestore(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ Crowdsec{{if and .Crowdsec.Enable (not (ValueBool .Crowdsec.Enable))}} (disabled
|
|||
cscli:
|
||||
- Output : {{.Cscli.Output}}
|
||||
- Hub Branch : {{.Cscli.HubBranch}}
|
||||
- Hub Folder : {{.Cscli.HubDir}}
|
||||
{{- end }}
|
||||
|
||||
{{- if .API }}
|
||||
|
|
|
@ -71,11 +71,12 @@ After running this command your will need to validate the enrollment in the weba
|
|||
return fmt.Errorf("could not parse CAPI URL: %s", err)
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scenarios, err := cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
scenarios, err := hub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get installed scenarios: %s", err)
|
||||
}
|
||||
|
|
|
@ -50,12 +50,13 @@ func runHubList(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err = require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// use LocalSync to get warnings about tainted / outdated items
|
||||
warn, _ := cwhub.LocalSync(csConfig.Hub)
|
||||
warn, _ := hub.LocalSync()
|
||||
for _, v := range warn {
|
||||
log.Info(v)
|
||||
}
|
||||
|
@ -88,19 +89,24 @@ func NewHubListCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
func runHubUpdate(cmd *cobra.Command, args []string) error {
|
||||
if err := cwhub.UpdateHubIdx(csConfig.Hub); err != nil {
|
||||
cwhub.SetHubBranch()
|
||||
|
||||
// don't use require.Hub because if there is no index file, it would fail
|
||||
|
||||
hub, err := cwhub.InitHubUpdate(csConfig.Hub)
|
||||
if err != nil {
|
||||
if !errors.Is(err, cwhub.ErrIndexNotFound) {
|
||||
return fmt.Errorf("failed to get Hub index : %w", err)
|
||||
}
|
||||
log.Warnf("Could not find index file for branch '%s', using 'master'", cwhub.HubBranch)
|
||||
cwhub.HubBranch = "master"
|
||||
if err := cwhub.UpdateHubIdx(csConfig.Hub); err != nil {
|
||||
if hub, err = cwhub.InitHubUpdate(csConfig.Hub); err != nil {
|
||||
return fmt.Errorf("failed to get Hub index after retry: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// use LocalSync to get warnings about tainted / outdated items
|
||||
warn, _ := cwhub.LocalSync(csConfig.Hub)
|
||||
warn, _ := hub.LocalSync()
|
||||
for _, v := range warn {
|
||||
log.Info(v)
|
||||
}
|
||||
|
@ -122,8 +128,6 @@ Fetches the [.index.json](https://github.com/crowdsecurity/hub/blob/master/.inde
|
|||
return fmt.Errorf("you must configure cli before interacting with hub")
|
||||
}
|
||||
|
||||
cwhub.SetHubBranch()
|
||||
|
||||
return nil
|
||||
},
|
||||
RunE: runHubUpdate,
|
||||
|
@ -140,27 +144,28 @@ func runHubUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Upgrading collections")
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.COLLECTIONS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.COLLECTIONS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Upgrading parsers")
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.PARSERS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.PARSERS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Upgrading scenarios")
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.SCENARIOS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.SCENARIOS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Upgrading postoverflows")
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.POSTOVERFLOWS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.POSTOVERFLOWS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
func ShowMetrics(hubItem *cwhub.Item) {
|
||||
func ShowMetrics(hub *cwhub.Hub, hubItem *cwhub.Item) {
|
||||
switch hubItem.Type {
|
||||
case cwhub.PARSERS:
|
||||
metrics := GetParserMetric(csConfig.Cscli.PrometheusUrl, hubItem.Name)
|
||||
|
@ -36,11 +36,11 @@ func ShowMetrics(hubItem *cwhub.Item) {
|
|||
scenarioMetricsTable(color.Output, item, metrics)
|
||||
}
|
||||
for _, item := range hubItem.Collections {
|
||||
hubItem = cwhub.GetItem(cwhub.COLLECTIONS, item)
|
||||
hubItem = hub.GetItem(cwhub.COLLECTIONS, item)
|
||||
if hubItem == nil {
|
||||
log.Fatalf("unable to retrieve item '%s' from collection '%s'", item, hubItem.Name)
|
||||
}
|
||||
ShowMetrics(hubItem)
|
||||
ShowMetrics(hub, hubItem)
|
||||
}
|
||||
case cwhub.WAAP_RULES:
|
||||
log.Fatalf("FIXME: not implemented yet")
|
||||
|
|
|
@ -33,7 +33,11 @@ func GetDistance(itemType string, itemName string) (*cwhub.Item, int) {
|
|||
allItems := make([]string, 0)
|
||||
nearestScore := 100
|
||||
nearestItem := &cwhub.Item{}
|
||||
hubItems := cwhub.GetItemMap(itemType)
|
||||
|
||||
// XXX: handle error
|
||||
hub, _ := cwhub.GetHub()
|
||||
|
||||
hubItems := hub.GetItemMap(itemType)
|
||||
for _, item := range hubItems {
|
||||
allItems = append(allItems, item.Name)
|
||||
}
|
||||
|
@ -42,19 +46,20 @@ func GetDistance(itemType string, itemName string) (*cwhub.Item, int) {
|
|||
d := levenshtein.Distance(itemName, s, nil)
|
||||
if d < nearestScore {
|
||||
nearestScore = d
|
||||
nearestItem = cwhub.GetItem(itemType, s)
|
||||
nearestItem = hub.GetItem(itemType, s)
|
||||
}
|
||||
}
|
||||
return nearestItem, nearestScore
|
||||
}
|
||||
|
||||
func compAllItems(itemType string, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
|
||||
comp := make([]string, 0)
|
||||
hubItems := cwhub.GetItemMap(itemType)
|
||||
hubItems := hub.GetItemMap(itemType)
|
||||
for _, item := range hubItems {
|
||||
if !slices.Contains(args, item.Name) && strings.Contains(item.Name, toComplete) {
|
||||
comp = append(comp, item.Name)
|
||||
|
@ -65,11 +70,12 @@ func compAllItems(itemType string, args []string, toComplete string) ([]string,
|
|||
}
|
||||
|
||||
func compInstalledItems(itemType string, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
|
||||
items, err := cwhub.GetInstalledItemsAsString(itemType)
|
||||
items, err := hub.GetInstalledItemsAsString(itemType)
|
||||
if err != nil {
|
||||
cobra.CompDebugln(fmt.Sprintf("list installed %s err: %s", itemType, err), true)
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
|
|
|
@ -16,8 +16,8 @@ import (
|
|||
)
|
||||
|
||||
|
||||
func selectItems(itemType string, args []string, installedOnly bool) ([]string, error) {
|
||||
itemNames := cwhub.GetItemNames(itemType)
|
||||
func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]string, error) {
|
||||
itemNames := hub.GetItemNames(itemType)
|
||||
|
||||
notExist := []string{}
|
||||
if len(args) > 0 {
|
||||
|
@ -40,7 +40,7 @@ func selectItems(itemType string, args []string, installedOnly bool) ([]string,
|
|||
if installedOnly {
|
||||
installed := []string{}
|
||||
for _, item := range itemNames {
|
||||
if cwhub.GetItem(itemType, item).Installed {
|
||||
if hub.GetItem(itemType, item).Installed {
|
||||
installed = append(installed, item)
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +52,15 @@ func selectItems(itemType string, args []string, installedOnly bool) ([]string,
|
|||
|
||||
func ListItems(out io.Writer, itemTypes []string, args []string, showType bool, showHeader bool, all bool) error {
|
||||
var err error
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
items := make(map[string][]string)
|
||||
for _, itemType := range itemTypes {
|
||||
if items[itemType], err = selectItems(itemType, args, !all); err != nil {
|
||||
if items[itemType], err = selectItems(hub, itemType, args, !all); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +84,7 @@ func ListItems(out io.Writer, itemTypes []string, args []string, showType bool,
|
|||
// 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 := cwhub.GetItem(itemType, itemName)
|
||||
item := hub.GetItem(itemType, itemName)
|
||||
status, emo := item.Status()
|
||||
hubStatus[itemType][i] = itemHubStatus{
|
||||
Name: item.Name,
|
||||
|
@ -112,7 +118,7 @@ func ListItems(out io.Writer, itemTypes []string, args []string, showType bool,
|
|||
}
|
||||
for _, itemType := range itemTypes {
|
||||
for _, itemName := range items[itemType] {
|
||||
item := cwhub.GetItem(itemType, itemName)
|
||||
item := hub.GetItem(itemType, itemName)
|
||||
status, _ := item.Status()
|
||||
if item.LocalVersion == "" {
|
||||
item.LocalVersion = "n/a"
|
||||
|
@ -138,15 +144,17 @@ func ListItems(out io.Writer, itemTypes []string, args []string, showType bool,
|
|||
}
|
||||
|
||||
func InspectItem(name string, itemType string, noMetrics bool) error {
|
||||
hubItem := cwhub.GetItem(itemType, name)
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hubItem := hub.GetItem(itemType, name)
|
||||
if hubItem == nil {
|
||||
return fmt.Errorf("can't find '%s' in %s", name, itemType)
|
||||
}
|
||||
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
var b []byte
|
||||
|
||||
switch csConfig.Cscli.Output {
|
||||
case "human", "raw":
|
||||
|
@ -168,7 +176,7 @@ func InspectItem(name string, itemType string, noMetrics bool) error {
|
|||
}
|
||||
|
||||
fmt.Printf("\nCurrent metrics: \n")
|
||||
ShowMetrics(hubItem)
|
||||
ShowMetrics(hub, hubItem)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -38,11 +38,12 @@ func runLapiStatus(cmd *cobra.Command, args []string) error {
|
|||
log.Fatalf("parsing api url ('%s'): %s", apiurl, err)
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
scenarios, err := cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
scenarios, err := hub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get scenarios : %s", err)
|
||||
}
|
||||
|
@ -338,9 +339,9 @@ cscli lapi context detect crowdsecurity/sshd-logs
|
|||
log.Fatalf("Failed to init expr helpers : %s", err)
|
||||
}
|
||||
|
||||
// Populate cwhub package tools
|
||||
if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
|
||||
log.Fatalf("Failed to load hub index : %s", err)
|
||||
_, err = require.Hub(csConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
csParsers := parser.NewParsers()
|
||||
|
|
|
@ -25,7 +25,7 @@ cscli parsers remove crowdsecurity/caddy-logs crowdsecurity/sshd-logs
|
|||
Aliases: []string{"parser"},
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,13 @@ func runParsersInstall(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range args {
|
||||
t := cwhub.GetItem(cwhub.PARSERS, name)
|
||||
t := hub.GetItem(cwhub.PARSERS, name)
|
||||
if t == nil {
|
||||
nearestItem, score := GetDistance(cwhub.PARSERS, name)
|
||||
Suggest(cwhub.PARSERS, name, nearestItem.Name, score, ignoreError)
|
||||
|
@ -75,7 +80,7 @@ func runParsersInstall(cmd *cobra.Command, args []string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, name, cwhub.PARSERS, force, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(name, cwhub.PARSERS, force, downloadOnly); err != nil {
|
||||
if !ignoreError {
|
||||
return fmt.Errorf("error while installing '%s': %w", name, err)
|
||||
}
|
||||
|
@ -126,8 +131,13 @@ func runParsersRemove(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.PARSERS, "", all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.PARSERS, "", all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -140,7 +150,7 @@ func runParsersRemove(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.PARSERS, name, all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.PARSERS, name, all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -184,8 +194,13 @@ func runParsersUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.PARSERS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.PARSERS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -196,7 +211,7 @@ func runParsersUpgrade(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.PARSERS, name, force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.PARSERS, name, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ cscli postoverflows remove crowdsecurity/cdn-whitelist crowdsecurity/rdns
|
|||
Aliases: []string{"postoverflow"},
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,13 @@ func runPostOverflowsInstall(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range args {
|
||||
t := cwhub.GetItem(cwhub.POSTOVERFLOWS, name)
|
||||
t := hub.GetItem(cwhub.POSTOVERFLOWS, name)
|
||||
if t == nil {
|
||||
nearestItem, score := GetDistance(cwhub.POSTOVERFLOWS, name)
|
||||
Suggest(cwhub.POSTOVERFLOWS, name, nearestItem.Name, score, ignoreError)
|
||||
|
@ -75,7 +80,7 @@ func runPostOverflowsInstall(cmd *cobra.Command, args []string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, name, cwhub.POSTOVERFLOWS, force, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(name, cwhub.POSTOVERFLOWS, force, downloadOnly); err != nil {
|
||||
if !ignoreError {
|
||||
return fmt.Errorf("error while installing '%s': %w", name, err)
|
||||
}
|
||||
|
@ -126,8 +131,13 @@ func runPostOverflowsRemove(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.POSTOVERFLOWS, "", all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.POSTOVERFLOWS, "", all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -140,7 +150,7 @@ func runPostOverflowsRemove(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.POSTOVERFLOWS, name, all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.POSTOVERFLOWS, name, all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -184,8 +194,13 @@ func runPostOverflowUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.POSTOVERFLOWS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.POSTOVERFLOWS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -196,7 +211,7 @@ func runPostOverflowUpgrade(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.POSTOVERFLOWS, name, force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.POSTOVERFLOWS, name, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,16 +64,17 @@ func Notifications(c *csconfig.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func Hub (c *csconfig.Config) error {
|
||||
func Hub (c *csconfig.Config) (*cwhub.Hub, error) {
|
||||
if c.Hub == nil {
|
||||
return fmt.Errorf("you must configure cli before interacting with hub")
|
||||
return nil, fmt.Errorf("you must configure cli before interacting with hub")
|
||||
}
|
||||
|
||||
cwhub.SetHubBranch()
|
||||
|
||||
if err := cwhub.GetHubIdx(c.Hub); err != nil {
|
||||
return fmt.Errorf("failed to read Hub index: '%w'. Run 'sudo cscli hub update' to download the index again", err)
|
||||
hub, err := cwhub.InitHub(c.Hub)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read Hub index: '%w'. Run 'sudo cscli hub update' to download the index again", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return hub, nil
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ cscli scenarios remove crowdsecurity/ssh-bf crowdsecurity/http-probing
|
|||
Aliases: []string{"scenario"},
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,13 @@ func runScenariosInstall(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range args {
|
||||
t := cwhub.GetItem(cwhub.SCENARIOS, name)
|
||||
t := hub.GetItem(cwhub.SCENARIOS, name)
|
||||
if t == nil {
|
||||
nearestItem, score := GetDistance(cwhub.SCENARIOS, name)
|
||||
Suggest(cwhub.SCENARIOS, name, nearestItem.Name, score, ignoreError)
|
||||
|
@ -75,7 +80,7 @@ func runScenariosInstall(cmd *cobra.Command, args []string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, name, cwhub.SCENARIOS, force, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(name, cwhub.SCENARIOS, force, downloadOnly); err != nil {
|
||||
if !ignoreError {
|
||||
return fmt.Errorf("error while installing '%s': %w", name, err)
|
||||
}
|
||||
|
@ -126,8 +131,13 @@ func runScenariosRemove(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.SCENARIOS, "", all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.SCENARIOS, "", all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -140,7 +150,7 @@ func runScenariosRemove(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.SCENARIOS, name, all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.SCENARIOS, name, all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -184,8 +194,13 @@ func runScenariosUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.SCENARIOS, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.SCENARIOS, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -196,7 +211,7 @@ func runScenariosUpgrade(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.SCENARIOS, name, force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.SCENARIOS, name, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,13 +145,14 @@ func NewSimulationEnableCmd() *cobra.Command {
|
|||
Example: `cscli simulation enable`,
|
||||
DisableAutoGenTag: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
for _, scenario := range args {
|
||||
var item = cwhub.GetItem(cwhub.SCENARIOS, scenario)
|
||||
var item = hub.GetItem(cwhub.SCENARIOS, scenario)
|
||||
if item == nil {
|
||||
log.Errorf("'%s' doesn't exist or is not a scenario", scenario)
|
||||
continue
|
||||
|
|
|
@ -155,7 +155,7 @@ func collectAgents(dbClient *database.Client) ([]byte, error) {
|
|||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
func collectAPIStatus(login string, password string, endpoint string, prefix string) []byte {
|
||||
func collectAPIStatus(login string, password string, endpoint string, prefix string, hub *cwhub.Hub) []byte {
|
||||
if csConfig.API.Client == nil || csConfig.API.Client.Credentials == nil {
|
||||
return []byte("No agent credentials found, are we LAPI ?")
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ func collectAPIStatus(login string, password string, endpoint string, prefix str
|
|||
if err != nil {
|
||||
return []byte(fmt.Sprintf("cannot parse API URL: %s", err))
|
||||
}
|
||||
scenarios, err := cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
scenarios, err := hub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
if err != nil {
|
||||
return []byte(fmt.Sprintf("could not collect scenarios: %s", err))
|
||||
}
|
||||
|
@ -293,7 +293,8 @@ cscli support dump -f /tmp/crowdsec-support.zip
|
|||
skipAgent = true
|
||||
}
|
||||
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
hub, err := require.Hub(csConfig)
|
||||
if err != nil {
|
||||
log.Warn("Could not init hub, running on LAPI ? Hub related information will not be collected")
|
||||
skipHub = true
|
||||
infos[SUPPORT_PARSERS_PATH] = []byte(err.Error())
|
||||
|
@ -356,7 +357,8 @@ cscli support dump -f /tmp/crowdsec-support.zip
|
|||
infos[SUPPORT_CAPI_STATUS_PATH] = collectAPIStatus(csConfig.API.Server.OnlineClient.Credentials.Login,
|
||||
csConfig.API.Server.OnlineClient.Credentials.Password,
|
||||
csConfig.API.Server.OnlineClient.Credentials.URL,
|
||||
CAPIURLPrefix)
|
||||
CAPIURLPrefix,
|
||||
hub)
|
||||
}
|
||||
|
||||
if !skipLAPI {
|
||||
|
@ -364,7 +366,8 @@ cscli support dump -f /tmp/crowdsec-support.zip
|
|||
infos[SUPPORT_LAPI_STATUS_PATH] = collectAPIStatus(csConfig.API.Client.Credentials.Login,
|
||||
csConfig.API.Client.Credentials.Password,
|
||||
csConfig.API.Client.Credentials.URL,
|
||||
LAPIURLPrefix)
|
||||
LAPIURLPrefix,
|
||||
hub)
|
||||
infos[SUPPORT_CROWDSEC_PROFILE_PATH] = collectCrowdsecProfile()
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,10 @@ func listHubItemTable(out io.Writer, title string, itemType string, itemNames []
|
|||
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
|
||||
hub, _ := cwhub.GetHub()
|
||||
|
||||
for itemName := range itemNames {
|
||||
item := cwhub.GetItem(itemType, itemNames[itemName])
|
||||
item := hub.GetItem(itemType, itemNames[itemName])
|
||||
status, emo := item.Status()
|
||||
t.AddRow(item.Name, fmt.Sprintf("%v %s", emo, status), item.LocalVersion, item.LocalPath)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ cscli waap-rules remove crowdsecurity/crs
|
|||
Aliases: []string{"waap-rule"},
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := require.Hub(csConfig); err != nil {
|
||||
if _, err := require.Hub(csConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,13 @@ func runWaapRulesInstall(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range args {
|
||||
t := cwhub.GetItem(cwhub.WAAP_RULES, name)
|
||||
t := hub.GetItem(cwhub.WAAP_RULES, name)
|
||||
if t == nil {
|
||||
nearestItem, score := GetDistance(cwhub.WAAP_RULES, name)
|
||||
Suggest(cwhub.WAAP_RULES, name, nearestItem.Name, score, ignoreError)
|
||||
|
@ -75,7 +80,7 @@ func runWaapRulesInstall(cmd *cobra.Command, args []string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, name, cwhub.WAAP_RULES, force, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(name, cwhub.WAAP_RULES, force, downloadOnly); err != nil {
|
||||
if !ignoreError {
|
||||
return fmt.Errorf("error while installing '%s': %w", name, err)
|
||||
}
|
||||
|
@ -126,8 +131,13 @@ func runWaapRulesRemove(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.WAAP_RULES, "", all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.WAAP_RULES, "", all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -140,7 +150,7 @@ func runWaapRulesRemove(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
err := cwhub.RemoveMany(csConfig, cwhub.WAAP_RULES, name, all, purge, force)
|
||||
err := hub.RemoveMany(cwhub.WAAP_RULES, name, all, purge, force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -184,8 +194,13 @@ func runWaapRulesUpgrade(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if all {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.WAAP_RULES, "", force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.WAAP_RULES, "", force); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -196,7 +211,7 @@ func runWaapRulesUpgrade(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
for _, name := range args {
|
||||
if err := cwhub.UpgradeConfig(csConfig, cwhub.WAAP_RULES, name, force); err != nil {
|
||||
if err := hub.UpgradeConfig(cwhub.WAAP_RULES, name, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ import (
|
|||
func initCrowdsec(cConfig *csconfig.Config) (*parser.Parsers, error) {
|
||||
var err error
|
||||
|
||||
// Populate cwhub package tools
|
||||
if err = cwhub.GetHubIdx(cConfig.Hub); err != nil {
|
||||
hub, err := cwhub.InitHub(cConfig.Hub)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while loading hub index: %w", err)
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ func initCrowdsec(cConfig *csconfig.Config) (*parser.Parsers, error) {
|
|||
return nil, fmt.Errorf("while loading parsers: %w", err)
|
||||
}
|
||||
|
||||
if err := LoadBuckets(cConfig); err != nil {
|
||||
if err := LoadBuckets(cConfig, hub); err != nil {
|
||||
return nil, fmt.Errorf("while loading scenarios: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -75,12 +75,12 @@ type Flags struct {
|
|||
|
||||
type labelsMap map[string]string
|
||||
|
||||
func LoadBuckets(cConfig *csconfig.Config) error {
|
||||
func LoadBuckets(cConfig *csconfig.Config, hub *cwhub.Hub) error {
|
||||
var (
|
||||
err error
|
||||
files []string
|
||||
)
|
||||
for _, hubScenarioItem := range cwhub.GetItemMap(cwhub.SCENARIOS) {
|
||||
for _, hubScenarioItem := range hub.GetItemMap(cwhub.SCENARIOS) {
|
||||
if hubScenarioItem.Installed {
|
||||
files = append(files, hubScenarioItem.LocalPath)
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ func LoadBuckets(cConfig *csconfig.Config) error {
|
|||
buckets = leakybucket.NewBuckets()
|
||||
|
||||
log.Infof("Loading %d scenario files", len(files))
|
||||
holders, outputEventChan, err = leakybucket.LoadBuckets(cConfig.Crowdsec, files, &bucketsTomb, buckets, flags.OrderEvent)
|
||||
holders, outputEventChan, err = leakybucket.LoadBuckets(cConfig.Crowdsec, cConfig.ConfigPaths.DataDir, files, &bucketsTomb, buckets, flags.OrderEvent)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("scenario loading failed: %v", err)
|
||||
|
|
|
@ -70,7 +70,12 @@ func runOutput(input chan types.Event, overflow chan types.Event, buckets *leaky
|
|||
var cache []types.RuntimeAlert
|
||||
var cacheMutex sync.Mutex
|
||||
|
||||
scenarios, err := cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scenarios, err := hub.GetInstalledItemsAsString(cwhub.SCENARIOS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading list of installed hub scenarios: %w", err)
|
||||
}
|
||||
|
@ -93,7 +98,7 @@ func runOutput(input chan types.Event, overflow chan types.Event, buckets *leaky
|
|||
URL: apiURL,
|
||||
PapiURL: papiURL,
|
||||
VersionPrefix: "v1",
|
||||
UpdateScenario: func() ([]string, error) {return cwhub.GetInstalledItemsAsString(cwhub.SCENARIOS)},
|
||||
UpdateScenario: func() ([]string, error) {return hub.GetInstalledItemsAsString(cwhub.SCENARIOS)},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("new client api: %w", err)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
corazatypes "github.com/crowdsecurity/coraza/v3/types"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
||||
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||
|
@ -157,6 +158,12 @@ func (w *WaapSource) Configure(yamlConfig []byte, logger *log.Entry) error {
|
|||
|
||||
w.WaapRunners = make([]WaapRunner, w.config.Routines)
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load hub : %s", err)
|
||||
}
|
||||
|
||||
for nbRoutine := 0; nbRoutine < w.config.Routines; nbRoutine++ {
|
||||
|
||||
wafUUID := uuid.New().String()
|
||||
|
@ -186,7 +193,7 @@ func (w *WaapSource) Configure(yamlConfig []byte, logger *log.Entry) error {
|
|||
logger: wafLogger,
|
||||
WaapRuntime: &wrt,
|
||||
}
|
||||
err := runner.Init()
|
||||
err := runner.Init(hub.GetDataDir())
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to initialize runner : %s", err)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/crowdsecurity/coraza/v3"
|
||||
"github.com/crowdsecurity/coraza/v3/experimental"
|
||||
corazatypes "github.com/crowdsecurity/coraza/v3/types"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/waf"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
@ -27,9 +26,9 @@ type WaapRunner struct {
|
|||
logger *log.Entry
|
||||
}
|
||||
|
||||
func (r *WaapRunner) Init() error {
|
||||
func (r *WaapRunner) Init(datadir string) error {
|
||||
var err error
|
||||
fs := os.DirFS(csconfig.DataDir)
|
||||
fs := os.DirFS(datadir)
|
||||
|
||||
inBandRules := ""
|
||||
outOfBandRules := ""
|
||||
|
|
|
@ -100,7 +100,7 @@ func NewDefaultConfig() *Config {
|
|||
commonCfg := CommonCfg{
|
||||
Daemonize: false,
|
||||
LogMedia: "stdout",
|
||||
LogLevel: &logLevel,
|
||||
LogLevel: &logLevel,
|
||||
}
|
||||
prometheus := PrometheusCfg{
|
||||
Enabled: true,
|
||||
|
|
|
@ -30,10 +30,6 @@ type CrowdsecServiceCfg struct {
|
|||
BucketStateDumpDir string `yaml:"state_output_dir,omitempty"` // if we need to unserialize buckets on shutdown
|
||||
BucketsGCEnabled bool `yaml:"-"` // we need to garbage collect buckets when in forensic mode
|
||||
|
||||
HubDir string `yaml:"-"`
|
||||
DataDir string `yaml:"-"`
|
||||
ConfigDir string `yaml:"-"`
|
||||
HubIndexFile string `yaml:"-"`
|
||||
SimulationFilePath string `yaml:"-"`
|
||||
ContextToSend map[string][]string `yaml:"-"`
|
||||
}
|
||||
|
@ -103,13 +99,6 @@ func (c *Config) LoadCrowdsec() error {
|
|||
return fmt.Errorf("load error (simulation): %w", err)
|
||||
}
|
||||
|
||||
c.Crowdsec.ConfigDir = c.ConfigPaths.ConfigDir
|
||||
c.Crowdsec.DataDir = c.ConfigPaths.DataDir
|
||||
c.Crowdsec.HubDir = c.ConfigPaths.HubDir
|
||||
c.Crowdsec.HubIndexFile = c.ConfigPaths.HubIndexFile
|
||||
|
||||
DataDir = c.Crowdsec.DataDir // FIXME: find a better way to give it to the waf
|
||||
|
||||
if c.Crowdsec.ParserRoutinesCount <= 0 {
|
||||
c.Crowdsec.ParserRoutinesCount = 1
|
||||
}
|
||||
|
@ -153,7 +142,7 @@ func (c *Config) LoadCrowdsec() error {
|
|||
fallback := false
|
||||
if c.Crowdsec.ConsoleContextPath == "" {
|
||||
// fallback to default config file
|
||||
c.Crowdsec.ConsoleContextPath = filepath.Join(c.Crowdsec.ConfigDir, "console", "context.yaml")
|
||||
c.Crowdsec.ConsoleContextPath = filepath.Join(c.ConfigPaths.ConfigDir, "console", "context.yaml")
|
||||
fallback = true
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,6 @@ func TestLoadCrowdsec(t *testing.T) {
|
|||
AcquisitionDirPath: "",
|
||||
ConsoleContextPath: contextFileFullPath,
|
||||
AcquisitionFilePath: acquisFullPath,
|
||||
ConfigDir: "./testdata",
|
||||
DataDir: "./data",
|
||||
HubDir: "./hub",
|
||||
// XXX: need to ensure a default here
|
||||
HubIndexFile: "",
|
||||
BucketsRoutinesCount: 1,
|
||||
ParserRoutinesCount: 1,
|
||||
OutputRoutinesCount: 1,
|
||||
|
@ -98,11 +93,6 @@ func TestLoadCrowdsec(t *testing.T) {
|
|||
AcquisitionDirPath: acquisDirFullPath,
|
||||
AcquisitionFilePath: acquisFullPath,
|
||||
ConsoleContextPath: contextFileFullPath,
|
||||
ConfigDir: "./testdata",
|
||||
// XXX: need to ensure a default here
|
||||
HubIndexFile: "",
|
||||
DataDir: "./data",
|
||||
HubDir: "./hub",
|
||||
BucketsRoutinesCount: 1,
|
||||
ParserRoutinesCount: 1,
|
||||
OutputRoutinesCount: 1,
|
||||
|
@ -139,11 +129,6 @@ func TestLoadCrowdsec(t *testing.T) {
|
|||
Enable: ptr.Of(true),
|
||||
AcquisitionDirPath: "",
|
||||
AcquisitionFilePath: "",
|
||||
ConfigDir: "./testdata",
|
||||
// XXX: need to ensure a default here
|
||||
HubIndexFile: "",
|
||||
DataDir: "./data",
|
||||
HubDir: "./hub",
|
||||
ConsoleContextPath: contextFileFullPath,
|
||||
BucketsRoutinesCount: 1,
|
||||
ParserRoutinesCount: 1,
|
||||
|
|
|
@ -11,10 +11,7 @@ type CscliCfg struct {
|
|||
HubBranch string `yaml:"hub_branch"`
|
||||
SimulationConfig *SimulationConfig `yaml:"-"`
|
||||
DbConfig *DatabaseCfg `yaml:"-"`
|
||||
HubDir string `yaml:"-"`
|
||||
DataDir string `yaml:"-"`
|
||||
ConfigDir string `yaml:"-"`
|
||||
HubIndexFile string `yaml:"-"`
|
||||
|
||||
SimulationFilePath string `yaml:"-"`
|
||||
PrometheusUrl string `yaml:"prometheus_uri"`
|
||||
}
|
||||
|
@ -23,10 +20,8 @@ func (c *Config) loadCSCLI() error {
|
|||
if c.Cscli == nil {
|
||||
c.Cscli = &CscliCfg{}
|
||||
}
|
||||
c.Cscli.ConfigDir = c.ConfigPaths.ConfigDir
|
||||
c.Cscli.DataDir = c.ConfigPaths.DataDir
|
||||
c.Cscli.HubDir = c.ConfigPaths.HubDir
|
||||
c.Cscli.HubIndexFile = c.ConfigPaths.HubIndexFile
|
||||
|
||||
// XXX: HubBranch default should be set here and fed to HubCfg?
|
||||
|
||||
if c.Prometheus.ListenAddr != "" && c.Prometheus.ListenPort != 0 {
|
||||
c.Cscli.PrometheusUrl = fmt.Sprintf("http://%s:%d/metrics", c.Prometheus.ListenAddr, c.Prometheus.ListenPort)
|
||||
|
|
|
@ -32,10 +32,6 @@ func TestLoadCSCLI(t *testing.T) {
|
|||
},
|
||||
},
|
||||
expected: &CscliCfg{
|
||||
ConfigDir: "./testdata",
|
||||
DataDir: "./data",
|
||||
HubDir: "./hub",
|
||||
HubIndexFile: "./hub/.index.json",
|
||||
PrometheusUrl: "http://127.0.0.1:6060/metrics",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,6 +9,9 @@ type HubCfg struct {
|
|||
}
|
||||
|
||||
func (c *Config) loadHub() error {
|
||||
|
||||
// XXX: HubBranch too -- from cscli or chooseHubBranch() ?
|
||||
|
||||
c.Hub = &HubCfg{
|
||||
HubIndexFile: c.ConfigPaths.HubIndexFile,
|
||||
HubDir: c.ConfigPaths.HubDir,
|
||||
|
|
|
@ -62,7 +62,7 @@ type Item struct {
|
|||
PostOverflows []string `json:"postoverflows,omitempty" yaml:"postoverflows,omitempty"`
|
||||
Scenarios []string `json:"scenarios,omitempty" yaml:"scenarios,omitempty"`
|
||||
Collections []string `json:"collections,omitempty" yaml:"collections,omitempty"`
|
||||
WafRules []string `json:"waap-rules,omitempty" yaml:"waap-rules,omitempty"`
|
||||
WaapRules []string `json:"waap-rules,omitempty" yaml:"waap-rules,omitempty"`
|
||||
}
|
||||
|
||||
// Status returns the status of the item as a string and an emoji
|
||||
|
@ -112,9 +112,16 @@ func (i *Item) versionStatus() int {
|
|||
return semver.Compare("v"+i.Version, "v"+i.LocalVersion)
|
||||
}
|
||||
|
||||
// validPath returns true if the (relative) path is allowed for the item
|
||||
// dirNmae: the directory name (ie. crowdsecurity)
|
||||
// fileName: the filename (ie. apache2-logs.yaml)
|
||||
func (i *Item) validPath(dirName, fileName string) bool {
|
||||
return (dirName+"/"+fileName == i.Name+".yaml") || (dirName+"/"+fileName == i.Name+".yml")
|
||||
}
|
||||
|
||||
// GetItemMap returns the map of items for a given type
|
||||
func GetItemMap(itemType string) map[string]Item {
|
||||
m, ok := hubIdx.Items[itemType]
|
||||
func (h *Hub) GetItemMap(itemType string) map[string]Item {
|
||||
m, ok := h.Items[itemType]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
@ -123,6 +130,7 @@ func GetItemMap(itemType string) map[string]Item {
|
|||
}
|
||||
|
||||
// itemKey extracts the map key of an item (i.e. author/name) from its pathname. Follows a symlink if necessary
|
||||
// XXX: only used by leakybucket manager
|
||||
func itemKey(itemPath string) (string, error) {
|
||||
f, err := os.Lstat(itemPath)
|
||||
if err != nil {
|
||||
|
@ -150,13 +158,13 @@ func itemKey(itemPath string) (string, error) {
|
|||
}
|
||||
|
||||
// GetItemByPath retrieves the item from hubIdx based on the path. To achieve this it will resolve symlink to find associated hub item.
|
||||
func GetItemByPath(itemType string, itemPath string) (*Item, error) {
|
||||
func (h *Hub) GetItemByPath(itemType string, itemPath string) (*Item, error) {
|
||||
itemKey, err := itemKey(itemPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := GetItemMap(itemType)
|
||||
m := h.GetItemMap(itemType)
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("item type %s doesn't exist", itemType)
|
||||
}
|
||||
|
@ -170,19 +178,20 @@ func GetItemByPath(itemType string, itemPath string) (*Item, error) {
|
|||
}
|
||||
|
||||
// GetItem returns the item from hub based on its type and full name (author/name)
|
||||
func GetItem(itemType string, itemName string) *Item {
|
||||
if m, ok := GetItemMap(itemType)[itemName]; ok {
|
||||
return &m
|
||||
func (h *Hub) GetItem(itemType string, itemName string) *Item {
|
||||
m, ok := h.GetItemMap(itemType)[itemName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return &m
|
||||
}
|
||||
|
||||
// GetItemNames returns the list of item (full) names for a given type
|
||||
// ie. for parsers: crowdsecurity/apache2 crowdsecurity/nginx
|
||||
// The names can be used to retrieve the item with GetItem()
|
||||
func GetItemNames(itemType string) []string {
|
||||
m := GetItemMap(itemType)
|
||||
func (h *Hub) GetItemNames(itemType string) []string {
|
||||
m := h.GetItemMap(itemType)
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -196,10 +205,10 @@ func GetItemNames(itemType string) []string {
|
|||
}
|
||||
|
||||
// AddItem adds an item to the hub index
|
||||
func AddItem(itemType string, item Item) error {
|
||||
func (h *Hub) AddItem(itemType string, item Item) error {
|
||||
for _, itype := range ItemTypes {
|
||||
if itype == itemType {
|
||||
hubIdx.Items[itemType][item.Name] = item
|
||||
h.Items[itemType][item.Name] = item
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -208,8 +217,8 @@ func AddItem(itemType string, item Item) error {
|
|||
}
|
||||
|
||||
// GetInstalledItems returns the list of installed items
|
||||
func GetInstalledItems(itemType string) ([]Item, error) {
|
||||
items, ok := hubIdx.Items[itemType]
|
||||
func (h *Hub) GetInstalledItems(itemType string) ([]Item, error) {
|
||||
items, ok := h.Items[itemType]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no %s in hubIdx", itemType)
|
||||
}
|
||||
|
@ -226,8 +235,8 @@ func GetInstalledItems(itemType string) ([]Item, error) {
|
|||
}
|
||||
|
||||
// GetInstalledItemsAsString returns the names of the installed items
|
||||
func GetInstalledItemsAsString(itemType string) ([]string, error) {
|
||||
items, err := GetInstalledItems(itemType)
|
||||
func (h *Hub) GetInstalledItemsAsString(itemType string) ([]string, error) {
|
||||
items, err := h.GetInstalledItems(itemType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -29,23 +29,15 @@ import (
|
|||
var responseByPath map[string]string
|
||||
|
||||
func TestItemStatus(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
|
||||
// DownloadHubIdx()
|
||||
err := UpdateHubIdx(cfg.Hub)
|
||||
require.NoError(t, err, "failed to download index")
|
||||
|
||||
err = GetHubIdx(cfg.Hub)
|
||||
require.NoError(t, err, "failed to load hub index")
|
||||
hub := envSetup(t)
|
||||
|
||||
// get existing map
|
||||
x := GetItemMap(COLLECTIONS)
|
||||
x := hub.GetItemMap(COLLECTIONS)
|
||||
require.NotEmpty(t, x)
|
||||
|
||||
// Get item : good and bad
|
||||
for k := range x {
|
||||
item := GetItem(COLLECTIONS, k)
|
||||
item := hub.GetItem(COLLECTIONS, k)
|
||||
require.NotNil(t, item)
|
||||
|
||||
item.Installed = true
|
||||
|
@ -65,76 +57,101 @@ func TestItemStatus(t *testing.T) {
|
|||
require.Equal(t, "disabled,local", txt)
|
||||
}
|
||||
|
||||
DisplaySummary()
|
||||
err := DisplaySummary()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGetters(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
|
||||
// DownloadHubIdx()
|
||||
err := UpdateHubIdx(cfg.Hub)
|
||||
require.NoError(t, err, "failed to download index")
|
||||
|
||||
err = GetHubIdx(cfg.Hub)
|
||||
require.NoError(t, err, "failed to load hub index")
|
||||
hub := envSetup(t)
|
||||
|
||||
// get non existing map
|
||||
empty := GetItemMap("ratata")
|
||||
empty := hub.GetItemMap("ratata")
|
||||
require.Nil(t, empty)
|
||||
|
||||
// get existing map
|
||||
x := GetItemMap(COLLECTIONS)
|
||||
x := hub.GetItemMap(COLLECTIONS)
|
||||
require.NotEmpty(t, x)
|
||||
|
||||
// Get item : good and bad
|
||||
for k := range x {
|
||||
empty := GetItem(COLLECTIONS, k+"nope")
|
||||
empty := hub.GetItem(COLLECTIONS, k+"nope")
|
||||
require.Nil(t, empty)
|
||||
|
||||
item := GetItem(COLLECTIONS, k)
|
||||
item := hub.GetItem(COLLECTIONS, k)
|
||||
require.NotNil(t, item)
|
||||
|
||||
// Add item and get it
|
||||
item.Name += "nope"
|
||||
err := AddItem(COLLECTIONS, *item)
|
||||
err := hub.AddItem(COLLECTIONS, *item)
|
||||
require.NoError(t, err)
|
||||
|
||||
newitem := GetItem(COLLECTIONS, item.Name)
|
||||
newitem := hub.GetItem(COLLECTIONS, item.Name)
|
||||
require.NotNil(t, newitem)
|
||||
|
||||
err = AddItem("ratata", *item)
|
||||
err = hub.AddItem("ratata", *item)
|
||||
cstest.RequireErrorContains(t, err, "ItemType ratata is unknown")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexDownload(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
// DownloadHubIdx()
|
||||
err := UpdateHubIdx(cfg.Hub)
|
||||
_, err := InitHubUpdate(hub.cfg)
|
||||
require.NoError(t, err, "failed to download index")
|
||||
|
||||
err = GetHubIdx(cfg.Hub)
|
||||
_, err = GetHub()
|
||||
require.NoError(t, err, "failed to load hub index")
|
||||
}
|
||||
|
||||
func getTestCfg() *csconfig.Config {
|
||||
cfg := &csconfig.Config{Hub: &csconfig.HubCfg{}}
|
||||
cfg.Hub.InstallDir, _ = filepath.Abs("./install")
|
||||
cfg.Hub.HubDir, _ = filepath.Abs("./hubdir")
|
||||
cfg.Hub.HubIndexFile = filepath.Clean("./hubdir/.index.json")
|
||||
// testHub initializes a temporary hub with an empty json file, optionally updating it
|
||||
func testHub(t *testing.T, update bool) *Hub {
|
||||
tmpDir, err := os.MkdirTemp("", "testhub")
|
||||
require.NoError(t, err)
|
||||
|
||||
return cfg
|
||||
hubCfg := &csconfig.HubCfg{
|
||||
HubDir: filepath.Join(tmpDir, "crowdsec", "hub"),
|
||||
HubIndexFile: filepath.Join(tmpDir, "crowdsec", "hub", ".index.json"),
|
||||
InstallDir: filepath.Join(tmpDir, "crowdsec"),
|
||||
InstallDataDir: filepath.Join(tmpDir, "installed-data"),
|
||||
}
|
||||
|
||||
err = os.MkdirAll(hubCfg.HubDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(hubCfg.InstallDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(hubCfg.InstallDataDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
index, err := os.Create(hubCfg.HubIndexFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = index.WriteString(`{}`)
|
||||
require.NoError(t, err)
|
||||
|
||||
index.Close()
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
constructor := InitHub
|
||||
|
||||
if update {
|
||||
constructor = InitHubUpdate
|
||||
}
|
||||
|
||||
hub, err := constructor(hubCfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
return hub
|
||||
}
|
||||
|
||||
func envSetup(t *testing.T) *csconfig.Config {
|
||||
func envSetup(t *testing.T) *Hub {
|
||||
resetResponseByPath()
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
cfg := getTestCfg()
|
||||
|
||||
defaultTransport := http.DefaultClient.Transport
|
||||
|
||||
t.Cleanup(func() {
|
||||
|
@ -144,14 +161,7 @@ func envSetup(t *testing.T) *csconfig.Config {
|
|||
// Mock the http client
|
||||
http.DefaultClient.Transport = newMockTransport()
|
||||
|
||||
err := os.MkdirAll(cfg.Hub.InstallDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(cfg.Hub.HubDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = UpdateHubIdx(cfg.Hub)
|
||||
require.NoError(t, err)
|
||||
hub := testHub(t, true)
|
||||
|
||||
// if err := os.RemoveAll(cfg.Hub.InstallDir); err != nil {
|
||||
// log.Fatalf("failed to remove %s : %s", cfg.Hub.InstallDir, err)
|
||||
|
@ -159,42 +169,33 @@ func envSetup(t *testing.T) *csconfig.Config {
|
|||
// if err := os.MkdirAll(cfg.Hub.InstallDir, 0700); err != nil {
|
||||
// log.Fatalf("failed to mkdir %s : %s", cfg.Hub.InstallDir, err)
|
||||
// }
|
||||
return cfg
|
||||
return hub
|
||||
}
|
||||
|
||||
func envTearDown(cfg *csconfig.Config) {
|
||||
if err := os.RemoveAll(cfg.Hub.InstallDir); err != nil {
|
||||
log.Fatalf("failed to remove %s : %s", cfg.Hub.InstallDir, err)
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(cfg.Hub.HubDir); err != nil {
|
||||
log.Fatalf("failed to remove %s : %s", cfg.Hub.HubDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
func testInstallItem(cfg *csconfig.HubCfg, t *testing.T, item Item) {
|
||||
func testInstallItem(hub *Hub, t *testing.T, item Item) {
|
||||
// Install the parser
|
||||
err := DownloadLatest(cfg, &item, false, false)
|
||||
|
||||
err := hub.DownloadLatest(&item, false, false)
|
||||
require.NoError(t, err, "failed to download %s", item.Name)
|
||||
|
||||
_, err = LocalSync(cfg)
|
||||
_, err = hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Installed, "%s should not be installed", item.Name)
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
|
||||
assert.True(t, hub.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
|
||||
|
||||
err = EnableItem(cfg, &item)
|
||||
err = hub.EnableItem(&item)
|
||||
require.NoError(t, err, "failed to enable %s", item.Name)
|
||||
|
||||
_, err = LocalSync(cfg)
|
||||
_, err = hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
|
||||
assert.True(t, hub.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
|
||||
}
|
||||
|
||||
func testTaintItem(cfg *csconfig.HubCfg, t *testing.T, item Item) {
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
|
||||
func testTaintItem(hub *Hub, t *testing.T, item Item) {
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted", item.Name)
|
||||
|
||||
f, err := os.OpenFile(item.LocalPath, os.O_APPEND|os.O_WRONLY, 0600)
|
||||
require.NoError(t, err, "failed to open %s (%s)", item.LocalPath, item.Name)
|
||||
|
@ -205,54 +206,54 @@ func testTaintItem(cfg *csconfig.HubCfg, t *testing.T, item Item) {
|
|||
require.NoError(t, err, "failed to write to %s (%s)", item.LocalPath, item.Name)
|
||||
|
||||
// Local sync and check status
|
||||
_, err = LocalSync(cfg)
|
||||
_, err = hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].Tainted, "%s should be tainted", item.Name)
|
||||
assert.True(t, hub.Items[item.Type][item.Name].Tainted, "%s should be tainted", item.Name)
|
||||
}
|
||||
|
||||
func testUpdateItem(cfg *csconfig.HubCfg, t *testing.T, item Item) {
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].UpToDate, "%s should not be up-to-date", item.Name)
|
||||
func testUpdateItem(hub *Hub, t *testing.T, item Item) {
|
||||
assert.False(t, hub.Items[item.Type][item.Name].UpToDate, "%s should not be up-to-date", item.Name)
|
||||
|
||||
// Update it + check status
|
||||
err := DownloadLatest(cfg, &item, true, true)
|
||||
err := hub.DownloadLatest(&item, true, true)
|
||||
require.NoError(t, err, "failed to update %s", item.Name)
|
||||
|
||||
// Local sync and check status
|
||||
_, err = LocalSync(cfg)
|
||||
_, err = hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
|
||||
assert.True(t, hub.Items[item.Type][item.Name].UpToDate, "%s should be up-to-date", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
|
||||
}
|
||||
|
||||
func testDisableItem(cfg *csconfig.HubCfg, t *testing.T, item Item) {
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
|
||||
func testDisableItem(hub *Hub, t *testing.T, item Item) {
|
||||
assert.True(t, hub.Items[item.Type][item.Name].Installed, "%s should be installed", item.Name)
|
||||
|
||||
// Remove
|
||||
err := DisableItem(cfg, &item, false, false)
|
||||
err := hub.DisableItem(&item, false, false)
|
||||
require.NoError(t, err, "failed to disable %s", item.Name)
|
||||
|
||||
// Local sync and check status
|
||||
warns, err := LocalSync(cfg)
|
||||
warns, err := hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
require.Empty(t, warns, "unexpected warnings : %+v", warns)
|
||||
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
|
||||
assert.True(t, hubIdx.Items[item.Type][item.Name].Downloaded, "%s should still be downloaded", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Tainted, "%s should not be tainted anymore", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
|
||||
assert.True(t, hub.Items[item.Type][item.Name].Downloaded, "%s should still be downloaded", item.Name)
|
||||
|
||||
// Purge
|
||||
err = DisableItem(cfg, &item, true, false)
|
||||
err = hub.DisableItem(&item, true, false)
|
||||
require.NoError(t, err, "failed to purge %s", item.Name)
|
||||
|
||||
// Local sync and check status
|
||||
warns, err = LocalSync(cfg)
|
||||
warns, err = hub.LocalSync()
|
||||
require.NoError(t, err, "failed to run localSync")
|
||||
require.Empty(t, warns, "unexpected warnings : %+v", warns)
|
||||
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
|
||||
assert.False(t, hubIdx.Items[item.Type][item.Name].Downloaded, "%s should not be downloaded", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Installed, "%s should not be installed anymore", item.Name)
|
||||
assert.False(t, hub.Items[item.Type][item.Name].Downloaded, "%s should not be downloaded", item.Name)
|
||||
}
|
||||
|
||||
func TestInstallParser(t *testing.T) {
|
||||
|
@ -265,20 +266,18 @@ func TestInstallParser(t *testing.T) {
|
|||
- check its status
|
||||
- remove it
|
||||
*/
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
// map iteration is random by itself
|
||||
for _, it := range hubIdx.Items[PARSERS] {
|
||||
testInstallItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[PARSERS][it.Name]
|
||||
testTaintItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[PARSERS][it.Name]
|
||||
testUpdateItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[PARSERS][it.Name]
|
||||
testDisableItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[PARSERS][it.Name]
|
||||
for _, it := range hub.Items[PARSERS] {
|
||||
testInstallItem(hub, t, it)
|
||||
it = hub.Items[PARSERS][it.Name]
|
||||
testTaintItem(hub, t, it)
|
||||
it = hub.Items[PARSERS][it.Name]
|
||||
testUpdateItem(hub, t, it)
|
||||
it = hub.Items[PARSERS][it.Name]
|
||||
testDisableItem(hub, t, it)
|
||||
it = hub.Items[PARSERS][it.Name]
|
||||
|
||||
break
|
||||
}
|
||||
|
@ -294,19 +293,17 @@ func TestInstallCollection(t *testing.T) {
|
|||
- check its status
|
||||
- remove it
|
||||
*/
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
// map iteration is random by itself
|
||||
for _, it := range hubIdx.Items[COLLECTIONS] {
|
||||
testInstallItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[COLLECTIONS][it.Name]
|
||||
testTaintItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[COLLECTIONS][it.Name]
|
||||
testUpdateItem(cfg.Hub, t, it)
|
||||
it = hubIdx.Items[COLLECTIONS][it.Name]
|
||||
testDisableItem(cfg.Hub, t, it)
|
||||
for _, it := range hub.Items[COLLECTIONS] {
|
||||
testInstallItem(hub, t, it)
|
||||
it = hub.Items[COLLECTIONS][it.Name]
|
||||
testTaintItem(hub, t, it)
|
||||
it = hub.Items[COLLECTIONS][it.Name]
|
||||
testUpdateItem(hub, t, it)
|
||||
it = hub.Items[COLLECTIONS][it.Name]
|
||||
testDisableItem(hub, t, it)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,31 +19,39 @@ import (
|
|||
|
||||
var ErrIndexNotFound = fmt.Errorf("index not found")
|
||||
|
||||
// UpdateHubIdx downloads the latest version of the index and updates the one in memory
|
||||
func UpdateHubIdx(hub *csconfig.HubCfg) error {
|
||||
bidx, err := DownloadHubIdx(hub)
|
||||
// InitHubUpdate is like InitHub but downloads and updates the index instead of reading from the disk
|
||||
// It is used to inizialize the hub when there is no index file yet
|
||||
func InitHubUpdate(cfg *csconfig.HubCfg) (*Hub, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("no configuration found for hub")
|
||||
}
|
||||
|
||||
bidx, err := DownloadHubIdx(cfg.HubIndexFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download index: %w", err)
|
||||
return nil, fmt.Errorf("failed to download index: %w", err)
|
||||
}
|
||||
|
||||
ret, err := ParseIndex(bidx)
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrMissingReference) {
|
||||
return fmt.Errorf("failed to read index: %w", err)
|
||||
return nil, fmt.Errorf("failed to read index: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
hubIdx = HubIndex{Items: ret}
|
||||
|
||||
if _, err := LocalSync(hub); err != nil {
|
||||
return fmt.Errorf("failed to sync: %w", err)
|
||||
theHub = &Hub{
|
||||
Items: ret,
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
return nil
|
||||
if _, err := theHub.LocalSync(); err != nil {
|
||||
return nil, fmt.Errorf("failed to sync: %w", err)
|
||||
}
|
||||
|
||||
return theHub, nil
|
||||
}
|
||||
|
||||
// DownloadHubIdx downloads the latest version of the index and returns the content
|
||||
func DownloadHubIdx(hub *csconfig.HubCfg) ([]byte, error) {
|
||||
func DownloadHubIdx(indexPath string) ([]byte, error) {
|
||||
log.Debugf("fetching index from branch %s (%s)", HubBranch, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile))
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile), nil)
|
||||
|
@ -70,7 +78,7 @@ func DownloadHubIdx(hub *csconfig.HubCfg) ([]byte, error) {
|
|||
return nil, fmt.Errorf("failed to read request answer for hub index: %w", err)
|
||||
}
|
||||
|
||||
oldContent, err := os.ReadFile(hub.HubIndexFile)
|
||||
oldContent, err := os.ReadFile(indexPath)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
log.Warningf("failed to read hub index: %s", err)
|
||||
|
@ -80,7 +88,7 @@ func DownloadHubIdx(hub *csconfig.HubCfg) ([]byte, error) {
|
|||
// write it anyway, can't hurt
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(hub.HubIndexFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
file, err := os.OpenFile(indexPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while opening hub index file: %w", err)
|
||||
|
@ -92,13 +100,13 @@ func DownloadHubIdx(hub *csconfig.HubCfg) ([]byte, error) {
|
|||
return nil, fmt.Errorf("while writing hub index file: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("Wrote new %d bytes index to %s", wsize, hub.HubIndexFile)
|
||||
log.Infof("Wrote new %d bytes index to %s", wsize, indexPath)
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
// DownloadLatest will download the latest version of Item to the tdir directory
|
||||
func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOnly bool) error {
|
||||
func (h *Hub) DownloadLatest(target *Item, overwrite bool, updateOnly bool) error {
|
||||
var err error
|
||||
|
||||
log.Debugf("Downloading %s %s", target.Type, target.Name)
|
||||
|
@ -109,7 +117,7 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
return nil
|
||||
}
|
||||
|
||||
return DownloadItem(hub, target, overwrite)
|
||||
return h.DownloadItem(target, overwrite)
|
||||
}
|
||||
|
||||
// collection
|
||||
|
@ -117,7 +125,7 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
for idx, ptr := range tmp {
|
||||
ptrtype := ItemTypes[idx]
|
||||
for _, p := range ptr {
|
||||
val, ok := hubIdx.Items[ptrtype][p]
|
||||
val, ok := h.Items[ptrtype][p]
|
||||
if !ok {
|
||||
return fmt.Errorf("required %s %s of %s doesn't exist, abort", ptrtype, p, target.Name)
|
||||
}
|
||||
|
@ -132,7 +140,7 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
if ptrtype == COLLECTIONS {
|
||||
log.Tracef("collection, recurse")
|
||||
|
||||
err = DownloadLatest(hub, &val, overwrite, updateOnly)
|
||||
err = h.DownloadLatest(&val, overwrite, updateOnly)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while downloading %s: %w", val.Name, err)
|
||||
}
|
||||
|
@ -140,7 +148,7 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
|
||||
downloaded := val.Downloaded
|
||||
|
||||
err = DownloadItem(hub, &val, overwrite)
|
||||
err = h.DownloadItem(&val, overwrite)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while downloading %s: %w", val.Name, err)
|
||||
}
|
||||
|
@ -148,16 +156,16 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
// We need to enable an item when it has been added to a collection since latest release of the collection.
|
||||
// We check if val.Downloaded is false because maybe the item has been disabled by the user.
|
||||
if !val.Installed && !downloaded {
|
||||
if err = EnableItem(hub, &val); err != nil {
|
||||
if err = h.EnableItem(&val); err != nil {
|
||||
return fmt.Errorf("enabling '%s': %w", val.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
hubIdx.Items[ptrtype][p] = val
|
||||
h.Items[ptrtype][p] = val
|
||||
}
|
||||
}
|
||||
|
||||
err = DownloadItem(hub, target, overwrite)
|
||||
err = h.DownloadItem(target, overwrite)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download item: %w", err)
|
||||
}
|
||||
|
@ -165,8 +173,8 @@ func DownloadLatest(hub *csconfig.HubCfg, target *Item, overwrite bool, updateOn
|
|||
return nil
|
||||
}
|
||||
|
||||
func DownloadItem(hub *csconfig.HubCfg, target *Item, overwrite bool) error {
|
||||
tdir := hub.HubDir
|
||||
func (h *Hub) DownloadItem(target *Item, overwrite bool) error {
|
||||
tdir := h.cfg.HubDir
|
||||
|
||||
// if user didn't --force, don't overwrite local, tainted, up-to-date files
|
||||
if !overwrite {
|
||||
|
@ -202,12 +210,12 @@ func DownloadItem(hub *csconfig.HubCfg, target *Item, overwrite bool) error {
|
|||
return fmt.Errorf("while reading %s: %w", req.URL.String(), err)
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
if _, err = h.Write(body); err != nil {
|
||||
hash := sha256.New()
|
||||
if _, err = hash.Write(body); err != nil {
|
||||
return fmt.Errorf("while hashing %s: %w", target.Name, err)
|
||||
}
|
||||
|
||||
meow := fmt.Sprintf("%x", h.Sum(nil))
|
||||
meow := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
if meow != target.Versions[target.Version].Digest {
|
||||
log.Errorf("Downloaded version doesn't match index, please 'hub update'")
|
||||
log.Debugf("got %s, expected %s", meow, target.Versions[target.Version].Digest)
|
||||
|
@ -263,18 +271,18 @@ func DownloadItem(hub *csconfig.HubCfg, target *Item, overwrite bool) error {
|
|||
target.Tainted = false
|
||||
target.UpToDate = true
|
||||
|
||||
if err = downloadData(hub.InstallDataDir, overwrite, bytes.NewReader(body)); err != nil {
|
||||
if err = downloadData(h.cfg.InstallDataDir, overwrite, bytes.NewReader(body)); err != nil {
|
||||
return fmt.Errorf("while downloading data for %s: %w", target.FileName, err)
|
||||
}
|
||||
|
||||
hubIdx.Items[target.Type][target.Name] = *target
|
||||
h.Items[target.Type][target.Name] = *target
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DownloadDataIfNeeded downloads the data files for an item
|
||||
func DownloadDataIfNeeded(hub *csconfig.HubCfg, target Item, force bool) error {
|
||||
itemFilePath := fmt.Sprintf("%s/%s/%s/%s", hub.InstallDir, target.Type, target.Stage, target.FileName)
|
||||
func (h *Hub) DownloadDataIfNeeded(target Item, force bool) error {
|
||||
itemFilePath := fmt.Sprintf("%s/%s/%s/%s", h.cfg.InstallDir, target.Type, target.Stage, target.FileName)
|
||||
|
||||
itemFile, err := os.Open(itemFilePath)
|
||||
if err != nil {
|
||||
|
@ -283,7 +291,7 @@ func DownloadDataIfNeeded(hub *csconfig.HubCfg, target Item, force bool) error {
|
|||
|
||||
defer itemFile.Close()
|
||||
|
||||
if err = downloadData(hub.InstallDataDir, force, itemFile); err != nil {
|
||||
if err = downloadData(h.cfg.InstallDataDir, force, itemFile); err != nil {
|
||||
return fmt.Errorf("while downloading data for %s: %w", itemFilePath, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,11 @@ package cwhub
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
)
|
||||
|
||||
func TestDownloadHubIdx(t *testing.T) {
|
||||
|
@ -15,9 +14,18 @@ func TestDownloadHubIdx(t *testing.T) {
|
|||
// bad url template
|
||||
fmt.Println("Test 'bad URL'")
|
||||
|
||||
tmpIndex, err := os.CreateTemp("", "index.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file : %s", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Remove(tmpIndex.Name())
|
||||
})
|
||||
|
||||
RawFileURLTemplate = "x"
|
||||
|
||||
ret, err := DownloadHubIdx(&csconfig.HubCfg{})
|
||||
ret, err := DownloadHubIdx(tmpIndex.Name())
|
||||
if err == nil || !strings.HasPrefix(fmt.Sprintf("%s", err), "failed to build request for hub index: parse ") {
|
||||
log.Errorf("unexpected error %s", err)
|
||||
}
|
||||
|
@ -29,7 +37,7 @@ func TestDownloadHubIdx(t *testing.T) {
|
|||
|
||||
RawFileURLTemplate = "https://baddomain/%s/%s"
|
||||
|
||||
ret, err = DownloadHubIdx(&csconfig.HubCfg{})
|
||||
ret, err = DownloadHubIdx(tmpIndex.Name())
|
||||
if err == nil || !strings.HasPrefix(fmt.Sprintf("%s", err), "failed http request for hub index: Get") {
|
||||
log.Errorf("unexpected error %s", err)
|
||||
}
|
||||
|
@ -41,7 +49,7 @@ func TestDownloadHubIdx(t *testing.T) {
|
|||
|
||||
RawFileURLTemplate = back
|
||||
|
||||
ret, err = DownloadHubIdx(&csconfig.HubCfg{HubIndexFile: "/does/not/exist/index.json"})
|
||||
ret, err = DownloadHubIdx("/does/not/exist/index.json")
|
||||
if err == nil || !strings.HasPrefix(fmt.Sprintf("%s", err), "while opening hub index file: open /does/not/exist/index.json:") {
|
||||
log.Errorf("unexpected error %s", err)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/mod/semver"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
|
||||
)
|
||||
|
||||
|
@ -62,8 +61,8 @@ func SetHubBranch() {
|
|||
}
|
||||
|
||||
// InstallItem installs an item from the hub
|
||||
func InstallItem(csConfig *csconfig.Config, name string, itemType string, force bool, downloadOnly bool) error {
|
||||
item := GetItem(itemType, name)
|
||||
func (h *Hub) InstallItem(name string, itemType string, force bool, downloadOnly bool) error {
|
||||
item := h.GetItem(itemType, name)
|
||||
if item == nil {
|
||||
return fmt.Errorf("unable to retrieve item: %s", name)
|
||||
}
|
||||
|
@ -76,26 +75,26 @@ func InstallItem(csConfig *csconfig.Config, name string, itemType string, force
|
|||
}
|
||||
}
|
||||
|
||||
err := DownloadLatest(csConfig.Hub, item, force, true)
|
||||
err := h.DownloadLatest(item, force, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while downloading %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
if err = AddItem(itemType, *item); err != nil {
|
||||
if err = h.AddItem(itemType, *item); err != nil {
|
||||
return fmt.Errorf("while adding %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
if downloadOnly {
|
||||
log.Infof("Downloaded %s to %s", item.Name, filepath.Join(csConfig.Hub.HubDir, item.RemotePath))
|
||||
log.Infof("Downloaded %s to %s", item.Name, filepath.Join(h.cfg.HubDir, item.RemotePath))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = EnableItem(csConfig.Hub, item)
|
||||
err = h.EnableItem(item)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while enabling %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
if err := AddItem(itemType, *item); err != nil {
|
||||
if err := h.AddItem(itemType, *item); err != nil {
|
||||
return fmt.Errorf("while adding %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
|
@ -105,20 +104,20 @@ func InstallItem(csConfig *csconfig.Config, name string, itemType string, force
|
|||
}
|
||||
|
||||
// RemoveItem removes one - or all - the items from the hub
|
||||
func RemoveMany(csConfig *csconfig.Config, itemType string, name string, all bool, purge bool, forceAction bool) error {
|
||||
func (h *Hub) RemoveMany(itemType string, name string, all bool, purge bool, forceAction bool) error {
|
||||
if name != "" {
|
||||
item := GetItem(itemType, name)
|
||||
item := h.GetItem(itemType, name)
|
||||
if item == nil {
|
||||
return fmt.Errorf("can't find '%s' in %s", name, itemType)
|
||||
}
|
||||
|
||||
err := DisableItem(csConfig.Hub, item, purge, forceAction)
|
||||
err := h.DisableItem(item, purge, forceAction)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to disable %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
if err = AddItem(itemType, *item); err != nil {
|
||||
if err = h.AddItem(itemType, *item); err != nil {
|
||||
return fmt.Errorf("unable to add %s: %w", item.Name, err)
|
||||
}
|
||||
|
||||
|
@ -132,17 +131,17 @@ func RemoveMany(csConfig *csconfig.Config, itemType string, name string, all boo
|
|||
disabled := 0
|
||||
|
||||
// remove all
|
||||
for _, v := range GetItemMap(itemType) {
|
||||
for _, v := range h.GetItemMap(itemType) {
|
||||
if !v.Installed {
|
||||
continue
|
||||
}
|
||||
|
||||
err := DisableItem(csConfig.Hub, &v, purge, forceAction)
|
||||
err := h.DisableItem(&v, purge, forceAction)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to disable %s: %w", v.Name, err)
|
||||
}
|
||||
|
||||
if err := AddItem(itemType, v); err != nil {
|
||||
if err := h.AddItem(itemType, v); err != nil {
|
||||
return fmt.Errorf("unable to add %s: %w", v.Name, err)
|
||||
}
|
||||
disabled++
|
||||
|
@ -154,11 +153,11 @@ func RemoveMany(csConfig *csconfig.Config, itemType string, name string, all boo
|
|||
}
|
||||
|
||||
// UpgradeConfig upgrades an item from the hub
|
||||
func UpgradeConfig(csConfig *csconfig.Config, itemType string, name string, force bool) error {
|
||||
func (h *Hub) UpgradeConfig(itemType string, name string, force bool) error {
|
||||
updated := 0
|
||||
found := false
|
||||
|
||||
for _, v := range GetItemMap(itemType) {
|
||||
for _, v := range h.GetItemMap(itemType) {
|
||||
if name != "" && name != v.Name {
|
||||
continue
|
||||
}
|
||||
|
@ -178,7 +177,7 @@ func UpgradeConfig(csConfig *csconfig.Config, itemType string, name string, forc
|
|||
if v.UpToDate {
|
||||
log.Infof("%s: up-to-date", v.Name)
|
||||
|
||||
if err := DownloadDataIfNeeded(csConfig.Hub, v, force); err != nil {
|
||||
if err := h.DownloadDataIfNeeded(v, force); err != nil {
|
||||
return fmt.Errorf("%s: download failed: %w", v.Name, err)
|
||||
}
|
||||
|
||||
|
@ -187,7 +186,7 @@ func UpgradeConfig(csConfig *csconfig.Config, itemType string, name string, forc
|
|||
}
|
||||
}
|
||||
|
||||
if err := DownloadLatest(csConfig.Hub, &v, force, true); err != nil {
|
||||
if err := h.DownloadLatest(&v, force, true); err != nil {
|
||||
return fmt.Errorf("%s: download failed: %w", v.Name, err)
|
||||
}
|
||||
|
||||
|
@ -205,7 +204,7 @@ func UpgradeConfig(csConfig *csconfig.Config, itemType string, name string, forc
|
|||
updated++
|
||||
}
|
||||
|
||||
if err := AddItem(itemType, v); err != nil {
|
||||
if err := h.AddItem(itemType, v); err != nil {
|
||||
return fmt.Errorf("unable to add %s: %w", v.Name, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,165 +4,165 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
)
|
||||
|
||||
// Download index, install collection. Add scenario to collection (hub-side), update index, upgrade collection
|
||||
// We expect the new scenario to be installed
|
||||
func TestUpgradeConfigNewScenarioInCollection(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
// fresh install of collection
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
|
||||
require.NoError(t, InstallItem(cfg, "crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
require.NoError(t, hub.InstallItem("crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
|
||||
// This is the scenario that gets added in next version of collection
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
|
||||
assertCollectionDepsInstalled(t, "crowdsecurity/test_collection")
|
||||
|
||||
// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
|
||||
pushUpdateToCollectionInHub()
|
||||
|
||||
if err := UpdateHubIdx(cfg.Hub); err != nil {
|
||||
t.Fatalf("failed to download index : %s", err)
|
||||
}
|
||||
hub, err := InitHubUpdate(hub.cfg)
|
||||
require.NoError(t, err, "failed to download index: %s", err)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
|
||||
err := UpgradeConfig(cfg, COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
err = hub.UpgradeConfig(COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
require.NoError(t, err)
|
||||
assertCollectionDepsInstalled(t, "crowdsecurity/test_collection")
|
||||
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
}
|
||||
|
||||
// Install a collection, disable a scenario.
|
||||
// Upgrade should install should not enable/download the disabled scenario.
|
||||
func TestUpgradeConfigInDisabledScenarioShouldNotBeInstalled(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
// fresh install of collection
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
|
||||
require.NoError(t, InstallItem(cfg, "crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
require.NoError(t, hub.InstallItem("crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
assertCollectionDepsInstalled(t, "crowdsecurity/test_collection")
|
||||
|
||||
err := RemoveMany(cfg, SCENARIOS, "crowdsecurity/foobar_scenario", false, false, false)
|
||||
err := hub.RemoveMany(SCENARIOS, "crowdsecurity/foobar_scenario", false, false, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
// scenario referenced by collection was deleted hence, collection should be tainted
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
|
||||
if err = UpdateHubIdx(cfg.Hub); err != nil {
|
||||
t.Fatalf("failed to download index : %s", err)
|
||||
}
|
||||
hub, err = InitHubUpdate(hub.cfg)
|
||||
require.NoError(t, err, "failed to download index: %s", err)
|
||||
|
||||
err = UpgradeConfig(cfg, COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
err = hub.UpgradeConfig(COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
}
|
||||
|
||||
func getHubIdxOrFail(t *testing.T) {
|
||||
if err := GetHubIdx(getTestCfg().Hub); err != nil {
|
||||
t.Fatalf("failed to load hub index")
|
||||
}
|
||||
// getHubOrFail refreshes the hub state (load index, sync) and returns the singleton, or fails the test
|
||||
func getHubOrFail(t *testing.T, hubCfg *csconfig.HubCfg) *Hub {
|
||||
hub, err := InitHub(hubCfg)
|
||||
require.NoError(t, err, "failed to load hub index")
|
||||
return hub
|
||||
}
|
||||
|
||||
// Install a collection. Disable a referenced scenario. Publish new version of collection with new scenario
|
||||
// Upgrade should not enable/download the disabled scenario.
|
||||
// Upgrade should install and enable the newly added scenario.
|
||||
func TestUpgradeConfigNewScenarioIsInstalledWhenReferencedScenarioIsDisabled(t *testing.T) {
|
||||
cfg := envSetup(t)
|
||||
defer envTearDown(cfg)
|
||||
hub := envSetup(t)
|
||||
|
||||
// fresh install of collection
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
|
||||
require.NoError(t, InstallItem(cfg, "crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
require.NoError(t, hub.InstallItem("crowdsecurity/test_collection", COLLECTIONS, false, false))
|
||||
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
assertCollectionDepsInstalled(t, "crowdsecurity/test_collection")
|
||||
|
||||
err := RemoveMany(cfg, SCENARIOS, "crowdsecurity/foobar_scenario", false, false, false)
|
||||
err := hub.RemoveMany(SCENARIOS, "crowdsecurity/foobar_scenario", false, false, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
// scenario referenced by collection was deleted hence, collection should be tainted
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Downloaded) // this fails
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hubIdx.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Downloaded) // this fails
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Downloaded)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].Installed)
|
||||
require.True(t, hub.Items[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||
|
||||
// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
|
||||
// we now attempt to upgrade the collection, however it shouldn't install the foobar_scenario
|
||||
// we just removed. Nor should it install the newly added scenario
|
||||
pushUpdateToCollectionInHub()
|
||||
|
||||
if err = UpdateHubIdx(cfg.Hub); err != nil {
|
||||
t.Fatalf("failed to download index : %s", err)
|
||||
}
|
||||
hub, err = InitHubUpdate(hub.cfg)
|
||||
require.NoError(t, err, "failed to download index: %s", err)
|
||||
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
getHubIdxOrFail(t)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
|
||||
err = UpgradeConfig(cfg, COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
err = hub.UpgradeConfig(COLLECTIONS, "crowdsecurity/test_collection", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
getHubIdxOrFail(t)
|
||||
require.False(t, hubIdx.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hubIdx.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
hub = getHubOrFail(t, hub.cfg)
|
||||
require.False(t, hub.Items[SCENARIOS]["crowdsecurity/foobar_scenario"].Installed)
|
||||
require.True(t, hub.Items[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||
}
|
||||
|
||||
func assertCollectionDepsInstalled(t *testing.T, collection string) {
|
||||
t.Helper()
|
||||
|
||||
c := hubIdx.Items[COLLECTIONS][collection]
|
||||
require.NoError(t, CollecDepsCheck(&c))
|
||||
hub, err := GetHub()
|
||||
require.NoError(t, err)
|
||||
|
||||
c := hub.Items[COLLECTIONS][collection]
|
||||
require.NoError(t, hub.CollectDepsCheck(&c))
|
||||
}
|
||||
|
||||
func pushUpdateToCollectionInHub() {
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -20,24 +22,38 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// XXX: The order is important, as it is used to construct the
|
||||
// index tree in memory --> collections must be last
|
||||
ItemTypes = []string{PARSERS, POSTOVERFLOWS, SCENARIOS, COLLECTIONS, WAAP_RULES}
|
||||
hubIdx = HubIndex{}
|
||||
// XXX: The order is important, as it is used to range over sub-items in collections
|
||||
ItemTypes = []string{PARSERS, POSTOVERFLOWS, SCENARIOS, WAAP_RULES, COLLECTIONS}
|
||||
)
|
||||
|
||||
type HubItems map[string]map[string]Item
|
||||
|
||||
// HubIndex represents the runtime status of the hub (parsed items, etc.)
|
||||
// XXX: this could be renamed "Hub" tout court once the confusion with HubCfg is cleared
|
||||
type HubIndex struct {
|
||||
// Hub represents the runtime status of the hub (parsed items, etc.)
|
||||
type Hub struct {
|
||||
Items HubItems
|
||||
cfg *csconfig.HubCfg
|
||||
skippedLocal int
|
||||
skippedTainted int
|
||||
}
|
||||
|
||||
var theHub *Hub
|
||||
|
||||
// GetHub returns the hub singleton
|
||||
// it returns an error if it's not initialized to avoid nil dereference
|
||||
func GetHub() (*Hub, error) {
|
||||
if theHub == nil {
|
||||
return nil, fmt.Errorf("hub not initialized")
|
||||
}
|
||||
|
||||
return theHub, nil
|
||||
}
|
||||
|
||||
func (h Hub) GetDataDir() string {
|
||||
return h.cfg.InstallDataDir
|
||||
}
|
||||
|
||||
// displaySummary prints a total count of the hub items
|
||||
func (h HubIndex) displaySummary() {
|
||||
func (h Hub) displaySummary() {
|
||||
msg := "Loaded: "
|
||||
for itemType := range h.Items {
|
||||
msg += fmt.Sprintf("%d %s, ", len(h.Items[itemType]), itemType)
|
||||
|
@ -51,8 +67,14 @@ func (h HubIndex) displaySummary() {
|
|||
|
||||
// DisplaySummary prints a total count of the hub items.
|
||||
// It is a wrapper around HubIndex.displaySummary() to avoid exporting the hub singleton
|
||||
func DisplaySummary() {
|
||||
hubIdx.displaySummary()
|
||||
// XXX: to be removed later
|
||||
func DisplaySummary() error {
|
||||
hub, err := GetHub()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hub.displaySummary()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseIndex takes the content of a .index.json file and returns the map of associated parsers/scenarios/collections
|
||||
|
@ -85,7 +107,7 @@ func ParseIndex(buff []byte) (HubItems, error) {
|
|||
|
||||
// if it's a collection, check its sub-items are present
|
||||
// XXX should be done later
|
||||
for idx, ptr := range [][]string{item.Parsers, item.PostOverflows, item.Scenarios, item.Collections} {
|
||||
for idx, ptr := range [][]string{item.Parsers, item.PostOverflows, item.Scenarios, item.WaapRules, item.Collections} {
|
||||
ptrtype := ItemTypes[idx]
|
||||
for _, p := range ptr {
|
||||
if _, ok := RawIndex[ptrtype][p]; !ok {
|
|
@ -6,12 +6,10 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
)
|
||||
|
||||
func purgeItem(hub *csconfig.HubCfg, target Item) (Item, error) {
|
||||
itempath := hub.HubDir + "/" + target.RemotePath
|
||||
func (h *Hub) purgeItem(target Item) (Item, error) {
|
||||
itempath := h.cfg.HubDir + "/" + target.RemotePath
|
||||
|
||||
// disable hub file
|
||||
if err := os.Remove(itempath); err != nil {
|
||||
|
@ -20,19 +18,19 @@ func purgeItem(hub *csconfig.HubCfg, target Item) (Item, error) {
|
|||
|
||||
target.Downloaded = false
|
||||
log.Infof("Removed source file [%s]: %s", target.Name, itempath)
|
||||
hubIdx.Items[target.Type][target.Name] = target
|
||||
h.Items[target.Type][target.Name] = target
|
||||
|
||||
return target, nil
|
||||
}
|
||||
|
||||
// DisableItem to disable an item managed by the hub, removes the symlink if purge is true
|
||||
func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) error {
|
||||
func (h *Hub) DisableItem(target *Item, purge bool, force bool) error {
|
||||
var err error
|
||||
|
||||
// already disabled, noop unless purge
|
||||
if !target.Installed {
|
||||
if purge {
|
||||
*target, err = purgeItem(hub, *target)
|
||||
*target, err = h.purgeItem(*target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -54,7 +52,7 @@ func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) err
|
|||
for idx, ptr := range [][]string{target.Parsers, target.PostOverflows, target.Scenarios, target.Collections} {
|
||||
ptrtype := ItemTypes[idx]
|
||||
for _, p := range ptr {
|
||||
if val, ok := hubIdx.Items[ptrtype][p]; ok {
|
||||
if val, ok := h.Items[ptrtype][p]; ok {
|
||||
// check if the item doesn't belong to another collection before removing it
|
||||
toRemove := true
|
||||
|
||||
|
@ -66,7 +64,7 @@ func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) err
|
|||
}
|
||||
|
||||
if toRemove {
|
||||
err = DisableItem(hub, &val, purge, force)
|
||||
err = h.DisableItem(&val, purge, force)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while disabling %s: %w", p, err)
|
||||
}
|
||||
|
@ -80,7 +78,7 @@ func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) err
|
|||
}
|
||||
}
|
||||
|
||||
syml, err := filepath.Abs(hub.InstallDir + "/" + target.Type + "/" + target.Stage + "/" + target.FileName)
|
||||
syml, err := filepath.Abs(h.cfg.InstallDir + "/" + target.Type + "/" + target.Stage + "/" + target.FileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -103,7 +101,7 @@ func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) err
|
|||
return fmt.Errorf("while reading symlink: %w", err)
|
||||
}
|
||||
|
||||
absPath, err := filepath.Abs(hub.HubDir + "/" + target.RemotePath)
|
||||
absPath, err := filepath.Abs(h.cfg.HubDir + "/" + target.RemotePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while abs path: %w", err)
|
||||
}
|
||||
|
@ -124,23 +122,23 @@ func DisableItem(hub *csconfig.HubCfg, target *Item, purge bool, force bool) err
|
|||
target.Installed = false
|
||||
|
||||
if purge {
|
||||
*target, err = purgeItem(hub, *target)
|
||||
*target, err = h.purgeItem(*target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
hubIdx.Items[target.Type][target.Name] = *target
|
||||
h.Items[target.Type][target.Name] = *target
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// creates symlink between actual config file at hub.HubDir and hub.ConfigDir
|
||||
// Handles collections recursively
|
||||
func EnableItem(hub *csconfig.HubCfg, target *Item) error {
|
||||
func (h *Hub) EnableItem(target *Item) error {
|
||||
var err error
|
||||
|
||||
parentDir := filepath.Clean(hub.InstallDir + "/" + target.Type + "/" + target.Stage + "/")
|
||||
parentDir := filepath.Clean(h.cfg.InstallDir + "/" + target.Type + "/" + target.Stage + "/")
|
||||
|
||||
// create directories if needed
|
||||
if target.Installed {
|
||||
|
@ -172,12 +170,12 @@ func EnableItem(hub *csconfig.HubCfg, target *Item) error {
|
|||
for idx, ptr := range [][]string{target.Parsers, target.PostOverflows, target.Scenarios, target.Collections} {
|
||||
ptrtype := ItemTypes[idx]
|
||||
for _, p := range ptr {
|
||||
val, ok := hubIdx.Items[ptrtype][p]
|
||||
val, ok := h.Items[ptrtype][p]
|
||||
if !ok {
|
||||
return fmt.Errorf("required %s %s of %s doesn't exist, abort", ptrtype, p, target.Name)
|
||||
}
|
||||
|
||||
err = EnableItem(hub, &val)
|
||||
err = h.EnableItem(&val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while installing %s: %w", p, err)
|
||||
}
|
||||
|
@ -192,7 +190,7 @@ func EnableItem(hub *csconfig.HubCfg, target *Item) error {
|
|||
}
|
||||
|
||||
// hub.ConfigDir + target.RemotePath
|
||||
srcPath, err := filepath.Abs(hub.HubDir + "/" + target.RemotePath)
|
||||
srcPath, err := filepath.Abs(h.cfg.HubDir + "/" + target.RemotePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while getting source path: %w", err)
|
||||
}
|
||||
|
@ -208,7 +206,7 @@ func EnableItem(hub *csconfig.HubCfg, target *Item) error {
|
|||
|
||||
log.Infof("Enabled %s : %s", target.Type, target.Name)
|
||||
target.Installed = true
|
||||
hubIdx.Items[target.Type][target.Name] = *target
|
||||
h.Items[target.Type][target.Name] = *target
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -19,10 +19,6 @@ func isYAMLFileName(path string) bool {
|
|||
return strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml")
|
||||
}
|
||||
|
||||
func validItemFileName(vname string, fauthor string, fname string) bool {
|
||||
return (fauthor+"/"+fname == vname+".yaml") || (fauthor+"/"+fname == vname+".yml")
|
||||
}
|
||||
|
||||
func handleSymlink(path string) (string, error) {
|
||||
hubpath, err := os.Readlink(path)
|
||||
if err != nil {
|
||||
|
@ -60,19 +56,6 @@ func getSHA256(filepath string) (string, error) {
|
|||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
type Walker struct {
|
||||
// the walk/parserVisit function can't receive extra args
|
||||
hubdir string
|
||||
installdir string
|
||||
}
|
||||
|
||||
func NewWalker(hub *csconfig.HubCfg) Walker {
|
||||
return Walker{
|
||||
hubdir: hub.HubDir,
|
||||
installdir: hub.InstallDir,
|
||||
}
|
||||
}
|
||||
|
||||
type itemFileInfo struct {
|
||||
fname string
|
||||
stage string
|
||||
|
@ -80,16 +63,19 @@ type itemFileInfo struct {
|
|||
fauthor string
|
||||
}
|
||||
|
||||
func (w Walker) getItemInfo(path string) (itemFileInfo, bool, error) {
|
||||
func (h *Hub) getItemInfo(path string) (itemFileInfo, bool, error) {
|
||||
ret := itemFileInfo{}
|
||||
inhub := false
|
||||
|
||||
hubDir := h.cfg.HubDir
|
||||
installDir := h.cfg.InstallDir
|
||||
|
||||
subs := strings.Split(path, string(os.PathSeparator))
|
||||
|
||||
log.Tracef("path:%s, hubdir:%s, installdir:%s", path, w.hubdir, w.installdir)
|
||||
log.Tracef("path:%s, hubdir:%s, installdir:%s", path, hubDir, installDir)
|
||||
log.Tracef("subs:%v", subs)
|
||||
// we're in hub (~/.hub/hub/)
|
||||
if strings.HasPrefix(path, w.hubdir) {
|
||||
if strings.HasPrefix(path, hubDir) {
|
||||
log.Tracef("in hub dir")
|
||||
|
||||
inhub = true
|
||||
|
@ -104,7 +90,7 @@ func (w Walker) getItemInfo(path string) (itemFileInfo, bool, error) {
|
|||
ret.fauthor = subs[len(subs)-2]
|
||||
ret.stage = subs[len(subs)-3]
|
||||
ret.ftype = subs[len(subs)-4]
|
||||
} else if strings.HasPrefix(path, w.installdir) { // we're in install /etc/crowdsec/<type>/...
|
||||
} else if strings.HasPrefix(path, installDir) { // we're in install /etc/crowdsec/<type>/...
|
||||
log.Tracef("in install dir")
|
||||
if len(subs) < 3 {
|
||||
return itemFileInfo{}, false, fmt.Errorf("path is too short: %s (%d)", path, len(subs))
|
||||
|
@ -118,7 +104,7 @@ func (w Walker) getItemInfo(path string) (itemFileInfo, bool, error) {
|
|||
ret.ftype = subs[len(subs)-3]
|
||||
ret.fauthor = ""
|
||||
} else {
|
||||
return itemFileInfo{}, false, fmt.Errorf("file '%s' is not from hub '%s' nor from the configuration directory '%s'", path, w.hubdir, w.installdir)
|
||||
return itemFileInfo{}, false, fmt.Errorf("file '%s' is not from hub '%s' nor from the configuration directory '%s'", path, hubDir, installDir)
|
||||
}
|
||||
|
||||
log.Tracef("stage:%s ftype:%s", ret.stage, ret.ftype)
|
||||
|
@ -143,7 +129,7 @@ func (w Walker) getItemInfo(path string) (itemFileInfo, bool, error) {
|
|||
return ret, inhub, nil
|
||||
}
|
||||
|
||||
func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
||||
func (h *Hub) itemVisit(path string, f os.DirEntry, err error) error {
|
||||
var (
|
||||
local bool
|
||||
hubpath string
|
||||
|
@ -169,7 +155,7 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
info, inhub, err := w.getItemInfo(path)
|
||||
info, inhub, err := h.getItemInfo(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -200,12 +186,12 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
// if it's not a symlink and not in hub, it's a local file, don't bother
|
||||
if local && !inhub {
|
||||
log.Tracef("%s is a local file, skip", path)
|
||||
hubIdx.skippedLocal++
|
||||
h.skippedLocal++
|
||||
// log.Infof("local scenario, skip.")
|
||||
|
||||
_, fileName := filepath.Split(path)
|
||||
|
||||
hubIdx.Items[info.ftype][info.fname] = Item{
|
||||
h.Items[info.ftype][info.fname] = Item{
|
||||
Name: info.fname,
|
||||
Stage: info.stage,
|
||||
Installed: true,
|
||||
|
@ -224,7 +210,7 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
|
||||
match := false
|
||||
|
||||
for name, item := range hubIdx.Items[info.ftype] {
|
||||
for name, item := range h.Items[info.ftype] {
|
||||
log.Tracef("check [%s] vs [%s] : %s", info.fname, item.RemotePath, info.ftype+"/"+info.stage+"/"+info.fname+".yaml")
|
||||
|
||||
if info.fname != item.FileName {
|
||||
|
@ -244,12 +230,12 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
continue
|
||||
}
|
||||
|
||||
// wrong file
|
||||
if !validItemFileName(item.Name, info.fauthor, info.fname) {
|
||||
// not the item we're looking for
|
||||
if !item.validPath(info.fauthor, info.fname) {
|
||||
continue
|
||||
}
|
||||
|
||||
if path == w.hubdir+"/"+item.RemotePath {
|
||||
if path == h.cfg.HubDir+"/"+item.RemotePath {
|
||||
log.Tracef("marking %s as downloaded", item.Name)
|
||||
item.Downloaded = true
|
||||
}
|
||||
|
@ -306,7 +292,7 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
if !match {
|
||||
log.Tracef("got tainted match for %s: %s", item.Name, path)
|
||||
|
||||
hubIdx.skippedTainted++
|
||||
h.skippedTainted++
|
||||
// the file and the stage is right, but the hash is wrong, it has been tainted by user
|
||||
if !inhub {
|
||||
item.LocalPath = path
|
||||
|
@ -319,7 +305,7 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
item.LocalHash = sha
|
||||
}
|
||||
|
||||
hubIdx.Items[info.ftype][name] = item
|
||||
h.Items[info.ftype][name] = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -329,13 +315,13 @@ func (w Walker) itemVisit(path string, f os.DirEntry, err error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func CollecDepsCheck(v *Item) error {
|
||||
if v.versionStatus() != 0 { // not up-to-date
|
||||
log.Debugf("%s dependencies not checked : not up-to-date", v.Name)
|
||||
func (h *Hub) CollectDepsCheck(v *Item) error {
|
||||
if v.Type != COLLECTIONS {
|
||||
return nil
|
||||
}
|
||||
|
||||
if v.Type != COLLECTIONS {
|
||||
if v.versionStatus() != 0 { // not up-to-date
|
||||
log.Debugf("%s dependencies not checked: not up-to-date", v.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -345,7 +331,7 @@ func CollecDepsCheck(v *Item) error {
|
|||
for idx, itemSlice := range [][]string{v.Parsers, v.PostOverflows, v.Scenarios, v.Collections} {
|
||||
sliceType := ItemTypes[idx]
|
||||
for _, subName := range itemSlice {
|
||||
subItem, ok := hubIdx.Items[sliceType][subName]
|
||||
subItem, ok := h.Items[sliceType][subName]
|
||||
if !ok {
|
||||
return fmt.Errorf("referred %s %s in collection %s doesn't exist", sliceType, subName, v.Name)
|
||||
}
|
||||
|
@ -359,7 +345,7 @@ func CollecDepsCheck(v *Item) error {
|
|||
if subItem.Type == COLLECTIONS {
|
||||
log.Tracef("collec, recurse.")
|
||||
|
||||
if err := CollecDepsCheck(&subItem); err != nil {
|
||||
if err := h.CollectDepsCheck(&subItem); err != nil {
|
||||
if subItem.Tainted {
|
||||
v.Tainted = true
|
||||
}
|
||||
|
@ -367,7 +353,7 @@ func CollecDepsCheck(v *Item) error {
|
|||
return fmt.Errorf("sub collection %s is broken: %w", subItem.Name, err)
|
||||
}
|
||||
|
||||
hubIdx.Items[sliceType][subName] = subItem
|
||||
h.Items[sliceType][subName] = subItem
|
||||
}
|
||||
|
||||
// propagate the state of sub-items to set
|
||||
|
@ -398,7 +384,7 @@ func CollecDepsCheck(v *Item) error {
|
|||
subItem.BelongsToCollections = append(subItem.BelongsToCollections, v.Name)
|
||||
}
|
||||
|
||||
hubIdx.Items[sliceType][subName] = subItem
|
||||
h.Items[sliceType][subName] = subItem
|
||||
|
||||
log.Tracef("checking for %s - tainted:%t uptodate:%t", subName, v.Tainted, v.UpToDate)
|
||||
}
|
||||
|
@ -407,7 +393,7 @@ func CollecDepsCheck(v *Item) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func SyncDir(hub *csconfig.HubCfg, dir string) ([]string, error) {
|
||||
func (h *Hub) SyncDir(dir string) ([]string, error) {
|
||||
warnings := []string{}
|
||||
|
||||
// For each, scan PARSERS, POSTOVERFLOWS, SCENARIOS and COLLECTIONS last
|
||||
|
@ -417,13 +403,13 @@ func SyncDir(hub *csconfig.HubCfg, dir string) ([]string, error) {
|
|||
log.Errorf("failed %s : %s", cpath, err)
|
||||
}
|
||||
|
||||
err = filepath.WalkDir(cpath, NewWalker(hub).itemVisit)
|
||||
err = filepath.WalkDir(cpath, h.itemVisit)
|
||||
if err != nil {
|
||||
return warnings, err
|
||||
}
|
||||
}
|
||||
|
||||
for name, item := range hubIdx.Items[COLLECTIONS] {
|
||||
for name, item := range h.Items[COLLECTIONS] {
|
||||
if !item.Installed {
|
||||
continue
|
||||
}
|
||||
|
@ -431,9 +417,9 @@ func SyncDir(hub *csconfig.HubCfg, dir string) ([]string, error) {
|
|||
vs := item.versionStatus()
|
||||
switch vs {
|
||||
case 0: // latest
|
||||
if err := CollecDepsCheck(&item); err != nil {
|
||||
if err := h.CollectDepsCheck(&item); err != nil {
|
||||
warnings = append(warnings, fmt.Sprintf("dependency of %s: %s", item.Name, err))
|
||||
hubIdx.Items[COLLECTIONS][name] = item
|
||||
h.Items[COLLECTIONS][name] = item
|
||||
}
|
||||
case 1: // not up-to-date
|
||||
warnings = append(warnings, fmt.Sprintf("update for collection %s available (currently:%s, latest:%s)", item.Name, item.LocalVersion, item.Version))
|
||||
|
@ -448,51 +434,55 @@ func SyncDir(hub *csconfig.HubCfg, dir string) ([]string, error) {
|
|||
}
|
||||
|
||||
// Updates the info from HubInit() with the local state
|
||||
func LocalSync(hub *csconfig.HubCfg) ([]string, error) {
|
||||
hubIdx.skippedLocal = 0
|
||||
hubIdx.skippedTainted = 0
|
||||
func (h *Hub) LocalSync() ([]string, error) {
|
||||
h.skippedLocal = 0
|
||||
h.skippedTainted = 0
|
||||
|
||||
warnings, err := SyncDir(hub, hub.InstallDir)
|
||||
warnings, err := h.SyncDir(h.cfg.InstallDir)
|
||||
if err != nil {
|
||||
return warnings, fmt.Errorf("failed to scan %s: %w", hub.InstallDir, err)
|
||||
return warnings, fmt.Errorf("failed to scan %s: %w", h.cfg.InstallDir, err)
|
||||
}
|
||||
|
||||
_, err = SyncDir(hub, hub.HubDir)
|
||||
_, err = h.SyncDir(h.cfg.HubDir)
|
||||
if err != nil {
|
||||
return warnings, fmt.Errorf("failed to scan %s: %w", hub.HubDir, err)
|
||||
return warnings, fmt.Errorf("failed to scan %s: %w", h.cfg.HubDir, err)
|
||||
}
|
||||
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
func GetHubIdx(hub *csconfig.HubCfg) error {
|
||||
if hub == nil {
|
||||
return fmt.Errorf("no configuration found for hub")
|
||||
// InitHub initializes the Hub, syncs the local state and returns the singleton for immediate use
|
||||
func InitHub(cfg *csconfig.HubCfg) (*Hub, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("no configuration found for hub")
|
||||
}
|
||||
|
||||
log.Debugf("loading hub idx %s", hub.HubIndexFile)
|
||||
log.Debugf("loading hub idx %s", cfg.HubIndexFile)
|
||||
|
||||
bidx, err := os.ReadFile(hub.HubIndexFile)
|
||||
bidx, err := os.ReadFile(cfg.HubIndexFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read index file: %w", err)
|
||||
return nil, fmt.Errorf("unable to read index file: %w", err)
|
||||
}
|
||||
|
||||
ret, err := ParseIndex(bidx)
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrMissingReference) {
|
||||
return fmt.Errorf("unable to load existing index: %w", err)
|
||||
return nil, fmt.Errorf("unable to load existing index: %w", err)
|
||||
}
|
||||
|
||||
// XXX: why the error check if we bail out anyway?
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hubIdx = HubIndex{Items: ret}
|
||||
theHub = &Hub{
|
||||
Items: ret,
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
_, err = LocalSync(hub)
|
||||
_, err = theHub.LocalSync()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sync Hub index with local deployment : %w", err)
|
||||
return nil, fmt.Errorf("failed to sync Hub index with local deployment : %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return theHub, nil
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ type HubTest struct {
|
|||
TemplateConfigPath string
|
||||
TemplateProfilePath string
|
||||
TemplateSimulationPath string
|
||||
HubIndex *cwhub.HubIndex
|
||||
HubIndex *cwhub.Hub
|
||||
Tests []*HubTestItem
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ func NewHubTest(hubPath string, crowdsecPath string, cscliPath string) (HubTest,
|
|||
TemplateConfigPath: templateConfigFilePath,
|
||||
TemplateProfilePath: templateProfilePath,
|
||||
TemplateSimulationPath: templateSimulationPath,
|
||||
HubIndex: &cwhub.HubIndex{Items: hubIndex},
|
||||
HubIndex: &cwhub.Hub{Items: hubIndex},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ type HubTestItem struct {
|
|||
TemplateConfigPath string
|
||||
TemplateProfilePath string
|
||||
TemplateSimulationPath string
|
||||
HubIndex *cwhub.HubIndex
|
||||
HubIndex *cwhub.Hub
|
||||
|
||||
Config *HubTestItemConfig
|
||||
|
||||
|
@ -391,16 +391,16 @@ func (t *HubTestItem) InstallHub() error {
|
|||
}
|
||||
|
||||
// load installed hub
|
||||
err := cwhub.GetHubIdx(t.RuntimeHubConfig)
|
||||
hub, err := cwhub.InitHub(t.RuntimeHubConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("can't local sync the hub: %+v", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// install data for parsers if needed
|
||||
ret := cwhub.GetItemMap(cwhub.PARSERS)
|
||||
ret := hub.GetItemMap(cwhub.PARSERS)
|
||||
for parserName, item := range ret {
|
||||
if item.Installed {
|
||||
if err := cwhub.DownloadDataIfNeeded(t.RuntimeHubConfig, item, true); err != nil {
|
||||
if err := hub.DownloadDataIfNeeded(item, true); err != nil {
|
||||
return fmt.Errorf("unable to download data for parser '%s': %+v", parserName, err)
|
||||
}
|
||||
log.Debugf("parser '%s' installed successfully in runtime environment", parserName)
|
||||
|
@ -408,10 +408,10 @@ func (t *HubTestItem) InstallHub() error {
|
|||
}
|
||||
|
||||
// install data for scenarios if needed
|
||||
ret = cwhub.GetItemMap(cwhub.SCENARIOS)
|
||||
ret = hub.GetItemMap(cwhub.SCENARIOS)
|
||||
for scenarioName, item := range ret {
|
||||
if item.Installed {
|
||||
if err := cwhub.DownloadDataIfNeeded(t.RuntimeHubConfig, item, true); err != nil {
|
||||
if err := hub.DownloadDataIfNeeded(item, true); err != nil {
|
||||
return fmt.Errorf("unable to download data for parser '%s': %+v", scenarioName, err)
|
||||
}
|
||||
log.Debugf("scenario '%s' installed successfully in runtime environment", scenarioName)
|
||||
|
@ -419,10 +419,10 @@ func (t *HubTestItem) InstallHub() error {
|
|||
}
|
||||
|
||||
// install data for postoverflows if needed
|
||||
ret = cwhub.GetItemMap(cwhub.POSTOVERFLOWS)
|
||||
ret = hub.GetItemMap(cwhub.POSTOVERFLOWS)
|
||||
for postoverflowName, item := range ret {
|
||||
if item.Installed {
|
||||
if err := cwhub.DownloadDataIfNeeded(t.RuntimeHubConfig, item, true); err != nil {
|
||||
if err := hub.DownloadDataIfNeeded(item, true); err != nil {
|
||||
return fmt.Errorf("unable to download data for parser '%s': %+v", postoverflowName, err)
|
||||
}
|
||||
log.Debugf("postoverflow '%s' installed successfully in runtime environment", postoverflowName)
|
||||
|
|
|
@ -8,12 +8,14 @@ import (
|
|||
"html/template"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/parser"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
|
@ -33,7 +35,20 @@ func TestBucket(t *testing.T) {
|
|||
envSetting = os.Getenv("TEST_ONLY")
|
||||
tomb = &tomb.Tomb{}
|
||||
)
|
||||
err := exprhelpers.Init(nil)
|
||||
|
||||
testdata := "./tests"
|
||||
|
||||
hubCfg := &csconfig.HubCfg{
|
||||
HubDir: filepath.Join(testdata, "hub"),
|
||||
HubIndexFile: filepath.Join(testdata, "hub", "index.json"),
|
||||
}
|
||||
|
||||
_, err := cwhub.InitHub(hubCfg)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to init hub : %s", err)
|
||||
}
|
||||
|
||||
err = exprhelpers.Init(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("exprhelpers init failed: %s", err)
|
||||
}
|
||||
|
@ -44,12 +59,15 @@ func TestBucket(t *testing.T) {
|
|||
}
|
||||
} else {
|
||||
wg := new(sync.WaitGroup)
|
||||
fds, err := os.ReadDir("./tests/")
|
||||
fds, err := os.ReadDir(testdata)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read test directory : %s", err)
|
||||
}
|
||||
for _, fd := range fds {
|
||||
fname := "./tests/" + fd.Name()
|
||||
if fd.Name() == "hub" {
|
||||
continue
|
||||
}
|
||||
fname := filepath.Join(testdata, fd.Name())
|
||||
log.Infof("Running test on %s", fname)
|
||||
tomb.Go(func() error {
|
||||
wg.Add(1)
|
||||
|
@ -112,10 +130,8 @@ func testOneBucket(t *testing.T, dir string, tomb *tomb.Tomb) error {
|
|||
files = append(files, x.Filename)
|
||||
}
|
||||
|
||||
cscfg := &csconfig.CrowdsecServiceCfg{
|
||||
DataDir: "tests",
|
||||
}
|
||||
holders, response, err := LoadBuckets(cscfg, files, tomb, buckets, false)
|
||||
cscfg := &csconfig.CrowdsecServiceCfg{}
|
||||
holders, response, err := LoadBuckets(cscfg, "tests", files, tomb, buckets, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed loading bucket : %s", err)
|
||||
}
|
||||
|
@ -123,7 +139,7 @@ func testOneBucket(t *testing.T, dir string, tomb *tomb.Tomb) error {
|
|||
watchTomb(tomb)
|
||||
return nil
|
||||
})
|
||||
if !testFile(t, dir+"/test.json", dir+"/in-buckets_state.json", holders, response, buckets) {
|
||||
if !testFile(t, filepath.Join(dir, "test.json"), filepath.Join(dir, "in-buckets_state.json"), holders, response, buckets) {
|
||||
return fmt.Errorf("tests from %s failed", dir)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -179,12 +179,17 @@ func ValidateFactory(bucketFactory *BucketFactory) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func LoadBuckets(cscfg *csconfig.CrowdsecServiceCfg, files []string, tomb *tomb.Tomb, buckets *Buckets, orderEvent bool) ([]BucketFactory, chan types.Event, error) {
|
||||
func LoadBuckets(cscfg *csconfig.CrowdsecServiceCfg, dataDir string, files []string, tomb *tomb.Tomb, buckets *Buckets, orderEvent bool) ([]BucketFactory, chan types.Event, error) {
|
||||
var (
|
||||
ret = []BucketFactory{}
|
||||
response chan types.Event
|
||||
)
|
||||
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
response = make(chan types.Event, 1)
|
||||
for _, f := range files {
|
||||
log.Debugf("Loading '%s'", f)
|
||||
|
@ -212,7 +217,7 @@ func LoadBuckets(cscfg *csconfig.CrowdsecServiceCfg, files []string, tomb *tomb.
|
|||
log.Tracef("End of yaml file")
|
||||
break
|
||||
}
|
||||
bucketFactory.DataDir = cscfg.DataDir
|
||||
bucketFactory.DataDir = dataDir
|
||||
//check empty
|
||||
if bucketFactory.Name == "" {
|
||||
log.Errorf("Won't load nameless bucket")
|
||||
|
@ -235,7 +240,7 @@ func LoadBuckets(cscfg *csconfig.CrowdsecServiceCfg, files []string, tomb *tomb.
|
|||
bucketFactory.Filename = filepath.Clean(f)
|
||||
bucketFactory.BucketName = seed.Generate()
|
||||
bucketFactory.ret = response
|
||||
hubItem, err := cwhub.GetItemByPath(cwhub.SCENARIOS, bucketFactory.Filename)
|
||||
hubItem, err := hub.GetItemByPath(cwhub.SCENARIOS, bucketFactory.Filename)
|
||||
if err != nil {
|
||||
log.Errorf("scenario %s (%s) couldn't be find in hub (ignore if in unit tests)", bucketFactory.Name, bucketFactory.Filename)
|
||||
} else {
|
||||
|
|
1
pkg/leakybucket/tests/hub/index.json
Normal file
1
pkg/leakybucket/tests/hub/index.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -64,8 +64,12 @@ func NewParsers() *Parsers {
|
|||
StageFiles: make([]Stagefile, 0),
|
||||
PovfwStageFiles: make([]Stagefile, 0),
|
||||
}
|
||||
|
||||
// XXX: handle error
|
||||
hub, _ := cwhub.GetHub()
|
||||
|
||||
for _, itemType := range []string{cwhub.PARSERS, cwhub.POSTOVERFLOWS} {
|
||||
for _, hubParserItem := range cwhub.GetItemMap(itemType) {
|
||||
for _, hubParserItem := range hub.GetItemMap(itemType) {
|
||||
if hubParserItem.Installed {
|
||||
stagefile := Stagefile{
|
||||
Filename: hubParserItem.LocalPath,
|
||||
|
@ -97,16 +101,16 @@ func NewParsers() *Parsers {
|
|||
func LoadParsers(cConfig *csconfig.Config, parsers *Parsers) (*Parsers, error) {
|
||||
var err error
|
||||
|
||||
patternsDir := filepath.Join(cConfig.Crowdsec.ConfigDir, "patterns/")
|
||||
patternsDir := filepath.Join(cConfig.ConfigPaths.ConfigDir, "patterns/")
|
||||
log.Infof("Loading grok library %s", patternsDir)
|
||||
/* load base regexps for two grok parsers */
|
||||
parsers.Ctx, err = Init(map[string]interface{}{"patterns": patternsDir,
|
||||
"data": cConfig.Crowdsec.DataDir})
|
||||
"data": cConfig.ConfigPaths.DataDir})
|
||||
if err != nil {
|
||||
return parsers, fmt.Errorf("failed to load parser patterns : %v", err)
|
||||
}
|
||||
parsers.Povfwctx, err = Init(map[string]interface{}{"patterns": patternsDir,
|
||||
"data": cConfig.Crowdsec.DataDir})
|
||||
"data": cConfig.ConfigPaths.DataDir})
|
||||
if err != nil {
|
||||
return parsers, fmt.Errorf("failed to load postovflw parser patterns : %v", err)
|
||||
}
|
||||
|
@ -116,7 +120,7 @@ func LoadParsers(cConfig *csconfig.Config, parsers *Parsers) (*Parsers, error) {
|
|||
*/
|
||||
log.Infof("Loading enrich plugins")
|
||||
|
||||
parsers.EnricherCtx, err = Loadplugin(cConfig.Crowdsec.DataDir)
|
||||
parsers.EnricherCtx, err = Loadplugin(cConfig.ConfigPaths.DataDir)
|
||||
if err != nil {
|
||||
return parsers, fmt.Errorf("failed to load enrich plugin : %v", err)
|
||||
}
|
||||
|
|
|
@ -54,7 +54,8 @@ func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error
|
|||
|
||||
cwhub.SetHubBranch()
|
||||
|
||||
if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
|
||||
hub, err := cwhub.InitHub(csConfig.Hub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting hub index: %w", err)
|
||||
}
|
||||
|
||||
|
@ -75,7 +76,7 @@ func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, collection, cwhub.COLLECTIONS, forceAction, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(collection, cwhub.COLLECTIONS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing collection %s: %w", collection, err)
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, parser, cwhub.PARSERS, forceAction, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(parser, cwhub.PARSERS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing parser %s: %w", parser, err)
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, scenario, cwhub.SCENARIOS, forceAction, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(scenario, cwhub.SCENARIOS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing scenario %s: %w", scenario, err)
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +118,7 @@ func InstallHubItems(csConfig *csconfig.Config, input []byte, dryRun bool) error
|
|||
continue
|
||||
}
|
||||
|
||||
if err := cwhub.InstallItem(csConfig, postoverflow, cwhub.POSTOVERFLOWS, forceAction, downloadOnly); err != nil {
|
||||
if err := hub.InstallItem(postoverflow, cwhub.POSTOVERFLOWS, forceAction, downloadOnly); err != nil {
|
||||
return fmt.Errorf("while installing postoverflow %s: %w", postoverflow, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"strings"
|
||||
|
||||
corazatypes "github.com/crowdsecurity/coraza/v3/types"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
|
@ -37,7 +36,12 @@ func LoadCollection(collection string) (WaapCollection, error) {
|
|||
//FIXME: do it once globally
|
||||
waapRules := make(map[string]WaapCollectionConfig)
|
||||
|
||||
for _, hubWafRuleItem := range cwhub.GetItemMap(cwhub.WAAP_RULES) {
|
||||
hub, err := cwhub.GetHub()
|
||||
if err != nil {
|
||||
return WaapCollection{}, fmt.Errorf("unable to load hub : %s", err)
|
||||
}
|
||||
|
||||
for _, hubWafRuleItem := range hub.GetItemMap(cwhub.WAAP_RULES) {
|
||||
log.Infof("loading %s", hubWafRuleItem.LocalPath)
|
||||
if !hubWafRuleItem.Installed {
|
||||
continue
|
||||
|
@ -86,7 +90,7 @@ func LoadCollection(collection string) (WaapCollection, error) {
|
|||
|
||||
if loadedRule.SecLangFilesRules != nil {
|
||||
for _, rulesFile := range loadedRule.SecLangFilesRules {
|
||||
fullPath := filepath.Join(csconfig.DataDir, rulesFile)
|
||||
fullPath := filepath.Join(hub.GetDataDir(), rulesFile)
|
||||
c, err := os.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
log.Errorf("unable to read file %s : %s", rulesFile, err)
|
||||
|
|
Loading…
Reference in a new issue