knife-audit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in knife-audit.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ knife-audit
2
+ ========
3
+ A knife plugin for determining which cookbooks are in use on which nodes of your Chef server or Opscode organization.
4
+ Allows you to safely maintain a chef cookbook set by determining which cookbooks are currently in use by nodes (included in node runlists).
5
+
6
+
7
+ Installing knife-audit
8
+ -------------------
9
+
10
+ #### Script install
11
+
12
+ Copy the knife-audit script from https://github.com/jbz/knife-audit/blob/master/lib/chef/knife/audit.rb to your .chef/plugins/knife directory.
13
+
14
+
15
+ Usage
16
+ ---------------
17
+
18
+ knife audit <COOKBOOK COOKBOOK ...>
19
+
20
+ If no cookbooks are specified, knife-audit will return a list of *all* cookbooks available on the currently configured Chef server or Opscode Platform organization, along with a count for each of how many nodes in the current Chef server or Opscode Platform organization explicitly reference that cookbook in their expanded runlist.
21
+
22
+ Note that this does *not* include nodes that call the cookbook via 'include' and/or 'depends' statements. The 'complete runlist' for nodes, which includes all cookbooks pulled in due to includes, is kept in Node.run_state.seen_recipes], but this is an ephemeral attribute and is only populated locally on the node during a client run. It is not saved to the Chef server, therefore knife-audit cannot 'see' it.
23
+
24
+ If one or more cookbook names are specified on the command line, knife-audit will return a list of only those cookbooks and their counts. Specifying a cookbook which is not available on the Chef server will result in an error.
25
+
26
+ The '-s' or '--show-nodelist' option will cause knife-audit to include in its output a list of all nodes which reference each cookbook.
27
+
28
+ **NOTE** knife-audit retrieves an array of *all* nodes present on your chef server for each run. As a result, it is relatively slow; if you have many ( >= 16) nodes, it will take noticeable wallclock time to complete its run. In addition. it may use lots of memory to hold those node objects.
29
+
30
+
31
+ Disclaimer
32
+ ----------
33
+
34
+ This is my first knife plugin, and I haven't been using Ruby that long. Plus, I'm an op, not a software engineer. :-) If you run into problems with knife-audit, by all means let me know; you can find me via the github page or on irc at freenode #chef, usually. Thanks.
35
+
36
+
37
+ License terms
38
+ -------------
39
+ Authors:: J.B. Zimmerman
40
+ Copyright:: Copyright (c) 2009-2011 J.B. Zimmerman
41
+ License:: Apache License, Version 2.0
42
+
43
+
44
+ Licensed under the Apache License, Version 2.0 (the "License");
45
+ you may not use this file except in compliance with the License.
46
+ You may obtain a copy of the License at
47
+
48
+ http://www.apache.org/licenses/LICENSE-2.0
49
+
50
+ Unless required by applicable law or agreed to in writing, software
51
+ distributed under the License is distributed on an "AS IS" BASIS,
52
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53
+ See the License for the specific language governing permissions and
54
+ limitations under the License.
55
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "knife-audit/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "knife-audit"
7
+ s.version = Knife::Audit::VERSION
8
+ s.authors = ["Jacob Zimmerman"]
9
+ s.email = ["jzimmerman@mdsol.com"]
10
+ s.homepage = "https://github.com/jbz/knife-audit"
11
+ s.summary = %q{A Chef plugin for determining which cookbooks are in use on which nodes of your Chef server or Opscode organization.}
12
+ s.description = %q{Allows you to safely maintain a chef cookbook set by determining which cookbooks are currently in use by nodes (included in node runlists).}
13
+
14
+ s.rubyforge_project = "knife-audit"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,136 @@
1
+ #
2
+ ## Author:: Jacob Zimmermann (<jzimmerman@mdsol.com>)
3
+ ##
4
+ ## Licensed under the Apache License, Version 2.0 (the "License");
5
+ ## you may not use this file except in compliance with the License.
6
+ ## You may obtain a copy of the License at
7
+ ##
8
+ ## http://www.apache.org/licenses/LICENSE-2.0
9
+ ##
10
+ ## Unless required by applicable law or agreed to in writing, software
11
+ ## distributed under the License is distributed on an "AS IS" BASIS,
12
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ ## See the License for the specific language governing permissions and
14
+ ## limitations under the License.
15
+ ##
16
+ #
17
+
18
+ require 'chef/knife'
19
+
20
+ module KnifeAudit
21
+ class Audit < Chef::Knife
22
+
23
+ deps do
24
+ require 'chef/cookbook_loader'
25
+ require 'chef/environment'
26
+ require 'chef/node'
27
+ require 'chef/run_list'
28
+ require 'chef/json_compat'
29
+ require 'chef/shef/ext'
30
+ end
31
+
32
+ banner "knife audit <COOKBOOK COOKBOOK ...>"
33
+
34
+ option :show_nodelist,
35
+ :short => "-s",
36
+ :long => "--show-nodelist",
37
+ :description => "Show all nodes running each cookbook"
38
+
39
+ def run
40
+
41
+ if @name_args.empty?
42
+ display_cookbooks = {}
43
+ else
44
+ display_cookbooks = @name_args
45
+ end
46
+
47
+ self.config = Chef::Config.merge!(config)
48
+
49
+ # 1) Get a list (hash, actually, with key of 'name') of cookbooks available on the current server/org
50
+ # unless we've been given a cookbook/cookbooks on the command line
51
+ env = config[:environment]
52
+ num_versions = config[:all_versions] ? "num_versions=all" : "num_versions=1"
53
+
54
+ if display_cookbooks.empty?
55
+ api_endpoint = env ? "/environments/#{env}/cookbooks?#{num_versions}" : "/cookbooks?#{num_versions}"
56
+ cookbook_list = rest.get_rest(api_endpoint)
57
+ else
58
+ cookbook_list = {}
59
+ display_cookbooks.each do |cookbook_name|
60
+ api_endpoint = env ? "/environments/#{env}/cookbooks/#{cookbook_name}" : "cookbooks/#{cookbook_name}"
61
+ begin
62
+ cookbook_list.merge!(rest.get_rest(api_endpoint))
63
+ rescue
64
+ ui.error("Cookbook #{cookbook_name} could not be found on the server!")
65
+ exit 1
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+
72
+ # add count => 0 to each cookbook hash
73
+ cookbook_list.each do |name,book|
74
+ book["count"] = 0
75
+ book["nodes"] = []
76
+ end
77
+
78
+
79
+ # 2) Get an array of Chef::Nodes known to the current server/org
80
+
81
+ query = "*:*" # find all nodes
82
+
83
+ Shef::Extensions.extend_context_object(self)
84
+ node_list = nodes.find(query)
85
+
86
+ # 3) Iterate over each node
87
+
88
+ node_list.each do |node|
89
+
90
+ # 3a) Get node's runlist
91
+
92
+ # using expand!.recipes catches multi-level roles (roles with roles with recipes, etc.)
93
+ recipes = node.expand!.recipes.to_a
94
+ node_cookbook_list = recipes.map{ |x| x.match(/[^\:]+/)[0] }.uniq
95
+
96
+ # 3b) For each cookbook in the node runlist, if it's in our cookbook array increment its count and
97
+ # add the node to its running node array
98
+
99
+ node_cookbook_list.each do |cookbook|
100
+ if cookbook_list.has_key?(cookbook)
101
+ # Up the cookbook count
102
+ cookbook_list[cookbook]["count"] += 1
103
+ # Add the node to the cookbook's nodes array
104
+ cookbook_list[cookbook]["nodes"] << node.name
105
+ end
106
+ end
107
+
108
+ end # step 3 iterate end
109
+
110
+ # 4) Output
111
+
112
+ format_cookbook_audit_list_for_display(cookbook_list).each do |line|
113
+ ui.msg(line)
114
+ end
115
+
116
+ end # 'run' def end
117
+
118
+
119
+ def format_cookbook_audit_list_for_display(item)
120
+ key_length = item.empty? ? 0 : item.keys.map {|name| name.size }.max + 2
121
+ if config[:show_nodelist]
122
+ item.sort.map do |name, cookbook|
123
+ "#{name.ljust(key_length)} #{cookbook["count"]} [ #{cookbook["nodes"].join(' ')} ]"
124
+ end
125
+ else
126
+ item.sort.map do |name, cookbook|
127
+ "#{name.ljust(key_length)} #{cookbook["count"]}"
128
+ end
129
+ end
130
+
131
+ end # format_cokbook_audit... def end
132
+
133
+
134
+ end #class end
135
+
136
+ end #module end
@@ -0,0 +1,5 @@
1
+ module Knife
2
+ module Audit
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knife-audit
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jacob Zimmerman
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-31 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Allows you to safely maintain a chef cookbook set by determining which cookbooks are currently in use by nodes (included in node runlists).
23
+ email:
24
+ - jzimmerman@mdsol.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - Gemfile
33
+ - README.md
34
+ - Rakefile
35
+ - knife-audit.gemspec
36
+ - lib/chef/knife/audit.rb
37
+ - lib/knife-audit/version.rb
38
+ has_rdoc: true
39
+ homepage: https://github.com/jbz/knife-audit
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: knife-audit
68
+ rubygems_version: 1.5.2
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: A Chef plugin for determining which cookbooks are in use on which nodes of your Chef server or Opscode organization.
72
+ test_files: []
73
+