puppet-graph-petems 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: