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:
parent
20ccb32124
commit
20ef67a699
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue