mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
refactor: cleanup cli apply functions (#11928)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
72f932c3bc
commit
a50911d8b5
1 changed files with 54 additions and 52 deletions
|
@ -170,61 +170,58 @@ func Command() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
||||||
rc, resources1, skipInvalidPolicies, responses1, err := c.checkArguments()
|
var skippedInvalidPolicies SkippedInvalidPolicies
|
||||||
|
err := c.checkArguments()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
rc, resources1, skipInvalidPolicies, responses1, err, mutateLogPathIsDir := c.getMutateLogPathIsDir(skipInvalidPolicies)
|
mutateLogPathIsDir, err := c.getMutateLogPathIsDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
rc, resources1, skipInvalidPolicies, responses1, err = c.cleanPreviousContent(mutateLogPathIsDir, skipInvalidPolicies)
|
if err := c.cleanPreviousContent(mutateLogPathIsDir); err != nil {
|
||||||
if err != nil {
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
|
||||||
}
|
}
|
||||||
var userInfo *kyvernov2.RequestInfo
|
var userInfo *kyvernov2.RequestInfo
|
||||||
if c.UserInfoPath != "" {
|
if c.UserInfoPath != "" {
|
||||||
info, err := userinfo.Load(nil, c.UserInfoPath, "")
|
info, err := userinfo.Load(nil, c.UserInfoPath, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("failed to load request info (%w)", err)
|
return nil, nil, skippedInvalidPolicies, nil, fmt.Errorf("failed to load request info (%w)", err)
|
||||||
}
|
}
|
||||||
deprecations.CheckUserInfo(out, c.UserInfoPath, info)
|
deprecations.CheckUserInfo(out, c.UserInfoPath, info)
|
||||||
userInfo = &info.RequestInfo
|
userInfo = &info.RequestInfo
|
||||||
}
|
}
|
||||||
variables, err := variables.New(out, nil, "", c.ValuesFile, nil, c.Variables...)
|
variables, err := variables.New(out, nil, "", c.ValuesFile, nil, c.Variables...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("failed to decode yaml (%w)", err)
|
return nil, nil, skippedInvalidPolicies, nil, fmt.Errorf("failed to decode yaml (%w)", err)
|
||||||
}
|
}
|
||||||
var store store.Store
|
var store store.Store
|
||||||
rc, resources1, skipInvalidPolicies, responses1, policies, vaps, vapBindings, err := c.loadPolicies(skipInvalidPolicies)
|
policies, vaps, vapBindings, err := c.loadPolicies()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
var targetResources []*unstructured.Unstructured
|
var targetResources []*unstructured.Unstructured
|
||||||
if len(c.TargetResourcePaths) > 0 {
|
if len(c.TargetResourcePaths) > 0 {
|
||||||
targetResources, err = c.loadResources(out, c.TargetResourcePaths, policies, vaps, nil)
|
targetResources, err = c.loadResources(out, c.TargetResourcePaths, policies, vaps, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dClient, err := c.initStoreAndClusterClient(&store, targetResources...)
|
||||||
rc, resources1, skipInvalidPolicies, responses1, dClient, err := c.initStoreAndClusterClient(&store, skipInvalidPolicies, targetResources...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resources, err := c.loadResources(out, c.ResourcePaths, policies, vaps, dClient)
|
resources, err := c.loadResources(out, c.ResourcePaths, policies, vaps, dClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return nil, nil, skippedInvalidPolicies, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var exceptions []*kyvernov2.PolicyException
|
var exceptions []*kyvernov2.PolicyException
|
||||||
if c.inlineExceptions {
|
if c.inlineExceptions {
|
||||||
exceptions = exception.SelectFrom(resources)
|
exceptions = exception.SelectFrom(resources)
|
||||||
} else {
|
} else {
|
||||||
exceptions, err = exception.Load(c.Exception...)
|
exceptions, err = exception.Load(c.Exception...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, fmt.Errorf("Error: failed to load exceptions (%s)", err)
|
return nil, nil, skippedInvalidPolicies, nil, fmt.Errorf("Error: failed to load exceptions (%s)", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !c.Stdin && !c.PolicyReport && !c.GenerateExceptions {
|
if !c.Stdin && !c.PolicyReport && !c.GenerateExceptions {
|
||||||
|
@ -239,38 +236,37 @@ func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.Resul
|
||||||
fmt.Fprintf(out, "\nApplying %d policy rule(s) to %d resource(s)...\n", policyRulesCount, len(resources))
|
fmt.Fprintf(out, "\nApplying %d policy rule(s) to %d resource(s)...\n", policyRulesCount, len(resources))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rc, resources1, responses1, err := c.applyPolicytoResource(
|
||||||
rc, resources1, responses1, err = c.applyPolicytoResource(
|
|
||||||
out,
|
out,
|
||||||
&store,
|
&store,
|
||||||
variables,
|
variables,
|
||||||
policies,
|
policies,
|
||||||
resources,
|
resources,
|
||||||
exceptions,
|
exceptions,
|
||||||
&skipInvalidPolicies,
|
&skippedInvalidPolicies,
|
||||||
dClient,
|
dClient,
|
||||||
userInfo,
|
userInfo,
|
||||||
mutateLogPathIsDir,
|
mutateLogPathIsDir,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return rc, resources1, skippedInvalidPolicies, responses1, err
|
||||||
}
|
}
|
||||||
responses2, err := c.applyValidatingAdmissionPolicytoResource(vaps, vapBindings, resources1, variables.NamespaceSelectors(), rc, dClient)
|
responses2, err := c.applyValidatingAdmissionPolicytoResource(vaps, vapBindings, resources1, variables.NamespaceSelectors(), rc, dClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rc, resources1, skipInvalidPolicies, responses1, err
|
return rc, resources1, skippedInvalidPolicies, responses1, err
|
||||||
}
|
}
|
||||||
var responses []engineapi.EngineResponse
|
var responses []engineapi.EngineResponse
|
||||||
responses = append(responses, responses1...)
|
responses = append(responses, responses1...)
|
||||||
responses = append(responses, responses2...)
|
responses = append(responses, responses2...)
|
||||||
return rc, resources1, skipInvalidPolicies, responses, nil
|
return rc, resources1, skippedInvalidPolicies, responses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) getMutateLogPathIsDir(skipInvalidPolicies SkippedInvalidPolicies) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error, bool) {
|
func (c *ApplyCommandConfig) getMutateLogPathIsDir() (bool, error) {
|
||||||
mutateLogPathIsDir, err := checkMutateLogPath(c.MutateLogPath)
|
mutateLogPathIsDir, err := checkMutateLogPath(c.MutateLogPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("failed to create file/folder (%w)", err), false
|
return false, fmt.Errorf("failed to create file/folder (%w)", err)
|
||||||
}
|
}
|
||||||
return nil, nil, skipInvalidPolicies, nil, err, mutateLogPathIsDir
|
return mutateLogPathIsDir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) applyValidatingAdmissionPolicytoResource(
|
func (c *ApplyCommandConfig) applyValidatingAdmissionPolicytoResource(
|
||||||
|
@ -388,7 +384,12 @@ func (c *ApplyCommandConfig) loadResources(out io.Writer, paths []string, polici
|
||||||
return resources, nil
|
return resources, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) loadPolicies(skipInvalidPolicies SkippedInvalidPolicies) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, []kyvernov1.PolicyInterface, []admissionregistrationv1beta1.ValidatingAdmissionPolicy, []admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding, error) {
|
func (c *ApplyCommandConfig) loadPolicies() (
|
||||||
|
[]kyvernov1.PolicyInterface,
|
||||||
|
[]admissionregistrationv1beta1.ValidatingAdmissionPolicy,
|
||||||
|
[]admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
// load policies
|
// load policies
|
||||||
var policies []kyvernov1.PolicyInterface
|
var policies []kyvernov1.PolicyInterface
|
||||||
var vaps []admissionregistrationv1beta1.ValidatingAdmissionPolicy
|
var vaps []admissionregistrationv1beta1.ValidatingAdmissionPolicy
|
||||||
|
@ -399,12 +400,12 @@ func (c *ApplyCommandConfig) loadPolicies(skipInvalidPolicies SkippedInvalidPoli
|
||||||
if isGit {
|
if isGit {
|
||||||
gitSourceURL, err := url.Parse(path)
|
gitSourceURL, err := url.Parse(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, nil, nil, fmt.Errorf("failed to load policies (%w)", err)
|
return nil, nil, nil, fmt.Errorf("failed to load policies (%w)", err)
|
||||||
}
|
}
|
||||||
pathElems := strings.Split(gitSourceURL.Path[1:], "/")
|
pathElems := strings.Split(gitSourceURL.Path[1:], "/")
|
||||||
if len(pathElems) <= 1 {
|
if len(pathElems) <= 1 {
|
||||||
err := fmt.Errorf("invalid URL path %s - expected https://<any_git_source_domain>/:owner/:repository/:branch (without --git-branch flag) OR https://<any_git_source_domain>/:owner/:repository/:directory (with --git-branch flag)", gitSourceURL.Path)
|
err := fmt.Errorf("invalid URL path %s - expected https://<any_git_source_domain>/:owner/:repository/:branch (without --git-branch flag) OR https://<any_git_source_domain>/:owner/:repository/:directory (with --git-branch flag)", gitSourceURL.Path)
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, nil, nil, fmt.Errorf("failed to parse URL (%w)", err)
|
return nil, nil, nil, fmt.Errorf("failed to parse URL (%w)", err)
|
||||||
}
|
}
|
||||||
gitSourceURL.Path = strings.Join([]string{pathElems[0], pathElems[1]}, "/")
|
gitSourceURL.Path = strings.Join([]string{pathElems[0], pathElems[1]}, "/")
|
||||||
repoURL := gitSourceURL.String()
|
repoURL := gitSourceURL.String()
|
||||||
|
@ -413,11 +414,11 @@ func (c *ApplyCommandConfig) loadPolicies(skipInvalidPolicies SkippedInvalidPoli
|
||||||
fs := memfs.New()
|
fs := memfs.New()
|
||||||
if _, err := gitutils.Clone(repoURL, fs, c.GitBranch); err != nil {
|
if _, err := gitutils.Clone(repoURL, fs, c.GitBranch); err != nil {
|
||||||
log.Log.V(3).Info(fmt.Sprintf("failed to clone repository %v as it is not valid", repoURL), "error", err)
|
log.Log.V(3).Info(fmt.Sprintf("failed to clone repository %v as it is not valid", repoURL), "error", err)
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, nil, nil, fmt.Errorf("failed to clone repository (%w)", err)
|
return nil, nil, nil, fmt.Errorf("failed to clone repository (%w)", err)
|
||||||
}
|
}
|
||||||
policyYamls, err := gitutils.ListYamls(fs, gitPathToYamls)
|
policyYamls, err := gitutils.ListYamls(fs, gitPathToYamls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, nil, nil, fmt.Errorf("failed to list YAMLs in repository (%w)", err)
|
return nil, nil, nil, fmt.Errorf("failed to list YAMLs in repository (%w)", err)
|
||||||
}
|
}
|
||||||
for _, policyYaml := range policyYamls {
|
for _, policyYaml := range policyYamls {
|
||||||
loaderResults, err := policy.Load(fs, "", policyYaml)
|
loaderResults, err := policy.Load(fs, "", policyYaml)
|
||||||
|
@ -444,10 +445,13 @@ func (c *ApplyCommandConfig) loadPolicies(skipInvalidPolicies SkippedInvalidPoli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, skipInvalidPolicies, nil, policies, vaps, vapBindings, nil
|
return policies, vaps, vapBindings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipInvalidPolicies SkippedInvalidPolicies, targetResources ...*unstructured.Unstructured) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, dclient.Interface, error) {
|
func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, targetResources ...*unstructured.Unstructured) (
|
||||||
|
dclient.Interface,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
store.SetLocal(true)
|
store.SetLocal(true)
|
||||||
store.SetRegistryAccess(c.RegistryAccess)
|
store.SetRegistryAccess(c.RegistryAccess)
|
||||||
if c.Cluster {
|
if c.Cluster {
|
||||||
|
@ -458,19 +462,19 @@ func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipI
|
||||||
if c.Cluster {
|
if c.Cluster {
|
||||||
restConfig, err := config.CreateClientConfigWithContext(c.KubeConfig, c.Context)
|
restConfig, err := config.CreateClientConfigWithContext(c.KubeConfig, c.Context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
kubeClient, err := kubernetes.NewForConfig(restConfig)
|
kubeClient, err := kubernetes.NewForConfig(restConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dynamicClient, err := dynamic.NewForConfig(restConfig)
|
dynamicClient, err := dynamic.NewForConfig(restConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dClient, err = dclient.NewClient(context.Background(), dynamicClient, kubeClient, 15*time.Minute)
|
dClient, err = dclient.NewClient(context.Background(), dynamicClient, kubeClient, 15*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(targetResources) > 0 && !c.Cluster {
|
if len(targetResources) > 0 && !c.Cluster {
|
||||||
|
@ -478,17 +482,16 @@ func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipI
|
||||||
for _, t := range targetResources {
|
for _, t := range targetResources {
|
||||||
targets = append(targets, t)
|
targets = append(targets, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
dClient, err = dclient.NewFakeClient(runtime.NewScheme(), map[schema.GroupVersionResource]string{}, targets...)
|
dClient, err = dclient.NewFakeClient(runtime.NewScheme(), map[schema.GroupVersionResource]string{}, targets...)
|
||||||
dClient.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
dClient.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, skipInvalidPolicies, nil, dClient, err
|
return dClient, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) cleanPreviousContent(mutateLogPathIsDir bool, skipInvalidPolicies SkippedInvalidPolicies) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
func (c *ApplyCommandConfig) cleanPreviousContent(mutateLogPathIsDir bool) error {
|
||||||
// empty the previous contents of the file just in case if the file already existed before with some content(so as to perform overwrites)
|
// empty the previous contents of the file just in case if the file already existed before with some content(so as to perform overwrites)
|
||||||
// the truncation of files for the case when mutateLogPath is dir, is handled under pkg/kyverno/apply/common.go
|
// the truncation of files for the case when mutateLogPath is dir, is handled under pkg/kyverno/apply/common.go
|
||||||
if !mutateLogPathIsDir && c.MutateLogPath != "" {
|
if !mutateLogPathIsDir && c.MutateLogPath != "" {
|
||||||
|
@ -496,27 +499,26 @@ func (c *ApplyCommandConfig) cleanPreviousContent(mutateLogPathIsDir bool, skipI
|
||||||
// Necessary for us to include the file via variable as it is part of the CLI.
|
// Necessary for us to include the file via variable as it is part of the CLI.
|
||||||
_, err := os.OpenFile(c.MutateLogPath, os.O_TRUNC|os.O_WRONLY, 0o600) // #nosec G304
|
_, err := os.OpenFile(c.MutateLogPath, os.O_TRUNC|os.O_WRONLY, 0o600) // #nosec G304
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("failed to truncate the existing file at %s (%w)", c.MutateLogPath, err)
|
return fmt.Errorf("failed to truncate the existing file at %s (%w)", c.MutateLogPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApplyCommandConfig) checkArguments() (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
func (c *ApplyCommandConfig) checkArguments() error {
|
||||||
var skipInvalidPolicies SkippedInvalidPolicies
|
|
||||||
if c.ValuesFile != "" && c.Variables != nil {
|
if c.ValuesFile != "" && c.Variables != nil {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("pass the values either using set flag or values_file flag")
|
return fmt.Errorf("pass the values either using set flag or values_file flag")
|
||||||
}
|
}
|
||||||
if len(c.PolicyPaths) == 0 {
|
if len(c.PolicyPaths) == 0 {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("require policy")
|
return fmt.Errorf("require policy")
|
||||||
}
|
}
|
||||||
if (len(c.PolicyPaths) > 0 && c.PolicyPaths[0] == "-") && len(c.ResourcePaths) > 0 && c.ResourcePaths[0] == "-" {
|
if (len(c.PolicyPaths) > 0 && c.PolicyPaths[0] == "-") && len(c.ResourcePaths) > 0 && c.ResourcePaths[0] == "-" {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("a stdin pipe can be used for either policies or resources, not both")
|
return fmt.Errorf("a stdin pipe can be used for either policies or resources, not both")
|
||||||
}
|
}
|
||||||
if len(c.ResourcePaths) == 0 && !c.Cluster {
|
if len(c.ResourcePaths) == 0 && !c.Cluster {
|
||||||
return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("resource file(s) or cluster required")
|
return fmt.Errorf("resource file(s) or cluster required")
|
||||||
}
|
}
|
||||||
return nil, nil, skipInvalidPolicies, nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type WarnExitCodeError struct {
|
type WarnExitCodeError struct {
|
||||||
|
|
Loading…
Add table
Reference in a new issue