Class: Bolt::PAL::YamlPlan
- Inherits:
-
Object
- Object
- Bolt::PAL::YamlPlan
- Defined in:
- lib/bolt/pal/yaml_plan.rb,
lib/bolt/pal/yaml_plan/loader.rb,
lib/bolt/pal/yaml_plan/evaluator.rb
Defined Under Namespace
Classes: BareString, CodeLiteral, DoubleQuotedString, EvaluableString, Evaluator, Loader, Parameter
Constant Summary collapse
- VAR_NAME_PATTERN =
/\A[a-z_][a-z0-9_]*\z/.freeze
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#parameters ⇒ Object
readonly
Returns the value of attribute parameters.
-
#return ⇒ Object
readonly
Returns the value of attribute return.
-
#steps ⇒ Object
readonly
Returns the value of attribute steps.
Instance Method Summary collapse
- #body ⇒ Object
-
#initialize(name, plan) ⇒ YamlPlan
constructor
A new instance of YamlPlan.
- #return_type ⇒ Object
-
#stringify(value) ⇒ Object
Turn all “potential” strings in the object into actual strings.
- #validate ⇒ Object
Constructor Details
#initialize(name, plan) ⇒ YamlPlan
Returns a new instance of YamlPlan.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/bolt/pal/yaml_plan.rb', line 14 def initialize(name, plan) # Top-level plan keys aren't allowed to be Puppet code, so force them # all to strings. plan = Bolt::Util.walk_keys(plan) { |key| stringify(key) } @name = name.freeze # Nothing in parameters is allowed to be code, since no variables are defined yet params_hash = stringify(plan.fetch('parameters', {})) # Munge parameters into an array of Parameter objects, which is what # the Puppet API expects @parameters = params_hash.map do |param, definition| definition ||= {} type = Puppet::Pops::Types::TypeParser.singleton.parse(definition['type']) if definition.key?('type') Parameter.new(param, definition['default'], type) end.freeze @steps = plan['steps']&.map do |step| # Step keys also aren't allowed to be code and neither is the value of "name" stringified_step = Bolt::Util.walk_keys(step) { |key| stringify(key) } stringified_step['name'] = stringify(stringified_step['name']) if stringified_step.key?('name') stringified_step end.freeze @return = plan['return'] validate end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
12 13 14 |
# File 'lib/bolt/pal/yaml_plan.rb', line 12 def name @name end |
#parameters ⇒ Object (readonly)
Returns the value of attribute parameters.
12 13 14 |
# File 'lib/bolt/pal/yaml_plan.rb', line 12 def parameters @parameters end |
#return ⇒ Object (readonly)
Returns the value of attribute return.
12 13 14 |
# File 'lib/bolt/pal/yaml_plan.rb', line 12 def return @return end |
#steps ⇒ Object (readonly)
Returns the value of attribute steps.
12 13 14 |
# File 'lib/bolt/pal/yaml_plan.rb', line 12 def steps @steps end |
Instance Method Details
#body ⇒ Object
78 79 80 |
# File 'lib/bolt/pal/yaml_plan.rb', line 78 def body self end |
#return_type ⇒ Object
102 103 104 |
# File 'lib/bolt/pal/yaml_plan.rb', line 102 def return_type Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult') end |
#stringify(value) ⇒ Object
Turn all “potential” strings in the object into actual strings. Because we interpret bare strings as potential Puppet code, even in places where Puppet code isn’t allowed (like some hash keys), we need to be able to force them back into regular strings, as if we had parsed them normally.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/bolt/pal/yaml_plan.rb', line 87 def stringify(value) case value when Array value.map { |element| stringify(element) } when Hash value.each_with_object({}) do |(k, v), o| o[stringify(k)] = stringify(v) end when EvaluableString value.value else value end end |
#validate ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/bolt/pal/yaml_plan.rb', line 46 def validate unless @steps.is_a?(Array) raise Bolt::Error.new("Plan must specify an array of steps", "bolt/invalid-plan") end used_names = Set.new # Parameters come in a hash, so they must be unique @parameters.each do |param| unless param.name.is_a?(String) && param.name.match?(VAR_NAME_PATTERN) raise Bolt::Error.new("Invalid parameter name #{param.name.inspect}", "bolt/invalid-plan") end used_names << param.name end @steps.each do |step| next unless step.key?('name') unless step['name'].is_a?(String) && step['name'].match?(VAR_NAME_PATTERN) raise Bolt::Error.new("Invalid step name #{step['name'].inspect}", "bolt/invalid-plan") end if used_names.include?(step['name']) msg = "Step name #{step['name'].inspect} matches an existing parameter or step name" raise Bolt::Error.new(msg, "bolt/invalid-plan") end used_names << step['name'] end end |