Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-7822

Add get(), getvar() functions that use dot syntax to "dig" into hash/array

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: PUP 5.0.1
    • Fix Version/s: PUP 6.0.0
    • Component/s: None
    • Labels:
      None
    • Template:
    • Acceptance Criteria:
      Hide

      A get() function that supports the dot-syntax for digging into a value and that optionally handles returning a default value if the result would otherwise be undef.

      A getvar() function that digs into a value when given a <var>.<navigation> dot-syntax string, where <var> is a variable name

      Show
      A get() function that supports the dot-syntax for digging into a value and that optionally handles returning a default value if the result would otherwise be undef. A getvar() function that digs into a value when given a <var>.<navigation> dot-syntax string, where <var> is a variable name
    • Team:
      Platform Core
    • CS Priority:
      Minor
    • CS Frequency:
      1 - 1-5% of Customers
    • CS Severity:
      2 - Annoyance
    • CS Business Value:
      2 - $$$
    • CS Impact:
      With stdlib having similar functionality this not a high priority.
    • Release Notes:
      New Feature
    • Release Notes Summary:
      Hide
      It is now possible to use the same "dot notation" to dig out a value from a structure like in hiera/lookup and elsewhere in puppet. To support this, the {{getvar()}} function has moved from stdlib to puppet, and we have added a new function {{get()}}. You can now for example use {{getvar('facts.os.family')}} starting with the variable name. The {{get}} function is the general function which takes a value and a dot-notation string.
      Show
      It is now possible to use the same "dot notation" to dig out a value from a structure like in hiera/lookup and elsewhere in puppet. To support this, the {{getvar()}} function has moved from stdlib to puppet, and we have added a new function {{get()}}. You can now for example use {{getvar('facts.os.family')}} starting with the variable name. The {{get}} function is the general function which takes a value and a dot-notation string.
    • QA Risk Assessment:
      Needs Assessment

      Description

      Supporting the dot-notation for digging into structured values (arrays and hashes) is of value. The current available function dig() does not parse the dot notation (it takes an array of segments) and it cannot be changed as that would break compatibility, and it also does not support a default value.

      A new function get(<dotted_key>) that also takes an optional lambda that gets called if the result would be undef. If the lambda takes no arguments it is simply called. If it accepts one argument, that is a Struct[segments => Array[String], values => Array], thus making it possible to figure out how far the "dig" got before giving up, and to use that in a custom warning or error message (or simply logging it when debugging). (The value array ends with the undef value that caused the dig to give up). The lambda is not called if the final segment results in a nil value being found in a hash, but is called if the last segment did not exist.

      A new companion function to get(), getvar("<var>.<dotted_key>").

      Examples:

      $facts.get('some.fact')
      getvar('facts.some.fact')
       
      $facts.get('some.fact') || { 'go fish' } # 'go fish' is the default
      getvar('facts.some.fact') || { 'go fish' }
       
      $facts.get('some.facts.detail.0.x') |$resolution| { 
        $size = $resolution['values'].size() # std lib function for now since size is not in core
        notice(@("MESSAGE"))
          Could not lookup all given segments: ${resolution['segments']}
          Got an undef value for the key: ${resolution['segments'][$size-1]}
          Values per segment are: ${resolution['values']}
          |- MESSAGE
      }
      

      When implementing this, it is of value to write a helper function parse_dig(String) that returns an array of segments from the dot-notation string. The get function uses that if it gets a string, if it gets an array it is taken as already parsed segments. The dig function should be given the lambda support to process the walked path. Thus:

      • Add a parse_dig(String) function
      • Add a lambda for processing default to dig
      • Add get(Variant[Array, String]), calling parse_dig for a String arg, and then calling dig to do the digging.
      • Add a default value parameter to get which is mutually exclusive with giving a lambda - the default value is returned if value is undef (irrespective of reason) - if there is the need to differentiate between actual undef value, and not found, a lambda must be used.

      ORIGINAL


      The fact() function provides a way to use the dot syntax for indexing into structured in the DSL. This was recently merged into stdlib(PR: https://github.com/puppetlabs/puppetlabs-stdlib/pull/787 Docs: https://github.com/puppetlabs/puppetlabs-stdlib#fact).

      Ideally this would be part of core puppet instead of the stdlib module given it's the syntax used in facter and heira for structured facts.

        Attachments

          Activity

            jsd-sla-details-panel

              People

              • Assignee:
                Unassigned
                Reporter:
                owen Owen Rodabaugh
              • Votes:
                0 Vote for this issue
                Watchers:
                8 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: