Class: FqdnFacts::Handler

Inherits:
Object show all
Defined in:
lib/fqdn_facts/handler.rb

Overview

base class for all handlers.

DSL collapse

Instance Attribute Summary collapse

DSL collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) ⇒ Handler

initilalizer

Parameters:

  • data (Hash) (defaults to: {})

    seeds the handler with base data

Options Hash (data):

  • :priority (Integer)

    sets the initial priority level

  • :conversions (Hash)

    sets the initial set of conversions

  • :components (Hash)

    sets the initial component validations

  • :order (Array)

    sets the initial order of components

  • :facts (Hash)

    sets the initial set of facts



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/fqdn_facts/handler.rb', line 56

def initialize(data = {})
  # rubocop:disable Style/SpaceAroundOperators
  @priority        = data.delete(:priority)    || 1
  @conversions     = data.delete(:conversions) || {}
  @components      = data.delete(:components)  || DEFAULT_COMPONENTS.dup
  @order           = data.delete(:order)       || DEFAULT_COMPONENTS.keys
  @facts           = data.delete(:facts)       || {}
  @fqdn            = ''
  # rubocop:enable Style/SpaceAroundOperators

  add_fact(:fqdn) { fqdn }
  add_fact(:handler_class, self.class.to_s)
  add_fact(:handler_name) { handler_class.split('::').last.underscore }
end

Instance Attribute Details

#factsObject

Returns the value of attribute facts.



38
39
40
# File 'lib/fqdn_facts/handler.rb', line 38

def facts
  @facts
end

#fqdnObject

Returns the value of attribute fqdn.



38
39
40
# File 'lib/fqdn_facts/handler.rb', line 38

def fqdn
  @fqdn
end

#priority(value) ⇒ Object #priorityObject

The priority of the registered Fqdn Fact handler

Lower priority fqdn fact handlers win out over higer priority handlers.

Overloads:

  • #priority(value) ⇒ Object

    Sets the priority level

    Parameters:

    • value (Integer)

      higher numbers denote lower priority, lower numbers denote higher

  • #priorityObject

    Retrieves the current priority level

Returns:

  • Integer



85
86
87
# File 'lib/fqdn_facts/handler.rb', line 85

def priority
  @priority
end

Class Method Details

.copy_from(other) ⇒ Handler

Creates a new instance of this object using the internal state of another handler object

Parameters:

  • other (Handler)

    the handler to copy

Returns:



33
34
35
# File 'lib/fqdn_facts/handler.rb', line 33

def copy_from(other)
  new(other.export)
end

Instance Method Details

#<=>(other) ⇒ -1, ...

Compares the priority of this handler to another handler

Parameters:

  • other (Handler)

    the handler to compare against

Returns:

  • (-1, 0, 1)

    if other is <=, =, or >= self



276
277
278
# File 'lib/fqdn_facts/handler.rb', line 276

def <=>(other)
  priority <=> other.priority
end

#add_fact(name, value = nil, &block) ⇒ Object

Adds a fact, either using a static value, or a Proc/Lambda for runtime determination of the value.

Parameters:

  • name (String)

    Symbol name of the fact to add

  • value (Scalar, Array, Hash, Proc) (defaults to: nil)

    value of the fact



185
186
187
188
# File 'lib/fqdn_facts/handler.rb', line 185

def add_fact(name, value = nil, &block)
  value = block if block_given?
  facts[name.to_sym] = value
end

#all(prefix = nil) ⇒ Hash{Symbol=><Scalar,Hash,Array>} Also known as: retrieve_facts

Retrieve all facts, possibly prefixing their names (@see #retrieve)

Parameters:

  • prefix (String) (defaults to: nil)

    a string to prefix every fact name with

Returns:

  • (Hash{Symbol=><Scalar,Hash,Array>})


224
225
226
# File 'lib/fqdn_facts/handler.rb', line 224

def all(prefix = nil)
  retrieve prefix: prefix
end

#component(component, validate = :any) ⇒ Object

Define a component’s validation rule.

Validation rules can be one of the following

* :any (the same as /.+/)
* A Hash of sub_component => regexp
* An array of valid values
* A scalar for exact matching

Parameters:

  • component (Symbol)

    the name of the component to set validation for

  • validate (Hash{Symbol=>Symbol,Hash,Array,Scalar}) (defaults to: :any)

    validation to perform for component



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
141
142
143
144
145
146
147
# File 'lib/fqdn_facts/handler.rb', line 113

def component(component, validate = :any)
  value = case validate
    when :any then %r:(.+):
    when Hash then
      if @components[component.to_sym].is_a?(Hash)
        basis = @components[component.to_sym]
      else
        basis = {}
      end

      basis.merge(
        Hash[validate.keys.zip(
          validate.values.collect {|v|
            case v
              when :any then %r:(.+):
              when Regexp then v
              else Regexp.new(v)
            end
          }
        )]
      )
    when Array then
      %r:(#{validate.join('|')}):
    else validate
  end

  if @components[component.to_sym]
    # if their not the same class, then remove any conversions
    unless @components[component.to_sym].is_a?(value.class)
      @conversions.delete(component.to_sym)
    end
  end

  @components[component.to_sym] = value
end

#convert(component, conversion = nil, &block) ⇒ Object

Defines a conversion rule for a given component. The conversion must be a Proc/Lambda

Parameters:

  • component (Symbol)

    the name of the component to set validation for

  • conversion (Hash, Proc) (defaults to: nil)

    optional conversion hash, proc/lambda

  • block (Proc)

    optional block

Raises:

  • (ArgumentError)

    if conversion isn’t Hash, Proc or Block



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/fqdn_facts/handler.rb', line 156

def convert(component, conversion = nil, &block)
  unless [Proc, Hash].any? { |klass| conversion.is_a?(klass) } || block_given?
    raise ArgumentError, 'expected Hash, Proc or Block'
  end

  component  = component.to_sym
  conversion ||= block

  conversion = if conversion.is_a? Hash
    (@conversions[component] ||= {}).merge(conversion)
  else
    conversion
  end

  @conversions[component] = conversion
end

#exportObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Exports the internal state as a hash



282
283
284
285
286
287
288
289
290
291
# File 'lib/fqdn_facts/handler.rb', line 282

def export
  instance_variables.each_with_object({}) do |name, exports|
    varname = name.to_s.tr('@', '').to_sym
    exports[varname] = begin
      Marshal.load(Marshal.dump(instance_variable_get(name)))
    rescue TypeError
      instance_variable_get(name).dup
    end
  end
end

#get_fact(name) ⇒ Object

Returns the value of a fact

Parameters:



176
177
178
# File 'lib/fqdn_facts/handler.rb', line 176

def get_fact(name)
  retrieve_facts[name.to_sym]
end

#match?(fqdn) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks to see if the fqdn matches this particular FQDN Fact Handler

Returns:

  • (Boolean)


238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/fqdn_facts/handler.rb', line 238

def match?(fqdn)
  parts = fqdn.split('.', @order.size)
  return unless parts.size == @order.size

  debug "Validating #{self.class}:"

  test_data = @order.zip(parts)
  debug "  test data -> #{test_data.inspect}"

  test_data.all? do |name, value|
    debug "  validating component '#{name}'"
    validation = case @components[name]
      when Hash then Regexp.new(@components[name].values.join)
      when nil then %r:.+:
      else @components[name]
    end

    case validation
      when Regexp then
        (value =~ validation).tap { |r|
          debug "    Regexp -> #{value.inspect} =~ #{validation.inspect} == #{r.inspect}"
        }
      when Array  then
        validation.include?(value).tap { |r|
          debug "    Array -> #{validation.inspect}.include?(#{value.inspect}) == #{r.inspect}"
        }
      else
        (value == validation).tap { |r|
          debug "    #{validation.class} -> #{value.inspect} == #{validation.inspect} == #{r.inspect}"
        }
    end
  end.tap { |r| debug " ---> validation #{r ? 'successful' : 'failed'} for #{self.class}" }
end

#order(*args) ⇒ Object Also known as: components

Defines the order of the defined components that make up the FQDN.

This defaults to: host, :sub, :tld

Parameters:

  • args (Array<Symbol>)

    list of ordered components

Raises:

  • (ArgumentError)

    if args is empty



97
98
99
100
# File 'lib/fqdn_facts/handler.rb', line 97

def order(*args)
  raise ArgumentError, 'empty list of components' unless args.present?
  @order = args
end

#remove_fact(name) ⇒ Object

Removes a fact from the list of facts.

Parameters:



192
193
194
# File 'lib/fqdn_facts/handler.rb', line 192

def remove_fact(name)
  facts.delete(name.to_sym)
end

#retrieve(options = {}) ⇒ Hash{Symbol=><Scalar,Hash,Array>}

retrieve aggregated facts

Parameters:

  • options (Hash) (defaults to: {})

    options to use when retrieving facts

Options Hash (options):

  • :prefix (String)

    a string to prefix every fact name with

  • :only (Array<Symbol>)

    a list of specific facts to retrieve

Returns:

  • (Hash{Symbol=><Scalar,Hash,Array>})


206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/fqdn_facts/handler.rb', line 206

def retrieve(options = {})
  prefix = options.delete(:prefix)
  only   = (o = options.delete(:only)).empty? ? nil : o.collect(&:to_sym)

  assemble.dup.tap do |facts|
    facts.replace(
      Hash[facts.each_with_object({}) do |(fact, value), hash|
        next unless only.empty? || only.include?(fact)
        key = prefix.empty? ? fact : "#{prefix}_#{fact}"
        hash[key] = value
      end.sort]
    )
  end
end

#to_hObject

Returns Hash all aggregate facts.

Returns:

  • Hash all aggregate facts



232
233
234
# File 'lib/fqdn_facts/handler.rb', line 232

def to_h
  merge_facts.dup
end