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

Property validation should allow for cross-property validation; lazy property validation should always be forced at converge time before running the action #6505

Closed
atheiman opened this issue Oct 18, 2017 · 9 comments
Labels
Triage: Feature Request Indicates an issue requesting new functionality.

Comments

@atheiman
Copy link

I want to be able to validate properties of custom resources using the callbacks validator as described in the docs with more complexity:

  • Validate based on the value of another property
  • Validate based on the action of the resource

I quickly looked through the validator code and I think there are two possible approaches to this:

  1. Allow the callback lambdas to also receive the resource object with access to other properties and the action:
property :a, String
property :b, String, callbacks: {
  'required if property `a` is unset' => lambda { |property, resource|
    if resource.properties.a.nil?
      # if property is nil, return false which raises validation error
      !property.nil?
    end
  },
  'required for `:configure` action' => lambda { |property, resource|
    if resource.action == :configure
      # if property is nil, return false which raises validation error
      !property.nil? 
    else
      true
    end
  }
}
  1. Allow the callback lambdas to also receive the action, and introduce a required_with validator that requires at least one of the properties to be set:
property :a, String, required_with: [:b]
property :b, String, required_with: [:a], callbacks: {
  'required for `:configure` action' => lambda { |property, action|
    if action == :configure
      # if property is nil, return false which raises validation error
      !property.nil? 
    else
      true
    end
  }
}
@lamont-granquist
Copy link
Contributor

can you solve this problem a lot easier by just writing an action_helper like def assert_properties_valid! and calling that in all your actions or all the appropriate actions?

the only real utility to doing property validation in the resource is to catch errors at compile time. if you're requiring an action and doing validation between properties, then you're already going to have to lazy validation to converge time (when you have that information accurately available), and might as well do it a lot more directly in the action class itself.

@coderanger
Copy link
Contributor

This kind of thing usually belongs in #after_created, so there is a defined life-cycle point for the multi-property check. Otherwise you can get weird issues with mutation-y objects.

@lamont-granquist
Copy link
Contributor

even in after_created its a bit weird because of possible chef-rewind-ey things. if you've got complicated validation based on multiple properties plus the action then in core chef we usually put that in define_resource_requirements which is morally equivalent to just running a helper inside of the action.

@atheiman
Copy link
Author

Yes what I’ve been doing so far is an action helper method like you’ve described. If youre not interested in implementing this and think the helper is a better approach thats fine with me.

@lamont-granquist
Copy link
Contributor

Yeah, the action helper approach is much clearer behavior on both sides (both for the core chef author of the properties code, and for the writer of custom resources).

A meta-question is if you went down this road due to being excessively paranoid about input validation. We used to do a lot of regex checking against e.g. usernames in core chef, but when you go down that road and start worrying about UTF-8 and Latin-1 and all the variations, and strange hacks people use for directory services, then the result was that we just banned a few always-bad characters like ':' on unix-related usernames, and then rely on the underlying O/S useradd to barf for us and catch the ShellOut exception. Trying to precisely replicate the validation that different platforms used across all the different O/S distros and versions was just going to be a neverending source of bugs and pain -- so instead of having Chef do validation we allowed the distro to be the source of truth...

Just something to consider...

@tas50 tas50 added the Type: Enhancement Adds new functionality. label Mar 17, 2018
@tas50 tas50 added Triage: Feature Request Indicates an issue requesting new functionality. and removed Type: Enhancement Adds new functionality. labels Oct 28, 2019
@lamont-granquist
Copy link
Contributor

Doing this as validation in after_created always breaks lazy values. So if property A depends on validating property B then if you validate them in after_created you force A and B to un-lazy at compile-time. That always generates bug reports by people who lazy absolutely everything.

@lamont-granquist
Copy link
Contributor

I think we also have issues around if you lazy a required value and such as well. We should really run through all the properties and force validation at converge time before running the action to make sure that all lazy validation is forced to be run.

@lamont-granquist lamont-granquist changed the title Allow more complex property validation for custom resources Property validation should allow for cross-property validation; lazy property validation should always be forced at converge time before running the action Oct 28, 2019
@lamont-granquist
Copy link
Contributor

We have the check_resource_semantics! callback on the provider which should be used for this kind of lazy cross resource validation. The lazy required validation is being done in #9688. We might look at implementing cross-property-lazy-aware-validation directly in properties, but its probably going to be driven by cleanup of our existing resource code at some point. For now all that code should be moved to check_resource_semantics! in the provider.

@lock
Copy link

lock bot commented May 5, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Triage: Feature Request Indicates an issue requesting new functionality.
Projects
None yet
Development

No branches or pull requests

4 participants