Puppet Function: netbase::services::merge

Defined in:
modules/netbase/lib/puppet/functions/netbase/services/merge.rb
Function type:
Ruby 4.x API

Summary

This functions merges two Hashs of Netbase::Service's. The merge performed compares either the port or the port+protocol values (depending on the strict value) as opposed to just merging on the hash key, which is the default for both puppet and ruby. We also have the ability to append aliases into the winning match

Overview

netbase::services::merge(Hash[String,Netbase::Service] $values, Hash[String,Netbase::Service] $overrides, Optional[Boolean] $append_aliases, Optional[Boolean] $strict)Hash[String,Netbase::Service]

Examples:

$values    = {'foo' => {'port' => 25, 'protocols' => ['tcp'], 'aliases' => ['bar']}}
$overrides = {'smtp' => {'port' => 25, 'protocols' => ['tcp'], 'aliases' => ['mail']}}

$results = $values.netbase::merge($overrides)
$results = {'smtp' => {'port' => 25, 'protocols' => ['tcp'], 'aliases' => ['mail']}}

$results = $values.netbase::merge($overrides, append_aliases => true)
$results = {'smtp' => {'port' => 25, 'protocols' => ['tcp'], 'aliases' => ['mail', 'foo', 'bar']}}

$values    = {'https' => {'port' => 443, 'protocols' => ['tcp', udp']}}
$overrides = {'api-https' => {'port' => 443, 'protocols' => ['tcp']}}

$results = $values.netbase::merge($overrides)
$results == {'https' => {'port' => 443, 'protocols' => ['tcp', udp']}, 'api-https' => {'port' => 443, 'protocols' => ['tcp']}}

$results = $values.netbase::merge($overrides, strict => false)
$results == {'https' => {'port' => 443, 'protocols' => ['tcp', udp']}, 'api-https' => {'port' => 443, 'protocols' => ['tcp']}}

Parameters:

  • values (Hash[String,Netbase::Service])
  • overrides (Hash[String,Netbase::Service])
  • append_aliases (Optional[Boolean])
  • strict (Optional[Boolean])

Returns:

  • (Hash[String,Netbase::Service])


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'modules/netbase/lib/puppet/functions/netbase/services/merge.rb', line 84

Puppet::Functions.create_function(:'netbase::services::merge', Puppet::Functions::InternalFunction) do
  dispatch :merge do
    param 'Hash[String,Netbase::Service]', :values
    param 'Hash[String,Netbase::Service]', :overrides
    optional_param 'Boolean', :append_aliases
    optional_param 'Boolean', :strict
    return_type 'Hash[String,Netbase::Service]'
  end
  def merge(values, overrides, append_aliases = false, strict = true)
    _values = Set[]
    _overrides = Set[]
    results = {}
    # To make it easier to compare the values we convert the hashes into
    # Sets of `Service` objects
    values.each { |k, v| _values.add(Service.new(k, v, strict)) }
    overrides.each { |k, v| _overrides.add(Service.new(k, v, strict)) }
    # Merge the objects
    # As the objects are sets the will call `Service.eq?` to perform the equality test
    # This means that depending on the strict value we will only compare either the
    # the port+protocol (strict: true) or just the port (strict: false).
    # Had we just tried to merge the hashes then only the hash key would be considered
    # which is undesirable
    _overrides.merge(_values).each do |override|
      # We remap the results back into a hash in the form puppet expects e.g.
      # Hash[String,Netbase::Service]
      results[override.name] = override.puppet_type
    end
    # If append overrides is true we want to add the `aliases` and `name` from
    # `value` to there matching element in `override`.  e.g.
    # if:   _values    = [Service(name: ftp, port: 21, protocols: ['tcp'])]
    # and:  _overrides = [Service(name: unicorn, port: 21, protocols: ['tcp'])]
    # then: results    = {unicorn: {port: 21, protocols: ['tcp'], aliases: ['ftp']}}
    # Further
    # if:   _values    = [Service(name: foo, port: 25, protocols: ['tcp'], aliases: ['bar'])]
    # and:  _overrides = [Service(name: smtp, port: 25, protocols: ['tcp'], aliases: ['mail'])]
    # then: results    = {smtp: {port: 25, protocols: ['tcp'], aliases: ['mail', 'foo', 'bar']}}
    if append_aliases
      _overrides.each do |override|
        results[override.name] = override.puppet_type
        next unless _values.include?(override)
        # The sets are not quite the same i.e. they are only matched on port
        # or port/protocol.  This allows use to get the "matching" element from
        # _values so we can inspect the other elements
        value = Set[override].intersection(_values).to_a[0]
        # Reconstruct the aliases from scratch
        # with a.merge(b); b is preferred
        # As such we add the values then the overrides
        aliases = Set[value.name]
        aliases.merge(value.aliases) unless value.aliases.empty?
        aliases.merge(override.aliases) unless override.aliases.empty?
        aliases.delete(override.name)
        results[override.name]['aliases'] = aliases.to_a unless aliases.empty?
      end
    end
    results
  end
end