add silent flag

This commit is contained in:
danielgrunbergerarmo
2021-08-26 13:50:48 +03:00
parent 5a5f2b408c
commit b2fcf295ce
9 changed files with 90 additions and 77 deletions
-3
View File
@@ -1,7 +1,5 @@
package armotypes
import "github.com/golang/glog"
var IgnoreLabels = []string{AttributeCluster, AttributeNamespace}
// DigestPortalDesignator - get cluster namespace and labels from designator
@@ -12,7 +10,6 @@ func DigestPortalDesignator(designator *PortalDesignator) (string, string, map[s
// case DesignatorWlid: TODO
// case DesignatorWildWlid: TODO
default:
glog.Warningf("in 'digestPortalDesignator' designator type: '%v' not yet supported. please contact Armo team", designator.DesignatorType)
}
return "", "", nil
}
+23 -1
View File
@@ -10,6 +10,16 @@ import (
"github.com/mattn/go-isatty"
)
var silent = false
func SetSilentMode(s bool) {
silent = s
}
func IsSilent() bool {
return silent
}
var FailureDisplay = color.New(color.Bold, color.FgHiRed).FprintfFunc()
var FailureTextDisplay = color.New(color.Faint, color.FgHiRed).FprintfFunc()
var InfoDisplay = color.New(color.Bold, color.FgHiYellow).FprintfFunc()
@@ -20,19 +30,31 @@ var DescriptionDisplay = color.New(color.Faint, color.FgWhite).FprintfFunc()
var Spinner *spinner.Spinner
func ScanStartDisplay() {
if !IsSilent() {
InfoDisplay(os.Stdout, "ARMO security scanner starting\n")
}
}
func SuccessTextDisplay(str string) {
if IsSilent() {
return
}
SuccessDisplay(os.Stdout, "[success] ")
SimpleDisplay(os.Stdout, fmt.Sprintf("%s\n", str))
}
func ProgressTextDisplay(str string) {
if IsSilent() {
return
}
InfoDisplay(os.Stdout, "[progress] ")
SimpleDisplay(os.Stdout, fmt.Sprintf("%s\n", str))
}
func StartSpinner() {
if isatty.IsTerminal(os.Stdout.Fd()) {
if isatty.IsTerminal(os.Stdout.Fd()) && !IsSilent() {
Spinner = spinner.New(spinner.CharSets[7], 100*time.Millisecond) // Build our new spinner
Spinner.Start()
}
+5 -5
View File
@@ -150,9 +150,9 @@ type PolicyIdentifier struct {
}
type ScanInfo struct {
PolicyIdentifier PolicyIdentifier `json:"policyIdentifier"`
Output string `json:"output"`
ExcludedNamespaces string `json:"excludedNamespaces"`
Input []string `json:"input"`
Silent bool `json:"silent"`
PolicyIdentifier PolicyIdentifier
Output string
ExcludedNamespaces string
InputPatterns []string
Silent bool
}
+7 -6
View File
@@ -18,6 +18,8 @@ import (
)
var scanInfo opapolicy.ScanInfo
var supportedFrameworks = []string{"nsa", "mitre"}
var isSilent bool
type CLIHandler struct {
policyHandler *policyhandler.PolicyHandler
@@ -42,22 +44,22 @@ var frameworkCmd = &cobra.Command{
scanInfo.PolicyIdentifier = opapolicy.PolicyIdentifier{}
scanInfo.PolicyIdentifier.Kind = opapolicy.KindFramework
scanInfo.PolicyIdentifier.Name = args[0]
scanInfo.Input = args[1:]
scanInfo.InputPatterns = args[1:]
cautils.SetSilentMode(scanInfo.Silent)
CliSetup()
},
}
func isValidFramework(framework string) bool {
return framework == "nsa" || framework != "mitre"
return cautils.StringInSlice(supportedFrameworks, framework) != cautils.ValueNotFound
}
func init() {
scanCmd.AddCommand(frameworkCmd)
scanInfo = opapolicy.ScanInfo{}
frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "excluded-namespaces", "e", "", "namespaces to exclude from check")
frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "namespaces to exclude from check")
frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "pretty-printer", "output format")
frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "silent output")
}
func processYamlInput(yamls string) {
@@ -106,8 +108,7 @@ func NewCLIHandler(policyHandler *policyhandler.PolicyHandler) *CLIHandler {
}
func (clihandler *CLIHandler) Scan() error {
cautils.InfoDisplay(os.Stdout, "ARMO security scanner starting\n")
cautils.ScanStartDisplay()
policyNotification := &opapolicy.PolicyNotification{
NotificationType: opapolicy.TypeExecPostureScan,
Rules: []opapolicy.PolicyIdentifier{
-2
View File
@@ -56,7 +56,6 @@ func (opap *OPAProcessor) ProcessRulesListenner() {
}
func (opap *OPAProcessor) ProcessRulesHandler(opaSessionObj *cautils.OPASessionObj) error {
glog.Infof(fmt.Sprintf("Starting 'ProcessRulesHandler'. reportID: %s", opaSessionObj.PostureReport.ReportID))
cautils.ProgressTextDisplay(fmt.Sprintf("Scanning cluster %s", cautils.ClusterName))
cautils.StartSpinner()
frameworkReports := []opapolicy.FrameworkReport{}
@@ -99,7 +98,6 @@ func (opap *OPAProcessor) ProcessRulesHandler(opaSessionObj *cautils.OPASessionO
opaSessionObj.PostureReport.FrameworkReports = frameworkReports
opaSessionObj.PostureReport.ReportGenerationTime = time.Now().UTC()
glog.Infof(fmt.Sprintf("Done 'ProcessRulesHandler'. reportID: %s", opaSessionObj.PostureReport.ReportID))
cautils.StopSpinner()
cautils.SuccessTextDisplay(fmt.Sprintf("Done scanning cluster %s", cautils.ClusterName))
return errs
-4
View File
@@ -27,13 +27,11 @@ func NewPolicyHandler(processPolicy *chan *cautils.OPASessionObj, k8s *k8sinterf
}
func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opapolicy.PolicyNotification, excludedNamespaces string) error {
glog.Infof("Processing notification. reportID: %s", notification.ReportID)
opaSessionObj := cautils.NewOPASessionObj(nil, nil)
// validate notification
// TODO
// get policies
glog.Infof(fmt.Sprintf("Getting %d policies from backend. reportID: %s", len(notification.Rules), notification.ReportID))
cautils.ProgressTextDisplay("Downloading framework definitions")
frameworks, err := policyHandler.GetPoliciesFromBackend(notification)
if err != nil {
@@ -51,8 +49,6 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opap
// get k8s resources
cautils.ProgressTextDisplay("Accessing Kubernetes objects")
glog.Infof(fmt.Sprintf("Getting kubernetes objects. reportID: %s", notification.ReportID))
k8sResources, err := policyHandler.getK8sResources(frameworks, &notification.Designators, excludedNamespaces)
if err != nil || len(*k8sResources) == 0 {
glog.Error(err)
+30 -31
View File
@@ -33,7 +33,7 @@ type Printer struct {
func NewPrinter(opaSessionObj *chan *cautils.OPASessionObj, printerType string) *Printer {
return &Printer{
opaSessionObj: opaSessionObj,
summary: NewSummery(),
summary: NewSummary(),
printerType: printerType,
}
}
@@ -42,9 +42,8 @@ func (printer *Printer) ActionPrint() {
for {
opaSessionObj := <-*printer.opaSessionObj
if printer.printerType == PrettyPrinter {
printer.SummerySetup(opaSessionObj.PostureReport)
printer.SummarySetup(opaSessionObj.PostureReport)
printer.PrintResults()
printer.PrintSummaryTable()
} else if printer.printerType == JsonPrinter {
@@ -66,7 +65,7 @@ func (printer *Printer) ActionPrint() {
os.Exit(1)
}
os.Stdout.Write(postureReportStr)
} else {
} else if !cautils.IsSilent() {
fmt.Println("unknown output printer")
os.Exit(1)
}
@@ -77,19 +76,19 @@ func (printer *Printer) ActionPrint() {
}
}
func (printer *Printer) SummerySetup(postureReport *opapolicy.PostureReport) {
func (printer *Printer) SummarySetup(postureReport *opapolicy.PostureReport) {
for _, fr := range postureReport.FrameworkReports {
for _, cr := range fr.ControlReports {
if len(cr.RuleReports) == 0 {
continue
}
workloadsSummery := listResultSummery(cr.RuleReports)
mapResources := groupByNamespace(workloadsSummery)
workloadsSummary := listResultSummary(cr.RuleReports)
mapResources := groupByNamespace(workloadsSummary)
printer.summary[cr.Name] = ControlSummery{
printer.summary[cr.Name] = ControlSummary{
TotalResources: cr.GetNumberOfResources(),
TotalFailed: len(workloadsSummery),
WorkloadSummery: mapResources,
TotalFailed: len(workloadsSummary),
WorkloadSummary: mapResources,
Description: cr.Description,
Remediation: cr.Remediation,
}
@@ -101,46 +100,46 @@ func (printer *Printer) SummerySetup(postureReport *opapolicy.PostureReport) {
func (printer *Printer) PrintResults() {
for i := 0; i < len(printer.sortedControlNames); i++ {
controlSummery := printer.summary[printer.sortedControlNames[i]]
printer.printTitle(printer.sortedControlNames[i], &controlSummery)
printer.printResult(printer.sortedControlNames[i], &controlSummery)
controlSummary := printer.summary[printer.sortedControlNames[i]]
printer.printTitle(printer.sortedControlNames[i], &controlSummary)
printer.printResult(printer.sortedControlNames[i], &controlSummary)
if printer.summary[printer.sortedControlNames[i]].TotalResources > 0 {
printer.printSummery(printer.sortedControlNames[i], &controlSummery)
printer.printSummary(printer.sortedControlNames[i], &controlSummary)
}
}
}
func (print *Printer) printSummery(controlName string, controlSummery *ControlSummery) {
func (print *Printer) printSummary(controlName string, controlSummary *ControlSummary) {
cautils.SimpleDisplay(os.Stdout, "Summary - ")
cautils.SuccessDisplay(os.Stdout, "Passed:%v ", controlSummery.TotalResources-controlSummery.TotalFailed)
cautils.FailureDisplay(os.Stdout, "Failed:%v ", controlSummery.TotalFailed)
cautils.InfoDisplay(os.Stdout, "Total:%v\n", controlSummery.TotalResources)
if controlSummery.TotalFailed > 0 {
cautils.DescriptionDisplay(os.Stdout, "Remediation: %v\n", controlSummery.Remediation)
cautils.SuccessDisplay(os.Stdout, "Passed:%v ", controlSummary.TotalResources-controlSummary.TotalFailed)
cautils.FailureDisplay(os.Stdout, "Failed:%v ", controlSummary.TotalFailed)
cautils.InfoDisplay(os.Stdout, "Total:%v\n", controlSummary.TotalResources)
if controlSummary.TotalFailed > 0 {
cautils.DescriptionDisplay(os.Stdout, "Remediation: %v\n", controlSummary.Remediation)
}
cautils.DescriptionDisplay(os.Stdout, "\n")
}
func (printer *Printer) printTitle(controlName string, controlSummery *ControlSummery) {
func (printer *Printer) printTitle(controlName string, controlSummary *ControlSummary) {
cautils.InfoDisplay(os.Stdout, "[control: %s] ", controlName)
if controlSummery.TotalResources == 0 {
if controlSummary.TotalResources == 0 {
cautils.InfoDisplay(os.Stdout, "resources not found %v\n", emoji.ConfusedFace)
} else if controlSummery.TotalFailed == 0 {
} else if controlSummary.TotalFailed == 0 {
cautils.SuccessDisplay(os.Stdout, "passed %v\n", emoji.ThumbsUp)
} else {
cautils.FailureDisplay(os.Stdout, "failed %v\n", emoji.SadButRelievedFace)
}
cautils.DescriptionDisplay(os.Stdout, "Description: %s\n", controlSummery.Description)
cautils.DescriptionDisplay(os.Stdout, "Description: %s\n", controlSummary.Description)
}
func (printer *Printer) printResult(controlName string, controlSummery *ControlSummery) {
func (printer *Printer) printResult(controlName string, controlSummary *ControlSummary) {
indent := INDENT
for ns, rsc := range controlSummery.WorkloadSummery {
for ns, rsc := range controlSummary.WorkloadSummary {
preIndent := indent
if ns != "" {
cautils.SimpleDisplay(os.Stdout, "%sNamespace %s\n", indent, ns)
@@ -156,7 +155,7 @@ func (printer *Printer) printResult(controlName string, controlSummery *ControlS
}
func generateRow(control string, cs ControlSummery) []string {
func generateRow(control string, cs ControlSummary) []string {
row := []string{control}
row = append(row, cs.ToSlice()...)
row = append(row, fmt.Sprintf("%d%s", percentage(cs.TotalResources, cs.TotalFailed), "%"))
@@ -195,10 +194,10 @@ func (printer *Printer) PrintSummaryTable() {
sumFailed := 0
for i := 0; i < len(printer.sortedControlNames); i++ {
controlSummery := printer.summary[printer.sortedControlNames[i]]
summaryTable.Append(generateRow(printer.sortedControlNames[i], controlSummery))
sumFailed += controlSummery.TotalFailed
sumTotal += controlSummery.TotalResources
controlSummary := printer.summary[printer.sortedControlNames[i]]
summaryTable.Append(generateRow(printer.sortedControlNames[i], controlSummary))
sumFailed += controlSummary.TotalFailed
sumTotal += controlSummary.TotalResources
}
summaryTable.SetFooter(generateFooter(len(printer.summary), sumFailed, sumTotal))
summaryTable.Render()
+11 -11
View File
@@ -4,34 +4,34 @@ import (
"fmt"
)
type Summary map[string]ControlSummery
type Summary map[string]ControlSummary
func NewSummery() Summary {
return make(map[string]ControlSummery)
func NewSummary() Summary {
return make(map[string]ControlSummary)
}
type ControlSummery struct {
type ControlSummary struct {
TotalResources int
TotalFailed int
Description string
Remediation string
WorkloadSummery map[string][]WorkloadSummery // <namespace>:[<WorkloadSummery>]
WorkloadSummary map[string][]WorkloadSummary // <namespace>:[<WorkloadSummary>]
}
type WorkloadSummery struct {
type WorkloadSummary struct {
Kind string
Name string
Namespace string
Group string
}
func (controlSummery *ControlSummery) ToSlice() []string {
func (controlSummary *ControlSummary) ToSlice() []string {
s := []string{}
s = append(s, fmt.Sprintf("%d", controlSummery.TotalFailed))
s = append(s, fmt.Sprintf("%d", controlSummery.TotalResources))
s = append(s, fmt.Sprintf("%d", controlSummary.TotalFailed))
s = append(s, fmt.Sprintf("%d", controlSummary.TotalResources))
return s
}
func (workloadSummery *WorkloadSummery) ToString() string {
return fmt.Sprintf("/%s/%s/%s/%s", workloadSummery.Group, workloadSummery.Namespace, workloadSummery.Kind, workloadSummery.Name)
func (workloadSummary *WorkloadSummary) ToString() string {
return fmt.Sprintf("/%s/%s/%s/%s", workloadSummary.Group, workloadSummary.Namespace, workloadSummary.Kind, workloadSummary.Name)
}
+14 -14
View File
@@ -7,26 +7,26 @@ import (
"kube-escape/cautils/opapolicy"
)
// Group workloads by namespace - return {"namespace": <[]WorkloadSummery>}
func groupByNamespace(resources []WorkloadSummery) map[string][]WorkloadSummery {
mapResources := make(map[string][]WorkloadSummery)
// Group workloads by namespace - return {"namespace": <[]WorkloadSummary>}
func groupByNamespace(resources []WorkloadSummary) map[string][]WorkloadSummary {
mapResources := make(map[string][]WorkloadSummary)
for i := range resources {
if r, ok := mapResources[resources[i].Namespace]; ok {
r = append(r, resources[i])
mapResources[resources[i].Namespace] = r
} else {
mapResources[resources[i].Namespace] = []WorkloadSummery{resources[i]}
mapResources[resources[i].Namespace] = []WorkloadSummary{resources[i]}
}
}
return mapResources
}
func listResultSummery(ruleReports []opapolicy.RuleReport) []WorkloadSummery {
workloadsSummery := []WorkloadSummery{}
func listResultSummary(ruleReports []opapolicy.RuleReport) []WorkloadSummary {
workloadsSummary := []WorkloadSummary{}
track := map[string]bool{}
for c := range ruleReports {
for _, ruleReport := range ruleReports[c].RuleResponses {
resource, err := ruleResultSummery(ruleReport.AlertObject)
resource, err := ruleResultSummary(ruleReport.AlertObject)
if err != nil {
fmt.Println(err.Error())
continue
@@ -36,18 +36,18 @@ func listResultSummery(ruleReports []opapolicy.RuleReport) []WorkloadSummery {
for i := range resource {
if ok := track[resource[i].ToString()]; !ok {
track[resource[i].ToString()] = true
workloadsSummery = append(workloadsSummery, resource[i])
workloadsSummary = append(workloadsSummary, resource[i])
}
}
}
}
return workloadsSummery
return workloadsSummary
}
func ruleResultSummery(obj opapolicy.AlertObject) ([]WorkloadSummery, error) {
resource := []WorkloadSummery{}
func ruleResultSummary(obj opapolicy.AlertObject) ([]WorkloadSummary, error) {
resource := []WorkloadSummary{}
for i := range obj.K8SApiObjects {
r, err := newWorkloadSummery(obj.K8SApiObjects[i])
r, err := newWorkloadSummary(obj.K8SApiObjects[i])
if err != nil {
return resource, err
}
@@ -57,8 +57,8 @@ func ruleResultSummery(obj opapolicy.AlertObject) ([]WorkloadSummery, error) {
return resource, nil
}
func newWorkloadSummery(obj map[string]interface{}) (*WorkloadSummery, error) {
r := &WorkloadSummery{}
func newWorkloadSummary(obj map[string]interface{}) (*WorkloadSummary, error) {
r := &WorkloadSummary{}
workload := k8sinterface.NewWorkloadObj(obj)
if workload == nil {