rfacter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/lib/rfacter/dsl.rb
ADDED
@@ -0,0 +1,330 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
require 'rfacter'
|
4
|
+
require_relative 'config'
|
5
|
+
require_relative 'util/non_nullable'
|
6
|
+
|
7
|
+
# Facter compatibility layer
|
8
|
+
#
|
9
|
+
# This module exists to provide compatibility shims for Facter DSL methods as
|
10
|
+
# exposed by the Facter 3.0 Ruby API. Any fact source code that is executed
|
11
|
+
# within the {RFacter::Util} namespace via `instance_eval` should pick up on
|
12
|
+
# these shims. The methods in this module should never be called directly.
|
13
|
+
#
|
14
|
+
# However, lexical scope is a tricky thing, so "should" is the operative word
|
15
|
+
# here.
|
16
|
+
#
|
17
|
+
# @see https://github.com/puppetlabs/facter/blob/master/Extensibility.md
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
# @since 0.1.0
|
21
|
+
module RFacter::DSL
|
22
|
+
# FIXME: Add i18n for the following.
|
23
|
+
COLLECTION = RFacter::Util::NonNullable.new(err_message: <<-EOS)
|
24
|
+
A Facter DSL method that manipulates a fact collection was called without the
|
25
|
+
collection being set. This usually happens if the DSL method is called directly
|
26
|
+
instead of via an instance of RFacter::Util::Collection.
|
27
|
+
EOS
|
28
|
+
|
29
|
+
NODE = RFacter::Util::NonNullable.new(err_message: <<-EOS)
|
30
|
+
A Facter DSL method that executes shell commands was called without a
|
31
|
+
node to execute on being set. This usually happens if the DSL method is called
|
32
|
+
directly instead of via an instance of RFacter::Util::Collection.
|
33
|
+
EOS
|
34
|
+
|
35
|
+
# DSL for top-level Facter methods
|
36
|
+
#
|
37
|
+
# @todo Implement `reset`
|
38
|
+
# @todo Implement `search`
|
39
|
+
module Facter
|
40
|
+
# Returns a fact object by name.
|
41
|
+
#
|
42
|
+
# If you use this, you still have to call
|
43
|
+
# {RFacter::Util::Fact#value `value`} on it to retrieve the actual value.
|
44
|
+
#
|
45
|
+
# @param name [String, Symbol] the name of the fact
|
46
|
+
#
|
47
|
+
# @return [RFacter::Util::Fact, nil] The fact object, or nil if no fact
|
48
|
+
# is found.
|
49
|
+
def self.[](name)
|
50
|
+
COLLECTION.value.fact(name)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Adds a {RFacter::Util::Resolution resolution} mechanism for a named
|
54
|
+
# fact. This does not distinguish between adding a new fact and adding
|
55
|
+
# a new way to resolve a fact.
|
56
|
+
#
|
57
|
+
# @overload add(name, options = {}, { || ... })
|
58
|
+
# @param name [String] the fact name
|
59
|
+
# @param options [Hash] optional parameters for the fact - attributes
|
60
|
+
# of {RFacter::Util::Fact} and {Facter::Util::Resolution} can be
|
61
|
+
# supplied here
|
62
|
+
# @option options [Integer] :timeout set the
|
63
|
+
# {RFacter::Util::Resolution#timeout timeout} for this resolution
|
64
|
+
# @param block [Proc] a block defining a fact resolution
|
65
|
+
#
|
66
|
+
# @return [RFacter::Util::Fact] the fact object, which includes any previously
|
67
|
+
# defined resolutions
|
68
|
+
def self.add(name, options = {}, &block)
|
69
|
+
COLLECTION.value.add(name, options, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Clears all cached values and removes all facts from memory.
|
73
|
+
#
|
74
|
+
# @return [void]
|
75
|
+
def self.clear
|
76
|
+
self.flush
|
77
|
+
self.reset
|
78
|
+
end
|
79
|
+
|
80
|
+
# Prints a debug message if debugging is turned on
|
81
|
+
#
|
82
|
+
# @param msg [String] the debug message
|
83
|
+
#
|
84
|
+
# @return [void]
|
85
|
+
def self.debug(msg)
|
86
|
+
::RFacter::Config.config.logger.debug(msg)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Prints a debug message only once.
|
90
|
+
#
|
91
|
+
# @note Uniqueness is based on the string, not the specific location
|
92
|
+
# of the method call.
|
93
|
+
#
|
94
|
+
# @param msg [String] the debug message
|
95
|
+
# @return [void]
|
96
|
+
def self.debugonce(msg)
|
97
|
+
::RFacter::Config.config.logger.debugonce(msg)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Define a new fact or extend an existing fact.
|
101
|
+
#
|
102
|
+
# @param name [Symbol] The name of the fact to define
|
103
|
+
# @param options [Hash] A hash of options to set on the fact
|
104
|
+
#
|
105
|
+
# @return [RFacter::Util::Fact] The fact that was defined
|
106
|
+
#
|
107
|
+
# @see {RFacter::Util::Collection#define_fact}
|
108
|
+
def self.define_fact(name, options = {}, &block)
|
109
|
+
COLLECTION.value.define_fact(name, options, &block)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Iterates over fact names and values
|
113
|
+
#
|
114
|
+
# @yieldparam [String] name the fact name
|
115
|
+
# @yieldparam [String] value the current value of the fact
|
116
|
+
#
|
117
|
+
# @return [void]
|
118
|
+
def self.each
|
119
|
+
COLLECTION.value.each(NODE.value) do |*args|
|
120
|
+
yield(*args)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# (see [])
|
125
|
+
def self.fact(name)
|
126
|
+
COLLECTION.value.fact(name)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Flushes cached values for all facts. This does not cause code to be
|
130
|
+
# reloaded; it only clears the cached results.
|
131
|
+
#
|
132
|
+
# @return [void]
|
133
|
+
def self.flush
|
134
|
+
COLLECTION.value.flush
|
135
|
+
end
|
136
|
+
|
137
|
+
# Lists all fact names
|
138
|
+
#
|
139
|
+
# @return [Array<String>] array of fact names
|
140
|
+
def self.list
|
141
|
+
COLLECTION.value.list
|
142
|
+
end
|
143
|
+
|
144
|
+
# Loads all facts.
|
145
|
+
#
|
146
|
+
# @return [void]
|
147
|
+
def self.loadfacts
|
148
|
+
COLLECTION.value.load_all
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.log_exception(exception, message = nil)
|
152
|
+
::RFacter::Config.config.logger.log_exception(exception, messge)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Removes all facts from memory. Use this when the fact code has
|
156
|
+
# changed on disk and needs to be reloaded.
|
157
|
+
#
|
158
|
+
# @note This is currently a no-op for RFacter pending changes to how
|
159
|
+
# collections are handled.
|
160
|
+
#
|
161
|
+
# @return [void]
|
162
|
+
def self.reset
|
163
|
+
end
|
164
|
+
|
165
|
+
# Register directories to be searched for facts. The registered directories
|
166
|
+
# must be absolute paths or they will be ignored.
|
167
|
+
#
|
168
|
+
# @param dirs [String] directories to search
|
169
|
+
#
|
170
|
+
# @note This is currently a no-op for RFacter pending changes to how
|
171
|
+
# collections are handled.
|
172
|
+
#
|
173
|
+
# @return [void]
|
174
|
+
def self.search(*dirs)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns the registered search directories.
|
178
|
+
#
|
179
|
+
# @return [Array<String>] An array of the directories searched
|
180
|
+
def self.search_path
|
181
|
+
COLLECTION.value.search_path
|
182
|
+
end
|
183
|
+
|
184
|
+
# Gets a hash mapping fact names to their values.
|
185
|
+
#
|
186
|
+
# @return [Hash{String => Object}] the hash of fact names and values
|
187
|
+
def self.to_hash
|
188
|
+
COLLECTION.value.to_hash(NODE.value)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Gets the value for a fact.
|
192
|
+
#
|
193
|
+
# @param name [String, Symbol] the fact name
|
194
|
+
#
|
195
|
+
# @return [Object, nil] the value of the fact, or nil if no fact is
|
196
|
+
# found
|
197
|
+
def self.value(name)
|
198
|
+
COLLECTION.value.value(name, NODE.value)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns the current RFacter version
|
202
|
+
#
|
203
|
+
# @return [String]
|
204
|
+
def self.version
|
205
|
+
RFacter::VERSION
|
206
|
+
end
|
207
|
+
|
208
|
+
# Prints a warning message. The message is only printed if debugging
|
209
|
+
# is enabled.
|
210
|
+
#
|
211
|
+
# @param msg [String] the warning message to be printed
|
212
|
+
#
|
213
|
+
# @return [void]
|
214
|
+
def self.warn(msg)
|
215
|
+
::RFacter::Config.config.logger.warn(msg)
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
# Prints a warning message only once per process. Each unique string
|
220
|
+
# is printed once.
|
221
|
+
#
|
222
|
+
# @note Unlike {warn} the message will be printed even if debugging is
|
223
|
+
# not turned on. This behavior is likely to change and should not be
|
224
|
+
# relied on.
|
225
|
+
#
|
226
|
+
# @param msg [String] the warning message to be printed
|
227
|
+
#
|
228
|
+
# @return [void]
|
229
|
+
def self.warnonce(msg)
|
230
|
+
::RFacter::Config.config.logger.warnonce(msg)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Facter::Core DSL methods
|
234
|
+
module Core
|
235
|
+
require_relative 'core/aggregate'
|
236
|
+
# (see RFacter::Core::Aggregate)
|
237
|
+
Aggregate = ::RFacter::Core::Aggregate
|
238
|
+
|
239
|
+
# Shims for Facter::Core::Exection methods
|
240
|
+
#
|
241
|
+
# @todo Implement execution options
|
242
|
+
module Execution
|
243
|
+
# Error raised when :on_fail is set
|
244
|
+
class ExecutionFailure < StandardError; end
|
245
|
+
|
246
|
+
# Try to execute a command and return the output.
|
247
|
+
#
|
248
|
+
# @param command [String] the program to run
|
249
|
+
#
|
250
|
+
# @return [String] the output of the program, or nil if the command
|
251
|
+
# does not exist or could not be executed.
|
252
|
+
#
|
253
|
+
# @deprecated Use #{execute} instead
|
254
|
+
def self.exec(command)
|
255
|
+
execute(command, on_fail: nil)
|
256
|
+
end
|
257
|
+
|
258
|
+
# Execute a command and return the output of that program.
|
259
|
+
#
|
260
|
+
# @param command [String] the program to run
|
261
|
+
# @param options [Hash]
|
262
|
+
#
|
263
|
+
# @option options [Object] :on_fail How to behave when the command
|
264
|
+
# could not be run. Specifying `:raise` will raise an error, anything
|
265
|
+
# else will return that object on failure. Default is `:raise`.
|
266
|
+
#
|
267
|
+
# @raise [RFacter::Util::DSL::Facter::Core::Execution::ExecutionFailure]
|
268
|
+
# If the command does not exist or could not be executed.
|
269
|
+
#
|
270
|
+
# @return [String] The stdout of the program.
|
271
|
+
#
|
272
|
+
# @return [Object] The value of `:on_fail` if command execution failed
|
273
|
+
# and `:on_fail` was specified.
|
274
|
+
def self.execute(command, on_fail: :raise, **options)
|
275
|
+
begin
|
276
|
+
output = NODE.value.execute(command).stdout.chomp
|
277
|
+
rescue => detail
|
278
|
+
if on_fail == :raise
|
279
|
+
raise ::RFacter::DSL::Facter::Core::Execution::ExecutionFailure.new,
|
280
|
+
"Failed while executing '#{command}': #{detail.message}"
|
281
|
+
else
|
282
|
+
return on_fail
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
output
|
287
|
+
end
|
288
|
+
|
289
|
+
# Determines the full path to a binary.
|
290
|
+
#
|
291
|
+
# Returns nil if no matching executable can be found otherwise returns
|
292
|
+
# the expanded pathname.
|
293
|
+
#
|
294
|
+
# @param bin [String] the executable to locate
|
295
|
+
#
|
296
|
+
# @return [String,nil] the full path to the executable or nil if not
|
297
|
+
# found
|
298
|
+
def self.which(bin)
|
299
|
+
NODE.value.which(bin)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Facter::Util DSL methods
|
305
|
+
module Util
|
306
|
+
require_relative 'util/fact'
|
307
|
+
# (see RFacter::Util::Fact)
|
308
|
+
Fact = ::RFacter::Util::Fact
|
309
|
+
|
310
|
+
require_relative 'util/resolution'
|
311
|
+
# (see RFacter::Util::Resolution)
|
312
|
+
Resolution = ::RFacter::Util::Resolution
|
313
|
+
|
314
|
+
# Methods for interacting with remote files.
|
315
|
+
#
|
316
|
+
# @note The `exists?` part is uniqe to RFacter.
|
317
|
+
#
|
318
|
+
# @todo Possibly augment this with some top-level shims for File?
|
319
|
+
module FileRead
|
320
|
+
def self.read(path)
|
321
|
+
NODE.value.file(path).content
|
322
|
+
end
|
323
|
+
|
324
|
+
def self.exists?(path)
|
325
|
+
NODE.value.file(path).exist?
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Fact: kernel
|
2
|
+
#
|
3
|
+
# Purpose: Returns the operating system's name.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Uses Ruby's RbConfig to find host_os, if that is a Windows derivative, then
|
7
|
+
# returns `windows`, otherwise returns the output of `uname -s` verbatim.
|
8
|
+
#
|
9
|
+
# Caveats:
|
10
|
+
#
|
11
|
+
|
12
|
+
Facter.add(:kernel) do
|
13
|
+
setcode do
|
14
|
+
# FIXME: This is a bit naive as winrm could conceivably connect to
|
15
|
+
# PowerShell running on POSIX and ssh could connect to a Windows node due
|
16
|
+
# to recent investments by Microsoft in Open Source.
|
17
|
+
#
|
18
|
+
# This also won't work correctly for local execution on a Windows node.
|
19
|
+
case NODE.value.scheme
|
20
|
+
when 'winrm'
|
21
|
+
'windows'
|
22
|
+
else
|
23
|
+
Facter::Core::Execution.exec("uname -s")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Fact: kernelmajversion
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's release number's major value.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Takes the first two elements of the kernel version as delimited by periods.
|
7
|
+
# Takes the first element of the kernel version on FreeBSD.
|
8
|
+
#
|
9
|
+
# Caveats:
|
10
|
+
#
|
11
|
+
|
12
|
+
Facter.add("kernelmajversion") do
|
13
|
+
setcode do
|
14
|
+
Facter.value(:kernelversion).split('.')[0..1].join('.')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Facter.add("kernelmajversion") do
|
19
|
+
confine :kernel => [:FreeBSD, :SunOS]
|
20
|
+
setcode do
|
21
|
+
Facter.value(:kernelversion).split('.')[0]
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Fact: kernelrelease
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's release number.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On AIX, returns the output from the `oslevel -s` system command.
|
7
|
+
# On Windows-based systems, uses `Get-WmiObject` to query Windows Management
|
8
|
+
# for the `Win32_OperatingSystem` value.
|
9
|
+
# Otherwise uses the output of `uname -r` system command.
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
Facter.add(:kernelrelease) do
|
14
|
+
setcode 'uname -r'
|
15
|
+
end
|
16
|
+
|
17
|
+
Facter.add(:kernelrelease) do
|
18
|
+
confine :kernel => "aix"
|
19
|
+
setcode 'oslevel -s'
|
20
|
+
end
|
21
|
+
|
22
|
+
Facter.add("kernelrelease") do
|
23
|
+
confine :kernel => :openbsd
|
24
|
+
setcode do
|
25
|
+
version = Facter::Core::Execution.execute('sysctl -n kern.version')
|
26
|
+
version.split(' ')[1]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Facter.add(:kernelrelease) do
|
31
|
+
confine :kernel => "hp-ux"
|
32
|
+
setcode do
|
33
|
+
version = Facter::Core::Execution.execute('uname -r')
|
34
|
+
version[2..-1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Facter.add(:kernelrelease) do
|
39
|
+
confine :kernel => "windows"
|
40
|
+
setcode '(Get-WmiObject -Class Win32_OperatingSystem -Property Version).Version'
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Fact: kernelversion
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's kernel version.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On Solaris and SunOS based machines, returns the output of `uname -v`.
|
7
|
+
# Otherwise returns the kernerlversion fact up to the first `-`. This may be
|
8
|
+
# the entire kernelversion fact in many cases.
|
9
|
+
#
|
10
|
+
# Caveats:
|
11
|
+
#
|
12
|
+
|
13
|
+
Facter.add("kernelversion") do
|
14
|
+
setcode do
|
15
|
+
Facter['kernelrelease'].value.split('-')[0]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Facter.add("kernelversion") do
|
20
|
+
confine :kernel => :sunos
|
21
|
+
setcode 'uname -v'
|
22
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Fact: networking
|
2
|
+
#
|
3
|
+
# Purpose: Return the system's short hostname.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On all systems but Darwin, parses the output of the `hostname` system command
|
7
|
+
# to everything before the first period.
|
8
|
+
# On Darwin, uses the system configuration util to get the LocalHostName
|
9
|
+
# variable.
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
|
14
|
+
Facter.add(:networking, :type => :aggregate) do
|
15
|
+
chunk(:hostname) do
|
16
|
+
name = Facter::Core::Execution.execute('hostname')
|
17
|
+
|
18
|
+
if name.empty?
|
19
|
+
{}
|
20
|
+
else
|
21
|
+
{'hostname' => name.split('.').first}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
chunk(:domain) do
|
26
|
+
return_value = nil
|
27
|
+
|
28
|
+
hostname_command = case Facter.value(:kernel)
|
29
|
+
when /Linux/i, /FreeBSD/i, /Darwin/i
|
30
|
+
'hostname -f 2> /dev/null'
|
31
|
+
else
|
32
|
+
'hostname 2> /dev/null'
|
33
|
+
end
|
34
|
+
|
35
|
+
if name = Facter::Core::Execution.exec(hostname_command) \
|
36
|
+
and match = name.match(/.*?\.(.+$)/)
|
37
|
+
|
38
|
+
return_value = match.captures.first
|
39
|
+
elsif domain = Facter::Core::Execution.exec('dnsdomainname 2> /dev/null') \
|
40
|
+
and domain.match(/.+/)
|
41
|
+
|
42
|
+
return_value = domain
|
43
|
+
elsif Facter::Util::FileRead.exists?("/etc/resolv.conf")
|
44
|
+
domain = nil
|
45
|
+
search = nil
|
46
|
+
Facter::Util::FileRead.read('/etc/resolv.conf').lines.each do |line|
|
47
|
+
if (match = line.match(/^\s*domain\s+(\S+)/))
|
48
|
+
domain = match.captures.first
|
49
|
+
elsif (match = line.match(/^\s*search\s+(\S+)/))
|
50
|
+
search = match.captures.first
|
51
|
+
end
|
52
|
+
end
|
53
|
+
return_value ||= domain
|
54
|
+
return_value ||= search
|
55
|
+
end
|
56
|
+
|
57
|
+
if return_value.nil?
|
58
|
+
{}
|
59
|
+
else
|
60
|
+
{'domain' => return_value.gsub(/\.$/, '')}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
chunk(:fqdn, require: [:hostname, :domain]) do |net_hostname, net_domain|
|
65
|
+
host = net_hostname['hostname']
|
66
|
+
domain = net_domain['domain']
|
67
|
+
|
68
|
+
fqdn = if host && domain
|
69
|
+
[host, domain].join(".")
|
70
|
+
elsif host
|
71
|
+
host
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
if fqdn.nil?
|
77
|
+
{}
|
78
|
+
else
|
79
|
+
{'fqdn' => fqdn}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Facter.add(:hostname, :type => :aggregate) do
|
85
|
+
confine :kernel => :windows
|
86
|
+
|
87
|
+
chunk(:hostname) do
|
88
|
+
name = Facter::Core::Execution.execute('hostname')
|
89
|
+
|
90
|
+
if name.empty?
|
91
|
+
{}
|
92
|
+
else
|
93
|
+
{'hostname' => name.split('.').first}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
chunk(:domain) do
|
98
|
+
return_value = nil
|
99
|
+
|
100
|
+
network_info = Facter::Core::Execution.execute(<<-PS1)
|
101
|
+
(Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Property DNSDomain -Filter 'IPEnabled = True'|
|
102
|
+
Select-Object -First 1).DNSDomain
|
103
|
+
PS1
|
104
|
+
|
105
|
+
if network_info.empty?
|
106
|
+
{}
|
107
|
+
else
|
108
|
+
{'domain' => network_info.strip}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
chunk(:fqdn, require: [:hostname, :domain]) do |net_hostname, net_domain|
|
113
|
+
host = net_hostname['hostname']
|
114
|
+
domain = net_domain['domain']
|
115
|
+
|
116
|
+
fqdn = if host && domain
|
117
|
+
[host, domain].join(".")
|
118
|
+
elsif host
|
119
|
+
host
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
124
|
+
if fqdn.nil?
|
125
|
+
{}
|
126
|
+
else
|
127
|
+
{'fqdn' => fqdn}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|