1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00

Add flag for JSON output in policy reports (#11840)

* Add flag for JSON output in policy reports

Signed-off-by: Rokibul Hasan <mdrokibulhasan@appscode.com>

* make codegen-docs-all

Signed-off-by: Rokibul Hasan <mdrokibulhasan@appscode.com>

---------

Signed-off-by: Rokibul Hasan <mdrokibulhasan@appscode.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Rokibul Hasan 2025-01-07 12:22:11 +06:00 committed by GitHub
parent c282f71212
commit 236ac9c216
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 15 deletions

View file

@ -57,6 +57,7 @@ type ApplyCommandConfig struct {
UserInfoPath string
Cluster bool
PolicyReport bool
OutputFormat string
Stdin bool
RegistryAccess bool
AuditWarn bool
@ -93,9 +94,9 @@ func Command() *cobra.Command {
cmd.SilenceErrors = true
printSkippedAndInvalidPolicies(out, skipInvalidPolicies)
if applyCommandConfig.PolicyReport {
printReports(out, responses, applyCommandConfig.AuditWarn)
printReports(out, responses, applyCommandConfig.AuditWarn, applyCommandConfig.OutputFormat)
} else if applyCommandConfig.GenerateExceptions {
printExceptions(out, responses, applyCommandConfig.AuditWarn, applyCommandConfig.GeneratedExceptionTTL)
printExceptions(out, responses, applyCommandConfig.AuditWarn, applyCommandConfig.OutputFormat, applyCommandConfig.GeneratedExceptionTTL)
} else if table {
printTable(out, detailedResults, applyCommandConfig.AuditWarn, responses...)
} else {
@ -146,6 +147,7 @@ func Command() *cobra.Command {
cmd.Flags().StringSliceVarP(&applyCommandConfig.Variables, "set", "s", nil, "Variables that are required")
cmd.Flags().StringVarP(&applyCommandConfig.ValuesFile, "values-file", "f", "", "File containing values for policy variables")
cmd.Flags().BoolVarP(&applyCommandConfig.PolicyReport, "policy-report", "p", false, "Generates policy report when passed (default policyviolation)")
cmd.Flags().StringVarP(&applyCommandConfig.OutputFormat, "output-format", "", "yaml", "Specifies the policy report format (json or yaml). Default: yaml.")
cmd.Flags().StringVarP(&applyCommandConfig.Namespace, "namespace", "n", "", "Optional Policy parameter passed with cluster flag")
cmd.Flags().BoolVarP(&applyCommandConfig.Stdin, "stdin", "i", false, "Optional mutate policy parameter to pipe directly through to kubectl")
cmd.Flags().BoolVar(&applyCommandConfig.RegistryAccess, "registry", false, "If set to true, access the image registry using local docker credentials to populate external data")

View file

@ -40,26 +40,36 @@ func printSkippedAndInvalidPolicies(out io.Writer, skipInvalidPolicies SkippedIn
}
}
func printReports(out io.Writer, engineResponses []engineapi.EngineResponse, auditWarn bool) {
func printReports(out io.Writer, engineResponses []engineapi.EngineResponse, auditWarn bool, outputFormat string) {
clustered, namespaced := report.ComputePolicyReports(auditWarn, engineResponses...)
if len(clustered) > 0 {
report := report.MergeClusterReports(clustered)
yamlReport, _ := yaml.Marshal(report)
fmt.Fprintln(out, string(yamlReport))
printReport := func(report interface{}) {
var output []byte
if outputFormat == "json" {
output, _ = json.Marshal(report)
} else {
output, _ = yaml.Marshal(report)
}
fmt.Fprintln(out, string(output))
}
if len(clustered) > 0 {
clusterReport := report.MergeClusterReports(clustered)
printReport(clusterReport)
}
for _, r := range namespaced {
fmt.Fprintln(out, string("---"))
yamlReport, _ := yaml.Marshal(r)
fmt.Fprintln(out, string(yamlReport))
fmt.Fprintln(out, "---")
printReport(r)
}
}
func printExceptions(out io.Writer, engineResponses []engineapi.EngineResponse, auditWarn bool, ttl time.Duration) {
func printExceptions(out io.Writer, engineResponses []engineapi.EngineResponse, auditWarn bool, outputFormat string, ttl time.Duration) {
clustered, _ := report.ComputePolicyReports(auditWarn, engineResponses...)
for _, report := range clustered {
for _, result := range report.Results {
if result.Result == "fail" {
if err := printException(out, result, ttl); err != nil {
if err := printException(out, result, ttl, outputFormat); err != nil {
log.Error(err)
}
}
@ -67,7 +77,7 @@ func printExceptions(out io.Writer, engineResponses []engineapi.EngineResponse,
}
}
func printException(out io.Writer, result v1alpha2.PolicyReportResult, ttl time.Duration) error {
func printException(out io.Writer, result v1alpha2.PolicyReportResult, ttl time.Duration, outputFormat string) error {
for _, r := range result.Resources {
name := strings.Join([]string{result.Policy, result.Rule, r.Namespace, r.Name}, "-")
@ -141,13 +151,21 @@ func printException(out io.Writer, result v1alpha2.PolicyReportResult, ttl time.
exception.Spec.PodSecurity = pssList
}
exceptionYAML, err := yaml.Marshal(exception)
var exceptionReport []byte
marshal := func(report interface{}) ([]byte, error) {
if outputFormat == "json" {
return json.Marshal(report)
}
return yaml.Marshal(report)
}
exceptionReport, err := marshal(exception)
if err != nil {
return err
}
fmt.Fprint(out, "---\n")
fmt.Fprint(out, string(exceptionYAML))
fmt.Fprint(out, string(exceptionReport))
fmt.Fprint(out, "\n")
}

View file

@ -52,6 +52,7 @@ kyverno apply [flags]
--kubeconfig string path to kubeconfig file with authorization and master location information
-n, --namespace string Optional Policy parameter passed with cluster flag
-o, --output string Prints the mutated/generated resources in provided file/directory
--output-format string Specifies the policy report format (json or yaml). Default: yaml. (default "yaml")
-p, --policy-report Generates policy report when passed (default policyviolation)
--registry If set to true, access the image registry using local docker credentials to populate external data
--remove-color Remove any color from output