rfacter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/rfacter +5 -0
- data/lib/rfacter/cli.rb +51 -0
- data/lib/rfacter/config/settings.rb +31 -0
- data/lib/rfacter/config.rb +87 -0
- data/lib/rfacter/core/aggregate.rb +228 -0
- data/lib/rfacter/core/directed_graph.rb +48 -0
- data/lib/rfacter/core/resolvable.rb +97 -0
- data/lib/rfacter/core/suitable.rb +114 -0
- data/lib/rfacter/dsl.rb +330 -0
- data/lib/rfacter/facts/kernel.rb +26 -0
- data/lib/rfacter/facts/kernelmajversion.rb +23 -0
- data/lib/rfacter/facts/kernelrelease.rb +41 -0
- data/lib/rfacter/facts/kernelversion.rb +22 -0
- data/lib/rfacter/facts/networking.rb +130 -0
- data/lib/rfacter/facts/os.rb +591 -0
- data/lib/rfacter/node.rb +137 -0
- data/lib/rfacter/util/collection.rb +166 -0
- data/lib/rfacter/util/confine.rb +75 -0
- data/lib/rfacter/util/fact.rb +213 -0
- data/lib/rfacter/util/loader.rb +115 -0
- data/lib/rfacter/util/logger.rb +42 -0
- data/lib/rfacter/util/non_nullable.rb +46 -0
- data/lib/rfacter/util/normalization.rb +96 -0
- data/lib/rfacter/util/resolution.rb +163 -0
- data/lib/rfacter/util/values.rb +110 -0
- data/lib/rfacter/version.rb +3 -0
- data/lib/rfacter.rb +6 -0
- metadata +130 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'rfacter'
|
4
|
+
|
5
|
+
# RFacter Logger class
|
6
|
+
#
|
7
|
+
# This class provides all the methods of a standard Ruby Logger plus the
|
8
|
+
# following methods used by the Facter API:
|
9
|
+
#
|
10
|
+
# - `warnonce`
|
11
|
+
# - `debugonce`
|
12
|
+
# - `log_exception`
|
13
|
+
#
|
14
|
+
# @since 0.1.0
|
15
|
+
class RFacter::Util::Logger < ::Logger
|
16
|
+
@@warn_messages = Hash.new
|
17
|
+
@@debug_messages = Hash.new
|
18
|
+
|
19
|
+
def warnonce(msg)
|
20
|
+
if @@warn_messages[msg].nil?
|
21
|
+
self.warn(msg)
|
22
|
+
@@warn_messages[msg] = true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def debugonce(msg)
|
27
|
+
if @@debug_messages[msg].nil?
|
28
|
+
self.debug(msg)
|
29
|
+
@@debug_messages[msg] = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def log_exception(exception, message = nil)
|
34
|
+
message = exception.message if message.nil?
|
35
|
+
|
36
|
+
output = []
|
37
|
+
output << message
|
38
|
+
output.concat(exception.backtrace)
|
39
|
+
|
40
|
+
self.warn(output.flatten.join("\n"))
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
require 'rfacter'
|
4
|
+
|
5
|
+
# Non-nullable thread local variable
|
6
|
+
#
|
7
|
+
# A Subclass of Concurrent::ThreadLocalVar that raises a NameError
|
8
|
+
# if de-referenced to `nil`. This allows the creation of variables
|
9
|
+
# that must always be bound to a specific value before use.
|
10
|
+
#
|
11
|
+
# @since 0.1.0
|
12
|
+
class RFacter::Util::NonNullable < Concurrent::ThreadLocalVar
|
13
|
+
# @param err_message [String] The error message to raise if
|
14
|
+
# the instance is de-referenced to a `nil` value.
|
15
|
+
def initialize(default = nil, err_message:, &default_block)
|
16
|
+
@err_message = err_message
|
17
|
+
super(default, &default_block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Private reference to the superclass `value` method that won't
|
21
|
+
# raise an error. Allows the `bind` method to re-set the variable
|
22
|
+
# to nil at the end of an operation.
|
23
|
+
alias_method :nillable_value, :value
|
24
|
+
private :nillable_value
|
25
|
+
|
26
|
+
def bind(value, &block)
|
27
|
+
if block_given?
|
28
|
+
old_value = nillable_value
|
29
|
+
begin
|
30
|
+
self.value = value
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
self.value = old_value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @raise [NameError] when de-referenced to `nil`.
|
39
|
+
def value
|
40
|
+
result = super
|
41
|
+
|
42
|
+
raise(NameError, @err_message) if result.nil?
|
43
|
+
|
44
|
+
result
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'rfacter'
|
2
|
+
|
3
|
+
module RFacter
|
4
|
+
module Util
|
5
|
+
module Normalization
|
6
|
+
class NormalizationError < StandardError; end
|
7
|
+
|
8
|
+
VALID_TYPES = [Integer, Float, TrueClass, FalseClass, NilClass, String, Array, Hash]
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# Recursively normalize the given data structure
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
# @raise [NormalizationError] If the data structure contained an invalid element.
|
16
|
+
# @return [void]
|
17
|
+
def normalize(value)
|
18
|
+
case value
|
19
|
+
when Integer, Float, TrueClass, FalseClass, NilClass
|
20
|
+
value
|
21
|
+
when String
|
22
|
+
normalize_string(value)
|
23
|
+
when Array
|
24
|
+
normalize_array(value)
|
25
|
+
when Hash
|
26
|
+
normalize_hash(value)
|
27
|
+
else
|
28
|
+
raise NormalizationError, "Expected #{value} to be one of #{VALID_TYPES.inspect}, but was #{value.class}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @!method normalize_string(value)
|
33
|
+
#
|
34
|
+
# Attempt to normalize and validate the given string.
|
35
|
+
#
|
36
|
+
# On Ruby 1.8 the string is checked by stripping out all non UTF-8
|
37
|
+
# characters and comparing the converted string to the original. If they
|
38
|
+
# do not match then the string is considered invalid.
|
39
|
+
#
|
40
|
+
# On Ruby 1.9+, the string is validate by checking that the string encoding
|
41
|
+
# is UTF-8 and that the string content matches the encoding. If the string
|
42
|
+
# is not an expected encoding then it is converted to UTF-8.
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
# @raise [NormalizationError] If the string used an unsupported encoding or did not match its encoding
|
46
|
+
# @param value [String]
|
47
|
+
# @return [void]
|
48
|
+
|
49
|
+
if RUBY_VERSION =~ /^1\.8/
|
50
|
+
require 'iconv'
|
51
|
+
|
52
|
+
def normalize_string(value)
|
53
|
+
converted = Iconv.conv('UTF-8//IGNORE', 'UTF-8', value)
|
54
|
+
if converted != value
|
55
|
+
raise NormalizationError, "String #{value.inspect} is not valid UTF-8"
|
56
|
+
end
|
57
|
+
value
|
58
|
+
end
|
59
|
+
else
|
60
|
+
def normalize_string(value)
|
61
|
+
value = value.encode(Encoding::UTF_8)
|
62
|
+
|
63
|
+
unless value.valid_encoding?
|
64
|
+
raise NormalizationError, "String #{value.inspect} doesn't match the reported encoding #{value.encoding}"
|
65
|
+
end
|
66
|
+
|
67
|
+
value
|
68
|
+
rescue EncodingError
|
69
|
+
raise NormalizationError, "String encoding #{value.encoding} is not UTF-8 and could not be converted to UTF-8"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Validate all elements of the array.
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
# @raise [NormalizationError] If one of the elements failed validation
|
77
|
+
# @param value [Array]
|
78
|
+
# @return [void]
|
79
|
+
def normalize_array(value)
|
80
|
+
value.collect do |elem|
|
81
|
+
normalize(elem)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Validate all keys and values of the hash.
|
86
|
+
#
|
87
|
+
# @api public
|
88
|
+
# @raise [NormalizationError] If one of the keys or values failed normalization
|
89
|
+
# @param value [Hash]
|
90
|
+
# @return [void]
|
91
|
+
def normalize_hash(value)
|
92
|
+
Hash[value.collect { |k, v| [ normalize(k), normalize(v) ] } ]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'rfacter'
|
4
|
+
require_relative '../config'
|
5
|
+
|
6
|
+
# This represents a fact resolution. A resolution is a concrete
|
7
|
+
# implementation of a fact. A single fact can have many resolutions and
|
8
|
+
# the correct resolution will be chosen at runtime. Each time
|
9
|
+
# {Facter.add} is called, a new resolution is created and added to the
|
10
|
+
# set of resolutions for the fact named in the call. Each resolution
|
11
|
+
# has a {#has_weight weight}, which defines its priority over other
|
12
|
+
# resolutions, and a set of {#confine _confinements_}, which defines the
|
13
|
+
# conditions under which it will be chosen. All confinements must be
|
14
|
+
# satisfied for a fact to be considered _suitable_.
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
class RFacter::Util::Resolution
|
18
|
+
require_relative '../dsl'
|
19
|
+
require_relative '../core/resolvable'
|
20
|
+
require_relative '../core/suitable'
|
21
|
+
extend Forwardable
|
22
|
+
|
23
|
+
instance_delegate([:logger] => :@config)
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
attr_accessor :code
|
27
|
+
attr_writer :value
|
28
|
+
|
29
|
+
include RFacter::Core::Resolvable
|
30
|
+
include RFacter::Core::Suitable
|
31
|
+
|
32
|
+
# @!attribute [rw] name
|
33
|
+
# The name of this resolution. The resolution name should be unique with
|
34
|
+
# respect to the given fact.
|
35
|
+
# @return [String]
|
36
|
+
# @api public
|
37
|
+
attr_accessor :name
|
38
|
+
|
39
|
+
# @!attribute [r] fact
|
40
|
+
# @return [Facter::Util::Fact]
|
41
|
+
# @api private
|
42
|
+
attr_reader :fact
|
43
|
+
|
44
|
+
def which(command)
|
45
|
+
::RFacter::DSL::Facter::Core::Execution.which(command)
|
46
|
+
end
|
47
|
+
|
48
|
+
def exec(command)
|
49
|
+
::RFacter::DSL::Facter::Core::Execution.exec(command)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new resolution mechanism.
|
53
|
+
#
|
54
|
+
# @param name [String] The name of the resolution.
|
55
|
+
# @return [void]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def initialize(name, fact, config: RFacter::Config.config, **options)
|
59
|
+
@name = name
|
60
|
+
@fact = fact
|
61
|
+
@config = config
|
62
|
+
@confines = []
|
63
|
+
@value = nil
|
64
|
+
@timeout = 0
|
65
|
+
@weight = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def resolution_type
|
69
|
+
:simple
|
70
|
+
end
|
71
|
+
|
72
|
+
# Evaluate the given block in the context of this resolution. If a block has
|
73
|
+
# already been evaluated emit a warning to that effect.
|
74
|
+
#
|
75
|
+
# @return [void]
|
76
|
+
def evaluate(&block)
|
77
|
+
if @last_evaluated
|
78
|
+
msg = "Already evaluated #{@name}"
|
79
|
+
msg << " at #{@last_evaluated}" if msg.is_a? String
|
80
|
+
msg << ", reevaluating anyways"
|
81
|
+
logger.warn msg
|
82
|
+
end
|
83
|
+
|
84
|
+
instance_eval(&block)
|
85
|
+
|
86
|
+
# Ruby 1.9+ provides the source location of procs which can provide useful
|
87
|
+
# debugging information if a resolution is being evaluated twice. Since 1.8
|
88
|
+
# doesn't support this we opportunistically provide this information.
|
89
|
+
if block.respond_to? :source_location
|
90
|
+
@last_evaluated = block.source_location.join(':')
|
91
|
+
else
|
92
|
+
@last_evaluated = true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def set_options(options)
|
97
|
+
if options[:name]
|
98
|
+
@name = options.delete(:name)
|
99
|
+
end
|
100
|
+
|
101
|
+
if options.has_key?(:value)
|
102
|
+
@value = options.delete(:value)
|
103
|
+
end
|
104
|
+
|
105
|
+
if options.has_key?(:timeout)
|
106
|
+
@timeout = options.delete(:timeout)
|
107
|
+
end
|
108
|
+
|
109
|
+
if options.has_key?(:weight)
|
110
|
+
@weight = options.delete(:weight)
|
111
|
+
end
|
112
|
+
|
113
|
+
if not options.keys.empty?
|
114
|
+
raise ArgumentError, "Invalid resolution options #{options.keys.inspect}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Sets the code block or external program that will be evaluated to
|
119
|
+
# get the value of the fact.
|
120
|
+
#
|
121
|
+
# @return [void]
|
122
|
+
#
|
123
|
+
# @overload setcode(string)
|
124
|
+
# Sets an external program to call to get the value of the resolution
|
125
|
+
# @param [String] string the external program to run to get the
|
126
|
+
# value
|
127
|
+
#
|
128
|
+
# @overload setcode(&block)
|
129
|
+
# Sets the resolution's value by evaluating a block at runtime
|
130
|
+
# @param [Proc] block The block to determine the resolution's value.
|
131
|
+
# This block is run when the fact is evaluated. Errors raised from
|
132
|
+
# inside the block are rescued and printed to stderr.
|
133
|
+
#
|
134
|
+
# @api public
|
135
|
+
def setcode(string = nil, &block)
|
136
|
+
if string
|
137
|
+
@code = Proc.new do
|
138
|
+
output = exec(string)
|
139
|
+
if output.nil? or output.empty?
|
140
|
+
nil
|
141
|
+
else
|
142
|
+
output
|
143
|
+
end
|
144
|
+
end
|
145
|
+
elsif block_given?
|
146
|
+
@code = block
|
147
|
+
else
|
148
|
+
raise ArgumentError, "You must pass either code or a block"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def resolve_value
|
155
|
+
if @value
|
156
|
+
@value
|
157
|
+
elsif @code.nil?
|
158
|
+
nil
|
159
|
+
elsif @code
|
160
|
+
@code.call()
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'rfacter'
|
2
|
+
|
3
|
+
module RFacter
|
4
|
+
module Util
|
5
|
+
# A util module for facter containing helper methods
|
6
|
+
module Values
|
7
|
+
module_function
|
8
|
+
|
9
|
+
class DeepFreezeError < StandardError; end
|
10
|
+
|
11
|
+
# Duplicate and deeply freeze a given data structure
|
12
|
+
#
|
13
|
+
# @param value [Object] The structure to freeze
|
14
|
+
# @return [void]
|
15
|
+
def deep_freeze(value)
|
16
|
+
case value
|
17
|
+
when Numeric, Symbol, TrueClass, FalseClass, NilClass
|
18
|
+
# These are immutable values, we can safely ignore them
|
19
|
+
value
|
20
|
+
when String
|
21
|
+
value.dup.freeze
|
22
|
+
when Array
|
23
|
+
value.map do |entry|
|
24
|
+
deep_freeze(entry)
|
25
|
+
end.freeze
|
26
|
+
when Hash
|
27
|
+
value.inject({}) do |hash, (key, value)|
|
28
|
+
hash[deep_freeze(key)] = deep_freeze(value)
|
29
|
+
hash
|
30
|
+
end.freeze
|
31
|
+
else
|
32
|
+
raise DeepFreezeError, "Cannot deep freeze #{value}:#{value.class}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class DeepMergeError < StandardError; end
|
37
|
+
|
38
|
+
# Perform a deep merge of two nested data structures.
|
39
|
+
#
|
40
|
+
# @param left [Object]
|
41
|
+
# @param right [Object]
|
42
|
+
# @param path [Array<String>] The traversal path followed when merging nested hashes
|
43
|
+
#
|
44
|
+
# @return [Object] The merged data structure.
|
45
|
+
def deep_merge(left, right, path = [], &block)
|
46
|
+
ret = nil
|
47
|
+
|
48
|
+
if left.is_a? Hash and right.is_a? Hash
|
49
|
+
ret = left.merge(right) do |key, left_val, right_val|
|
50
|
+
path.push(key)
|
51
|
+
merged = deep_merge(left_val, right_val, path)
|
52
|
+
path.pop
|
53
|
+
merged
|
54
|
+
end
|
55
|
+
elsif left.is_a? Array and right.is_a? Array
|
56
|
+
ret = left.dup.concat(right)
|
57
|
+
elsif right.nil?
|
58
|
+
ret = left
|
59
|
+
elsif left.nil?
|
60
|
+
ret = right
|
61
|
+
elsif left.nil? and right.nil?
|
62
|
+
ret = nil
|
63
|
+
else
|
64
|
+
msg = "Cannot merge #{left.inspect}:#{left.class} and #{right.inspect}:#{right.class}"
|
65
|
+
if not path.empty?
|
66
|
+
msg << " at root"
|
67
|
+
msg << path.map { |part| "[#{part.inspect}]" }.join
|
68
|
+
end
|
69
|
+
raise DeepMergeError, msg
|
70
|
+
end
|
71
|
+
|
72
|
+
ret
|
73
|
+
end
|
74
|
+
|
75
|
+
def convert(value)
|
76
|
+
value = value.to_s if value.is_a?(Symbol)
|
77
|
+
value = value.downcase if value.is_a?(String)
|
78
|
+
value
|
79
|
+
end
|
80
|
+
|
81
|
+
# Flatten the given data structure to something that's suitable to return
|
82
|
+
# as flat facts.
|
83
|
+
#
|
84
|
+
# @param path [String] The fact path to be prefixed to the given value.
|
85
|
+
# @param structure [Object] The data structure to flatten. Nested hashes
|
86
|
+
# will be recursively flattened, everything else will be returned as-is.
|
87
|
+
#
|
88
|
+
# @return [Hash] The given data structure prefixed with the given path
|
89
|
+
def flatten_structure(path, structure)
|
90
|
+
results = {}
|
91
|
+
|
92
|
+
if structure.is_a? Hash
|
93
|
+
structure.each_pair do |name, value|
|
94
|
+
new_path = "#{path}_#{name}".gsub(/\-|\//, '_')
|
95
|
+
results.merge! flatten_structure(new_path, value)
|
96
|
+
end
|
97
|
+
elsif structure.is_a? Array
|
98
|
+
structure.each_with_index do |value, index|
|
99
|
+
new_path = "#{path}_#{index}"
|
100
|
+
results.merge! flatten_structure(new_path, value)
|
101
|
+
end
|
102
|
+
else
|
103
|
+
results[path] = structure
|
104
|
+
end
|
105
|
+
|
106
|
+
results
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/rfacter.rb
ADDED
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfacter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charlie Sharpsteen
|
8
|
+
- Puppet Labs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2017-05-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: train
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.23.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.23.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: concurrent-ruby
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: inch
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.7'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.7'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.1'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.1'
|
70
|
+
description: |
|
71
|
+
RFacter is a library for collecting facts from remote system(s) by executing
|
72
|
+
commands over transports such as SSH and WinRM.
|
73
|
+
email: source@sharpsteen.net
|
74
|
+
executables:
|
75
|
+
- rfacter
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- bin/rfacter
|
80
|
+
- lib/rfacter.rb
|
81
|
+
- lib/rfacter/cli.rb
|
82
|
+
- lib/rfacter/config.rb
|
83
|
+
- lib/rfacter/config/settings.rb
|
84
|
+
- lib/rfacter/core/aggregate.rb
|
85
|
+
- lib/rfacter/core/directed_graph.rb
|
86
|
+
- lib/rfacter/core/resolvable.rb
|
87
|
+
- lib/rfacter/core/suitable.rb
|
88
|
+
- lib/rfacter/dsl.rb
|
89
|
+
- lib/rfacter/facts/kernel.rb
|
90
|
+
- lib/rfacter/facts/kernelmajversion.rb
|
91
|
+
- lib/rfacter/facts/kernelrelease.rb
|
92
|
+
- lib/rfacter/facts/kernelversion.rb
|
93
|
+
- lib/rfacter/facts/networking.rb
|
94
|
+
- lib/rfacter/facts/os.rb
|
95
|
+
- lib/rfacter/node.rb
|
96
|
+
- lib/rfacter/util/collection.rb
|
97
|
+
- lib/rfacter/util/confine.rb
|
98
|
+
- lib/rfacter/util/fact.rb
|
99
|
+
- lib/rfacter/util/loader.rb
|
100
|
+
- lib/rfacter/util/logger.rb
|
101
|
+
- lib/rfacter/util/non_nullable.rb
|
102
|
+
- lib/rfacter/util/normalization.rb
|
103
|
+
- lib/rfacter/util/resolution.rb
|
104
|
+
- lib/rfacter/util/values.rb
|
105
|
+
- lib/rfacter/version.rb
|
106
|
+
homepage: https://github.com/Sharpie/rfacter
|
107
|
+
licenses:
|
108
|
+
- Apache-2.0
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 2.1.0
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.2.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Reduced, Remote-enabled, Ruby fork of Facter 2.x
|
130
|
+
test_files: []
|