-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Syntactically incorrect types cause nil types in Puppet::InfoService::ClassInformationService #9140
Comments
Migrated issue to PUP-11981 |
We recently saw a similar issue when a class parameter was defined as Edit: But none of our tests puppet-lint, unit, beaker) actually failed... I would have expected compilation to fail unless the compiler resolves the type to |
That API does not have a way to report detail errors, it either produces a result (and skips bad input) or returns an error. Code should have been validated before deploying and using the class info service. |
The type class foo(Integer[1-3] $i) {}
class { 'foo': i => 4 } The class info service is getting an error because it only accepts literal expressions: puppet/lib/puppet/info_service/class_information_service.rb Lines 94 to 97 in 775592c
Can we validate that class parameters don't contain non-literal expressions earlier? Or maybe a puppet-lint check? |
Should be possible to validate. |
Hi @hlindberg I see we validate class definitions here, for example to ensure class parameter names are unique. Would it make sense to add a check that class parameter types are literal too? diff --git a/lib/puppet/pops/issues.rb b/lib/puppet/pops/issues.rb
index b619636568..23cb80dbde 100644
--- a/lib/puppet/pops/issues.rb
+++ b/lib/puppet/pops/issues.rb
@@ -207,6 +207,9 @@ module Issues
_("The numeric parameter name '$%{name}' cannot be used (clashes with numeric match result variables)") % { name: name }
end
+ ILLEGAL_NONLITERAL_PARAMETER_TYPE = issue :ILLEGAL_NONLITERAL_PARAMETER_TYPE, :name, :type_class do
+ _("The parameter '$%{name}' must be a literal type, not %{type_class}") % { name: name, type_class: label.a_an(type_class) }
+ end
# In certain versions of Puppet it may be allowed to assign to a not already assigned key
# in an array or a hash. This is an optional validation that may be turned on to prevent accidental
# mutation.
diff --git a/lib/puppet/pops/validation/checker4_0.rb b/lib/puppet/pops/validation/checker4_0.rb
index eb7ac5cc77..66f62d1895 100644
--- a/lib/puppet/pops/validation/checker4_0.rb
+++ b/lib/puppet/pops/validation/checker4_0.rb
@@ -471,6 +471,7 @@ class Checker4_0 < Evaluator::LiteralEvaluator
internal_check_parameter_name_uniqueness(o)
internal_check_reserved_params(o)
internal_check_no_idem_last(o)
+ internal_check_parameter_type_literal(o)
end
def check_ResourceTypeDefinition(o)
@@ -683,6 +684,17 @@ class Checker4_0 < Evaluator::LiteralEvaluator
end
end
+ def internal_check_parameter_type_literal(o)
+ o.parameters.each do |p|
+ next unless p.type_expr
+ catch :not_literal do
+ literal(p.type_expr)
+ next
+ end
+ acceptor.accept(Issues::ILLEGAL_NONLITERAL_PARAMETER_TYPE, p, {name: p.name, type_class: p.type_expr.class})
+ end
+ end
+ The However, we have tests that class parameter types can be puppet/lib/puppet/pops/evaluator/literal_evaluator.rb Lines 15 to 16 in 775592c
Since the
Is there a different evaluator I should be using for class parameters? Or should I create a new evaluator and implement the missing class Something < LiteralEvaluator
def literal_QualifiedReference(o)
...
end I assume whatever we do, both the |
The one issue that bothers me a bit is that any type of reference that isn't defined as a data type or one of the built-in is considered a reference to a class, defined resource-type, or built-in resource type. Thus I am thinking that when validation takes place it isn't known if it is a reference to an actual thing or not. It probably does not matter as the problem here is that it cannot be turned into a human-readable string for the info-service. It will probably work to allow qualified references in a specialized evaluator like you suggest and then make sure it gets used in both places. The logic that turns I don't remember if the info-service also produces information for defined resources. If so the validator for those must do the same - otherwise it could be allowed (as for functions). In both those case it is still not good for generating documentation as it would need to produce somethng humany-readable. You may thus want to also validate functions to only accept literal type definitions. You should still allow it for lambdas and everywhere else - just not in any puppet language "definition" (i.e. May have to be adjusted for Bolt as well if they use specialized validators. Also take a look at what Puppet String does if faced with non-literal type in definitions and how it handles if it gets a The much simpler solution would be to consider Hope that helps. |
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140 (cherry picked from commit adbb02c)
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140 (cherry picked from commit adbb02c)
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140 (cherry picked from commit adbb02c) (PUP-11981) Add test for non-literal class params in ClassInfoService spec (cherry picked from commit 8992763)
Why wasn't this listed as a breaking change? It breaks many downstream modules that expect i.e: i.e: https://github.com/voxpupuli/puppet-dhcp/blob/master/manifests/init.pp#L29-L30
Not even the examples in the documentation work.
|
This commit adds logic to validate class parameters are literal and provides a descriptive warning if parameter(s) are not literal, adds QualifiedReference and AccessExpression as a valid literal values & updates spec tests to check for more cases of invalid class parameters and any that broke as a result of the changes. The logic to validate class parameters is done in internal_check_parameter_type_literal method where the appropriate literal method is called on each parameter. There are different literal methods for each literal object/type [1]. For example if the parameter is String type, then literal_LiteralString is called. If a parameter is found to be not literal, then a :not_literal will be thrown & warning message with the invalid class parameter and its type will be printed. QualifiedReference is considered literal since it is a literal reference, however, there is a possibility it could be a faulty dangling reference that doesn't reference anything. AccessExpresions are anything with the Access Operator ([ ]) such as Optional[String] or Variant[Boolean, Float] [2]. Since these are valid class parameters, AccessExpressions are also considered literal. The logic to add QualifiedReference & AccessExpression as valid literal values is done in the literal_QualifiedReference & literal_AccessExpression methods. The literal_AccessExpression works by validating each key in the expression is literal. The literal_QualifiedReference method looks at o.value, similar to other existing literal methods like literal_LiteralString. [1] http://puppet-on-the-edge.blogspot.com/2014/02/puppet-internals-polymorphic-dispatch.html [2] https://github.com/puppetlabs/puppet-specifications/blob/master/language/expressions.md#assignment-operator For more information on this issue, see puppetlabs#9140
Describe the Bug
When a type is incorrectly specified, e.g.
Integer[1-3]
for a class parameter, Puppet's class_information_service ignores this error, and produces an emptytype
specification.puppet/lib/puppet/info_service/class_information_service.rb
Lines 76 to 80 in 298762f
Expected Behavior
A warning should be produced, and a default type should be assigned in the
nil
case to prevent incorrect behavior. Note that this issue does not impact catalog compilation, but does impact the ability to get classes manifest information.Impacts both 7.x and 8.x
The text was updated successfully, but these errors were encountered: