Skip to content

Commit

Permalink
(todo) WIP Add Node Graph
Browse files Browse the repository at this point in the history
  • Loading branch information
glennsarti committed Jul 14, 2018
1 parent 161d041 commit c2b6c91
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/puppet-languageserver-sidecar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
cache/null
cache/filesystem
puppet_helper
puppet_parser_helper
puppet_monkey_patches
sidecar_protocol_extensions
workspace
Expand All @@ -46,6 +47,7 @@ def self.version
default_classes
default_functions
default_types
node_graph
resource_list
workspace_classes
workspace_functions
Expand Down Expand Up @@ -183,6 +185,20 @@ def self.execute(options)
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
PuppetLanguageServerSidecar::PuppetHelper.retrieve_types(cache)

when 'node_graph'
result = PuppetLanguageServerSidecar::Protocol::NodeGraph.new
if options[:action_parameters]['source'].nil?
log_message(:error, 'Missing source action parameter')
return result.set_error('Missing source action parameter')
end
begin
manifest = File.open(options[:action_parameters]['source'], 'r:UTF-8') { |f| f.read }
PuppetLanguageServerSidecar::PuppetParserHelper.compile_node_graph(manifest)
rescue StandardError => ex
log_message(:error, "Missing parsing manifest. #{ex}")
result.set_error("Missing parsing manifest. #{ex}")
end

when 'resource_list'
inject_workspace_as_module
typename = options[:action_parameters]['typename']
Expand Down
71 changes: 71 additions & 0 deletions lib/puppet-languageserver-sidecar/puppet_parser_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module PuppetLanguageServerSidecar
module PuppetParserHelper
def self.compile_node_graph(content)
result = PuppetLanguageServerSidecar::Protocol::NodeGraph.new

begin
# The fontsize is inserted in the puppet code. Need to remove it so the client can render appropriately. Need to
# set it to blank. The graph label is set to editorservices so that we can do text replacement client side to inject the
# appropriate styling.
options = {
'fontsize' => '""',
'name' => 'editorservices'
}
node_graph = compile_to_pretty_relationship_graph(content)
if node_graph.vertices.count.zero?
result.set_error('There were no resources created in the node graph. Is there an include statement missing?')
else
result.dot_content = node_graph.to_dot(options)
end
rescue StandardError => exception
result.set_error("Error while parsing the file. #{exception}")
end

result
end

# Reference - https://github.com/puppetlabs/puppet/blob/master/spec/lib/puppet_spec/compiler.rb
def self.compile_to_catalog(string, node = Puppet::Node.new('test'))
Puppet[:code] = string
# see lib/puppet/indirector/catalog/compiler.rb#filter
Puppet::Parser::Compiler.compile(node).filter(&:virtual?)
end

def self.compile_to_ral(manifest, node = Puppet::Node.new('test'))
# Add the node facts if they don't already exist
node.merge(Facter.to_hash) if node.facts.nil?

catalog = compile_to_catalog(manifest, node)
ral = catalog.to_ral
ral.finalize
ral
end

def self.compile_to_relationship_graph(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new)
ral = compile_to_ral(manifest)
graph = Puppet::Graph::RelationshipGraph.new(prioritizer)
graph.populate_from(ral)
graph
end

def self.compile_to_pretty_relationship_graph(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new)
graph = compile_to_relationship_graph(manifest, prioritizer)

# Remove vertexes which just clutter the graph

# Remove all of the Puppet::Type::Whit nodes. This is an internal only class
list = graph.vertices.select { |node| node.is_a?(Puppet::Type::Whit) }
list.each { |node| graph.remove_vertex!(node) }

# Remove all of the Puppet::Type::Schedule nodes
list = graph.vertices.select { |node| node.is_a?(Puppet::Type::Schedule) }
list.each { |node| graph.remove_vertex!(node) }

# Remove all of the Puppet::Type::Filebucket nodes
list = graph.vertices.select { |node| node.is_a?(Puppet::Type::Filebucket) }
list.each { |node| graph.remove_vertex!(node) }

graph
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

module PuppetLanguageServerSidecar
module Protocol
class NodeGraph < PuppetLanguageServer::Sidecar::Protocol::NodeGraph
def set_error(message) # rubocop:disable Naming/AccessorMethodName
self.error_content = message
self.dot_content = ''
self
end
end

class PuppetClass < PuppetLanguageServer::Sidecar::Protocol::PuppetClass
def self.from_puppet(name, item)
obj = PuppetLanguageServer::Sidecar::Protocol::PuppetClass.new
Expand Down
20 changes: 20 additions & 0 deletions lib/puppet-languageserver/sidecar_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ def child_type
end
end

class NodeGraph
include Base

attr_accessor :dot_content
attr_accessor :error_content

def to_json(*options)
{
'dot_content' => dot_content,
'errorcontent' => error_content
}.to_json(options)
end

def from_json!(json_string)
obj = JSON.parse(json_string)
self.dot_content = obj['dot_content']
self.error_content = obj['error_content']
end
end

class PuppetClass < BasePuppetObject
# TODO: Doc, parameters?
end
Expand Down

0 comments on commit c2b6c91

Please sign in to comment.