Fix json output of cscli hub list (#1143)
* Fix json output of cscli hub list * Fix functional tests. Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
This commit is contained in:
parent
cf175ab07e
commit
6c4ec64ca9
|
@ -142,7 +142,7 @@ func NewCollectionsCmd() *cobra.Command {
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
ListItem(cwhub.COLLECTIONS, args, false, true)
|
ListItems([]string{cwhub.COLLECTIONS}, args, false, true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdCollectionsList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
cmdCollectionsList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
||||||
|
|
|
@ -56,14 +56,7 @@ cscli hub update # Download list of available configurations from the hub
|
||||||
log.Info(v)
|
log.Info(v)
|
||||||
}
|
}
|
||||||
cwhub.DisplaySummary()
|
cwhub.DisplaySummary()
|
||||||
log.Printf("PARSERS:")
|
ListItems([]string{cwhub.PARSERS, cwhub.COLLECTIONS, cwhub.SCENARIOS, cwhub.PARSERS_OVFLW}, args, true, false)
|
||||||
ListItem(cwhub.PARSERS, args, true, true)
|
|
||||||
log.Printf("SCENARIOS:")
|
|
||||||
ListItem(cwhub.SCENARIOS, args, true, false)
|
|
||||||
log.Printf("COLLECTIONS:")
|
|
||||||
ListItem(cwhub.COLLECTIONS, args, true, false)
|
|
||||||
log.Printf("POSTOVERFLOWS:")
|
|
||||||
ListItem(cwhub.PARSERS_OVFLW, args, true, false)
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
cmdHubList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
||||||
|
|
|
@ -132,7 +132,7 @@ cscli parsers remove crowdsecurity/sshd-logs
|
||||||
cscli parser list crowdsecurity/xxx`,
|
cscli parser list crowdsecurity/xxx`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
ListItem(cwhub.PARSERS, args, false, true)
|
ListItems([]string{cwhub.PARSERS}, args, false, true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdParsersList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
cmdParsersList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
||||||
|
|
|
@ -130,7 +130,7 @@ func NewPostOverflowsCmd() *cobra.Command {
|
||||||
cscli postoverflows list crowdsecurity/xxx`,
|
cscli postoverflows list crowdsecurity/xxx`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
ListItem(cwhub.PARSERS_OVFLW, args, false, true)
|
ListItems([]string{cwhub.PARSERS_OVFLW}, args, false, true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdPostOverflowsList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
cmdPostOverflowsList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
||||||
|
|
|
@ -132,7 +132,7 @@ cscli scenarios remove crowdsecurity/ssh-bf
|
||||||
cscli scenarios list crowdsecurity/xxx`,
|
cscli scenarios list crowdsecurity/xxx`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
ListItem(cwhub.SCENARIOS, args, false, true)
|
ListItems([]string{cwhub.SCENARIOS}, args, false, true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdScenariosList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
cmdScenariosList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
|
||||||
|
|
|
@ -102,31 +102,35 @@ func setHubBranch() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListItem(itemType string, args []string, showType bool, showHeader bool) {
|
func ListItems(itemTypes []string, args []string, showType bool, showHeader bool) {
|
||||||
|
|
||||||
var hubStatus []map[string]string
|
var hubStatusByItemType = make(map[string][]cwhub.ItemHubStatus)
|
||||||
|
|
||||||
if len(args) == 1 {
|
for _, itemType := range itemTypes {
|
||||||
hubStatus = cwhub.HubStatus(itemType, args[0], all)
|
if len(args) == 1 {
|
||||||
} else {
|
// This means that user requested a specific item by name
|
||||||
hubStatus = cwhub.HubStatus(itemType, "", all)
|
hubStatusByItemType[itemType] = cwhub.GetHubStatusForItemType(itemType, args[0], all)
|
||||||
|
} else {
|
||||||
|
hubStatusByItemType[itemType] = cwhub.GetHubStatusForItemType(itemType, "", all)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if csConfig.Cscli.Output == "human" {
|
if csConfig.Cscli.Output == "human" {
|
||||||
|
for itemType, statuses := range hubStatusByItemType {
|
||||||
table := tablewriter.NewWriter(os.Stdout)
|
fmt.Println(strings.ToUpper(itemType))
|
||||||
table.SetCenterSeparator("")
|
table := tablewriter.NewWriter(os.Stdout)
|
||||||
table.SetColumnSeparator("")
|
table.SetCenterSeparator("")
|
||||||
|
table.SetColumnSeparator("")
|
||||||
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
|
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
|
||||||
table.SetAlignment(tablewriter.ALIGN_LEFT)
|
table.SetAlignment(tablewriter.ALIGN_LEFT)
|
||||||
table.SetHeader([]string{"Name", fmt.Sprintf("%v Status", emoji.Package), "Version", "Local Path"})
|
table.SetHeader([]string{"Name", fmt.Sprintf("%v Status", emoji.Package), "Version", "Local Path"})
|
||||||
for _, v := range hubStatus {
|
for _, status := range statuses {
|
||||||
table.Append([]string{v["name"], v["utf8_status"], v["local_version"], v["local_path"]})
|
table.Append([]string{status.Name, status.UTF8_Status, status.LocalVersion, status.LocalPath})
|
||||||
|
}
|
||||||
|
table.Render()
|
||||||
}
|
}
|
||||||
table.Render()
|
|
||||||
} else if csConfig.Cscli.Output == "json" {
|
} else if csConfig.Cscli.Output == "json" {
|
||||||
x, err := json.MarshalIndent(hubStatus, "", " ")
|
x, err := json.MarshalIndent(hubStatusByItemType, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to unmarshal")
|
log.Fatalf("failed to unmarshal")
|
||||||
}
|
}
|
||||||
|
@ -147,22 +151,24 @@ func ListItem(itemType string, args []string, showType bool, showHeader bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
for _, v := range hubStatus {
|
for itemType, statuses := range hubStatusByItemType {
|
||||||
if v["local_version"] == "" {
|
for _, status := range statuses {
|
||||||
v["local_version"] = "n/a"
|
if status.LocalVersion == "" {
|
||||||
}
|
status.LocalVersion = "n/a"
|
||||||
row := []string{
|
}
|
||||||
v["name"],
|
row := []string{
|
||||||
v["status"],
|
status.Name,
|
||||||
v["local_version"],
|
status.Status,
|
||||||
v["description"],
|
status.LocalVersion,
|
||||||
}
|
status.Description,
|
||||||
if showType {
|
}
|
||||||
row = append(row, itemType)
|
if showType {
|
||||||
}
|
row = append(row, itemType)
|
||||||
err := csvwriter.Write(row)
|
}
|
||||||
if err != nil {
|
err := csvwriter.Write(row)
|
||||||
log.Fatalf("failed to write raw output : %s", err)
|
if err != nil {
|
||||||
|
log.Fatalf("failed to write raw output : %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
csvwriter.Flush()
|
csvwriter.Flush()
|
||||||
|
|
|
@ -35,6 +35,15 @@ type ItemVersion struct {
|
||||||
Deprecated bool
|
Deprecated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ItemHubStatus struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
LocalVersion string `json:"local_version"`
|
||||||
|
LocalPath string `json:"local_path"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
UTF8_Status string `json:"utf8_status"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
//Item can be : parsed, scenario, collection
|
//Item can be : parsed, scenario, collection
|
||||||
type Item struct {
|
type Item struct {
|
||||||
/*descriptive info*/
|
/*descriptive info*/
|
||||||
|
@ -72,6 +81,27 @@ type Item struct {
|
||||||
Collections []string `yaml:"collections,omitempty"`
|
Collections []string `yaml:"collections,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Item) toHubStatus() ItemHubStatus {
|
||||||
|
hubStatus := ItemHubStatus{}
|
||||||
|
hubStatus.Name = i.Name
|
||||||
|
hubStatus.LocalVersion = i.LocalVersion
|
||||||
|
hubStatus.LocalPath = i.LocalPath
|
||||||
|
hubStatus.Description = i.Description
|
||||||
|
|
||||||
|
status, ok, warning, managed := ItemStatus(*i)
|
||||||
|
hubStatus.Status = status
|
||||||
|
if !managed {
|
||||||
|
hubStatus.UTF8_Status = fmt.Sprintf("%v %s", emoji.House, status)
|
||||||
|
} else if !i.Installed {
|
||||||
|
hubStatus.UTF8_Status = fmt.Sprintf("%v %s", emoji.Prohibited, status)
|
||||||
|
} else if warning {
|
||||||
|
hubStatus.UTF8_Status = fmt.Sprintf("%v %s", emoji.Warning, status)
|
||||||
|
} else if ok {
|
||||||
|
hubStatus.UTF8_Status = fmt.Sprintf("%v %s", emoji.CheckMark, status)
|
||||||
|
}
|
||||||
|
return hubStatus
|
||||||
|
}
|
||||||
|
|
||||||
var skippedLocal = 0
|
var skippedLocal = 0
|
||||||
var skippedTainted = 0
|
var skippedTainted = 0
|
||||||
|
|
||||||
|
@ -240,18 +270,18 @@ func GetUpstreamInstalledScenarios() ([]Item, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a list of entries for packages : name, status, local_path, local_version, utf8_status (fancy)
|
//Returns a list of entries for packages : name, status, local_path, local_version, utf8_status (fancy)
|
||||||
func HubStatus(itemType string, name string, all bool) []map[string]string {
|
func GetHubStatusForItemType(itemType string, name string, all bool) []ItemHubStatus {
|
||||||
if _, ok := hubIdx[itemType]; !ok {
|
if _, ok := hubIdx[itemType]; !ok {
|
||||||
log.Errorf("type %s doesn't exist", itemType)
|
log.Errorf("type %s doesn't exist", itemType)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret []map[string]string
|
var ret = make([]ItemHubStatus, 0)
|
||||||
/*remember, you do it for the user :)*/
|
/*remember, you do it for the user :)*/
|
||||||
for _, item := range hubIdx[itemType] {
|
for _, item := range hubIdx[itemType] {
|
||||||
if name != "" && name != item.Name {
|
if name != "" && name != item.Name {
|
||||||
//user has required a specific name
|
//user has requested a specific name
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//Only enabled items ?
|
//Only enabled items ?
|
||||||
|
@ -259,23 +289,7 @@ func HubStatus(itemType string, name string, all bool) []map[string]string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//Check the item status
|
//Check the item status
|
||||||
status, ok, warning, managed := ItemStatus(item)
|
ret = append(ret, item.toHubStatus())
|
||||||
tmp := make(map[string]string)
|
|
||||||
tmp["name"] = item.Name
|
|
||||||
tmp["status"] = status
|
|
||||||
tmp["local_version"] = item.LocalVersion
|
|
||||||
tmp["local_path"] = item.LocalPath
|
|
||||||
tmp["description"] = item.Description
|
|
||||||
if !managed {
|
|
||||||
tmp["utf8_status"] = fmt.Sprintf("%v %s", emoji.House, status)
|
|
||||||
} else if !item.Installed {
|
|
||||||
tmp["utf8_status"] = fmt.Sprintf("%v %s", emoji.Prohibited, status)
|
|
||||||
} else if warning {
|
|
||||||
tmp["utf8_status"] = fmt.Sprintf("%v %s", emoji.Warning, status)
|
|
||||||
} else if ok {
|
|
||||||
tmp["utf8_status"] = fmt.Sprintf("%v %s", emoji.CheckMark, status)
|
|
||||||
}
|
|
||||||
ret = append(ret, tmp)
|
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,10 +321,10 @@ func TestInstallParser(t *testing.T) {
|
||||||
for _, it := range hubIdx[PARSERS] {
|
for _, it := range hubIdx[PARSERS] {
|
||||||
testInstallItem(cfg.Hub, t, it)
|
testInstallItem(cfg.Hub, t, it)
|
||||||
it = hubIdx[PARSERS][it.Name]
|
it = hubIdx[PARSERS][it.Name]
|
||||||
_ = HubStatus(PARSERS, it.Name, false)
|
_ = GetHubStatusForItemType(PARSERS, it.Name, false)
|
||||||
testTaintItem(cfg.Hub, t, it)
|
testTaintItem(cfg.Hub, t, it)
|
||||||
it = hubIdx[PARSERS][it.Name]
|
it = hubIdx[PARSERS][it.Name]
|
||||||
_ = HubStatus(PARSERS, it.Name, false)
|
_ = GetHubStatusForItemType(PARSERS, it.Name, false)
|
||||||
testUpdateItem(cfg.Hub, t, it)
|
testUpdateItem(cfg.Hub, t, it)
|
||||||
it = hubIdx[PARSERS][it.Name]
|
it = hubIdx[PARSERS][it.Name]
|
||||||
testDisableItem(cfg.Hub, t, it)
|
testDisableItem(cfg.Hub, t, it)
|
||||||
|
@ -361,7 +361,7 @@ func TestInstallCollection(t *testing.T) {
|
||||||
testDisableItem(cfg.Hub, t, it)
|
testDisableItem(cfg.Hub, t, it)
|
||||||
|
|
||||||
it = hubIdx[COLLECTIONS][it.Name]
|
it = hubIdx[COLLECTIONS][it.Name]
|
||||||
x := HubStatus(COLLECTIONS, it.Name, false)
|
x := GetHubStatusForItemType(COLLECTIONS, it.Name, false)
|
||||||
log.Printf("%+v", x)
|
log.Printf("%+v", x)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ ${CSCLI_BIN} collections list || fail "failed to list collections"
|
||||||
BASE_COLLECTION_COUNT=2
|
BASE_COLLECTION_COUNT=2
|
||||||
|
|
||||||
# we expect 1 collections : linux
|
# we expect 1 collections : linux
|
||||||
${CSCLI_BIN} collections list -ojson | ${JQ} ". | length == ${BASE_COLLECTION_COUNT}" || fail "(first) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
${CSCLI_BIN} collections list -ojson | ${JQ} ".collections | length == ${BASE_COLLECTION_COUNT}" || fail "(first) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
||||||
|
|
||||||
# install an extra collection
|
# install an extra collection
|
||||||
${CSCLI} collections install crowdsecurity/mysql || fail "failed to install collection"
|
${CSCLI} collections install crowdsecurity/mysql || fail "failed to install collection"
|
||||||
|
@ -18,7 +18,7 @@ ${CSCLI} collections install crowdsecurity/mysql || fail "failed to install coll
|
||||||
BASE_COLLECTION_COUNT=$(($BASE_COLLECTION_COUNT+1))
|
BASE_COLLECTION_COUNT=$(($BASE_COLLECTION_COUNT+1))
|
||||||
|
|
||||||
# we should now have 2 collections :)
|
# we should now have 2 collections :)
|
||||||
${CSCLI_BIN} collections list -ojson | ${JQ} ". | length == ${BASE_COLLECTION_COUNT}" || fail "(post install) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
${CSCLI_BIN} collections list -ojson | ${JQ} ".collections | length == ${BASE_COLLECTION_COUNT}" || fail "(post install) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
||||||
|
|
||||||
# remove the collection
|
# remove the collection
|
||||||
${CSCLI} collections remove crowdsecurity/mysql || fail "failed to remove collection"
|
${CSCLI} collections remove crowdsecurity/mysql || fail "failed to remove collection"
|
||||||
|
@ -26,5 +26,5 @@ ${CSCLI} collections remove crowdsecurity/mysql || fail "failed to remove collec
|
||||||
BASE_COLLECTION_COUNT=$(($BASE_COLLECTION_COUNT-1))
|
BASE_COLLECTION_COUNT=$(($BASE_COLLECTION_COUNT-1))
|
||||||
|
|
||||||
# we expect 1 collections : linux
|
# we expect 1 collections : linux
|
||||||
${CSCLI_BIN} collections list -ojson | ${JQ} ". | length == ${BASE_COLLECTION_COUNT}" || fail "(post remove) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
${CSCLI_BIN} collections list -ojson | ${JQ} ".collections | length == ${BASE_COLLECTION_COUNT}" || fail "(post remove) expected exactly ${BASE_COLLECTION_COUNT} collection"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue