knife-spork-berks 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +19 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +284 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +35 -0
  7. data/README.md +406 -0
  8. data/Rakefile +2 -0
  9. data/knife-spork-berks.gemspec +22 -0
  10. data/lib/chef/knife/spork-bump.rb +86 -0
  11. data/lib/chef/knife/spork-check.rb +149 -0
  12. data/lib/chef/knife/spork-databag-create.rb +53 -0
  13. data/lib/chef/knife/spork-databag-delete.rb +51 -0
  14. data/lib/chef/knife/spork-databag-edit.rb +54 -0
  15. data/lib/chef/knife/spork-databag-fromfile.rb +82 -0
  16. data/lib/chef/knife/spork-environment-create.rb +43 -0
  17. data/lib/chef/knife/spork-environment-delete.rb +36 -0
  18. data/lib/chef/knife/spork-environment-edit.rb +37 -0
  19. data/lib/chef/knife/spork-environment-fromfile.rb +42 -0
  20. data/lib/chef/knife/spork-info.rb +30 -0
  21. data/lib/chef/knife/spork-node-create.rb +38 -0
  22. data/lib/chef/knife/spork-node-delete.rb +38 -0
  23. data/lib/chef/knife/spork-node-edit.rb +45 -0
  24. data/lib/chef/knife/spork-node-fromfile.rb +43 -0
  25. data/lib/chef/knife/spork-node-runlistadd.rb +48 -0
  26. data/lib/chef/knife/spork-node-runlistremove.rb +42 -0
  27. data/lib/chef/knife/spork-node-runlistset.rb +42 -0
  28. data/lib/chef/knife/spork-omni.rb +107 -0
  29. data/lib/chef/knife/spork-promote.rb +166 -0
  30. data/lib/chef/knife/spork-role-create.rb +43 -0
  31. data/lib/chef/knife/spork-role-delete.rb +36 -0
  32. data/lib/chef/knife/spork-role-edit.rb +37 -0
  33. data/lib/chef/knife/spork-role-fromfile.rb +42 -0
  34. data/lib/chef/knife/spork-upload.rb +129 -0
  35. data/lib/knife-spork.rb +3 -0
  36. data/lib/knife-spork/plugins.rb +25 -0
  37. data/lib/knife-spork/plugins/campfire.rb +211 -0
  38. data/lib/knife-spork/plugins/eventinator.rb +317 -0
  39. data/lib/knife-spork/plugins/foodcritic.rb +46 -0
  40. data/lib/knife-spork/plugins/git.rb +197 -0
  41. data/lib/knife-spork/plugins/graphite.rb +25 -0
  42. data/lib/knife-spork/plugins/grove.rb +161 -0
  43. data/lib/knife-spork/plugins/hipchat.rb +131 -0
  44. data/lib/knife-spork/plugins/irccat.rb +298 -0
  45. data/lib/knife-spork/plugins/jabber.rb +129 -0
  46. data/lib/knife-spork/plugins/plugin.rb +105 -0
  47. data/lib/knife-spork/plugins/statusnet.rb +118 -0
  48. data/lib/knife-spork/runner.rb +277 -0
  49. data/plugins/Campfire.md +43 -0
  50. data/plugins/Eventinator.md +30 -0
  51. data/plugins/Foodcritic.md +53 -0
  52. data/plugins/Git.md +46 -0
  53. data/plugins/Graphite.md +30 -0
  54. data/plugins/Grove.md +31 -0
  55. data/plugins/HipChat.md +50 -0
  56. data/plugins/Irccat.md +50 -0
  57. data/plugins/Jabber.md +61 -0
  58. data/plugins/README.md +70 -0
  59. data/plugins/StatusNet.md +41 -0
  60. data/plugins/Template.md +34 -0
  61. metadata +170 -0
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'knife-spork-berks'
5
+ gem.version = '1.3.2'
6
+ gem.authors = ["Jon Cowie"]
7
+ gem.email = 'jonlives@gmail.com'
8
+ gem.homepage = 'https://github.com/jonlives/knife-spork'
9
+ gem.summary = "A workflow plugin to help many devs work with the same chef repo/server. Includes fixes for using with Berkshelf."
10
+ gem.description = "A workflow plugin to help many devs work with the same chef repo/server. Includes fixes for using with Berkshelf."
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "knife-spork-berks"
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_runtime_dependency 'chef', '>= 11.0.0'
19
+ gem.add_runtime_dependency 'git', '>= 1.2.5'
20
+ gem.add_runtime_dependency 'app_conf', '>= 0.4.0'
21
+ gem.add_runtime_dependency 'diffy', '>= 3.0.1'
22
+ end
@@ -0,0 +1,86 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+
4
+ module KnifeSpork
5
+ class SporkBump < Chef::Knife
6
+ include KnifeSpork::Runner
7
+
8
+ TYPE_INDEX = { :major => 0, :minor => 1, :patch => 2, :manual => 3 }.freeze
9
+
10
+ option :cookbook_path,
11
+ :short => '-o PATH:PATH',
12
+ :long => '--cookbook-path PATH:PATH',
13
+ :description => 'A colon-separated path to look for cookbooks in',
14
+ :proc => lambda { |o| o.split(':') }
15
+
16
+ if defined?(::Berkshelf)
17
+ option :berksfile,
18
+ :short => '-b',
19
+ :long => 'berksfile',
20
+ :description => 'Path to a Berksfile to operate off of',
21
+ :default => File.join(Dir.pwd, ::Berkshelf::DEFAULT_FILENAME)
22
+
23
+ option :skip_dependencies,
24
+ :short => '-s',
25
+ :long => '--skip-dependencies',
26
+ :description => 'Berksfile skips resolving source cookbook dependencies',
27
+ :default => true
28
+ end
29
+
30
+ banner 'knife spork bump COOKBOOK [major|minor|patch|manual]'
31
+
32
+ def run
33
+ self.config = Chef::Config.merge!(config)
34
+ config[:cookbook_path] ||= Chef::Config[:cookbook_path]
35
+
36
+ if @name_args.empty?
37
+ show_usage
38
+ ui.error("You must specify at least a cookbook name")
39
+ exit 1
40
+ end
41
+
42
+ #First load so plugins etc know what to work with
43
+ @cookbook = load_cookbook(name_args.first)
44
+
45
+ run_plugins(:before_bump)
46
+
47
+ #Reload cookbook in case a VCS plugin found updates
48
+ @cookbook = load_cookbook(name_args.first)
49
+ bump
50
+ run_plugins(:after_bump)
51
+ end
52
+
53
+ private
54
+ def bump
55
+ old_version = @cookbook.version
56
+
57
+ if bump_type == 3
58
+ # manual bump
59
+ version_array = manual_bump_version.split('.')
60
+ else
61
+ # major, minor, or patch bump
62
+ version_array = old_version.split('.').collect{ |i| i.to_i }
63
+ version_array[bump_type] += 1
64
+ ((bump_type+1)..2).each{ |i| version_array[i] = 0 } # reset all lower version numbers to 0
65
+ end
66
+
67
+ new_version = version_array.join('.')
68
+
69
+ metadata_file = "#{@cookbook.root_dir}/metadata.rb"
70
+ new_contents = File.read(metadata_file).gsub(/(version\s+['"])[0-9\.]+(['"])/, "\\1#{new_version}\\2")
71
+ File.open(metadata_file, 'w'){ |f| f.write(new_contents) }
72
+
73
+ ui.info "Successfully bumped #{@cookbook.name} to v#{new_version}!"
74
+ end
75
+
76
+ def bump_type
77
+ TYPE_INDEX[(name_args[1] || 'patch').to_sym]
78
+ end
79
+
80
+ def manual_bump_version
81
+ version = name_args.last
82
+ validate_version!(version)
83
+ version
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,149 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+
4
+ module KnifeSpork
5
+ class SporkCheck < Chef::Knife
6
+ include KnifeSpork::Runner
7
+
8
+ banner 'knife spork check COOKBOOK (options)'
9
+
10
+ option :all,
11
+ :short => '--a',
12
+ :long => '--all',
13
+ :description => 'Show all uploaded versions of the cookbook'
14
+
15
+ option :fail,
16
+ :long => "--fail",
17
+ :description => "If the check fails exit with non-zero exit code"
18
+
19
+ option :cookbook_path,
20
+ :short => '-o PATH:PATH',
21
+ :long => '--cookbook-path PATH:PATH',
22
+ :description => 'A colon-separated path to look for cookbooks in',
23
+ :proc => lambda { |o| o.split(':') }
24
+
25
+ if defined?(::Berkshelf)
26
+ option :berksfile,
27
+ :short => '-b',
28
+ :long => 'berksfile',
29
+ :description => 'Path to a Berksfile to operate off of',
30
+ :default => File.join(Dir.pwd, ::Berkshelf::DEFAULT_FILENAME)
31
+
32
+ option :skip_dependencies,
33
+ :short => '-s',
34
+ :long => '--skip-dependencies',
35
+ :description => 'Berksfile skips resolving source cookbook dependencies',
36
+ :default => true
37
+ end
38
+
39
+ def run
40
+ self.config = Chef::Config.merge!(config)
41
+
42
+ if name_args.empty?
43
+ ui.fatal 'You must specify a cookbook name!'
44
+ show_usage
45
+ exit(1)
46
+ end
47
+
48
+ #First load so plugins etc know what to work with
49
+ initial_load
50
+
51
+ run_plugins(:before_check)
52
+
53
+ #Reload cookbook in case a VCS plugin found updates
54
+ initial_load
55
+
56
+ check
57
+ run_plugins(:after_check)
58
+ end
59
+
60
+ private
61
+ def check
62
+ ui.msg "Checking versions for cookbook #{@cookbook.name}..."
63
+ ui.msg ""
64
+ ui.msg "Local Version:"
65
+ ui.msg " #{local_version}"
66
+ ui.msg ""
67
+ ui.msg "Remote Versions: (* indicates frozen)"
68
+ remote_versions.each do |remote_version|
69
+ if frozen?(remote_version)
70
+ ui.msg " *#{remote_version}"
71
+ else
72
+ ui.msg " #{remote_version}"
73
+ end
74
+ end
75
+ ui.msg ""
76
+
77
+ remote_versions.each do |remote_version|
78
+ if remote_version == local_version
79
+ if frozen?(remote_version)
80
+ message = "Your local version (#{local_version}) is frozen on the remote server. You'll need to bump before you can upload."
81
+ if config[:fail]
82
+ fail_and_exit("#{message}")
83
+ else
84
+ ui.warn("#{message}")
85
+ answer = ui.ask("Would you like to perform a patch-level bump on the #{@cookbook.name} cookbook now? (Y/N)")
86
+ if answer == "Y" or answer == "y"
87
+ bump = SporkBump.new
88
+ bump.name_args = [@cookbook.name]
89
+ bump.run
90
+ else
91
+ ui.info "Skipping bump..."
92
+ end
93
+ end
94
+ else
95
+ message = "The version #{local_version} exists on the server and is not frozen. Uploading will overwrite!"
96
+ config[:fail] ? fail_and_exit("#{message}") : ui.error("#{message}")
97
+ end
98
+
99
+ return
100
+ end
101
+ end
102
+
103
+ ui.msg 'Everything looks good!'
104
+ end
105
+
106
+ def initial_load
107
+ begin
108
+ @cookbook = load_cookbook(name_args.first)
109
+ rescue Chef::Exceptions::CookbookNotFoundInRepo => e
110
+ ui.error "#{name_args.first} does not exist locally in your cookbook path(s), Exiting."
111
+ exit(1)
112
+ end
113
+ end
114
+
115
+ def local_version
116
+ @cookbook.version
117
+ end
118
+
119
+ def remote_versions
120
+ @remote_versions ||= begin
121
+ environment = config[:environment]
122
+ api_endpoint = environment ? "environments/#{environment}/cookbooks/#{@cookbook.name}" : "cookbooks/#{@cookbook.name}"
123
+ cookbooks = rest.get_rest(api_endpoint)
124
+
125
+ versions = cookbooks[@cookbook.name.to_s]['versions']
126
+ (config[:all] ? versions : versions[0..4]).collect{|v| v['version']}
127
+ rescue Net::HTTPServerException => e
128
+ ui.info "#{@cookbook.name} does not yet exist on the Chef Server!"
129
+ return []
130
+ end
131
+ end
132
+
133
+ def frozen?(version)
134
+ @versions_cache ||= {}
135
+
136
+ @versions_cache[version.to_sym] ||= begin
137
+ environment = config[:environment]
138
+ api_endpoint = environment ? "environments/#{environment}/cookbooks/#{@cookbook.name}" : "cookbooks/#{@cookbook.name}/#{version}"
139
+ rest.get_rest(api_endpoint).to_hash['frozen?']
140
+ end
141
+ end
142
+
143
+ def fail_and_exit(message, options={})
144
+ ui.fatal message
145
+ show_usage if options[:show_usage]
146
+ exit 1
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,53 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+ require 'json'
4
+
5
+ module KnifeSpork
6
+ class SporkDataBagCreate < Chef::Knife
7
+ include KnifeSpork::Runner
8
+
9
+ deps do
10
+ require 'chef/knife/data_bag_create'
11
+ end
12
+
13
+ banner 'knife data bag create BAG [ITEM] (options)'
14
+
15
+ option :secret,
16
+ :short => "-s SECRET",
17
+ :long => "--secret ",
18
+ :description => "The secret key to use to encrypt data bag item values"
19
+
20
+ option :secret_file,
21
+ :long => "--secret-file SECRET_FILE",
22
+ :description => "A file containing the secret key to use to encrypt data bag item values"
23
+
24
+ def run
25
+ self.config = Chef::Config.merge!(config)
26
+
27
+ if @name_args.nil?
28
+ ui.error "You must specify a data bag name"
29
+ ui.error opt_parser
30
+ exit 1
31
+ end
32
+
33
+ @object_name = @name_args.first
34
+
35
+ run_plugins(:before_databagcreate)
36
+ pre_databag = {}
37
+ databag_create
38
+ post_databag = load_databag(@object_name)
39
+ @object_difference = json_diff(pre_databag,post_databag).to_s
40
+ run_plugins(:after_databagcreate)
41
+ end
42
+
43
+ private
44
+ def databag_create
45
+ dbc = Chef::Knife::DataBagCreate.new
46
+ dbc.name_args = @name_args
47
+ dbc.config[:editor] = config[:editor]
48
+ dbc.config[:secret] = config[:secret]
49
+ dbc.config[:secret_file] = config[:secret_file]
50
+ dbc.run
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+ require 'json'
4
+
5
+ module KnifeSpork
6
+ class SporkDataBagDelete < Chef::Knife
7
+ include KnifeSpork::Runner
8
+
9
+ deps do
10
+ require 'chef/knife/data_bag_delete'
11
+ end
12
+
13
+ banner 'knife data bag delete BAG [ITEM] (options)'
14
+
15
+
16
+ def run
17
+ self.config = Chef::Config.merge!(config)
18
+
19
+ if @name_args.length == 2
20
+ @object_name = @name_args.first
21
+ @object_secondary_name = @name_args.last
22
+ run_plugins(:before_databagitemdelete)
23
+ pre_databag = load_databag_item(@object_name,@object_secondary_name)
24
+ databag_delete
25
+ post_databag = {}
26
+ @object_difference = json_diff(pre_databag,post_databag).to_s
27
+ run_plugins(:after_databagitemdelete)
28
+ elsif @name_args.length == 1
29
+ @object_name = @name_args.first
30
+ run_plugins(:before_databagdelete)
31
+ pre_databag = load_databag(@object_name)
32
+ databag_delete
33
+ post_databag = {}
34
+ @object_difference = json_diff(pre_databag,post_databag).to_s
35
+ run_plugins(:after_databagdelete)
36
+ else
37
+ show_usage
38
+ ui.fatal("You must specify at least a data bag name")
39
+ exit 1
40
+ end
41
+ end
42
+
43
+ private
44
+ def databag_delete
45
+ dbd = Chef::Knife::DataBagDelete.new
46
+ dbd.name_args = @name_args
47
+ dbd.config[:editor] = config[:editor]
48
+ dbd.run
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,54 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+ require 'json'
4
+
5
+ module KnifeSpork
6
+ class SporkDataBagEdit < Chef::Knife
7
+ include KnifeSpork::Runner
8
+
9
+ deps do
10
+ require 'chef/knife/data_bag_edit'
11
+ end
12
+
13
+ banner 'knife spork data bag edit BAG ITEM (options)'
14
+
15
+ option :secret,
16
+ :short => "-s SECRET",
17
+ :long => "--secret ",
18
+ :description => "The secret key to use to encrypt data bag item values"
19
+
20
+ option :secret_file,
21
+ :long => "--secret-file SECRET_FILE",
22
+ :description => "A file containing the secret key to use to encrypt data bag item values"
23
+
24
+ def run
25
+ self.config = Chef::Config.merge!(config)
26
+
27
+ if @name_args.length != 2
28
+ ui.error "You must supply the data bag and an item to edit!"
29
+ ui.error opt_parser
30
+ exit 1
31
+ end
32
+
33
+ @object_name = @name_args.first
34
+ @object_secondary_name = @name_args.last
35
+
36
+ run_plugins(:before_databagedit)
37
+ pre_databag = load_databag_item(@object_name, @object_secondary_name)
38
+ databag_edit
39
+ post_databag = load_databag_item(@object_name, @object_secondary_name)
40
+ @object_difference = json_diff(pre_databag,post_databag).to_s
41
+ run_plugins(:after_databagedit)
42
+ end
43
+
44
+ private
45
+ def databag_edit
46
+ dbe = Chef::Knife::DataBagEdit.new
47
+ dbe.name_args = @name_args
48
+ dbe.config[:editor] = config[:editor]
49
+ dbe.config[:secret] = config[:secret]
50
+ dbe.config[:secret_file] = config[:secret_file]
51
+ dbe.run
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,82 @@
1
+ require 'chef/knife'
2
+ require 'knife-spork/runner'
3
+ require 'json'
4
+
5
+ module KnifeSpork
6
+ class SporkDataBagFromFile < Chef::Knife
7
+ include KnifeSpork::Runner
8
+
9
+ deps do
10
+ require 'chef/knife/data_bag_from_file'
11
+ end
12
+
13
+ banner 'knife data bag from file BAG FILE|FOLDER [FILE|FOLDER..] (options)'
14
+
15
+ option :secret,
16
+ :short => "-s SECRET",
17
+ :long => "--secret ",
18
+ :description => "The secret key to use to encrypt data bag item values"
19
+
20
+ option :secret_file,
21
+ :long => "--secret-file SECRET_FILE",
22
+ :description => "A file containing the secret key to use to encrypt data bag item values"
23
+
24
+ option :all,
25
+ :short => "-a",
26
+ :long => "--all",
27
+ :description => "Upload all data bags"
28
+
29
+ def run
30
+ self.config = Chef::Config.merge!(config)
31
+
32
+ @object_name = @name_args.first
33
+
34
+ if config[:all] == true
35
+ test = Chef::Knife::DataBagFromFile.new
36
+ test.config[:verbosity] = 3
37
+ databags = test.send(:find_all_data_bags)
38
+ databags.each do |bag|
39
+ test.send(:find_all_data_bag_items,bag).each do |item|
40
+ @object_name = bag
41
+ @object_secondary_name = item.split("/").last
42
+ run_plugins(:before_databagfromfile)
43
+ begin
44
+ pre_databag = load_databag_item(@object_name, @object_secondary_name.gsub(".json",""))
45
+ rescue
46
+ pre_databag = {}
47
+ end
48
+ databag_from_file([@object_name,@object_secondary_name])
49
+ post_databag = load_databag_item(@object_name, @object_secondary_name.gsub(".json",""))
50
+ @object_difference = json_diff(pre_databag,post_databag).to_s
51
+ run_plugins(:after_databagfromfile)
52
+ end
53
+ end
54
+
55
+ else
56
+ @name_args[1..-1].each do |arg|
57
+ @object_secondary_name = arg.split("/").last
58
+ run_plugins(:before_databagfromfile)
59
+ begin
60
+ pre_databag = load_databag_item(@object_name, @object_secondary_name.gsub(".json",""))
61
+ rescue
62
+ pre_databag = {}
63
+ end
64
+ databag_from_file
65
+ post_databag = load_databag_item(@object_name, @object_secondary_name.gsub(".json",""))
66
+ @object_difference = json_diff(pre_databag,post_databag).to_s
67
+ run_plugins(:after_databagfromfile)
68
+ end
69
+ end
70
+ end
71
+
72
+ private
73
+ def databag_from_file(data_bag_names=nil)
74
+ dbff = Chef::Knife::DataBagFromFile.new
75
+ dbff.name_args = data_bag_names || @name_args
76
+ dbff.config[:editor] = config[:editor]
77
+ dbff.config[:secret] = config[:secret]
78
+ dbff.config[:secret_file] = config[:secret_file]
79
+ dbff.run
80
+ end
81
+ end
82
+ end