chef-dk 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/lib/chef-dk/builtin_commands.rb +7 -0
  4. data/lib/chef-dk/command/env.rb +90 -0
  5. data/lib/chef-dk/command/export.rb +22 -1
  6. data/lib/chef-dk/command/generate.rb +1 -1
  7. data/lib/chef-dk/command/provision.rb +43 -0
  8. data/lib/chef-dk/command/push_archive.rb +126 -0
  9. data/lib/chef-dk/command/show_policy.rb +166 -0
  10. data/lib/chef-dk/command/verify.rb +58 -1
  11. data/lib/chef-dk/cookbook_omnifetch.rb +3 -2
  12. data/lib/chef-dk/exceptions.rb +27 -0
  13. data/lib/chef-dk/helpers.rb +29 -0
  14. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +8 -0
  15. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +8 -0
  16. data/lib/chef-dk/policyfile/community_cookbook_source.rb +8 -0
  17. data/lib/chef-dk/policyfile/cookbook_locks.rb +76 -6
  18. data/lib/chef-dk/policyfile/dsl.rb +10 -5
  19. data/lib/chef-dk/policyfile/lister.rb +230 -0
  20. data/lib/chef-dk/policyfile/null_cookbook_source.rb +8 -0
  21. data/lib/chef-dk/policyfile_compiler.rb +35 -2
  22. data/lib/chef-dk/policyfile_lock.rb +43 -0
  23. data/lib/chef-dk/policyfile_services/clean_policies.rb +94 -0
  24. data/lib/chef-dk/policyfile_services/export_repo.rb +103 -16
  25. data/lib/chef-dk/policyfile_services/push_archive.rb +173 -0
  26. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -0
  27. data/lib/chef-dk/service_exceptions.rb +21 -0
  28. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +1 -0
  29. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +2 -40
  30. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +0 -2
  31. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +2 -2
  32. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +1 -1
  33. data/lib/chef-dk/version.rb +1 -1
  34. data/spec/unit/command/env_spec.rb +52 -0
  35. data/spec/unit/command/exec_spec.rb +2 -2
  36. data/spec/unit/command/export_spec.rb +13 -0
  37. data/spec/unit/command/provision_spec.rb +56 -0
  38. data/spec/unit/command/push_archive_spec.rb +153 -0
  39. data/spec/unit/command/show_policy_spec.rb +235 -0
  40. data/spec/unit/command/verify_spec.rb +1 -0
  41. data/spec/unit/helpers_spec.rb +68 -0
  42. data/spec/unit/policyfile/cookbook_locks_spec.rb +107 -1
  43. data/spec/unit/policyfile/lister_spec.rb +256 -0
  44. data/spec/unit/policyfile_demands_spec.rb +202 -10
  45. data/spec/unit/policyfile_evaluation_spec.rb +30 -4
  46. data/spec/unit/policyfile_lock_serialization_spec.rb +45 -0
  47. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -0
  48. data/spec/unit/policyfile_services/export_repo_spec.rb +99 -6
  49. data/spec/unit/policyfile_services/push_archive_spec.rb +345 -0
  50. data/spec/unit/policyfile_services/show_policy_spec.rb +839 -0
  51. metadata +139 -8
@@ -59,6 +59,19 @@ describe ChefDK::Command::Export do
59
59
  end
60
60
  end
61
61
 
62
+ context "when archive mode is set" do
63
+
64
+ let(:params) { [ "path/to/export", "-a" ] }
65
+
66
+ it "enables archiving the exported repo" do
67
+ expect(command.archive?).to be(true)
68
+ end
69
+
70
+ it "configures the export service to archive" do
71
+ expect(command.export_service.archive?).to be(true)
72
+ end
73
+ end
74
+
62
75
  context "when the path to the exported repo is given" do
63
76
 
64
77
  let(:params) { [ "path/to/export" ] }
@@ -195,6 +195,62 @@ describe ChefDK::Command::Provision do
195
195
 
196
196
  end
197
197
 
198
+ context "with --target" do
199
+
200
+ let(:extra_params) { %w[ -t 192.168.255.123 ] }
201
+
202
+ it "sets the target host to the given value" do
203
+ expect(context.target).to eq("192.168.255.123")
204
+ end
205
+
206
+ end
207
+
208
+ context "with --opt" do
209
+ context "with one user-specified option" do
210
+ let(:extra_params) { %w[ --opt color=ebfg ] }
211
+
212
+ it "sets the given option name to the given value" do
213
+ expect(context.opts.color).to eq("ebfg")
214
+ end
215
+ end
216
+
217
+ context "with an option given as a quoted arg with spaces" do
218
+
219
+ let(:extra_params) { [ '--opt', 'color = ebfg' ] }
220
+
221
+ it "sets the given option name to the given value" do
222
+ expect(context.opts.color).to eq("ebfg")
223
+ end
224
+ end
225
+
226
+ context "with an option with an '=' in it" do
227
+
228
+ let(:extra_params) { [ '--opt', 'api_key=abcdef==' ] }
229
+
230
+ it "sets the given option name to the given value" do
231
+ expect(context.opts.api_key).to eq("abcdef==")
232
+ end
233
+ end
234
+
235
+ context "with an option with a space in it" do
236
+
237
+ let(:extra_params) { [ '--opt', 'full_name=Bobo T. Clown' ] }
238
+
239
+ it "sets the given option name to the given value" do
240
+ expect(context.opts.full_name).to eq("Bobo T. Clown")
241
+ end
242
+ end
243
+
244
+ context "with multiple options given" do
245
+ let(:extra_params) { %w[ --opt color=ebfg --opt nope=seppb ] }
246
+
247
+ it "sets the given option name to the given value" do
248
+ expect(context.opts.color).to eq("ebfg")
249
+ expect(context.opts.nope).to eq("seppb")
250
+ end
251
+ end
252
+ end
253
+
198
254
  context "with -d" do
199
255
 
200
256
  let(:extra_params) { %w[ -d ] }
@@ -0,0 +1,153 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+ require 'shared/command_with_ui_object'
20
+ require 'chef-dk/command/push_archive'
21
+
22
+ describe ChefDK::Command::PushArchive do
23
+
24
+ subject(:command) { described_class.new }
25
+
26
+ let(:policy_group) { "staging" }
27
+
28
+ let(:archive_path) { "mypolicy-abc123.tgz" }
29
+
30
+ it_behaves_like "a command with a UI object"
31
+
32
+ let(:ui) { TestHelpers::TestUI.new }
33
+
34
+ let(:chef_config_loader) { instance_double("Chef::WorkstationConfigLoader") }
35
+
36
+ let(:config_arg) { nil }
37
+
38
+ before do
39
+ allow(Chef::WorkstationConfigLoader).to receive(:new).with(config_arg).and_return(chef_config_loader)
40
+ end
41
+
42
+ describe "evaluating params" do
43
+
44
+ before do
45
+ command.ui = ui
46
+ end
47
+
48
+ context "when given no arguments" do
49
+
50
+ it "prints the banner message and exits non-zero" do
51
+ expect(command.run([])).to eq(1)
52
+ expect(ui.output).to include(described_class.banner)
53
+ end
54
+
55
+ end
56
+
57
+ context "when the archive path is omitted" do
58
+
59
+ it "prints the banner message and exits non-zero" do
60
+ expect(command.run([policy_group])).to eq(1)
61
+ expect(ui.output).to include(described_class.banner)
62
+ end
63
+
64
+ end
65
+
66
+ context "when all required arguments are given" do
67
+
68
+ let(:params) { [ policy_group, archive_path ] }
69
+
70
+ before do
71
+ command.apply_params!(params)
72
+ end
73
+
74
+ it "disables debug by default" do
75
+ expect(command.debug?).to be(false)
76
+ end
77
+
78
+ context "and debug mode is set" do
79
+
80
+ let(:params) { [ policy_group, archive_path, "-D" ] }
81
+
82
+ it "enables debug messages" do
83
+ expect(command.debug?).to be(true)
84
+ end
85
+
86
+ end
87
+
88
+ describe "configuring settings that depend on the chef config file" do
89
+
90
+ before do
91
+ expect(chef_config_loader).to receive(:load)
92
+ end
93
+
94
+ it "sets the policy group" do
95
+ expect(command.policy_group).to eq(policy_group)
96
+ expect(command.push_archive_service.policy_group).to eq(policy_group)
97
+ end
98
+
99
+ it "sets the path to the archive file" do
100
+ expect(command.archive_path).to eq(archive_path)
101
+ expect(command.push_archive_service.archive_file).to eq(File.expand_path(archive_path))
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ end
108
+
109
+ describe "running the push operation" do
110
+
111
+ let(:push_archive_service) { instance_double("ChefDK::PolicyfileServices::PushArchive") }
112
+
113
+ let(:params) { [ policy_group, archive_path ] }
114
+
115
+ before do
116
+ allow(command).to receive(:push_archive_service).and_return(push_archive_service)
117
+ command.ui = ui
118
+ end
119
+
120
+ context "when the push is successful" do
121
+
122
+ it "exits 0" do
123
+ expect(push_archive_service).to receive(:run)
124
+ expect(command.run(params)).to eq(0)
125
+ end
126
+
127
+ end
128
+
129
+ context "when the push in not successful" do
130
+
131
+ let(:backtrace) { caller[0...3] }
132
+
133
+ let(:cause) do
134
+ e = StandardError.new("some operation failed")
135
+ e.set_backtrace(backtrace)
136
+ e
137
+ end
138
+
139
+ let(:exception) do
140
+ ChefDK::PolicyfilePushArchiveError.new("push failed", cause)
141
+ end
142
+
143
+ before do
144
+ expect(push_archive_service).to receive(:run).and_raise(exception)
145
+ end
146
+
147
+ it "exits non-zero" do
148
+ expect(command.run(params)).to eq(1)
149
+ end
150
+
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,235 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+ require 'shared/command_with_ui_object'
20
+ require 'chef-dk/command/show_policy'
21
+
22
+ describe ChefDK::Command::ShowPolicy do
23
+
24
+ it_behaves_like "a command with a UI object"
25
+
26
+ subject(:command) do
27
+ described_class.new
28
+ end
29
+
30
+ let(:show_policy_service) { command.show_policy_service }
31
+
32
+ let(:chef_config_loader) { instance_double("Chef::WorkstationConfigLoader") }
33
+
34
+ let(:chef_config) { double("Chef::Config") }
35
+
36
+ # nil means the config loader will do the default path lookup
37
+ let(:config_arg) { nil }
38
+
39
+ before do
40
+ stub_const("Chef::Config", chef_config)
41
+ allow(Chef::WorkstationConfigLoader).to receive(:new).with(config_arg).and_return(chef_config_loader)
42
+ end
43
+
44
+ describe "parsing args and options" do
45
+ let(:params) { [] }
46
+
47
+ before do
48
+ command.apply_params!(params)
49
+ end
50
+
51
+ context "when given a path to the config" do
52
+
53
+ let(:params) { %w[ -c ~/otherstuff/config.rb ] }
54
+
55
+ let(:config_arg) { "~/otherstuff/config.rb" }
56
+
57
+ before do
58
+ expect(chef_config_loader).to receive(:load)
59
+ end
60
+
61
+ it "reads the chef/knife config" do
62
+ expect(Chef::WorkstationConfigLoader).to receive(:new).with(config_arg).and_return(chef_config_loader)
63
+ expect(command.chef_config).to eq(chef_config)
64
+ expect(show_policy_service.chef_config).to eq(chef_config)
65
+ end
66
+
67
+ end
68
+
69
+ describe "settings that require loading chef config" do
70
+
71
+ before do
72
+ allow(chef_config_loader).to receive(:load)
73
+ end
74
+
75
+ context "with no params" do
76
+
77
+ it "disables debug by default" do
78
+ expect(command.debug?).to be(false)
79
+ end
80
+
81
+ it "is configured to show all policies across all groups" do
82
+ expect(show_policy_service.show_all_policies?).to be(true)
83
+ end
84
+
85
+ it "disables displaying orphans" do
86
+ expect(command.show_orphans?).to be(false)
87
+ expect(show_policy_service.show_orphans?).to be(false)
88
+ end
89
+
90
+ end
91
+
92
+ context "when debug mode is set" do
93
+
94
+ let(:params) { [ "-D" ] }
95
+
96
+ it "enables debug" do
97
+ expect(command.debug?).to be(true)
98
+ end
99
+
100
+ end
101
+
102
+ context "when --show-orphans is given" do
103
+
104
+ let(:params) { %w[ -o ] }
105
+
106
+ it "enables displaying orphans" do
107
+ expect(command.show_orphans?).to be(true)
108
+ expect(show_policy_service.show_orphans?).to be(true)
109
+ end
110
+
111
+ end
112
+
113
+ context "when given a policy name" do
114
+
115
+ let(:params) { %w[ appserver ] }
116
+
117
+ it "is not configured to show all policies" do
118
+ expect(show_policy_service.show_all_policies?).to be(false)
119
+ end
120
+
121
+ it "is configured to show the given policy" do
122
+ expect(command.policy_name).to eq("appserver")
123
+ expect(show_policy_service.policy_name).to eq("appserver")
124
+ end
125
+
126
+ end
127
+
128
+ context "when given a policy name and a policy group name" do
129
+
130
+ let(:params) { %w[ appserver production ] }
131
+
132
+ it "is not configured to show all policies" do
133
+ expect(show_policy_service.show_all_policies?).to be(false)
134
+ end
135
+
136
+ it "is configured to show the given policy" do
137
+ expect(command.policy_name).to eq("appserver")
138
+ expect(show_policy_service.policy_name).to eq("appserver")
139
+ end
140
+
141
+ it "is configured to display the exact revision for the given policy+group" do
142
+ expect(command.policy_group).to eq("production")
143
+ expect(show_policy_service.policy_group).to eq("production")
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+ end
150
+
151
+ describe "running the command" do
152
+
153
+ let(:ui) { TestHelpers::TestUI.new }
154
+
155
+ before do
156
+ allow(chef_config_loader).to receive(:load)
157
+ command.ui = ui
158
+ end
159
+
160
+ context "when given too many arguments" do
161
+
162
+ let(:params) { %w[ appserver policygroup wut-is-this ] }
163
+
164
+ it "shows usage and exits" do
165
+ expect(command.run(params)).to eq(1)
166
+ end
167
+
168
+ end
169
+
170
+ context "when the list service raises an exception" do
171
+
172
+ let(:backtrace) { caller[0...3] }
173
+
174
+ let(:cause) do
175
+ e = StandardError.new("some operation failed")
176
+ e.set_backtrace(backtrace)
177
+ e
178
+ end
179
+
180
+ let(:exception) do
181
+ ChefDK::PolicyfileListError.new("Failed to list policies", cause)
182
+ end
183
+
184
+ before do
185
+ allow(command.show_policy_service).to receive(:run).and_raise(exception)
186
+ end
187
+
188
+ it "prints a debugging message and exits non-zero" do
189
+ expect(command.run([])).to eq(1)
190
+
191
+ expected_output=<<-E
192
+ Error: Failed to list policies
193
+ Reason: (StandardError) some operation failed
194
+
195
+ E
196
+
197
+ expect(ui.output).to eq(expected_output)
198
+ end
199
+
200
+ context "when debug is enabled" do
201
+
202
+ it "includes the backtrace in the error" do
203
+
204
+ command.run(%w[ -D ])
205
+
206
+ expected_output=<<-E
207
+ Error: Failed to list policies
208
+ Reason: (StandardError) some operation failed
209
+
210
+
211
+ E
212
+ expected_output << backtrace.join("\n") << "\n"
213
+
214
+ expect(ui.output).to eq(expected_output)
215
+ end
216
+
217
+ end
218
+
219
+ end
220
+
221
+ context "when the list service executes successfully" do
222
+
223
+ before do
224
+ expect(command.show_policy_service).to receive(:run)
225
+ end
226
+
227
+ it "exits 0" do
228
+ expect(command.run([])).to eq(0)
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+ end
235
+