lib/puppetx/simp/compliance_mapper.rb
def enforcement(key, context=self, options={"mode" => "value"}, &block)
  # Throw away keys we know we can't handle.
  # This also prevents recursion since these are the only keys internally we call.
  case key
    when "lookup_options"
      # XXX ToDo See note about compiling a lookup_options hash in the compiler
      throw :no_such_key
    when "compliance_map"
      throw :no_such_key
    when "compliance_markup::compliance_map"
      throw :no_such_key
    when "compliance_markup::compliance_map::percent_sign"
      throw :no_such_key
    when "compliance_markup::enforcement"
      throw :no_such_key
    when "compliance_markup::version"
      throw :no_such_key
    when "compliance_markup::percent_sign"
      throw :no_such_key
    else
      retval = :notfound

      if context.cache_has_key("lock")
        lock = context.cached_value("lock")
      else
        lock = false
      end

      if lock == false

        debug_output = {}

        context.cache("lock", true)

        begin
          profile_list = cached_lookup "compliance_markup::enforcement", [], &block

          unless (profile_list == [])
            debug("debug: compliance_markup::enforcement set to #{profile_list}, attempting to enforce")

            profile = profile_list.hash.to_s

            if context.cache_has_key("compliance_map_#{profile}")
              # If we have a cache for this profile, we've already found
              # everything that we're going to find.
              if context.cache_has_key(key)
                return cached_value(key)
              else
                throw :no_such_key
              end

              profile_map = context.cached_value("compliance_map_#{profile}")

              # In this case, we've already loaded everything and didn't find
              # anything at all so go ahead and bail.
              throw :no_such_key if (profile_map && profile_map.empty?)
            else
              debug("debug: compliance map for #{profile_list} not found, starting compiler")

              compile_start_time = Time.now
              profile_compiler   = compiler_class.new(self)

              profile_compiler.load(&block)

              profile_map = profile_compiler.list_puppet_params(profile_list).cook do |item|
                debug_output[item["parameter"]] = item["telemetry"]
                item[options["mode"]]

                # Add this parameter to the context cache so that it is
                # preserved between calls.
                #
                # This allows us to prevent deep recursion and repeated digging
                # into files with no benefit.
                context.cache(item["parameter"], item["value"])
              end

              context.cache("debug_output_#{profile}", debug_output)
              context.cache("compliance_map_#{profile}", profile_map)

              compile_end_time = Time.now

              profile_map["compliance_markup::debug::hiera_backend_compile_time"] = (compile_end_time - compile_start_time)
              cache("compliance_map_#{profile}", profile_map)
              debug("debug: compiled compliance_map containing #{profile_map.size} keys in #{compile_end_time - compile_start_time} seconds")
            end
            if key == "compliance_markup::debug::dump"
               retval = profile_map
            else
              # Handle a knockout prefix
              unless profile_map.key?("--" + key)
                if profile_map.key?(key)
                  debug("debug: v2 details for #{key}")

                  retval = profile_map[key]
                  files  = {}

                  debug_output[key].each do |telemetryinfo|
                    unless files.key?(telemetryinfo["filename"])
                      files[telemetryinfo["filename"]] = []
                    end
                    files[telemetryinfo["filename"]] << telemetryinfo
                  end

                  files.each do |k, v|
                    debug("     #{k}:")

                    v.each do |value2|
                      debug("             #{value2['id']}")
                      debug("                        #{value2['value']['settings']['value']}")
                    end
                  end
                end
              end
            end

            # XXX ToDo: Generate a lookup_options hash, set to 'first', if the user specifies some
            # option that toggles it on. This would allow un-overridable enforcement at the hiera
            # layer (though it can still be overridden by resource-style class definitions)
          end
        rescue
        ensure
          context.cache("lock", false)
        end
      end
      if retval == :notfound
        throw :no_such_key
      end
  end

  return retval
end
# This is the shared codebase for the compliance_markup hiera
# backend. Each calling object (either the hiera backend class
# or the puppet lookup function) uses instance_eval to add these
# functions to the object.
#
# Then the object can call enforcement like so:
# enforcement('key::name') do |key, default|
#   lookup(key, { "default_value" => default})
# end
#
# The block is used to abstract lookup() since Hiera v5 and Hiera v3 have
# different calling conventions
#
# This block will also return a KeyError if there is no key found, which must be
# trapped and converted into the correct response for the api. either throw :no_such_key
# or context.not_found()
#
# We also expect a small api in the object that includes these functions:
#
# debug(message)
# cached(key)
# cache(key, value)
# cache_has_key(key)
#
# which allow for debug logging, and caching, respectively. Hiera v5 provides this function
# natively, while Hiera v3 has to create it itself
This is the shared codebase for the compliance_markup hiera
backend. Each calling object (either the hiera backend class
or the puppet lookup function) uses instance_eval to add these
functions to the object.

Then the object can call enforcement like so:
enforcement('key::name') do |key, default|
lookup(key, { "default_value" => default})
end

The block is used to abstract lookup() since Hiera v5 and Hiera v3 have
different calling conventions

This block will also return a KeyError if there is no key found, which must be
trapped and converted into the correct response for the api.

We also expect a small api in the object that includes these functions.



which allow for debug logging, and caching, respectively. Hiera v5 provides this function
natively, while Hiera v3 has to create it itself
This is the shared codebase for the compliance_markup hiera backend . Each calling object ( either the hiera backend class or the puppet lookup function ) uses instance_eval to add these functions to the object . Then the object can call enforcement like so : enforcement ( ' key :: name ' ) do |key default| lookup ( key { " default_value " = > default } ) end The block is used to abstract lookup () since Hiera v5 and Hiera v3 have different calling conventions This block will also return a KeyError if there is no key found which must be trapped and converted into the correct response for the api . We also expect a small api in the object that includes these functions . which allow for debug logging and caching respectively . Hiera v5 provides this function natively while Hiera v3 has to create it itself
def enforcement(key, context=self, options={"mode" => "value"}, &block)
  case key
    when "lookup_options"
      throw :no_such_key
    when "compliance_map"
      throw :no_such_key
    when "compliance_markup::compliance_map"
      throw :no_such_key
    when "compliance_markup::compliance_map::percent_sign"
      throw :no_such_key
    when "compliance_markup::enforcement"
      throw :no_such_key
    when "compliance_markup::version"
      throw :no_such_key
    when "compliance_markup::percent_sign"
      throw :no_such_key
    else
      retval = :notfound
      if context.cache_has_key("lock")
        lock = context.cached_value("lock")
      else
        lock = false
      end
      if lock == false
        debug_output = {}
        context.cache("lock", true)
        begin
          profile_list = cached_lookup "compliance_markup::enforcement", [], &block
          unless (profile_list == [])
            debug("debug: compliance_markup::enforcement set to {profile_list}, attempting to enforce")
            profile = profile_list.hash.to_s
            if context.cache_has_key("compliance_map_{profile}")
              if context.cache_has_key(key)
                return cached_value(key)
              else
                throw :no_such_key
              end
              profile_map = context.cached_value("compliance_map_{profile}")
              throw :no_such_key if (profile_map && profile_map.empty?)
            else
              debug("debug: compliance map for {profile_list} not found, starting compiler")
              compile_start_time = Time.now
              profile_compiler   = compiler_class.new(self)
              profile_compiler.load(&block)
              profile_map = profile_compiler.list_puppet_params(profile_list).cook do |item|
                debug_output[item["parameter"]] = item["telemetry"]
                item[options["mode"]]
                 This allows us to prevent deep recursion and repeated digging
                 into files with no benefit.
                context.cache(item["parameter"], item["value"])
              end
              context.cache("debug_output_{profile}", debug_output)
              context.cache("compliance_map_{profile}", profile_map)
              compile_end_time = Time.now
              profile_map["compliance_markup::debug::hiera_backend_compile_time"] = (compile_end_time - compile_start_time)
              cache("compliance_map_{profile}", profile_map)
              debug("debug: compiled compliance_map containing {profile_map.size} keys in {compile_end_time - compile_start_time} seconds")
            end
            if key == "compliance_markup::debug::dump"
               retval = profile_map
            else
               Handle a knockout prefix
              unless profile_map.key?("--" + key)
                if profile_map.key?(key)
                  debug("debug: v2 details for {key}")
                  retval = profile_map[key]
                  files  = {}
                  debug_output[key].each do |telemetryinfo|
                    unless files.key?(telemetryinfo["filename"])
                      files[telemetryinfo["filename"]] = []
                    end
                    files[telemetryinfo["filename"]] << telemetryinfo
                  end
                  files.each do |k, v|
                    debug("     {k}:")
                    v.each do |value2|
                      debug("             {value2['id']}")
                      debug("                        {value2['value']['settings']['value']}")
                    end
                  end
                end
              end
            end
             XXX ToDo: Generate a lookup_options hash, set to 'first', if the user specifies some
             option that toggles it on. This would allow un-overridable enforcement at the hiera
             layer (though it can still be overridden by resource-style class definitions)
          end
        rescue
        ensure
          context.cache("lock", false)
        end
      end
      if retval == :notfound
        throw :no_such_key
      end
  end
  return retval
end
def enforcement ( key , context = self , options = { "mode" => "value" } , & block ) case key when "lookup_options" throw :no_such_key when "compliance_map" throw :no_such_key when "compliance_markup::compliance_map" throw :no_such_key when "compliance_markup::compliance_map::percent_sign" throw :no_such_key when "compliance_markup::enforcement" throw :no_such_key when "compliance_markup::version" throw :no_such_key when "compliance_markup::percent_sign" throw :no_such_key else retval = :notfound if context . cache_has_key ( "lock" ) lock = context . cached_value ( "lock" ) else lock = false end if lock == false debug_output = { } context . cache ( "lock" , true ) begin profile_list = cached_lookup "compliance_markup::enforcement" , [ ] , & block unless ( profile_list == [ ] ) debug ( "debug: compliance_markup::enforcement set to #{profile_list}, attempting to enforce" ) profile = profile_list . hash . to_s if context . cache_has_key ( "compliance_map_#{profile}" ) if context . cache_has_key ( key ) return cached_value ( key ) else throw :no_such_key end profile_map = context . cached_value ( "compliance_map_#{profile}" ) throw :no_such_key if ( profile_map && profile_map . empty? ) else debug ( "debug: compliance map for #{profile_list} not found, starting compiler" ) compile_start_time = Time . now profile_compiler = compiler_class . new ( self ) profile_compiler . load ( & block ) profile_map = profile_compiler . list_puppet_params ( profile_list ) . cook do | item | debug_output [ item [ "parameter" ] ] = item [ "telemetry" ] item [ options [ "mode" ] ] context . cache ( item [ "parameter" ] , item [ "value" ] ) end context . cache ( "debug_output_#{profile}" , debug_output ) context . cache ( "compliance_map_#{profile}" , profile_map ) compile_end_time = Time . now profile_map [ "compliance_markup::debug::hiera_backend_compile_time" ] = ( compile_end_time - compile_start_time ) cache ( "compliance_map_#{profile}" , profile_map ) debug ( "debug: compiled compliance_map containing #{profile_map.size} keys in #{compile_end_time - compile_start_time} seconds" ) end if key == "compliance_markup::debug::dump" retval = profile_map else unless profile_map . key? ( "--" + key ) if profile_map . key? ( key ) debug ( "debug: v2 details for #{key}" ) retval = profile_map [ key ] files = { } debug_output [ key ] . each do | telemetryinfo | unless files . key? ( telemetryinfo [ "filename" ] ) files [ telemetryinfo [ "filename" ] ] = [ ] end files [ telemetryinfo [ "filename" ] ] << telemetryinfo end files . each do | k , v | debug ( "     #{k}:" ) v . each do | value2 | debug ( "             #{value2['id']}" ) debug ( "                        #{value2['value']['settings']['value']}" ) end end end end end end rescue ensure context . cache ( "lock" , false ) end end if retval == :notfound throw :no_such_key end end return retval end
This is the shared codebase for the compliance_markup hiera
backend.
This is the shared codebase for the compliance_markup hiera backend .
# Throw away keys we know we can't handle. # This also prevents recursion since these are the only keys internally we call. # XXX ToDo See note about compiling a lookup_options hash in the compiler # If we have a cache for this profile, we've already found # everything that we're going to find. # In this case, we've already loaded everything and didn't find # anything at all so go ahead and bail. # Add this parameter to the context cache so that it is # preserved between calls. # # This allows us to prevent deep recursion and repeated digging # into files with no benefit. # Handle a knockout prefix # XXX ToDo: Generate a lookup_options hash, set to 'first', if the user specifies some # option that toggles it on. This would allow un-overridable enforcement at the hiera # layer (though it can still be overridden by resource-style class definitions)
key
context
options
block