start using cobra pkg for cli flags

This commit is contained in:
danielgrunbergerarmo
2021-08-24 17:35:57 +03:00
parent 2606be8ecd
commit a7e69c8096
11 changed files with 177 additions and 103 deletions

View File

@@ -1,3 +1,4 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

View File

@@ -148,3 +148,9 @@ type PolicyIdentifier struct {
Kind NotificationPolicyKind `json:"kind"`
Name string `json:"name"`
}
type ScanInfo struct {
PolicyIdentifier PolicyIdentifier `json:"policyIdentifier"`
Output string `json:"output"`
ExcludedNamespaces string `json:"excludedNamespaces"`
}

102
cmd/framework.go Normal file
View File

@@ -0,0 +1,102 @@
package cmd
import (
"fmt"
"kube-escape/cautils"
"kube-escape/cautils/armotypes"
"kube-escape/cautils/k8sinterface"
"kube-escape/cautils/opapolicy"
"kube-escape/opaprocessor"
"kube-escape/policyhandler"
"kube-escape/printer"
"os"
"strings"
"github.com/spf13/cobra"
)
var scanInfo opapolicy.ScanInfo
type CLIHandler struct {
policyHandler *policyhandler.PolicyHandler
scanInfo *opapolicy.ScanInfo
}
var frameworkCmd = &cobra.Command{
Use: "framework <framework name>",
Short: "The framework you wish to use. Supported frameworks: nsa, mitre",
Long: ``,
ValidArgs: []string{"nsa", "mitre"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
scanInfo.PolicyIdentifier = opapolicy.PolicyIdentifier{}
scanInfo.PolicyIdentifier.Kind = "Framework"
scanInfo.PolicyIdentifier.Name = strings.Join(args, ",")
CliSetup()
},
}
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.Output, "output", "o", "", "output format")
}
func CliSetup() error {
k8s := k8sinterface.NewKubernetesApi()
processNotification := make(chan *cautils.OPASessionObj)
reportResults := make(chan *cautils.OPASessionObj)
// policy handler setup
policyHandler := policyhandler.NewPolicyHandler(&processNotification, k8s)
// cli handler setup
cli := NewCLIHandler(policyHandler)
if err := cli.Scan(); err != nil {
panic(err)
}
// processor setup - rego run
go func() {
reporterObj := opaprocessor.NewOPAProcessor(&processNotification, &reportResults)
reporterObj.ProcessRulesListenner()
}()
p := printer.NewPrinter(&reportResults)
p.ActionPrint()
return nil
}
func NewCLIHandler(policyHandler *policyhandler.PolicyHandler) *CLIHandler {
return &CLIHandler{
scanInfo: &scanInfo,
policyHandler: policyHandler,
}
}
func (clihandler *CLIHandler) Scan() error {
cautils.InfoDisplay(os.Stdout, "ARMO security scanner starting\n")
policyNotification := &opapolicy.PolicyNotification{
NotificationType: opapolicy.TypeExecPostureScan,
Rules: []opapolicy.PolicyIdentifier{
*&clihandler.scanInfo.PolicyIdentifier,
},
Designators: armotypes.PortalDesignator{},
}
switch policyNotification.NotificationType {
case opapolicy.TypeExecPostureScan:
go func() {
if err := clihandler.policyHandler.HandleNotificationRequest(policyNotification, scanInfo.ExcludedNamespaces); err != nil {
fmt.Printf("%v\n", err)
os.Exit(0)
}
}()
default:
return fmt.Errorf("notification type '%s' Unknown", policyNotification.NotificationType)
}
return nil
}

26
cmd/root.go Normal file
View File

@@ -0,0 +1,26 @@
package cmd
import (
"github.com/spf13/cobra"
)
var cfgFile string
var rootCmd = &cobra.Command{
Use: "kubescape",
Short: "A tool for running NSA recommended tests in your cluster ",
Long: `This tool pulls checks based on the NSA recommendations from the ARMO backend
and run these checks on your cluster resources `,
}
func Execute() {
rootCmd.Execute()
}
func init() {
cobra.OnInitialize(initConfig)
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
}

18
cmd/scan.go Normal file
View File

@@ -0,0 +1,18 @@
package cmd
import (
"github.com/spf13/cobra"
)
// scanCmd represents the scan command
var scanCmd = &cobra.Command{
Use: "scan",
Short: "Scan command",
Long: `The action you want to perform`,
Run: func(cmd *cobra.Command, args []string) {
},
}
func init() {
rootCmd.AddCommand(scanCmd)
}

4
go.mod
View File

@@ -12,6 +12,7 @@ require (
github.com/enescakir/emoji v1.0.0
github.com/fatih/color v1.12.0
github.com/francoispqt/gojay v1.2.13
github.com/fsnotify/fsnotify v1.5.0 // indirect
github.com/gofrs/uuid v4.0.0+incompatible
github.com/golang/glog v0.0.0-20210429001901-424d2337a529
github.com/mattn/go-isatty v0.0.13
@@ -21,7 +22,10 @@ require (
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/satori/go.uuid v1.2.0
github.com/spf13/cobra v1.2.1
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
k8s.io/api v0.22.0
k8s.io/apimachinery v0.22.0

View File

@@ -1,52 +0,0 @@
package clihandler
import (
"fmt"
"kube-escape/cautils"
"kube-escape/policyhandler"
"os"
"kube-escape/cautils/armotypes"
"kube-escape/cautils/opapolicy"
)
type CLIHandler struct {
policyHandler *policyhandler.PolicyHandler
flagHandler FlagHandler
}
func NewCLIHandler(policyHandler *policyhandler.PolicyHandler) *CLIHandler {
return &CLIHandler{
flagHandler: *NewFlagHandler(),
policyHandler: policyHandler,
}
}
func (clihandler *CLIHandler) Scan() error {
clihandler.flagHandler.ParseFlag()
if !clihandler.flagHandler.ExecuteScan() {
os.Exit(0)
}
cautils.InfoDisplay(os.Stdout, "ARMO security scanner starting\n")
policyNotification := &opapolicy.PolicyNotification{
NotificationType: opapolicy.TypeExecPostureScan,
Rules: []opapolicy.PolicyIdentifier{
*clihandler.flagHandler.policyIdentifier,
},
Designators: armotypes.PortalDesignator{},
}
switch policyNotification.NotificationType {
case opapolicy.TypeExecPostureScan:
go func() {
if err := clihandler.policyHandler.HandleNotificationRequest(policyNotification); err != nil {
fmt.Printf("%v\n", err)
os.Exit(0)
}
}()
default:
return fmt.Errorf("notification type '%s' Unknown", policyNotification.NotificationType)
}
return nil
}

61
main.go
View File

@@ -1,49 +1,22 @@
/*
Copyright © 2021 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"kube-escape/cautils"
k8sinterface "kube-escape/cautils/k8sinterface"
"kube-escape/inputhandler/clihandler"
"kube-escape/opaprocessor"
"kube-escape/policyhandler"
"kube-escape/printer"
"os"
)
import "kube-escape/cmd"
func main() {
if err := CliSetup(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
func CliSetup() error {
k8s := k8sinterface.NewKubernetesApi()
processNotification := make(chan *cautils.OPASessionObj)
reportResults := make(chan *cautils.OPASessionObj)
// policy handler setup
policyHandler := policyhandler.NewPolicyHandler(&processNotification, k8s)
// cli handler setup
cli := clihandler.NewCLIHandler(policyHandler)
if err := cli.Scan(); err != nil {
panic(err)
}
// processor setup - rego run
go func() {
reporterObj := opaprocessor.NewOPAProcessor(&processNotification, &reportResults)
reporterObj.ProcessRulesListenner()
}()
p := printer.NewPrinter(&reportResults)
p.ActionPrint()
return nil
cmd.Execute()
}

Binary file not shown.

View File

@@ -1,7 +1,6 @@
package policyhandler
import (
"flag"
"fmt"
"kube-escape/cautils"
@@ -27,7 +26,7 @@ func NewPolicyHandler(processPolicy *chan *cautils.OPASessionObj, k8s *k8sinterf
}
}
func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opapolicy.PolicyNotification) error {
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
@@ -53,10 +52,7 @@ 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))
excludedNamespaces := ""
if flag.Arg(3) == "--exclude-namespaces" {
excludedNamespaces = flag.Arg(4)
}
k8sResources, err := policyHandler.getK8sResources(frameworks, &notification.Designators, excludedNamespaces)
if err != nil || len(*k8sResources) == 0 {
glog.Error(err)

View File

@@ -61,7 +61,7 @@ func (db *ArmoAPI) GetHttpClient() *http.Client {
func (db *ArmoAPI) OPAFRAMEWORKGet(name string) ([]opapolicy.Framework, error) {
requestURI := "v1/armoFrameworks"
requestURI += fmt.Sprintf("?customerGUID=%s", "11111111-1111-1111-1111-111111111111")
requestURI += fmt.Sprintf("&frameworkName=%s", name)
requestURI += fmt.Sprintf("&frameworkName=%s", strings.ToUpper(name))
requestURI += "&getRules=true"
fullURL := URLEncoder(fmt.Sprintf("%s/%s", db.GetServerAddress(), requestURI))