Skip to content

Commit

Permalink
refactor: Rename --print flag to --log-fmt, accepts json
Browse files Browse the repository at this point in the history
Signed-off-by: Víctor Cuadrado Juan <[email protected]>
  • Loading branch information
viccuad committed Sep 6, 2023
1 parent 65b154b commit d453e52
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 58 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ or to get results in JSON:
./bin/audit-scanner \
-k kubewarden --namespace default \
--policy-server-url https://localhost:3000 \
-l debug --print
-l debug --log-fmt=json
```

### Run against audit-scanner SA
Expand All @@ -38,8 +38,8 @@ If needed, patch the resulting kubeconfig, adding the missing

```yaml
clusters:
- cluster:
certificate-authority: /home/vic/.minikube/ca.crt
- cluster:
certificate-authority: /home/vic/.minikube/ca.crt
```
And use it:
Expand Down
110 changes: 61 additions & 49 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,64 +26,75 @@ type Scanner interface {
// log level
var level logconfig.Level

// print result of scan as JSON to stdout
var printJSON bool
// format of logs to stdout & stderr
var logFormat string

// list of supported format of logs to stdout & stderr
var logFormatSupportedFormats = [1]string{"json"}

// list of namespaces to be skipped from scan
var skippedNs []string

// skip SSL cert validation when connecting to PolicyServers endpoints
var insecureSSL bool

var (
// rootCmd represents the base command when called without any subcommands
rootCmd = &cobra.Command{
Use: "audit-scanner",
Short: "Reports evaluation of existing Kubernetes resources with your already deployed Kubewarden policies",
Long: `Scans resources in your kubernetes cluster with your already deployed Kubewarden policies.
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "audit-scanner",
Short: "Reports evaluation of existing Kubernetes resources with your already deployed Kubewarden policies",
Long: `Scans resources in your kubernetes cluster with your already deployed Kubewarden policies.
Each namespace will have a PolicyReport with the outcome of the scan for resources within this namespace.
There will be a ClusterPolicyReport with results for cluster-wide resources.`,

RunE: func(cmd *cobra.Command, args []string) error {
level.SetZeroLogLevel()
namespace, err := cmd.Flags().GetString("namespace")
if err != nil {
return err
}
kubewardenNamespace, err := cmd.Flags().GetString("kubewarden-namespace")
if err != nil {
return err
}
clusterWide, err := cmd.Flags().GetBool("cluster")
if err != nil {
return err
}
policyServerURL, err := cmd.Flags().GetString("policy-server-url")
if err != nil {
return err
}
caCertFile, err := cmd.Flags().GetString("extra-ca")
if err != nil {
return err
}

policiesFetcher, err := policies.NewFetcher(kubewardenNamespace, skippedNs)
if err != nil {
return err
}
resourcesFetcher, err := resources.NewFetcher(kubewardenNamespace, policyServerURL)
if err != nil {
return err
}
scanner, err := scanner.NewScanner(policiesFetcher, resourcesFetcher, printJSON, insecureSSL, caCertFile)
if err != nil {
return err
}

return startScanner(namespace, clusterWide, scanner)
},
}
)
RunE: func(cmd *cobra.Command, args []string) error {
level.SetZeroLogLevel()
namespace, err := cmd.Flags().GetString("namespace")
if err != nil {
return err
}
kubewardenNamespace, err := cmd.Flags().GetString("kubewarden-namespace")
if err != nil {
return err
}
clusterWide, err := cmd.Flags().GetBool("cluster")
if err != nil {
return err
}
policyServerURL, err := cmd.Flags().GetString("policy-server-url")
if err != nil {
return err
}
caCertFile, err := cmd.Flags().GetString("extra-ca")
if err != nil {
return err
}
logFormat, err := cmd.Flags().GetString("log-fmt")
if err != nil {
return err
}
switch logFormat {
// TODO use slices package in go 1.21
case "json": // skip
default:
return fmt.Errorf("passed log-fmt not supported. Please select one of the supported formats: %v", logFormatSupportedFormats)
}

policiesFetcher, err := policies.NewFetcher(kubewardenNamespace, skippedNs)
if err != nil {
return err
}
resourcesFetcher, err := resources.NewFetcher(kubewardenNamespace, policyServerURL)
if err != nil {
return err
}
scanner, err := scanner.NewScanner(policiesFetcher, resourcesFetcher, logFormat, insecureSSL, caCertFile)
if err != nil {
return err
}

return startScanner(namespace, clusterWide, scanner)
},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
Expand All @@ -96,6 +107,7 @@ func Execute() {
log.Fatal().Err(err).Msg("Error on cmd.Execute()")
}
}

func startScanner(namespace string, clusterWide bool, scanner Scanner) error {
if clusterWide && namespace != "" {
log.Fatal().Msg("Cannot scan cluster wide and only a namespace at the same time")
Expand Down Expand Up @@ -124,7 +136,7 @@ func init() {
rootCmd.Flags().StringP("kubewarden-namespace", "k", defaultKubewardenNamespace, "namespace where the Kubewarden components (e.g. PolicyServer) are installed (required)")
rootCmd.Flags().StringP("policy-server-url", "u", "", "URI to the PolicyServers the Audit Scanner will query. Example: https://localhost:3000. Useful for out-of-cluster debugging")
rootCmd.Flags().VarP(&level, "loglevel", "l", fmt.Sprintf("level of the logs. Supported values are: %v", logconfig.SupportedValues))
rootCmd.Flags().BoolVarP(&printJSON, "print", "p", false, "print result of scan in JSON to stdout")
rootCmd.Flags().StringP("log-fmt", "o", logFormat, fmt.Sprintf("If set, print output result of scan to stdout in speficied format. Supported formats: %v", logFormatSupportedFormats))
rootCmd.Flags().StringSliceVarP(&skippedNs, "ignore-namespaces", "i", nil, "comma separated list of namespace names to be skipped from scan. This flag can be repeated")
rootCmd.Flags().BoolVar(&insecureSSL, "insecure-ssl", false, "skip SSL cert validation when connecting to PolicyServers endpoints. Useful for development")
rootCmd.Flags().StringP("extra-ca", "f", "", "File path to CA cert in PEM format of PolicyServer endpoints")
Expand Down
13 changes: 7 additions & 6 deletions internal/scanner/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,17 @@ type Scanner struct {
reportStore report.PolicyReportStore
// http client used to make requests against the Policy Server
httpClient http.Client
printJSON bool
logFormat string
}

// NewScanner creates a new scanner with the PoliciesFetcher provided. If
// insecureClient is false, it will read the caCertFile and add it to the in-app
// cert trust store. This gets used by the httpCLient when connection to
// PolicyServers endpoints.
func NewScanner(policiesFetcher PoliciesFetcher, resourcesFetcher ResourcesFetcher,
printJSON bool,
insecureClient bool, caCertFile string) (*Scanner, error) {
logFormat string,
insecureClient bool, caCertFile string,
) (*Scanner, error) {
report, err := report.NewPolicyReportStore()
if err != nil {
return nil, err
Expand Down Expand Up @@ -103,7 +104,7 @@ func NewScanner(policiesFetcher PoliciesFetcher, resourcesFetcher ResourcesFetch
log.Warn().Msg("connecting to PolicyServers endpoints without validating TLS connection")
}

return &Scanner{policiesFetcher, resourcesFetcher, *report, httpClient, printJSON}, nil
return &Scanner{policiesFetcher, resourcesFetcher, *report, httpClient, logFormat}, nil
}

// ScanNamespace scans resources for a given namespace.
Expand Down Expand Up @@ -158,7 +159,7 @@ func (s *Scanner) ScanNamespace(nsName string) error {
}
log.Info().Str("namespace", nsName).Msg("namespace scan finished")

if s.printJSON {
if s.logFormat == "json" {
str, err := s.reportStore.ToJSON()
if err != nil {
log.Error().Err(err).Msg("error marshaling reportStore to JSON")
Expand Down Expand Up @@ -227,7 +228,7 @@ func (s *Scanner) ScanClusterWideResources() error {
if err != nil {
log.Error().Err(err).Msg("error adding PolicyReport to store")
}
if s.printJSON {
if s.logFormat == "json" {
str, err := s.reportStore.ToJSON()
if err != nil {
log.Error().Err(err).Msg("error marshaling reportStore to JSON")
Expand Down

0 comments on commit d453e52

Please sign in to comment.