From 235a05cd1ba65b9304466b3a8aaab811e5ce3e62 Mon Sep 17 00:00:00 2001 From: James Pogran Date: Tue, 28 Apr 2020 16:06:30 -0400 Subject: [PATCH] (GH-242) Puppet Facts Endpoint --- CHANGELOG.md | 4 ++++ lib/lsp/lsp_custom.rb | 21 +++++++++++++++++++ lib/puppet-languageserver/message_handler.rb | 5 +++++ lib/puppet-languageserver/puppet_helper.rb | 9 ++++++++ lib/puppet-languageserver/sidecar_queue.rb | 10 +++++++++ lib/puppet_languageserver_sidecar.rb | 9 ++++++++ .../facter_helper_spec.rb | 17 +++++++++++++++ 7 files changed, 75 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 444a9bcc..99d9f290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## Unreleased +### Added + +- ([GH-242](https://github.com/puppetlabs/puppet-editor-services/issues/242)) Add Puppet Facts Endpoint + ## 0.25.0 - 2020-03-26 ### Fixed diff --git a/lib/lsp/lsp_custom.rb b/lib/lsp/lsp_custom.rb index eaa90d2d..04913f98 100644 --- a/lib/lsp/lsp_custom.rb +++ b/lib/lsp/lsp_custom.rb @@ -35,6 +35,27 @@ def from_h!(value) end end + # export interface GetPuppetFactResponse { + # data: string; + # error: string; + # } + class PuppetFactResponse < LSPBase + attr_accessor :facts # type: string + attr_accessor :error # type: string + + def initialize(initial_hash = nil) + super + @optional_method_names = %i[error] + end + + def from_h!(value) + value = {} if value.nil? + self.facts = value['facts'] + self.error = value['error'] + self + end + end + # export interface GetPuppetResourceResponse { # data: string; # error: string; diff --git a/lib/puppet-languageserver/message_handler.rb b/lib/puppet-languageserver/message_handler.rb index e1725e6d..3cf2333c 100644 --- a/lib/puppet-languageserver/message_handler.rb +++ b/lib/puppet-languageserver/message_handler.rb @@ -45,6 +45,11 @@ def request_puppet_getversion(_, _json_rpc_message) ) end + def request_puppet_getfacts(_, _json_rpc_message) + results = PuppetLanguageServer::PuppetHelper.get_all_facts(documents.store_root_path) + LSP::PuppetFactResponse.new('facts' => results) + end + def request_puppet_getresource(_, json_rpc_message) type_name = json_rpc_message.params['typename'] title = json_rpc_message.params['title'] diff --git a/lib/puppet-languageserver/puppet_helper.rb b/lib/puppet-languageserver/puppet_helper.rb index c01b63cf..2edde65d 100644 --- a/lib/puppet-languageserver/puppet_helper.rb +++ b/lib/puppet-languageserver/puppet_helper.rb @@ -54,6 +54,15 @@ def self.get_node_graph(content, local_workspace) end end + def self.get_all_facts(local_workspace) + ap = PuppetLanguageServer::Sidecar::Protocol::ActionParams.new + + args = ['--action-parameters=' + ap.to_json] + args << "--local-workspace=#{local_workspace}" unless local_workspace.nil? + + sidecar_queue.execute_sync('facts_all', args, false) + end + def self.get_puppet_resource(typename, title, local_workspace) ap = PuppetLanguageServer::Sidecar::Protocol::ActionParams.new ap['typename'] = typename diff --git a/lib/puppet-languageserver/sidecar_queue.rb b/lib/puppet-languageserver/sidecar_queue.rb index 9dbb5d61..8314e6bf 100644 --- a/lib/puppet-languageserver/sidecar_queue.rb +++ b/lib/puppet-languageserver/sidecar_queue.rb @@ -118,6 +118,16 @@ def execute_sync(action, additional_args, handle_errors = false) PuppetLanguageServer::FacterHelper.assert_facts_loaded + when 'facts_all' + list = {} + PuppetLanguageServer::Sidecar::Protocol::FactList + .new + .from_json!(result) + .map { |element| list[element.key] = element.value } + PuppetLanguageServer.log_message(:debug, "SidecarQueue Thread: facts returned #{list.count} items") + + return list + when 'node_graph' return PuppetLanguageServer::Sidecar::Protocol::PuppetNodeGraph.new.from_json!(result) diff --git a/lib/puppet_languageserver_sidecar.rb b/lib/puppet_languageserver_sidecar.rb index 142ca22c..2423a59b 100644 --- a/lib/puppet_languageserver_sidecar.rb +++ b/lib/puppet_languageserver_sidecar.rb @@ -119,6 +119,7 @@ def self.require_gems(options) workspace_functions workspace_types facts + facts_all ].freeze class CommandLineParser @@ -399,6 +400,14 @@ def self.execute(options) inject_workspace_as_environment unless injected PuppetLanguageServerSidecar::FacterHelper.retrieve_facts(cache) + when 'facts_all' + # Can't cache for facts + cache = PuppetLanguageServerSidecar::Cache::Null.new + # Inject the workspace etc. if present + injected = inject_workspace_as_module + inject_workspace_as_environment unless injected + PuppetLanguageServerSidecar::FacterHelper.retrieve_facts(cache) + else log_message(:error, "Unknown action #{options[:action]}. Expected one of #{ACTION_LIST}") end diff --git a/spec/languageserver-sidecar/integration/puppet-languageserver-sidecar/facter_helper_spec.rb b/spec/languageserver-sidecar/integration/puppet-languageserver-sidecar/facter_helper_spec.rb index 523c27e9..0820d1b2 100644 --- a/spec/languageserver-sidecar/integration/puppet-languageserver-sidecar/facter_helper_spec.rb +++ b/spec/languageserver-sidecar/integration/puppet-languageserver-sidecar/facter_helper_spec.rb @@ -51,6 +51,23 @@ def run_sidecar(cmd_options) end end + describe 'when running facts_all action' do + let (:cmd_options) { ['--action', 'facts_all'] } + + it 'should return a deserializable facts object with all default facts' do + result = run_sidecar(cmd_options) + deserial = PuppetLanguageServer::Sidecar::Protocol::FactList.new + expect { deserial.from_json!(result) }.to_not raise_error + default_fact_names.each do |name| + expect(deserial).to contain_child_with_key(name) + end + + module_fact_names.each do |name| + expect(deserial).to_not contain_child_with_key(name) + end + end + end + context 'given a workspace containing a module' do # Test fixtures used is fixtures/valid_module_workspace let(:workspace) { File.join($fixtures_dir, 'valid_module_workspace') }