Skip to content

Commit 590804e

Browse files
authored
Merge pull request #214 from glennsarti/refactor-factor
(GH-213) Gather facts using the Sidecar
2 parents 4d36a94 + 82f768b commit 590804e

File tree

13 files changed

+219
-1
lines changed

13 files changed

+219
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
module PuppetLanguageServerSidecar
4+
module FacterHelper
5+
def self.current_environment
6+
begin
7+
env = Puppet.lookup(:environments).get!(Puppet.settings[:environment])
8+
return env unless env.nil?
9+
rescue Puppet::Environments::EnvironmentNotFound
10+
PuppetLanguageServerSidecar.log_message(:warning, "[FacterHelper::current_environment] Unable to load environment #{Puppet.settings[:environment]}")
11+
rescue StandardError => e
12+
PuppetLanguageServerSidecar.log_message(:warning, "[FacterHelper::current_environment] Error loading environment #{Puppet.settings[:environment]}: #{e}")
13+
end
14+
Puppet.lookup(:current_environment)
15+
end
16+
17+
def self.retrieve_facts(_cache, _options = {})
18+
require 'puppet/indirector/facts/facter'
19+
20+
PuppetLanguageServerSidecar.log_message(:debug, '[FacterHelper::retrieve_facts] Starting')
21+
facts = PuppetLanguageServer::Sidecar::Protocol::Facts.new
22+
begin
23+
req = Puppet::Indirector::Request.new(:facts, :find, 'language_server', nil, environment: current_environment)
24+
result = Puppet::Node::Facts::Facter.new.find(req)
25+
facts.from_h!(result.values)
26+
rescue StandardError => e
27+
PuppetLanguageServerSidecar.log_message(:error, "[FacterHelper::_load_facts] Error loading facts #{e.message} #{e.backtrace}")
28+
rescue LoadError => e
29+
PuppetLanguageServerSidecar.log_message(:error, "[FacterHelper::_load_facts] Error loading facts (LoadError) #{e.message} #{e.backtrace}")
30+
end
31+
32+
PuppetLanguageServerSidecar.log_message(:debug, "[FacterHelper::retrieve_facts] Finished loading #{facts.keys.count} facts")
33+
facts
34+
end
35+
end
36+
end

lib/puppet-languageserver-sidecar/puppet_modulepath_monkey_patches.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,21 @@ def modulepath
122122
result
123123
end
124124
end
125+
126+
# Inject the workspace into the facter search paths
127+
require 'puppet/indirector/facts/facter'
128+
class Puppet::Node::Facts::Facter # rubocop:disable Style/ClassAndModuleChildren
129+
class << self
130+
alias_method :original_setup_search_paths, :setup_search_paths
131+
def setup_search_paths(request)
132+
result = original_setup_search_paths(request)
133+
return result unless PuppetLanguageServerSidecar::Workspace.has_module_metadata?
134+
135+
additional_dirs = %w[lib plugins].map { |path| File.join(PuppetLanguageServerSidecar::Workspace.root_path, path, 'facter') }
136+
.select { |path| FileTest.directory?(path) }
137+
138+
return result if additional_dirs.empty?
139+
Facter.search(*additional_dirs)
140+
end
141+
end
142+
end

lib/puppet-languageserver/sidecar_protocol.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,27 @@ def list_for_object_class(klass)
520520
raise "Unknown object class #{klass.name}"
521521
end
522522
end
523+
524+
class Facts < Hash
525+
include Base
526+
527+
def from_h!(value)
528+
value.keys.each { |key| self[key] = value[key] }
529+
self
530+
end
531+
532+
def to_json(*options)
533+
::JSON.generate(to_h, options)
534+
end
535+
536+
def from_json!(json_string)
537+
obj = ::JSON.parse(json_string)
538+
obj.each do |key, value|
539+
self[key] = value
540+
end
541+
self
542+
end
543+
end
523544
end
524545
end
525546
end

lib/puppet_languageserver_sidecar.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def self.require_gems(options)
8080
puppet_parser_helper
8181
sidecar_protocol_extensions
8282
workspace
83+
facter_helper
8384
]
8485

8586
# Load files based on feature flags
@@ -117,6 +118,7 @@ def self.require_gems(options)
117118
workspace_datatypes
118119
workspace_functions
119120
workspace_types
121+
facts
120122
].freeze
121123

122124
class CommandLineParser
@@ -389,6 +391,14 @@ def self.execute(options)
389391
PuppetLanguageServerSidecar::PuppetHelper.retrieve_types(null_cache)
390392
end
391393

394+
when 'facts'
395+
# Can't cache for facts
396+
cache = PuppetLanguageServerSidecar::Cache::Null.new
397+
# Inject the workspace etc. if present
398+
injected = inject_workspace_as_module
399+
inject_workspace_as_environment unless injected
400+
PuppetLanguageServerSidecar::FacterHelper.retrieve_facts(cache)
401+
392402
else
393403
log_message(:error, "Unknown action #{options[:action]}. Expected one of #{ACTION_LIST}")
394404
end

spec/languageserver-sidecar/fixtures/real_agent/cache/facts.d/.gitkeep

Whitespace-only changes.

spec/languageserver-sidecar/fixtures/real_agent/cache/lib/facter/.gitkeep

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Facter.add('fixture_agent_custom_fact') do
2+
setcode do
3+
'fixture_agent_custom_fact_value'
4+
end
5+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
fixture_environment_external_fact: "fixture_environment_external_fact_value"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Facter.add('fixture_environment_custom_fact') do
2+
setcode do
3+
'fixture_environment_custom_fact_value'
4+
end
5+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
fixture_module_external_fact: "fixture_module_external_fact_value"

0 commit comments

Comments
 (0)