class Puppet::Pops::Lookup::HieraConfigV5

@api private

Constants

DEFAULT_CONFIG_HASH
RESERVED_OPTION_KEYS

Public Class Methods

config_type() click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
545 def self.config_type
546   return @@CONFIG_TYPE if class_variable_defined?(:@@CONFIG_TYPE_V5)
547   tf = Types::TypeFactory
548   nes_t = Types::PStringType::NON_EMPTY
549 
550   # Validated using Ruby URI implementation
551   uri_t = Types::PStringType::NON_EMPTY
552 
553   # The option name must start with a letter and end with a letter or digit. May contain underscore and dash.
554   option_name_t = tf.pattern(/\A[A-Za-z](:?[0-9A-Za-z_-]*[0-9A-Za-z])?\z/)
555 
556   hierarchy_t = tf.array_of(tf.struct(
557     {
558       KEY_NAME => nes_t,
559       tf.optional(KEY_OPTIONS) => tf.hash_kv(option_name_t, tf.data),
560       tf.optional(KEY_DATA_HASH) => nes_t,
561       tf.optional(KEY_LOOKUP_KEY) => nes_t,
562       tf.optional(KEY_V3_BACKEND) => nes_t,
563       tf.optional(KEY_V4_DATA_HASH) => nes_t,
564       tf.optional(KEY_DATA_DIG) => nes_t,
565       tf.optional(KEY_PATH) => nes_t,
566       tf.optional(KEY_PATHS) => tf.array_of(nes_t, tf.range(1, :default)),
567       tf.optional(KEY_GLOB) => nes_t,
568       tf.optional(KEY_GLOBS) => tf.array_of(nes_t, tf.range(1, :default)),
569       tf.optional(KEY_URI) => uri_t,
570       tf.optional(KEY_URIS) => tf.array_of(uri_t, tf.range(1, :default)),
571       tf.optional(KEY_MAPPED_PATHS) => tf.array_of(nes_t, tf.range(3, 3)),
572       tf.optional(KEY_DATADIR) => nes_t
573     }))
574 
575   @@CONFIG_TYPE = tf.struct({
576     KEY_VERSION => tf.range(5, 5),
577     tf.optional(KEY_DEFAULTS) => tf.struct(
578       {
579         tf.optional(KEY_DATA_HASH) => nes_t,
580         tf.optional(KEY_LOOKUP_KEY) => nes_t,
581         tf.optional(KEY_DATA_DIG) => nes_t,
582         tf.optional(KEY_DATADIR) => nes_t,
583         tf.optional(KEY_OPTIONS) => tf.hash_kv(option_name_t, tf.data),
584       }),
585     tf.optional(KEY_HIERARCHY) => hierarchy_t,
586     tf.optional(KEY_PLAN_HIERARCHY) => hierarchy_t,
587     tf.optional(KEY_DEFAULT_HIERARCHY) => hierarchy_t
588   })
589 end

Public Instance Methods

create_configured_data_providers(lookup_invocation, parent_data_provider, use_default_hierarchy) click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
591 def create_configured_data_providers(lookup_invocation, parent_data_provider, use_default_hierarchy)
592   defaults = @config[KEY_DEFAULTS] || EMPTY_HASH
593   datadir = defaults[KEY_DATADIR] || 'data'
594 
595   # Hashes enumerate their values in the order that the corresponding keys were inserted so it's safe to use
596   # a hash for the data_providers.
597   data_providers = {}
598 
599   if @config.include?(KEY_DEFAULT_HIERARCHY)
600     unless parent_data_provider.is_a?(ModuleDataProvider)
601       fail(Issues::HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE, EMPTY_HASH, find_line_matching(/\s+default_hierarchy:/))
602     end
603   elsif use_default_hierarchy
604     return data_providers
605   end
606 
607   compiler = Puppet.lookup(:pal_compiler) { nil }
608   config_key = if compiler.is_a?(Puppet::Pal::ScriptCompiler) && !@config[KEY_PLAN_HIERARCHY].nil?
609         KEY_PLAN_HIERARCHY
610       elsif use_default_hierarchy
611         KEY_DEFAULT_HIERARCHY
612       else
613         KEY_HIERARCHY
614       end
615   @config[config_key].each do |he|
616     name = he[KEY_NAME]
617     if data_providers.include?(name)
618       first_line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/)
619       line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/, first_line + 1) if first_line
620       unless line
621         line = first_line
622         first_line = nil
623       end
624       fail(Issues::HIERA_HIERARCHY_NAME_MULTIPLY_DEFINED, { :name => name, :first_line => first_line }, line)
625     end
626     function_kind = ALL_FUNCTION_KEYS.find { |key| he.include?(key) }
627     if function_kind.nil?
628       function_kind = FUNCTION_KEYS.find { |key| defaults.include?(key) }
629       function_name = defaults[function_kind]
630     else
631       function_name = he[function_kind]
632     end
633 
634     entry_datadir = @config_root + (he[KEY_DATADIR] || datadir)
635     entry_datadir = Pathname(interpolate(entry_datadir.to_s, lookup_invocation, false))
636     location_key = LOCATION_KEYS.find { |key| he.include?(key) }
637     locations = []
638     Puppet.override(avoid_hiera_interpolation_errors: true) do
639       locations = case location_key
640                   when KEY_PATHS
641                     resolve_paths(entry_datadir, he[location_key], lookup_invocation, @config_path.nil?)
642                   when KEY_PATH
643                     resolve_paths(entry_datadir, [he[location_key]], lookup_invocation, @config_path.nil?)
644                   when KEY_GLOBS
645                     expand_globs(entry_datadir, he[location_key], lookup_invocation)
646                   when KEY_GLOB
647                     expand_globs(entry_datadir, [he[location_key]], lookup_invocation)
648                   when KEY_URIS
649                     expand_uris(he[location_key], lookup_invocation)
650                   when KEY_URI
651                     expand_uris([he[location_key]], lookup_invocation)
652                   when KEY_MAPPED_PATHS
653                     expand_mapped_paths(entry_datadir, he[location_key], lookup_invocation)
654                   else
655                     nil
656                   end
657     end
658     next if @config_path.nil? && !locations.nil? && locations.empty? # Default config and no existing paths found
659     options = he[KEY_OPTIONS] || defaults[KEY_OPTIONS]
660     options = options.nil? ? EMPTY_HASH : interpolate(options, lookup_invocation, false)
661     if(function_kind == KEY_V3_BACKEND)
662       v3options = { :datadir => entry_datadir.to_s }
663       options.each_pair { |k, v| v3options[k.to_sym] = v }
664       data_providers[name] = create_hiera3_backend_provider(name, function_name, parent_data_provider, entry_datadir, locations, {
665         :hierarchy =>
666           locations.nil? ? [] : locations.map do |loc|
667             path = loc.original_location
668             path.end_with?(".#{function_name}") ? path[0..-(function_name.length + 2)] : path
669           end,
670         function_name.to_sym => v3options,
671         :backends => [ function_name ],
672         :logger => 'puppet'
673       })
674     else
675       data_providers[name] = create_data_provider(name, parent_data_provider, function_kind, function_name, options, locations)
676     end
677   end
678   data_providers.values
679 end
has_default_hierarchy?() click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
681 def has_default_hierarchy?
682   @config.include?(KEY_DEFAULT_HIERARCHY)
683 end
validate_config(config, owner) click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
701 def validate_config(config, owner)
702   config[KEY_DEFAULTS] ||= DEFAULT_CONFIG_HASH[KEY_DEFAULTS]
703   config[KEY_HIERARCHY] ||= DEFAULT_CONFIG_HASH[KEY_HIERARCHY]
704 
705   Types::TypeAsserter.assert_instance_of(["The Lookup Configuration at '%s'", @config_path], self.class.config_type, config)
706   defaults = config[KEY_DEFAULTS]
707   validate_defaults(defaults) unless defaults.nil?
708   config[KEY_HIERARCHY].each { |he| validate_hierarchy(he, defaults, owner) }
709   if config.include?(KEY_PLAN_HIERARCHY)
710     config[KEY_PLAN_HIERARCHY].each { |he| validate_hierarchy(he, defaults, owner) }
711   end
712 
713   if config.include?(KEY_DEFAULT_HIERARCHY)
714     unless owner.is_a?(ModuleDataProvider)
715       fail(Issues::HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE, EMPTY_HASH, find_line_matching(/(?:^|\s+)#{KEY_DEFAULT_HIERARCHY}:/))
716     end
717     config[KEY_DEFAULT_HIERARCHY].each { |he| validate_hierarchy(he, defaults, owner) }
718   end
719   config
720 end
validate_defaults(defaults) click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
759 def validate_defaults(defaults)
760   case FUNCTION_KEYS.count { |key| defaults.include?(key) }
761   when 0, 1
762     # OK
763   else
764     fail(Issues::HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS_IN_DEFAULT)
765   end
766 
767   options = defaults[KEY_OPTIONS]
768   unless options.nil?
769     RESERVED_OPTION_KEYS.each do |key|
770       fail(Issues::HIERA_DEFAULT_OPTION_RESERVED_BY_PUPPET, :key => key) if options.include?(key)
771     end
772   end
773 end
validate_hierarchy(he, defaults, owner) click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
722 def validate_hierarchy(he, defaults, owner)
723   name = he[KEY_NAME]
724   case ALL_FUNCTION_KEYS.count { |key| he.include?(key) }
725   when 0
726     if defaults.nil? || FUNCTION_KEYS.count { |key| defaults.include?(key) } == 0
727       fail(Issues::HIERA_MISSING_DATA_PROVIDER_FUNCTION, :name => name)
728     end
729   when 1
730     # OK
731   else
732     fail(Issues::HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS, :name => name)
733   end
734 
735   v3_backend = he[KEY_V3_BACKEND]
736   unless v3_backend.nil?
737     unless owner.is_a?(GlobalDataProvider)
738       fail(Issues::HIERA_V3_BACKEND_NOT_GLOBAL, EMPTY_HASH, find_line_matching(/\s+#{KEY_V3_BACKEND}:/))
739     end
740     if v3_backend == 'json' || v3_backend == 'yaml' || v3_backend == 'hocon' &&  Puppet.features.hocon?
741       # Disallow use of backends that have corresponding "data_hash" functions in version 5
742       fail(Issues::HIERA_V3_BACKEND_REPLACED_BY_DATA_HASH, { :function_name => v3_backend },
743         find_line_matching(/\s+#{KEY_V3_BACKEND}:\s*['"]?#{v3_backend}(?:[^\w]|$)/))
744     end
745   end
746 
747   if LOCATION_KEYS.count { |key| he.include?(key) } > 1
748     fail(Issues::HIERA_MULTIPLE_LOCATION_SPECS, :name => name)
749   end
750 
751   options = he[KEY_OPTIONS]
752   unless options.nil?
753     RESERVED_OPTION_KEYS.each do |key|
754       fail(Issues::HIERA_OPTION_RESERVED_BY_PUPPET, :key => key, :name => name) if options.include?(key)
755     end
756   end
757 end
version() click to toggle source
    # File lib/puppet/pops/lookup/hiera_config.rb
775 def version
776   5
777 end