Skip to content

Instantly share code, notes, and snippets.

@atdt
Created September 12, 2012 04:45
Show Gist options
  • Save atdt/3704340 to your computer and use it in GitHub Desktop.
Save atdt/3704340 to your computer and use it in GitHub Desktop.
Parse Puppet manifests into JSON
#!/usr/bin/env ruby -W0
# -*- coding: utf-8 -*-
#
# Parse Puppet manifests into JSON
#
# Usage: punch.rb [--hostclass HOSTCLASS] manifest.pp
# --help, -h Show this help and exit
# --hostclass, -c Output only this host class (default: all)
#
# Example:
# punch -c 'role::cache::configuration' site.pp
#
# Author: Ori Livneh <ori@wikimedia.org>
#
require 'getoptlong'
require 'json'
require 'puppet'
include Puppet::Parser
# Public: Recursively convert a Puppet AST object to primitive Ruby
# types.
#
# When no equivalent primitive exists, converts to a hash of instance
# variables, omitting :@line, :@file_index and :@children, and adding
# a key, "type", with the node's class name as the value.
#
# Returned object is JSON-serializable.
#
def primitive(node)
case node
when Array
node.map { |child| primitive(child) }
when Hash
hash = {}
node.each { |k,v| hash[primitive(k)] = primitive(v) }
hash
when Regexp
node.to_s
when Puppet::Resource::Type
primitive(node.code)
when AST::ASTArray
primitive(node.children)
when AST::Boolean
node.value == "true"
when AST::Concat, AST::ASTHash
primitive(node.value)
when AST::Hostclass
{ node.name => primitive(node.code) }
when AST::Name, AST::String, AST::Type
node.value
when AST
hash = { 'type' => node.class.to_s }
vars = node.instance_variables - [:@line, :@file_index, :@children]
vars.each do |var|
k = var.to_s[1..-1]
v = node.instance_variable_get(var)
hash[k] = primitive(v)
end
hash
else
node
end
end
def show_usage
puts <<-END.gsub(/^ {4}/, '')
Parse Puppet manifests into JSON
Usage: #{$0} [--hostclass HOSTCLASS] manifest.pp
--help, -h Show this help and exit
--hostclass, -c Output only this host class (default: all)
Example:
punch -c 'role::cache::configuration' site.pp
END
exit 1
end
if __FILE__ == $0
hclass = nil
opts = GetoptLong.new(
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
[ '--hostclass', '-c', GetoptLong::OPTIONAL_ARGUMENT ]
)
opts.each do |opt, arg|
case opt
when '--help' then show_usage
when '--hostclass' then hclass = arg
end
end
manifest = ARGV.shift
show_usage unless manifest
pp = Puppet::Parser::Parser.new('')
pp.import(manifest)
if hclass != nil
root = pp.find_hostclass('', hclass)
else
root = pp.known_resource_types.hostclasses
end
prim = primitive(root)
puts JSON.pretty_generate(prim, :max_nesting => false)
end
@lbt
Copy link

lbt commented Jan 30, 2018

Do you have an updated version of this code for newer puppet releases?
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment