puppet-graph-petems 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 83060c133e25d36eb2892012c5e369eb1d8ce6bb
4
+ data.tar.gz: a76f94e88dc3d9ca823e8a4bcdd417f1305ffbd0
5
+ SHA512:
6
+ metadata.gz: ba24225d5539ab9053c87f52841bc8a0062009644e6c42f0dab6c1881662b02c1e547181df343804f48e64a09a73fbd912b689868aab9a8196f3f03cd76476f4
7
+ data.tar.gz: 1354174c09cd9a9ecd3cb8b608ee4d4fc9c7d6e7b3bacdd059f5c71ab1121df7e367d127799d9753d14c480866fcd9631885899574783659a2ce0ce79c5ec86b
@@ -0,0 +1,7 @@
1
+ /.bundle/
2
+ /vendor/gems/
3
+ /Gemfile.lock
4
+ /test.dot
5
+ /test.png
6
+ /test.foo
7
+ /coverage/
@@ -0,0 +1,20 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ script: "bundle exec rspec"
6
+ before_install:
7
+ - sudo apt-get update -qq
8
+ - sudo apt-get install -qq graphviz
9
+ env:
10
+ - PUPPET_VERSION=2.6.18
11
+ - PUPPET_VERSION=2.7.21
12
+ - PUPPET_VERSION=3.0.2
13
+ - PUPPET_VERSION=3.1.1
14
+ - PUPPET_VERSION=3.2.2
15
+ matrix:
16
+ exclude:
17
+ - rvm: 1.9.2
18
+ env: PUPPET_VERSION=2.6.18
19
+ - rvm: 1.9.3
20
+ env: PUPPET_VERSION=2.6.18
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ puppet_version = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : '>= 3'
4
+
5
+ gem 'puppet', puppet_version
6
+
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Tim Sharpe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ # Puppet-graph
2
+ [![Build
3
+ Status](https://secure.travis-ci.org/rodjek/puppet-graph.png)](http://travis-ci.org/rodjek/puppet-graph)
4
+
5
+ Trivially generate dependency graphs for any arbitrary bit of Puppet code (like
6
+ classes or defined types).
7
+
8
+ ## Requirements
9
+
10
+ * Graphviz for PNG generation (if `which dot` returns a path, you're good).
11
+
12
+ ## Installation
13
+
14
+ Install it as a standalone gem
15
+
16
+ gem install puppet-graph
17
+
18
+ Or as part of a bundler managed repo
19
+
20
+ group :development do
21
+ gem 'puppet-graph'
22
+ end
23
+
24
+ ## Usage
25
+
26
+ ```
27
+ Usage: puppet-graph [options]
28
+ -c, --code CODE Code to generate a graph of
29
+ -f, --fact FACT=VALUE Override a Facter fact
30
+ -m, --modulepath PATH The path to your Puppet modules. Defaults to modules/
31
+ -o, --output FILE The file to save the graph to
32
+ -r, --format FORMAT Output format (png or dot). Optional if your output file ends in .dot or .png
33
+ -h, --help Show this help output
34
+ -v, --version Show the version
35
+ ```
36
+
37
+ ### Building a graph of a class
38
+
39
+ ```
40
+ $ puppet-graph -c 'include foo' -o foo.png
41
+ ```
42
+
43
+ ### Building a graph of a defined type
44
+
45
+ ```
46
+ $ puppet-graph -c "foo { 'bar': baz => 'gronk' }" -o foo.png
47
+ ```
48
+
49
+ ### Overriding the value of a fact
50
+
51
+ ```
52
+ $ puppet-graph -c 'include foo' -f 'operatingsystem=Solaris' -o foo.png
53
+ ```
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w{.. lib})
4
+
5
+ require 'puppet-graph'
6
+ require 'puppet-graph/cli'
7
+
8
+ PuppetGraph::CLI.new.run(ARGV)
@@ -0,0 +1,7 @@
1
+ require 'puppet-graph/grapher'
2
+ require 'puppet-graph/version'
3
+
4
+ require 'puppet'
5
+
6
+ module PuppetGraph
7
+ end
@@ -0,0 +1,80 @@
1
+ require 'tempfile'
2
+ require 'optparse'
3
+
4
+ module PuppetGraph
5
+ class CLI
6
+ def run(args)
7
+ parser.parse!(args)
8
+
9
+ validate_options
10
+
11
+ g = PuppetGraph::Grapher.new
12
+ g.fact_overrides = options[:fact]
13
+ g.modulepath = options[:modulepath]
14
+ g.code = options[:code]
15
+ g.draw(options[:format], options[:output_file])
16
+ end
17
+
18
+ private
19
+
20
+ def options
21
+ @options ||= {
22
+ :modulepath => 'modules',
23
+ }
24
+ end
25
+
26
+ def parser
27
+ @parser ||= OptionParser.new do |opts|
28
+ opts.banner = 'Usage: puppet-graph [options]'
29
+
30
+ opts.on '-c', '--code CODE', 'Code to generate a graph of' do |val|
31
+ options[:code] = val
32
+ end
33
+
34
+ opts.on '-f', '--fact FACT=VALUE', 'Override a Facter fact' do |val|
35
+ key, value = val.split('=')
36
+ (options[:fact] ||= {})[key] = value
37
+ end
38
+
39
+ opts.on '-m', '--modulepath PATH', 'The path to your Puppet modules. Defaults to modules/' do |val|
40
+ options[:modulepath] = val
41
+ end
42
+
43
+ opts.on '-o', '--output FILE', 'The file to save the graph to' do |val|
44
+ options[:output_file] = val
45
+ if options[:format].nil?
46
+ options[:format] = File.extname(options[:output_file])[1..-1].to_sym
47
+ end
48
+ end
49
+
50
+ opts.on '-r', '--format FORMAT', 'Output format (png or dot). Optional if your output file ends in .dot or .png' do |val|
51
+ options[:format] = val.to_sym
52
+ end
53
+
54
+ opts.on_tail '-h', '--help', 'Show this help output' do
55
+ puts parser
56
+ exit 0
57
+ end
58
+
59
+ opts.on_tail '-v', '--version', 'Show the version' do
60
+ puts "puppet-graph v#{PuppetGraph::VERSION}"
61
+ exit 0
62
+ end
63
+ end
64
+ end
65
+
66
+ def validate_options
67
+ if options[:code].nil?
68
+ $stderr.puts "Error: No Puppet code provided to be graphed."
69
+ $stderr.puts parser
70
+ exit 1
71
+ end
72
+
73
+ unless [:dot, :png].include?(options[:format])
74
+ $stderr.puts "Error: Invalid format specified. Valid formats are: dot, png"
75
+ $stderr.puts parser
76
+ exit 1
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,93 @@
1
+ module PuppetGraph
2
+ class Grapher
3
+ attr_accessor :fact_overrides
4
+ attr_accessor :modulepath
5
+ attr_accessor :code
6
+
7
+ def draw(format, output_file)
8
+ self.send("draw_#{format}_graph", output_file)
9
+ end
10
+
11
+ def draw_png_graph(output_file)
12
+ dot_graph = relationship_graph.to_dot('label' => code)
13
+
14
+ tmp_dot_file = Tempfile.new('puppet-graph')
15
+ begin
16
+ tmp_dot_file.write dot_graph
17
+ tmp_dot_file.flush
18
+ `dot -o#{output_file} -Tpng #{tmp_dot_file.path}`
19
+ ensure
20
+ tmp_dot_file.close
21
+ tmp_dot_file.unlink
22
+ end
23
+ end
24
+
25
+ def draw_dot_graph(output_file)
26
+ dot_graph = relationship_graph.to_dot('label' => code)
27
+
28
+ File.open(output_file, 'wb') do |f|
29
+ f.puts dot_graph
30
+ end
31
+ end
32
+
33
+ def relationship_graph
34
+ @relationship_graph ||= lambda {
35
+ graph = catalogue.to_ral.relationship_graph
36
+ graph.vertices.select { |r| r.to_s == 'Class[Settings]' }.each do |vertex|
37
+ graph.remove_vertex! vertex
38
+ end
39
+ graph
40
+ }.call
41
+ end
42
+
43
+ def catalogue
44
+ with_tmpdir do |dir|
45
+ Puppet[:modulepath] = modulepath
46
+ Puppet[:vardir] = dir
47
+ Puppet[:confdir] = dir
48
+ Puppet[:logdir] = dir
49
+ Puppet[:rundir] = dir
50
+ Puppet[:code] = code
51
+
52
+ stub_facts
53
+
54
+ Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node)
55
+ end
56
+ end
57
+
58
+ def stub_facts
59
+ if fact_overrides.nil?
60
+ facts = default_facts
61
+ else
62
+ facts = default_facts.merge(fact_overrides)
63
+ end
64
+
65
+ facts.each do |key, value|
66
+ Facter.add(key) { setcode { value } }
67
+ end
68
+
69
+ node.merge(facts)
70
+ end
71
+
72
+ def default_facts
73
+ @default_facts ||= {
74
+ 'hostname' => node.name.split('p').first,
75
+ 'fqdn' => node.name,
76
+ 'domain' => node.name.split('.').last,
77
+ }
78
+ end
79
+
80
+ def with_tmpdir
81
+ dir = Dir.mktmpdir
82
+ begin
83
+ yield dir
84
+ ensure
85
+ FileUtils.remove_entry_secure dir
86
+ end
87
+ end
88
+
89
+ def node
90
+ @node ||= Puppet::Node.new('testnode')
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module PuppetGraph
2
+ VERSION = "0.0.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'puppet-graph/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'puppet-graph-petems'
6
+ s.version = PuppetGraph::VERSION
7
+ s.homepage = 'https://github.com/rodjek/puppet-graph/'
8
+ s.summary = ''
9
+ s.description = ''
10
+ s.required_ruby_version = '>= 1.8.7'
11
+
12
+ s.files = `git ls-files`.split($/)
13
+ s.executables = s.files.grep(/^bin\//).map { |f| File.basename(f) }
14
+ s.test_files = s.files.grep(/^(test|spec|features)\//)
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_development_dependency 'rspec'
18
+ s.add_development_dependency 'simplecov'
19
+
20
+ s.authors = ['Tim Sharpe']
21
+ s.email = 'tim@sharpe.id.au'
22
+ end
@@ -0,0 +1,7 @@
1
+ class test::facter {
2
+ if $::operatingsystem == 'foo' {
3
+ notify { 'foo': }
4
+ } else {
5
+ notify { 'other': }
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ class test {
2
+ notify { 'foo': }
3
+ notify { 'bar': }
4
+ notify { 'baz': }
5
+
6
+ Notify['foo'] -> Notify['bar'] -> Notify['baz']
7
+ }
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+ require 'puppet-graph/cli'
3
+ require 'fileutils'
4
+
5
+ class CommandRun
6
+ attr_reader :stdout, :stderr, :exitstatus
7
+
8
+ def initialize(args)
9
+ out = StringIO.new
10
+ err = StringIO.new
11
+
12
+ $stdout = out
13
+ $stderr = err
14
+
15
+ @exitstatus = 0
16
+ begin
17
+ PuppetGraph::CLI.new.run(args)
18
+ rescue SystemExit => e
19
+ @exitstatus = e.status
20
+ end
21
+ @stdout = out.string.strip
22
+ @stderr = err.string.strip
23
+
24
+ $stdout = STDOUT
25
+ $stderr = STDERR
26
+ end
27
+ end
28
+
29
+ describe PuppetGraph::CLI do
30
+ subject do
31
+ if args.is_a? Array
32
+ sane_args = args
33
+ else
34
+ sane_args = [args]
35
+ end
36
+
37
+ CommandRun.new(sane_args)
38
+ end
39
+
40
+ context 'when passed --version' do
41
+ let(:args) { '--version' }
42
+
43
+ its(:exitstatus) { should eq(0) }
44
+ its(:stdout) { should eq("puppet-graph v#{PuppetGraph::VERSION}") }
45
+ its(:stderr) { should eq('') }
46
+ end
47
+
48
+ context 'when passed --help' do
49
+ let(:args) { '--help' }
50
+
51
+ its(:exitstatus) { should eq(0) }
52
+ its(:stderr) { should eq('') }
53
+ its(:stdout) { should include('Usage: puppet-graph [options]') }
54
+ end
55
+
56
+ context 'when generating PNG graphs' do
57
+ let(:args) { [
58
+ '--modulepath', 'spec/fixtures/modules',
59
+ '--code', 'include test',
60
+ '--output', 'test.png'
61
+ ] }
62
+
63
+ its(:exitstatus) { should eq(0) }
64
+
65
+ it 'should create a PNG image' do
66
+ subject
67
+ expect(`file test.png`).to include('PNG image data')
68
+ end
69
+ end
70
+
71
+ context 'when generating DOT graphs' do
72
+ let(:args) { [
73
+ '--modulepath', 'spec/fixtures/modules',
74
+ '--code', 'include test',
75
+ '--output', 'test.dot',
76
+ ] }
77
+
78
+ its(:exitstatus) { should eq(0) }
79
+
80
+ it 'should create an ASCII file' do
81
+ subject
82
+ expect(`file test.dot`).to include('ASCII text')
83
+ end
84
+ end
85
+
86
+ context 'when overriding output format' do
87
+ let(:args) { [
88
+ '--modulepath', 'spec/fixtures/modules',
89
+ '--code', 'include test',
90
+ '--format', 'dot',
91
+ '--output', 'test.png',
92
+ ] }
93
+
94
+ its(:exitstatus) { should eq(0) }
95
+
96
+ it 'should create an ASCII file' do
97
+ subject
98
+ expect(`file test.png`).to include('ASCII text')
99
+ end
100
+ end
101
+
102
+ context 'when specifying a fact' do
103
+ let(:args) { [
104
+ '--modulepath', 'spec/fixtures/modules',
105
+ '--code', 'include test::facter',
106
+ '--fact', 'operatingsystem=foo',
107
+ '--output', 'test.dot',
108
+ ] }
109
+
110
+ its(:exitstatus) { should eq(0) }
111
+
112
+ it 'should contain Notify[foo]' do
113
+ subject
114
+ contents = File.read('test.dot')
115
+ expect(contents).to include('Notify[foo]')
116
+ expect(contents).to_not include('Notify[other]')
117
+ end
118
+ end
119
+
120
+ context 'when you dont provide --code' do
121
+ let(:args) { [
122
+ '--modulepath', 'spec/fixtures/modules',
123
+ '--output', 'test.png',
124
+ ] }
125
+
126
+ its(:exitstatus) { should eq(1) }
127
+ its(:stdout) { should eq('') }
128
+ its(:stderr) { should include('Error: No Puppet code') }
129
+ its(:stderr) { should include('Usage: puppet-graph') }
130
+ end
131
+
132
+ context 'when you specify an invalid output format' do
133
+ let(:args) { [
134
+ '--modulepath', 'spec/fixtures/modules',
135
+ '--code', 'include test',
136
+ '--output', 'test.foo',
137
+ ] }
138
+
139
+ its(:exitstatus) { should eq(1) }
140
+ its(:stdout) { should eq('') }
141
+ its(:stderr) { should include('Error: Invalid format') }
142
+ its(:stderr) { should include('Usage: puppet-graph') }
143
+ end
144
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec/autorun'
2
+ require 'puppet-graph'
3
+ require 'simplecov'
4
+
5
+ SimpleCov.start do
6
+ add_filter '/vendor/gems/'
7
+ end
8
+
9
+ RSpec.configure do |c|
10
+ c.mock_framework = :rspec
11
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-graph-petems
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Sharpe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ''
42
+ email: tim@sharpe.id.au
43
+ executables:
44
+ - puppet-graph
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .travis.yml
50
+ - Gemfile
51
+ - LICENSE
52
+ - README.md
53
+ - bin/puppet-graph
54
+ - lib/puppet-graph.rb
55
+ - lib/puppet-graph/cli.rb
56
+ - lib/puppet-graph/grapher.rb
57
+ - lib/puppet-graph/version.rb
58
+ - puppet-graph.gemspec
59
+ - spec/fixtures/modules/test/manifests/facter.pp
60
+ - spec/fixtures/modules/test/manifests/init.pp
61
+ - spec/puppet-graph/bin_spec.rb
62
+ - spec/spec_helper.rb
63
+ homepage: https://github.com/rodjek/puppet-graph/
64
+ licenses: []
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: 1.8.7
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.0.3
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: ''
86
+ test_files:
87
+ - spec/fixtures/modules/test/manifests/facter.pp
88
+ - spec/fixtures/modules/test/manifests/init.pp
89
+ - spec/puppet-graph/bin_spec.rb
90
+ - spec/spec_helper.rb
91
+ has_rdoc: