Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting validationFailureAction to enforce is going to enforce it for every Policy #601

Merged
merged 17 commits into from
Jan 11, 2020

Conversation

realshuting
Copy link
Member

@realshuting realshuting commented Jan 7, 2020

This PR fixes

@shivdudhani
Copy link
Contributor

shivdudhani commented Jan 7, 2020

but can we merge PR https://github.com/nirmata/kyverno/pull/594 and https://github.com/nirmata/kyverno/pull/587 first. As it uses reporting of PV in generate rules and will require changes to fix this PR.

@shivdudhani
Copy link
Contributor

Question 1:
Why are we removing the logic of owners while building violations?

Question 2:
Why does policyviolation package need to know engine.EngineResponse, this package dependency is not needed.

Each package should process engineResponse individually and then reports PV.

If you notice the package history, this dependency was intentionally removed(this discussion has been done before). But this PR adds the dependency again.

Please revert the corresponding changes.

Copy link
Contributor

@shivdudhani shivdudhani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question 1:
Why are we removing the logic of owners while building violations?

Question 2:
Why does policyviolation package need to know engine.EngineResponse, this package dependency is not needed.

Each package should process engineResponse individually and then reports PV.

If you notice the package history, this dependency was intentionally removed(this discussion has been done before). But this PR adds the dependency again.

Please revert the corresponding changes.

@realshuting
Copy link
Member Author

@shivdudhani
Q1: The violation created with owners was to inform the users if they have rule on Pod while deploying a pod controller. In this way we would have some sort of alarms and nothing go silent. After #518, we have an alternative solution to report such a scenario, please refer to comment.
Also it is natural to a Kubernetes user, for example, you would do a kubectl describe <podController> (event) or kubectl get -o yaml <podController> (status) to see why the pod does not get scheduled (when enforce).

Q2: If you notice, we create pvInfo in multiple components, with the change above, each of the function would have the same API, same logic. So it's better to use generic code to create this info instead of having it everywhere.

  1. https://github.com/nirmata/kyverno/blob/622d007e18dbcd743d2211a6a0f364eef86bf7b5/pkg/namespace/report.go#L22
  2. https://github.com/nirmata/kyverno/blob/c97b3ce5b0dbe6401f66e784079e7389a65aad5d/pkg/policy/report.go#L42
  3. https://github.com/nirmata/kyverno/blob/c97b3ce5b0dbe6401f66e784079e7389a65aad5d/pkg/webhooks/report.go#L109

@shivdudhani
Copy link
Contributor

Response to Q1: the whole idea of adding OwnerRef was to support any resources not just pod-controllers, as then we can report and this is how the feature was specified. With this we only support pod-controllers, so this will mean we are removing a feature. If this is the case, we can mention we have removed a feature.

Response to Q2: Yes, but it introduces package dependency and it was refactored to handle this. Generic code, it makes code easy but at the cost of increasing dependency. If the history of the package is looked at, it was refactored specifically for it. I'm not in favor of writing code that easy to write at the cost of code maintainability. The idea of policy violation is independent of a policy engine. We have had discussions to define standard design PV for any policy engine. But this adds the dependency.

@realshuting
Copy link
Member Author

Q1: Let's move the discussion to the issue, it's easier to track.
Q2: I'm ok to remove the dependency from policyviolation pkg, it's just that having the same code in separate places is not scalable, it's better to have a standard API that we can directly make use of. In this case, to get pvInfo from engineReponse.

@shivdudhani
Copy link
Contributor

PolicyViolation and EngineReponse are different resources, they don't need a direct dependency. You can define an interface that others implement to perform the conversion, but this again adds the dependency between the packages as the interface has to be defined in pkg engine or policy violation.

@shivdudhani
Copy link
Contributor

@realshuting
As the above change is regarding re-factoring and is taking time, it can be completed later(refactoring issue for tracking) and can focus on other pending issues,

@realshuting
Copy link
Member Author

As the above change is regarding re-factoring and is taking time, it can be completed later(refactoring issue for tracking) and can focus on other pending issues,

I'm not following, do you mean to keep the changes in PR or revert it back to the old way?

@shivdudhani
Copy link
Contributor

@realshuting whichever is easier for you, if we have time to refactor and also complete the pending issues for release v1.1.0 then that's great. If not I would suggest prioritizing the issues then the refactoring.

@shivdudhani
Copy link
Contributor

@realshuting as per the discussion the above behavior would change. Can you update this PR to include the reporting of PV if variable path is not found?

@shivdudhani
Copy link
Contributor

Can use interface EvalInterface in pkg/engine/context/context.go to check if the variable is present in context or not . And use this to understand if the query was evaluated or not.

If a path is not found a response will be nil interface. If there is any resource for which path exists but store nil value, the interface internal type will store the JSON type(mosty string) so will not be a nil interface.

@realshuting realshuting merged commit 28ccff0 into master Jan 11, 2020
@realshuting realshuting deleted the add_testscenario branch January 11, 2020 02:37
@realshuting
Copy link
Member Author

Merge to generate the release. If anything changes, would push a patch for that.

Copy link
Contributor

@shivdudhani shivdudhani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall:

  • some previous comments not addresed. (package dependency between policyvioltaion pkg and engine.

  • Curious to know y we adding a new field just for this check. As other checks use ruleResponse failure. It seems inconsistent to add a field and helper functions just for this check.

  • the check is performed before the resource is matched.

  • Some minor checks

glog.V(4).Infof("failed to unmarshall context")
return emptyResult, err
glog.V(4).Infof("failed to unmarshall context: %v", err)
return emptyResult, fmt.Errorf("failed to unmarshall context: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spelling unmarshal

var tempRule kyverno.Rule
var tempRulePattern interface{}

tempRule.MatchResources = rule.MatchResources
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

y use the tempRule variable here ?
As it as a copy of a copy of rule.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you see the description of this function, it validates the general ruleInfo: matchedResource, excludeResource and condition, not a specific rule, so it extracts the general rule info as a copy.

@@ -55,6 +61,13 @@ func filterRules(policy kyverno.ClusterPolicy, resource unstructured.Unstructure
}

for _, rule := range policy.Spec.Rules {
if paths := validateGeneralRuleInfoVariables(ctx, rule); len(paths) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Y is this not placed inside filterRule function ? as this is being processed per rule and we already have a function filterRule which already has checks per rule.

@@ -55,6 +57,13 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
continue
}

if paths := validateGeneralRuleInfoVariables(ctx, rule); len(paths) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldnt this check be after MatchesResourceDescription ? Now the variables are checked even if the resource does not statify the resource match/exclude block

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially the user could substitute the variable in match/exclude block, especially for userInfo, so the check performs before MatchesResourceDescription.

@@ -65,6 +65,8 @@ type RuleResponse struct {
Success bool `json:"success"`
// statistics
RuleStats `json:",inline"`
// PathNotPresent indicates whether referenced path in variable substitution exist
PathNotPresent bool `json:"pathNotPresent"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why we introducing a check for a path not present, as this could rule that failed with an error message.
So now for some errors, we have rule failure and message, and some new field added to a struct. (seems inconsistent design)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding,

  1. a rule failure refers to a rule application failure, while the path not present is much more a policy definition error
  2. since later we will have policy error reported as new CRD, it's more clear to have that 2 logic decoupled for the change.

@@ -7,6 +7,13 @@ import (
"github.com/nirmata/kyverno/pkg/engine/operator"
)

type ValidationFailureReason int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reference to some previous comments, a new type is introduced but this doesn't really add much value.
As the enum is not PathNotFound and the other value is RuleFailure(which is already default behavior if the rule has failed).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

)

func GeneratePVsFromEngineResponse(ers []response.EngineResponse) (pvInfos []Info) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed before, the policyviolation package is now dependent on engine (engine/response).
I believe the conclusion was to decouple the packages.

continue
}
// skip when response succeed AND referenced paths exist
if er.IsSuccesful() && !er.IsPathNotPresent() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reference to some above comments, the pathNotPresent is engineResponse error instead of adding a new filed and check specifically for it.
As this is one of the multiple check-in policy, others use a common field rule failure, which for this field we add a new field and new error checks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, as we gonna report pathNotPresent as the policy error, it would be helpful to decouple this type of error from violation.

return info
}

func buildViolatedRules(er response.EngineResponse) []kyverno.ViolatedRule {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the above comments adds package dependency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants