class Lono::Inspector::Graph

Public Class Methods

new(options={}) click to toggle source
Calls superclass method Lono::AbstractBase::new
# File lib/lono/inspector/graph.rb, line 6
def initialize(options={})
  super
  @nodes = [] # lookup map
end

Public Instance Methods

check_graphviz_installed() click to toggle source

Check if Graphiz is installed and prints a user friendly message if it is not installed. Provide instructions if on macosx.

# File lib/lono/inspector/graph.rb, line 99
def check_graphviz_installed
  installed = system("type dot > /dev/null 2>&1") # dot is a command that is part of the graphviz package
  unless installed
    puts "It appears that the Graphviz is not installed.  Please install it to generate the graph."
    if RUBY_PLATFORM =~ /darwin/
      puts "You can install Graphviz with homebrew:"
      puts "    brew install graphviz"
    end
    exit 1
  end
end
normalize_children(node_list, node) click to toggle source

It is possible with bad CloudFormation templates that the dependency is not resolved, but we wont deal with that. Users can validate their CloudFormation template before using this tool.

# File lib/lono/inspector/graph.rb, line 59
def normalize_children(node_list, node)
  kids = []
  node.depends_on.each do |dependent_logical_id|
    node = node_list.find { |n| n.name == dependent_logical_id }
    kids << node
  end
  kids
end
normalize_depends_on(resource) click to toggle source

normalized DependOn attribute to an Array of Strings

# File lib/lono/inspector/graph.rb, line 46
def normalize_depends_on(resource)
  dependencies = resource["DependOn"] || []
  [dependencies].flatten
end
normalize_resource_type(resource) click to toggle source
# File lib/lono/inspector/graph.rb, line 51
def normalize_resource_type(resource)
  type = resource["Type"]
  type.sub("AWS::", "") # strip out AWS to make less verbose
end
perform(template) click to toggle source
# File lib/lono/inspector/graph.rb, line 11
def perform(template)
  # little dirty but @template is used in data method so we dont have to pass it to the data method
  @template = template

  puts "Generating dependencies tree for template #{@template}..."
  return if @options[:noop]

  # First loop through top level nodes and build set depends_on property
  node_list = [] # top level node list
  resources = data["Resources"]
  resources.each do |logical_id, resource|
    node = Node.new(logical_id)
    node.depends_on = normalize_depends_on(resource)
    node.resource_type = normalize_resource_type(resource)
    node_list << node
  end

  # Now that we have loop through all the top level resources once
  # we can use the depends_on attribute on each node and set the
  # children property since the identity nodes are in memory.
  node_list.each do |node|
    node.children = normalize_children(node_list, node)
  end

  # At this point we have a tree of nodes.
  if @options[:display] == "text"
    puts "CloudFormation Dependencies:"
    node_list.each { |node| print_tree(node) }
  else
    print_graph(node_list)
    puts "CloudFormation Dependencies graph generated."
  end
end
print_graph(node_list) click to toggle source
print_tree(node, depth=0) click to toggle source