cscli hub mgmt improvements (#710)

* avoid this confusing behaviour where 'cscli parsers/scenarios/... upgrade' won't tell a thing if no arguments are given (and won't do anything neither)

* avoid repeating warnings about available update to the user
This commit is contained in:
Thibault "bui" Koechlin 2021-03-29 10:33:23 +02:00 committed by GitHub
parent 20ccb32124
commit 20ef67a699
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 26 deletions

View file

@ -98,6 +98,9 @@ func NewCollectionsCmd() *cobra.Command {
if all {
UpgradeConfig(cwhub.COLLECTIONS, "", forceAction)
} else {
if len(args) == 0 {
log.Fatalf("no target collection to upgrade")
}
for _, name := range args {
UpgradeConfig(cwhub.COLLECTIONS, name, forceAction)
}

View file

@ -40,6 +40,7 @@ cscli hub update # Download list of available configurations from the hub
Short: "List installed configs",
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
if err := csConfig.LoadHub(); err != nil {
log.Fatalf(err.Error())
}
@ -47,7 +48,11 @@ cscli hub update # Download list of available configurations from the hub
log.Fatalf("Failed to get Hub index : %v", err)
log.Infoln("Run 'sudo cscli hub update' to get the hub index")
}
//use LocalSync to get warnings about tainted / outdated items
_, warn := cwhub.LocalSync(csConfig.Hub)
for _, v := range warn {
log.Info(v)
}
cwhub.DisplaySummary()
log.Printf("PARSERS:")
ListItem(cwhub.PARSERS, args)
@ -86,6 +91,11 @@ Fetches the [.index.json](https://github.com/crowdsecurity/hub/blob/master/.inde
if err := cwhub.UpdateHubIdx(csConfig.Hub); err != nil {
log.Fatalf("Failed to get Hub index : %v", err)
}
//use LocalSync to get warnings about tainted / outdated items
_, warn := cwhub.LocalSync(csConfig.Hub)
for _, v := range warn {
log.Info(v)
}
},
}
cmdHub.AddCommand(cmdHubUpdate)
@ -115,6 +125,7 @@ Upgrade all configs installed from Crowdsec Hub. Run 'sudo cscli hub update' if
log.Fatalf("Failed to get Hub index : %v", err)
log.Infoln("Run 'sudo cscli hub update' to get the hub index")
}
log.Infof("Upgrading collections")
UpgradeConfig(cwhub.COLLECTIONS, "", forceAction)
log.Infof("Upgrading parsers")

View file

@ -93,6 +93,9 @@ cscli parsers remove crowdsecurity/sshd-logs
if all {
UpgradeConfig(cwhub.PARSERS, "", forceAction)
} else {
if len(args) == 0 {
log.Fatalf("no target parser to upgrade")
}
for _, name := range args {
UpgradeConfig(cwhub.PARSERS, name, forceAction)
}

View file

@ -92,6 +92,9 @@ func NewPostOverflowsCmd() *cobra.Command {
if all {
UpgradeConfig(cwhub.PARSERS_OVFLW, "", forceAction)
} else {
if len(args) == 0 {
log.Fatalf("no target postoverflow to upgrade")
}
for _, name := range args {
UpgradeConfig(cwhub.PARSERS_OVFLW, name, forceAction)
}

View file

@ -93,6 +93,9 @@ cscli scenarios remove crowdsecurity/ssh-bf
if all {
UpgradeConfig(cwhub.SCENARIOS, "", forceAction)
} else {
if len(args) == 0 {
log.Fatalf("no target scenario to upgrade")
}
for _, name := range args {
UpgradeConfig(cwhub.SCENARIOS, name, forceAction)
}

View file

@ -12,6 +12,7 @@ import (
"github.com/enescakir/emoji"
"github.com/pkg/errors"
"golang.org/x/mod/semver"
log "github.com/sirupsen/logrus"
)
@ -78,6 +79,11 @@ var skippedTainted = 0
var ReferenceMissingError = errors.New("Reference(s) missing in collection")
var MissingHubIndex = errors.New("hub index can't be found")
//GetVersionStatus : semver requires 'v' prefix
func GetVersionStatus(v *Item) int {
return semver.Compare("v"+v.Version, "v"+v.LocalVersion)
}
// calculate sha256 of a file
func getSHA256(filepath string) (string, error) {
/* Digest of file */

View file

@ -193,7 +193,7 @@ func testInstallItem(cfg *csconfig.Hub, t *testing.T, item Item) {
if err != nil {
t.Fatalf("error while downloading %s : %v", item.Name, err)
}
if err := LocalSync(cfg); err != nil {
if err, _ := LocalSync(cfg); err != nil {
t.Fatalf("taint: failed to run localSync : %s", err)
}
if !hubIdx[item.Type][item.Name].UpToDate {
@ -210,7 +210,7 @@ func testInstallItem(cfg *csconfig.Hub, t *testing.T, item Item) {
if err != nil {
t.Fatalf("error while enabled %s : %v.", item.Name, err)
}
if err := LocalSync(cfg); err != nil {
if err, _ := LocalSync(cfg); err != nil {
t.Fatalf("taint: failed to run localSync : %s", err)
}
if !hubIdx[item.Type][item.Name].Installed {
@ -232,7 +232,7 @@ func testTaintItem(cfg *csconfig.Hub, t *testing.T, item Item) {
}
f.Close()
//Local sync and check status
if err := LocalSync(cfg); err != nil {
if err, _ := LocalSync(cfg); err != nil {
t.Fatalf("taint: failed to run localSync : %s", err)
}
if !hubIdx[item.Type][item.Name].Tainted {
@ -251,7 +251,7 @@ func testUpdateItem(cfg *csconfig.Hub, t *testing.T, item Item) {
t.Fatalf("failed to update %s : %s", item.Name, err)
}
//Local sync and check status
if err := LocalSync(cfg); err != nil {
if err, _ := LocalSync(cfg); err != nil {
t.Fatalf("failed to run localSync : %s", err)
}
if !hubIdx[item.Type][item.Name].UpToDate {
@ -272,8 +272,8 @@ func testDisableItem(cfg *csconfig.Hub, t *testing.T, item Item) {
t.Fatalf("failed to disable item : %v", err)
}
//Local sync and check status
if err := LocalSync(cfg); err != nil {
t.Fatalf("failed to run localSync : %s", err)
if err, warns := LocalSync(cfg); err != nil || len(warns) > 0 {
t.Fatalf("failed to run localSync : %s (%+v)", err, warns)
}
if hubIdx[item.Type][item.Name].Tainted {
t.Fatalf("disable: %s should not be tainted anymore", item.Name)
@ -290,8 +290,8 @@ func testDisableItem(cfg *csconfig.Hub, t *testing.T, item Item) {
t.Fatalf("failed to purge item : %v", err)
}
//Local sync and check status
if err := LocalSync(cfg); err != nil {
t.Fatalf("failed to run localSync : %s", err)
if err, warns := LocalSync(cfg); err != nil || len(warns) > 0 {
t.Fatalf("failed to run localSync : %s (%+v)", err, warns)
}
if hubIdx[item.Type][item.Name].Installed {
t.Fatalf("disable: %s should not be installed anymore", item.Name)

View file

@ -35,7 +35,7 @@ func UpdateHubIdx(hub *csconfig.Hub) error {
}
}
hubIdx = ret
if err := LocalSync(hub); err != nil {
if err, _ := LocalSync(hub); err != nil {
return errors.Wrap(err, "failed to sync")
}
return nil

View file

@ -8,6 +8,7 @@ import (
"sort"
"github.com/pkg/errors"
"golang.org/x/mod/semver"
//"log"
@ -101,7 +102,6 @@ func parser_visit(path string, f os.FileInfo, err error) error {
//non symlinks are local user files or hub files
if f.Mode()&os.ModeSymlink == 0 {
local = true
skippedLocal++
log.Tracef("%s isn't a symlink", path)
} else {
hubpath, err = os.Readlink(path)
@ -243,6 +243,12 @@ func parser_visit(path string, f os.FileInfo, err error) error {
}
func CollecDepsCheck(v *Item) error {
if GetVersionStatus(v) != 0 { //not up-to-date
log.Debugf("%s dependencies not checked : not up-to-date", v.Name)
return nil
}
/*if it's a collection, ensure all the items are installed, or tag it as tainted*/
if v.Type == COLLECTIONS {
log.Tracef("checking submembers of %s installed:%t", v.Name, v.Installed)
@ -294,10 +300,11 @@ func CollecDepsCheck(v *Item) error {
return nil
}
func SyncDir(hub *csconfig.Hub, dir string) error {
func SyncDir(hub *csconfig.Hub, dir string) (error, []string) {
hubdir = hub.HubDir
installdir = hub.ConfigDir
indexpath = hub.HubIndexFile
warnings := []string{}
/*For each, scan PARSERS, PARSERS_OVFLW, SCENARIOS and COLLECTIONS last*/
for _, scan := range ItemTypes {
@ -307,33 +314,44 @@ func SyncDir(hub *csconfig.Hub, dir string) error {
}
err = filepath.Walk(cpath, parser_visit)
if err != nil {
return err
return err, warnings
}
}
for k, v := range hubIdx[COLLECTIONS] {
if err := CollecDepsCheck(&v); err != nil {
log.Infof("dependency issue %s : %s", v.Name, err)
if v.Installed {
versStat := GetVersionStatus(&v)
if versStat == 0 { //latest
if err := CollecDepsCheck(&v); err != nil {
warnings = append(warnings, fmt.Sprintf("dependency of %s : %s", v.Name, err))
hubIdx[COLLECTIONS][k] = v
}
} else if versStat == 1 { //not up-to-date
warnings = append(warnings, fmt.Sprintf("update for collection %s available (currently:%s, latest:%s)", v.Name, v.LocalVersion, v.Version))
} else { //version is higher than the highest available from hub?
warnings = append(warnings, fmt.Sprintf("collection %s is in the future (currently:%s, latest:%s)", v.Name, v.LocalVersion, v.Version))
}
log.Debugf("installed (%s) - status:%d | installed:%s | latest : %s | full : %+v", v.Name, semver.Compare("v"+v.Version, "v"+v.LocalVersion), v.LocalVersion, v.Version, v.Versions)
}
hubIdx[COLLECTIONS][k] = v
}
return nil
return nil, warnings
}
/* Updates the infos from HubInit() with the local state */
func LocalSync(hub *csconfig.Hub) error {
func LocalSync(hub *csconfig.Hub) (error, []string) {
skippedLocal = 0
skippedTainted = 0
for _, dir := range []string{hub.ConfigDir, hub.HubDir} {
log.Debugf("scanning %s", dir)
if err := SyncDir(hub, dir); err != nil {
return fmt.Errorf("failed to scan %s : %s", dir, err)
}
err, warnings := SyncDir(hub, hub.ConfigDir)
if err != nil {
return fmt.Errorf("failed to scan %s : %s", hub.ConfigDir, err), warnings
}
return nil
err, _ = SyncDir(hub, hub.HubDir)
if err != nil {
return fmt.Errorf("failed to scan %s : %s", hub.HubDir, err), warnings
}
return nil, warnings
}
func GetHubIdx(hub *csconfig.Hub) error {
@ -353,7 +371,8 @@ func GetHubIdx(hub *csconfig.Hub) error {
return err
}
hubIdx = ret
if err := LocalSync(hub); err != nil {
err, _ = LocalSync(hub)
if err != nil {
log.Fatalf("Failed to sync Hub index with local deployment : %v", err)
}
return nil