clc-cheffish 0.8.clc

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +4 -0
  4. data/Rakefile +23 -0
  5. data/lib/chef/provider/chef_acl.rb +434 -0
  6. data/lib/chef/provider/chef_client.rb +48 -0
  7. data/lib/chef/provider/chef_container.rb +50 -0
  8. data/lib/chef/provider/chef_data_bag.rb +50 -0
  9. data/lib/chef/provider/chef_data_bag_item.rb +273 -0
  10. data/lib/chef/provider/chef_environment.rb +78 -0
  11. data/lib/chef/provider/chef_group.rb +78 -0
  12. data/lib/chef/provider/chef_mirror.rb +138 -0
  13. data/lib/chef/provider/chef_node.rb +82 -0
  14. data/lib/chef/provider/chef_organization.rb +150 -0
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +41 -0
  16. data/lib/chef/provider/chef_role.rb +79 -0
  17. data/lib/chef/provider/chef_user.rb +53 -0
  18. data/lib/chef/provider/private_key.rb +219 -0
  19. data/lib/chef/provider/public_key.rb +82 -0
  20. data/lib/chef/resource/chef_acl.rb +65 -0
  21. data/lib/chef/resource/chef_client.rb +44 -0
  22. data/lib/chef/resource/chef_container.rb +18 -0
  23. data/lib/chef/resource/chef_data_bag.rb +18 -0
  24. data/lib/chef/resource/chef_data_bag_item.rb +114 -0
  25. data/lib/chef/resource/chef_environment.rb +71 -0
  26. data/lib/chef/resource/chef_group.rb +49 -0
  27. data/lib/chef/resource/chef_mirror.rb +47 -0
  28. data/lib/chef/resource/chef_node.rb +18 -0
  29. data/lib/chef/resource/chef_organization.rb +64 -0
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +31 -0
  31. data/lib/chef/resource/chef_role.rb +104 -0
  32. data/lib/chef/resource/chef_user.rb +51 -0
  33. data/lib/chef/resource/private_key.rb +44 -0
  34. data/lib/chef/resource/public_key.rb +21 -0
  35. data/lib/cheffish.rb +222 -0
  36. data/lib/cheffish/actor_provider_base.rb +131 -0
  37. data/lib/cheffish/basic_chef_client.rb +115 -0
  38. data/lib/cheffish/chef_provider_base.rb +231 -0
  39. data/lib/cheffish/chef_run_data.rb +19 -0
  40. data/lib/cheffish/chef_run_listener.rb +28 -0
  41. data/lib/cheffish/key_formatter.rb +109 -0
  42. data/lib/cheffish/merged_config.rb +94 -0
  43. data/lib/cheffish/recipe_dsl.rb +147 -0
  44. data/lib/cheffish/server_api.rb +52 -0
  45. data/lib/cheffish/version.rb +3 -0
  46. data/lib/cheffish/with_pattern.rb +21 -0
  47. data/spec/functional/fingerprint_spec.rb +64 -0
  48. data/spec/functional/merged_config_spec.rb +20 -0
  49. data/spec/integration/chef_acl_spec.rb +914 -0
  50. data/spec/integration/chef_client_spec.rb +110 -0
  51. data/spec/integration/chef_container_spec.rb +34 -0
  52. data/spec/integration/chef_group_spec.rb +324 -0
  53. data/spec/integration/chef_mirror_spec.rb +244 -0
  54. data/spec/integration/chef_node_spec.rb +211 -0
  55. data/spec/integration/chef_organization_spec.rb +244 -0
  56. data/spec/integration/chef_user_spec.rb +90 -0
  57. data/spec/integration/private_key_spec.rb +446 -0
  58. data/spec/integration/recipe_dsl_spec.rb +29 -0
  59. data/spec/support/key_support.rb +29 -0
  60. data/spec/support/repository_support.rb +103 -0
  61. data/spec/support/spec_support.rb +176 -0
  62. data/spec/unit/get_private_key_spec.rb +93 -0
  63. metadata +162 -0
@@ -0,0 +1,29 @@
1
+ require 'support/spec_support'
2
+ require 'chef/resource/chef_node'
3
+ require 'chef/provider/chef_node'
4
+ require 'tmpdir'
5
+
6
+ describe 'Cheffish Recipe DSL' do
7
+ extend SpecSupport
8
+
9
+ context 'when we include with_chef_local_server' do
10
+ before :each do
11
+ @tmp_repo = tmp_repo = Dir.mktmpdir('chef_repo')
12
+ load_recipe do
13
+ with_chef_local_server :chef_repo_path => tmp_repo
14
+ end
15
+ end
16
+
17
+ after :each do
18
+ FileUtils.remove_entry_secure @tmp_repo
19
+ end
20
+
21
+ it 'chef_nodes get put into said server' do
22
+ run_recipe do
23
+ chef_node 'blah'
24
+ end
25
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
26
+ expect(File).to exist("#{@tmp_repo}/nodes/blah.json")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ RSpec::Matchers.define :be_public_key_for do |private_key, pass_phrase|
2
+ match do |public_key|
3
+ if public_key.is_a?(String)
4
+ public_key, public_key_format = Cheffish::KeyFormatter.decode(IO.read(File.expand_path(public_key)), pass_phrase, public_key)
5
+ end
6
+ if private_key.is_a?(String)
7
+ private_key, private_key_format = Cheffish::KeyFormatter.decode(IO.read(File.expand_path(private_key)), pass_phrase, private_key)
8
+ end
9
+
10
+ encrypted = public_key.public_encrypt('hi there')
11
+ expect(private_key.private_decrypt(encrypted)).to eq('hi there')
12
+ end
13
+ end
14
+
15
+ RSpec::Matchers.define :match_private_key do |expected, pass_phrase|
16
+ match do |actual|
17
+ if expected.is_a?(String)
18
+ expected, format = Cheffish::KeyFormatter.decode(IO.read(File.expand_path(expected)), pass_phrase, expected)
19
+ end
20
+ if actual.is_a?(String)
21
+ actual, format = Cheffish::KeyFormatter.decode(IO.read(File.expand_path(actual)), pass_phrase, actual)
22
+ end
23
+
24
+ encrypted = actual.public_encrypt('hi there')
25
+ expect(expected.private_decrypt(encrypted)).to eq('hi there')
26
+ encrypted = expected.public_encrypt('hi there')
27
+ expect(actual.private_decrypt(encrypted)).to eq('hi there')
28
+ end
29
+ end
@@ -0,0 +1,103 @@
1
+ module RepositorySupport
2
+ def when_the_repository(desc, *tags, &block)
3
+ context("when the chef repo #{desc}", *tags) do
4
+ include_context "with a chef repo"
5
+ extend WhenTheRepositoryClassMethods
6
+ module_eval(&block)
7
+ end
8
+ end
9
+
10
+ RSpec.shared_context "with a chef repo" do
11
+ before :each do
12
+ raise "Can only create one directory per test" if @repository_dir
13
+ @repository_dir = Dir.mktmpdir('chef_repo')
14
+ Chef::Config.chef_repo_path = @repository_dir
15
+ %w(client cookbook data_bag environment node role user).each do |object_name|
16
+ Chef::Config.delete("#{object_name}_path".to_sym)
17
+ end
18
+ end
19
+
20
+ after :each do
21
+ if @repository_dir
22
+ begin
23
+ %w(client cookbook data_bag environment node role user).each do |object_name|
24
+ Chef::Config.delete("#{object_name}_path".to_sym)
25
+ end
26
+ Chef::Config.delete(:chef_repo_path)
27
+ FileUtils.remove_entry_secure(@repository_dir)
28
+ ensure
29
+ @repository_dir = nil
30
+ end
31
+ end
32
+ Dir.chdir(@old_cwd) if @old_cwd
33
+ end
34
+
35
+ def directory(relative_path, &block)
36
+ old_parent_path = @parent_path
37
+ @parent_path = path_to(relative_path)
38
+ FileUtils.mkdir_p(@parent_path)
39
+ instance_eval(&block) if block
40
+ @parent_path = old_parent_path
41
+ end
42
+
43
+ def file(relative_path, contents)
44
+ filename = path_to(relative_path)
45
+ dir = File.dirname(filename)
46
+ FileUtils.mkdir_p(dir) unless dir == '.'
47
+ File.open(filename, 'w') do |file|
48
+ raw = case contents
49
+ when Hash
50
+ JSON.pretty_generate(contents)
51
+ when Array
52
+ contents.join("\n")
53
+ else
54
+ contents
55
+ end
56
+ file.write(raw)
57
+ end
58
+ end
59
+
60
+ def symlink(relative_path, relative_dest)
61
+ filename = path_to(relative_path)
62
+ dir = File.dirname(filename)
63
+ FileUtils.mkdir_p(dir) unless dir == '.'
64
+ dest_filename = path_to(relative_dest)
65
+ File.symlink(dest_filename, filename)
66
+ end
67
+
68
+ def path_to(relative_path)
69
+ File.expand_path(relative_path, (@parent_path || @repository_dir))
70
+ end
71
+
72
+ def cwd(relative_path)
73
+ @old_cwd = Dir.pwd
74
+ Dir.chdir(path_to(relative_path))
75
+ end
76
+
77
+ module WhenTheRepositoryClassMethods
78
+ def directory(*args, &block)
79
+ before :each do
80
+ directory(*args, &block)
81
+ end
82
+ end
83
+
84
+ def file(*args, &block)
85
+ before :each do
86
+ file(*args, &block)
87
+ end
88
+ end
89
+
90
+ def symlink(*args, &block)
91
+ before :each do
92
+ symlink(*args, &block)
93
+ end
94
+ end
95
+
96
+ def path_to(*args, &block)
97
+ before :each do
98
+ file(*args, &block)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,176 @@
1
+ require 'chef_zero/rspec'
2
+ require 'chef/server_api'
3
+ require 'cheffish'
4
+ require 'cheffish/basic_chef_client'
5
+ require 'chef/provider/chef_acl'
6
+ require 'uri'
7
+ require 'support/repository_support'
8
+
9
+ module SpecSupport
10
+ include ChefZero::RSpec
11
+
12
+ def self.extended(klass)
13
+ klass.class_eval do
14
+ extend RepositorySupport
15
+
16
+ def rest
17
+ Chef::ServerAPI.new
18
+ end
19
+
20
+ def get(path, *args)
21
+ if path[0] == '/'
22
+ path = URI.join(rest.url, path)
23
+ end
24
+ rest.get(path, *args)
25
+ end
26
+
27
+ def chef_run
28
+ converge if !@converged
29
+ event_sink.events
30
+ end
31
+
32
+ def event_sink
33
+ @event_sink ||= EventSink.new
34
+ end
35
+
36
+ def basic_chef_client
37
+ @basic_chef_client ||= begin
38
+ Cheffish::BasicChefClient.new(nil, event_sink)
39
+ end
40
+ end
41
+
42
+ def load_recipe(&block)
43
+ basic_chef_client.load_block(&block)
44
+ end
45
+
46
+ def run_recipe(&block)
47
+ load_recipe(&block)
48
+ converge
49
+ end
50
+
51
+ def reset_chef_client
52
+ @event_sink = nil
53
+ @basic_chef_client = nil
54
+ @converged = false
55
+ end
56
+
57
+ def converge
58
+ if @converged
59
+ raise "Already converged! Cannot converge twice, that's bad mojo."
60
+ end
61
+ @converged = true
62
+ basic_chef_client.converge
63
+ end
64
+ end
65
+ end
66
+
67
+ def with_recipe(&block)
68
+ before :each do
69
+ load_recipe(&block)
70
+ end
71
+
72
+ after :each do
73
+ if !@converged
74
+ raise "Never tried to converge!"
75
+ end
76
+ end
77
+ end
78
+
79
+ def with_converge(&block)
80
+ before :each do
81
+ load_recipe(&block) if block_given?
82
+ converge
83
+ end
84
+ end
85
+
86
+ class EventSink
87
+ def initialize
88
+ @events = []
89
+ end
90
+
91
+ attr_reader :events
92
+
93
+ def method_missing(method, *args)
94
+ @events << [ method, *args ]
95
+ end
96
+ end
97
+ end
98
+
99
+ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
100
+ match do |actual|
101
+ actual_actions = actual.select { |event, resource, action| event == :resource_updated && resource.to_s == resource_name }.map { |event, resource, action| action }
102
+ expect(actual_actions).to eq(expected_actions)
103
+ end
104
+ failure_message do |actual|
105
+ updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
106
+ result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
107
+ if updates.size > 0
108
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
109
+ else
110
+ result << " Nothing was updated."
111
+ end
112
+ result
113
+ end
114
+ failure_message_when_negated do |actual|
115
+ updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
116
+ result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
117
+ if updates.size > 0
118
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
119
+ else
120
+ result << " Nothing was updated."
121
+ end
122
+ result
123
+ end
124
+ end
125
+
126
+ RSpec::Matchers.define :update_acls do |acl_paths, expected_acls|
127
+
128
+ errors = []
129
+
130
+ match do |block|
131
+ orig_json = {}
132
+ Array(acl_paths).each do |acl_path|
133
+ orig_json[acl_path] = get(acl_path)
134
+ end
135
+
136
+ block.call
137
+
138
+ orig_json.each_pair do |acl_path, orig|
139
+ changed = get(acl_path)
140
+ expected_acls.each do |permission, hash|
141
+ hash.each do |type, actors|
142
+ actors.each do |actor|
143
+ if actor[0] == '-'
144
+ actor = actor[1..-1]
145
+ errors << "#{acl_path} expected to remove #{type} #{actor} from #{permission} permissions" if changed[permission][type].include?(actor)
146
+ orig[permission][type].delete(actor)
147
+ else
148
+ errors << "#{acl_path} expected to add #{type} #{actor} to #{permission} permissions" if !changed[permission][type].include?(actor)
149
+ changed[permission][type].delete(actor)
150
+ end
151
+ end
152
+ end
153
+ end
154
+ # After checking everything, see if the remaining acl is the same as before
155
+ errors << "#{acl_path} updated more than expected!\nActual:\n#{changed}\nExpected:\n#{orig}" if changed != orig
156
+ end
157
+ errors.size == 0
158
+ end
159
+
160
+ failure_message do |block|
161
+ errors.join("\n")
162
+ end
163
+
164
+ supports_block_expectations
165
+ end
166
+
167
+ RSpec.configure do |config|
168
+ config.filter_run :focus => true
169
+ config.run_all_when_everything_filtered = true
170
+
171
+ config.before :each do
172
+ Chef::Config.reset
173
+ end
174
+ end
175
+
176
+ require 'chef/providers'
@@ -0,0 +1,93 @@
1
+ require 'support/spec_support'
2
+
3
+ describe Cheffish do
4
+ let(:directory_that_exists) {
5
+ Dir.mktmpdir("cheffish-rspec")
6
+ }
7
+
8
+ let(:directory_that_does_not_exist) {
9
+ dir = Dir.mktmpdir("cheffish-rspec")
10
+ FileUtils.remove_entry dir
11
+ dir
12
+ }
13
+
14
+ let(:private_key_contents) { "contents of private key" }
15
+
16
+ let(:private_key_pem_contents) { "contents of private key pem" }
17
+
18
+ let(:private_key_garbage_contents) { "da vinci virus" }
19
+
20
+ def setup_key
21
+ key_file = File.expand_path("ned_stark", directory_that_exists)
22
+ File.open(key_file, "w+") do |f|
23
+ f.write private_key_contents
24
+ end
25
+ end
26
+
27
+ def setup_pem_key
28
+ key_file = File.expand_path("ned_stark.pem", directory_that_exists)
29
+ File.open(key_file, "w+") do |f|
30
+ f.write private_key_pem_contents
31
+ end
32
+ end
33
+
34
+ def setup_garbage_key
35
+ key_file = File.expand_path("ned_stark.pem.bak", directory_that_exists)
36
+ File.open(key_file, "w+") do |f|
37
+ f.write private_key_garbage_contents
38
+ end
39
+ end
40
+
41
+ shared_examples_for "returning the contents of the key file if it finds one" do
42
+ it "returns nil if it cannot find the private key file" do
43
+ expect(Cheffish.get_private_key("ned_stark", config)).to be_nil
44
+ end
45
+
46
+ it "returns the contents of the key if it doesn't have an extension" do
47
+ setup_key
48
+ expect(Cheffish.get_private_key("ned_stark", config)).to eq(private_key_contents)
49
+ end
50
+
51
+ it "returns the contents of the key if it has an extension" do
52
+ setup_pem_key
53
+ expect(Cheffish.get_private_key("ned_stark", config)).to eq(private_key_pem_contents)
54
+ end
55
+
56
+ # we arbitrarily prefer "ned_stark" over "ned_stark.pem" for deterministic behavior
57
+ it "returns the contents of the key that does not have an extension if both exist" do
58
+ setup_key
59
+ setup_pem_key
60
+ expect(Cheffish.get_private_key("ned_stark", config)).to eq(private_key_contents)
61
+ end
62
+ end
63
+
64
+ context "#get_private_key" do
65
+ context "when private_key_paths has a directory which is empty" do
66
+ let(:config) {
67
+ { :private_key_paths => [ directory_that_exists ] }
68
+ }
69
+
70
+ it_behaves_like "returning the contents of the key file if it finds one"
71
+
72
+ context "when it also has a garbage file" do
73
+ before { setup_garbage_key }
74
+
75
+ it "does not return the da vinci virus if we find only the garbage file" do
76
+ setup_garbage_key
77
+ expect(Cheffish.get_private_key("ned_stark", config)).to be_nil
78
+ end
79
+
80
+ it_behaves_like "returning the contents of the key file if it finds one"
81
+ end
82
+
83
+ end
84
+
85
+ context "when private_key_paths leads with a directory that does not exist and then an empty directory" do
86
+ let(:config) {
87
+ { :private_key_paths => [ directory_that_does_not_exist, directory_that_exists ] }
88
+ }
89
+
90
+ it_behaves_like "returning the contents of the key file if it finds one"
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clc-cheffish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.clc
5
+ platform: ruby
6
+ authors:
7
+ - John Keiser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chef
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '11.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '11.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: chef-zero
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: A library to manipulate Chef in Chef.
70
+ email: jkeiser@opscode.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - README.md
75
+ - LICENSE
76
+ files:
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - lib/chef/provider/chef_acl.rb
81
+ - lib/chef/provider/chef_client.rb
82
+ - lib/chef/provider/chef_container.rb
83
+ - lib/chef/provider/chef_data_bag.rb
84
+ - lib/chef/provider/chef_data_bag_item.rb
85
+ - lib/chef/provider/chef_environment.rb
86
+ - lib/chef/provider/chef_group.rb
87
+ - lib/chef/provider/chef_mirror.rb
88
+ - lib/chef/provider/chef_node.rb
89
+ - lib/chef/provider/chef_organization.rb
90
+ - lib/chef/provider/chef_resolved_cookbooks.rb
91
+ - lib/chef/provider/chef_role.rb
92
+ - lib/chef/provider/chef_user.rb
93
+ - lib/chef/provider/private_key.rb
94
+ - lib/chef/provider/public_key.rb
95
+ - lib/chef/resource/chef_acl.rb
96
+ - lib/chef/resource/chef_client.rb
97
+ - lib/chef/resource/chef_container.rb
98
+ - lib/chef/resource/chef_data_bag.rb
99
+ - lib/chef/resource/chef_data_bag_item.rb
100
+ - lib/chef/resource/chef_environment.rb
101
+ - lib/chef/resource/chef_group.rb
102
+ - lib/chef/resource/chef_mirror.rb
103
+ - lib/chef/resource/chef_node.rb
104
+ - lib/chef/resource/chef_organization.rb
105
+ - lib/chef/resource/chef_resolved_cookbooks.rb
106
+ - lib/chef/resource/chef_role.rb
107
+ - lib/chef/resource/chef_user.rb
108
+ - lib/chef/resource/private_key.rb
109
+ - lib/chef/resource/public_key.rb
110
+ - lib/cheffish.rb
111
+ - lib/cheffish/actor_provider_base.rb
112
+ - lib/cheffish/basic_chef_client.rb
113
+ - lib/cheffish/chef_provider_base.rb
114
+ - lib/cheffish/chef_run_data.rb
115
+ - lib/cheffish/chef_run_listener.rb
116
+ - lib/cheffish/key_formatter.rb
117
+ - lib/cheffish/merged_config.rb
118
+ - lib/cheffish/recipe_dsl.rb
119
+ - lib/cheffish/server_api.rb
120
+ - lib/cheffish/version.rb
121
+ - lib/cheffish/with_pattern.rb
122
+ - spec/functional/fingerprint_spec.rb
123
+ - spec/functional/merged_config_spec.rb
124
+ - spec/integration/chef_acl_spec.rb
125
+ - spec/integration/chef_client_spec.rb
126
+ - spec/integration/chef_container_spec.rb
127
+ - spec/integration/chef_group_spec.rb
128
+ - spec/integration/chef_mirror_spec.rb
129
+ - spec/integration/chef_node_spec.rb
130
+ - spec/integration/chef_organization_spec.rb
131
+ - spec/integration/chef_user_spec.rb
132
+ - spec/integration/private_key_spec.rb
133
+ - spec/integration/recipe_dsl_spec.rb
134
+ - spec/support/key_support.rb
135
+ - spec/support/repository_support.rb
136
+ - spec/support/spec_support.rb
137
+ - spec/unit/get_private_key_spec.rb
138
+ homepage: http://wiki.opscode.com/display/chef
139
+ licenses: []
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">"
153
+ - !ruby/object:Gem::Version
154
+ version: 1.3.1
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.2.1
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: A library to manipulate Chef in Chef.
161
+ test_files: []
162
+ has_rdoc: