1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

Print generate output cli (#11634)

* refactor: Configure the policy processor to print generated resources

Refactor printMutatedOutput to printOutput which prints mutate or generate resources to a file or standard output
Introduce processGenerateResponse which extracts generated resources from the policy response and passes them to printOutput

Signed-off-by: aerosouund <aerosound161@gmail.com>

* chore: Update flag description to specify mutated and generated resources

Signed-off-by: aerosouund <aerosound161@gmail.com>

* chore: Run codegen

Signed-off-by: aerosouund <aerosound161@gmail.com>

---------

Signed-off-by: aerosouund <aerosound161@gmail.com>
This commit is contained in:
Ammar Yasser 2024-11-27 10:33:05 +02:00 committed by GitHub
parent 88306bb8cf
commit d100202d22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 31 deletions

View file

@ -135,7 +135,7 @@ func Command() *cobra.Command {
cmd.Flags().StringSliceVarP(&applyCommandConfig.ResourcePaths, "resource", "r", []string{}, "Path to resource files")
cmd.Flags().StringSliceVarP(&applyCommandConfig.ResourcePaths, "resources", "", []string{}, "Path to resource files")
cmd.Flags().BoolVarP(&applyCommandConfig.Cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
cmd.Flags().StringVarP(&applyCommandConfig.MutateLogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
cmd.Flags().StringVarP(&applyCommandConfig.MutateLogPath, "output", "o", "", "Prints the mutated/generated resources in provided file/directory")
// currently `set` flag supports variable for single policy applied on single resource
cmd.Flags().StringVarP(&applyCommandConfig.UserInfoPath, "userinfo", "u", "", "Admission Info including Roles, Cluster Roles and Subjects")
cmd.Flags().StringSliceVarP(&applyCommandConfig.Variables, "set", "s", nil, "Variables that are required")

View file

@ -203,6 +203,9 @@ func (p *PolicyProcessor) ApplyPoliciesOnResource() ([]engineapi.EngineResponse,
} else {
generateResponse.PolicyResponse.Rules = newRuleResponse
}
if err := p.processGenerateResponse(generateResponse, resPath); err != nil {
return responses, err
}
responses = append(responses, generateResponse)
}
p.Rc.addGenerateResponse(generateResponse)
@ -342,37 +345,61 @@ func (p *PolicyProcessor) makePolicyContext(
return policyContext, nil
}
func (p *PolicyProcessor) processMutateEngineResponse(response engineapi.EngineResponse, resourcePath string) error {
printMutatedRes := p.Rc.addMutateResponse(response)
if printMutatedRes && p.PrintPatchResource {
yamlEncodedResource, err := yamlv2.Marshal(response.PatchedResource.Object)
func (p *PolicyProcessor) processGenerateResponse(response engineapi.EngineResponse, resourcePath string) error {
generatedResources := []*unstructured.Unstructured{}
for _, rule := range response.PolicyResponse.Rules {
gen := rule.GeneratedResources()
generatedResources = append(generatedResources, gen...)
}
for _, r := range generatedResources {
err := p.printOutput(r.Object, response, resourcePath, true)
if err != nil {
return fmt.Errorf("failed to marshal (%w)", err)
}
if p.MutateLogPath == "" {
mutatedResource := string(yamlEncodedResource) + string("\n---")
if len(strings.TrimSpace(mutatedResource)) > 0 {
if !p.Stdin {
fmt.Fprintf(p.Out, "\nmutate policy %s applied to %s:", response.Policy().GetName(), resourcePath)
}
fmt.Fprintf(p.Out, "\n"+mutatedResource+"\n") //nolint:govet
}
} else {
err := p.printMutatedOutput(string(yamlEncodedResource))
if err != nil {
return fmt.Errorf("failed to print mutated result (%w)", err)
}
fmt.Fprintf(p.Out, "\n\nMutation:\nMutation has been applied successfully. Check the files.")
return fmt.Errorf("failed to print generate result (%w)", err)
}
fmt.Fprintf(p.Out, "\n\nGenerate:\nGeneration completed successfully.")
}
return nil
}
func (p *PolicyProcessor) printMutatedOutput(yaml string) error {
func (p *PolicyProcessor) processMutateEngineResponse(response engineapi.EngineResponse, resourcePath string) error {
p.Rc.addMutateResponse(response)
err := p.printOutput(response.PatchedResource.Object, response, resourcePath, false)
if err != nil {
return fmt.Errorf("failed to print mutated result (%w)", err)
}
fmt.Fprintf(p.Out, "\n\nMutation:\nMutation has been applied successfully.")
return nil
}
func (p *PolicyProcessor) printOutput(resource interface{}, response engineapi.EngineResponse, resourcePath string, isGenerate bool) error {
yamlEncodedResource, err := yamlv2.Marshal(resource)
if err != nil {
return fmt.Errorf("failed to marshal (%w)", err)
}
if p.MutateLogPath == "" {
resource := string(yamlEncodedResource) + string("\n---")
if len(strings.TrimSpace(resource)) > 0 {
if !p.Stdin {
fmt.Fprintf(p.Out, "\npolicy %s applied to %s:", response.Policy().GetName(), resourcePath)
}
fmt.Fprintf(p.Out, "\n"+resource+"\n") //nolint:govet
}
return nil
}
var file *os.File
mutateLogPath := filepath.Clean(p.MutateLogPath)
filename := p.Resource.GetName() + "-mutated"
if isGenerate {
filename = response.Policy().GetName() + "-generated"
}
file, err = os.OpenFile(filepath.Join(mutateLogPath, filename+".yaml"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600) // #nosec G304
if err != nil {
return err
}
if !p.MutateLogPathIsDir {
// truncation for the case when mutateLogPath is a file (not a directory) is handled under pkg/kyverno/apply/test_command.go
f, err := os.OpenFile(mutateLogPath, os.O_APPEND|os.O_WRONLY, 0o600) // #nosec G304
@ -380,14 +407,8 @@ func (p *PolicyProcessor) printMutatedOutput(yaml string) error {
return err
}
file = f
} else {
f, err := os.OpenFile(filepath.Join(mutateLogPath, filename+".yaml"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600) // #nosec G304
if err != nil {
return err
}
file = f
}
if _, err := file.Write([]byte(yaml + "\n---\n\n")); err != nil {
if _, err := file.Write([]byte(string(yamlEncodedResource) + "\n---\n\n")); err != nil {
if err := file.Close(); err != nil {
log.Log.Error(err, "failed to close file")
}

View file

@ -51,7 +51,7 @@ kyverno apply [flags]
-h, --help help for apply
--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 resources in provided file/directory
-o, --output string Prints the mutated/generated resources in provided file/directory
-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