r10k 3.7.0 → 3.9.3

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/pull_request_template.md +1 -1
  3. data/.github/workflows/docker.yml +4 -1
  4. data/.github/workflows/release.yml +3 -2
  5. data/.github/workflows/rspec_tests.yml +1 -1
  6. data/.github/workflows/stale.yml +19 -0
  7. data/.travis.yml +8 -1
  8. data/CHANGELOG.mkd +32 -0
  9. data/CODEOWNERS +2 -2
  10. data/doc/common-patterns.mkd +1 -0
  11. data/doc/dynamic-environments/configuration.mkd +114 -42
  12. data/doc/dynamic-environments/usage.mkd +12 -11
  13. data/doc/puppetfile.mkd +23 -3
  14. data/docker/Gemfile +1 -1
  15. data/docker/Makefile +4 -3
  16. data/docker/docker-compose.yml +18 -0
  17. data/docker/r10k/Dockerfile +1 -1
  18. data/docker/r10k/docker-entrypoint.sh +0 -1
  19. data/docker/r10k/release.Dockerfile +1 -1
  20. data/docker/spec/dockerfile_spec.rb +26 -32
  21. data/integration/tests/git_source/git_source_repeated_remote.rb +2 -2
  22. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module.rb +2 -1
  23. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb +2 -1
  24. data/integration/tests/user_scenario/basic_workflow/multi_source_custom_forge_git_module.rb +1 -1
  25. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_git_module.rb +2 -1
  26. data/lib/r10k/action/base.rb +10 -0
  27. data/lib/r10k/action/deploy/display.rb +49 -10
  28. data/lib/r10k/action/deploy/environment.rb +101 -51
  29. data/lib/r10k/action/deploy/module.rb +54 -30
  30. data/lib/r10k/action/puppetfile/check.rb +3 -1
  31. data/lib/r10k/action/puppetfile/install.rb +20 -23
  32. data/lib/r10k/action/puppetfile/purge.rb +8 -2
  33. data/lib/r10k/action/runner.rb +33 -0
  34. data/lib/r10k/cli/deploy.rb +13 -7
  35. data/lib/r10k/cli/puppetfile.rb +5 -5
  36. data/lib/r10k/content_synchronizer.rb +83 -0
  37. data/lib/r10k/deployment.rb +1 -1
  38. data/lib/r10k/environment/base.rb +29 -2
  39. data/lib/r10k/environment/git.rb +17 -5
  40. data/lib/r10k/environment/name.rb +22 -4
  41. data/lib/r10k/environment/svn.rb +11 -4
  42. data/lib/r10k/environment/with_modules.rb +46 -30
  43. data/lib/r10k/git.rb +1 -0
  44. data/lib/r10k/git/rugged/credentials.rb +39 -2
  45. data/lib/r10k/initializers.rb +1 -0
  46. data/lib/r10k/module.rb +1 -1
  47. data/lib/r10k/module/base.rb +17 -1
  48. data/lib/r10k/module/forge.rb +29 -11
  49. data/lib/r10k/module/git.rb +50 -27
  50. data/lib/r10k/module/local.rb +2 -1
  51. data/lib/r10k/module/svn.rb +24 -18
  52. data/lib/r10k/puppetfile.rb +66 -83
  53. data/lib/r10k/settings.rb +18 -2
  54. data/lib/r10k/source/base.rb +9 -0
  55. data/lib/r10k/source/git.rb +18 -7
  56. data/lib/r10k/source/hash.rb +5 -5
  57. data/lib/r10k/source/svn.rb +5 -3
  58. data/lib/r10k/util/cleaner.rb +21 -0
  59. data/lib/r10k/util/setopts.rb +33 -12
  60. data/lib/r10k/version.rb +1 -1
  61. data/locales/r10k.pot +98 -82
  62. data/r10k.gemspec +1 -1
  63. data/spec/fixtures/unit/action/r10k_creds.yaml +9 -0
  64. data/spec/r10k-mocks/mock_source.rb +1 -1
  65. data/spec/shared-examples/puppetfile-action.rb +7 -7
  66. data/spec/unit/action/deploy/display_spec.rb +35 -5
  67. data/spec/unit/action/deploy/environment_spec.rb +199 -38
  68. data/spec/unit/action/deploy/module_spec.rb +162 -28
  69. data/spec/unit/action/puppetfile/check_spec.rb +2 -2
  70. data/spec/unit/action/puppetfile/install_spec.rb +31 -10
  71. data/spec/unit/action/puppetfile/purge_spec.rb +25 -5
  72. data/spec/unit/action/runner_spec.rb +48 -1
  73. data/spec/unit/environment/git_spec.rb +19 -2
  74. data/spec/unit/environment/name_spec.rb +28 -0
  75. data/spec/unit/environment/svn_spec.rb +12 -0
  76. data/spec/unit/environment/with_modules_spec.rb +74 -0
  77. data/spec/unit/git/rugged/credentials_spec.rb +78 -1
  78. data/spec/unit/module/forge_spec.rb +21 -13
  79. data/spec/unit/module/git_spec.rb +63 -8
  80. data/spec/unit/module_spec.rb +77 -10
  81. data/spec/unit/puppetfile_spec.rb +63 -60
  82. data/spec/unit/util/purgeable_spec.rb +2 -8
  83. data/spec/unit/util/setopts_spec.rb +25 -1
  84. metadata +11 -12
  85. data/azure-pipelines.yml +0 -87
data/r10k.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.license = 'Apache-2.0'
24
24
 
25
25
  s.add_dependency 'colored2', '3.1.2'
26
- s.add_dependency 'cri', ['>= 2.15.10', '< 3.0.0']
26
+ s.add_dependency 'cri', '2.15.10'
27
27
 
28
28
  s.add_dependency 'log4r', '1.1.10'
29
29
  s.add_dependency 'multi_json', '~> 1.10'
@@ -0,0 +1,9 @@
1
+ ---
2
+ git:
3
+ private_key: '/global/config/private/key'
4
+ oauth_token: '/global/config/oauth/token'
5
+ repositories:
6
+ - remote: 'git@myfakegitserver.com:user/repo.git'
7
+ private_key: '/config/private/key'
8
+ - remote: 'https://myfakegitserver.com/user/repo.git'
9
+ oauth_token: '/config/oauth/token'
@@ -8,6 +8,6 @@ class R10K::Source::Mock < R10K::Source::Base
8
8
  corrected_environment_names = @options[:environments].map do |env|
9
9
  R10K::Environment::Name.new(env, :prefix => @prefix, :invalid => 'correct_and_warn')
10
10
  end
11
- corrected_environment_names.map { |env| R10K::Environment::Mock.new(env.name, @basedir, env.dirname) }
11
+ corrected_environment_names.map { |env| R10K::Environment::Mock.new(env.name, @basedir, env.dirname, { overrides: @options[:overrides] }) }
12
12
  end
13
13
  end
@@ -3,15 +3,15 @@ require 'spec_helper'
3
3
  shared_examples_for "a puppetfile action" do
4
4
  describe "initializing" do
5
5
  it "accepts the :root option" do
6
- described_class.new({root: "/some/nonexistent/path"}, [])
6
+ described_class.new({root: "/some/nonexistent/path"}, [], {})
7
7
  end
8
8
 
9
9
  it "accepts the :puppetfile option" do
10
- described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [])
10
+ described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [], {})
11
11
  end
12
12
 
13
13
  it "accepts the :moduledir option" do
14
- described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
14
+ described_class.new({moduledir: "/some/nonexistent/path/modules"}, [], {})
15
15
  end
16
16
 
17
17
  end
@@ -20,19 +20,19 @@ end
20
20
  shared_examples_for "a puppetfile install action" do
21
21
  describe "initializing" do
22
22
  it "accepts the :root option" do
23
- described_class.new({root: "/some/nonexistent/path"}, [])
23
+ described_class.new({root: "/some/nonexistent/path"}, [], {})
24
24
  end
25
25
 
26
26
  it "accepts the :puppetfile option" do
27
- described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [])
27
+ described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [], {})
28
28
  end
29
29
 
30
30
  it "accepts the :moduledir option" do
31
- described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
31
+ described_class.new({moduledir: "/some/nonexistent/path/modules"}, [], {})
32
32
  end
33
33
 
34
34
  it "accepts the :force option" do
35
- described_class.new({force: true}, [])
35
+ described_class.new({force: true}, [], {})
36
36
  end
37
37
 
38
38
  end
@@ -5,27 +5,57 @@ require 'r10k/action/deploy/display'
5
5
  describe R10K::Action::Deploy::Display do
6
6
  describe "initializing" do
7
7
  it "accepts a puppetfile option" do
8
- described_class.new({puppetfile: true}, [])
8
+ described_class.new({puppetfile: true}, [], {})
9
+ end
10
+
11
+ it "accepts a modules option" do
12
+ described_class.new({modules: true}, [], {})
9
13
  end
10
14
 
11
15
  it "accepts a detail option" do
12
- described_class.new({detail: true}, [])
16
+ described_class.new({detail: true}, [], {})
13
17
  end
14
18
 
15
19
  it "accepts a format option" do
16
- described_class.new({format: "json"}, [])
20
+ described_class.new({format: "json"}, [], {})
17
21
  end
18
22
 
19
23
  it "accepts a fetch option" do
20
- described_class.new({fetch: true}, [])
24
+ described_class.new({fetch: true}, [], {})
21
25
  end
22
26
  end
23
27
 
24
- subject { described_class.new({config: "/some/nonexistent/path"}, []) }
28
+ subject { described_class.new({config: "/some/nonexistent/path"}, [], {}) }
25
29
 
26
30
  before do
27
31
  allow(subject).to receive(:puts)
28
32
  end
29
33
 
30
34
  it_behaves_like "a deploy action that requires a config file"
35
+
36
+ describe "collecting info" do
37
+ subject { described_class.new({config: "/some/nonexistent/path", format: 'json', puppetfile: true, detail: true}, ['first'], {}) }
38
+
39
+ let(:mock_config) do
40
+ R10K::Deployment::MockConfig.new(
41
+ :sources => {
42
+ :control => {
43
+ :type => :mock,
44
+ :basedir => '/some/nonexistent/path/control',
45
+ :environments => %w[first second third env-that/will-be-corrected],
46
+ :prefix => 'PREFIX'
47
+ }
48
+ }
49
+ )
50
+ end
51
+
52
+ let(:deployment) { R10K::Deployment.new(mock_config) }
53
+
54
+ it "gathers environment info" do
55
+ source_info = subject.send(:source_info, deployment.sources.first, ['first'])
56
+ expect(source_info[:name]).to eq(:control)
57
+ expect(source_info[:environments].length).to eq(1)
58
+ expect(source_info[:environments][0][:name]).to eq('first')
59
+ end
60
+ end
31
61
  end
@@ -5,37 +5,58 @@ require 'r10k/action/deploy/environment'
5
5
 
6
6
  describe R10K::Action::Deploy::Environment do
7
7
 
8
- subject { described_class.new({config: "/some/nonexistent/path"}, []) }
8
+ subject { described_class.new({config: "/some/nonexistent/path"}, [], {}) }
9
9
 
10
10
  it_behaves_like "a deploy action that can be write locked"
11
11
  it_behaves_like "a deploy action that requires a config file"
12
12
 
13
13
  describe "initializing" do
14
14
  it "can accept a cachedir option" do
15
- described_class.new({cachedir: "/some/nonexistent/cachedir"}, [])
15
+ described_class.new({cachedir: "/some/nonexistent/cachedir"}, [], {})
16
16
  end
17
17
 
18
18
  it "can accept a puppetfile option" do
19
- described_class.new({puppetfile: true}, [])
19
+ described_class.new({puppetfile: true}, [], {})
20
+ end
21
+
22
+ it "can accept a modules option" do
23
+ described_class.new({modules: true}, [], {})
20
24
  end
21
25
 
22
26
  it "can accept a default_branch_override option" do
23
- described_class.new({:'default-branch-override' => 'default_branch_override_name'}, [])
27
+ described_class.new({:'default-branch-override' => 'default_branch_override_name'}, [], {})
24
28
  end
25
29
 
26
30
  it "can accept a no-force option" do
27
- described_class.new({:'no-force' => true}, [])
31
+ described_class.new({:'no-force' => true}, [], {})
28
32
  end
29
33
 
30
- it "normalizes environment names in the arg vector"
31
-
32
34
  it 'can accept a generate-types option' do
33
- described_class.new({ 'generate-types': true }, [])
35
+ described_class.new({ 'generate-types': true }, [], {})
34
36
  end
35
37
 
36
38
  it 'can accept a puppet-path option' do
37
- described_class.new({ 'puppet-path': '/nonexistent' }, [])
39
+ described_class.new({ 'puppet-path': '/nonexistent' }, [], {})
40
+ end
41
+
42
+ it 'can accept a private-key option' do
43
+ described_class.new({ 'private-key': '/nonexistent' }, [], {})
44
+ end
45
+
46
+ it 'can accept a token option' do
47
+ described_class.new({ 'oauth-token': '/nonexistent' }, [], {})
48
+ end
49
+
50
+ describe "initializing errors" do
51
+ let (:settings) { { deploy: { purge_levels: [:environment],
52
+ purge_whitelist: ['coolfile', 'coolfile2'],
53
+ purge_allowlist: ['anothercoolfile']}}}
54
+
55
+ subject { described_class.new({config: "/some/nonexistent/path"}, [], settings)}
56
+ it 'errors out when both purge_whitelist and purge_allowlist are set' do
57
+ expect{subject}.to raise_error(R10K::Error, /Values found for both purge_whitelist and purge_allowlist./)
38
58
  end
59
+ end
39
60
  end
40
61
 
41
62
  describe "when called" do
@@ -52,6 +73,29 @@ describe R10K::Action::Deploy::Environment do
52
73
  )
53
74
  end
54
75
 
76
+ describe "with puppetfile or modules flag" do
77
+ let(:deployment) { R10K::Deployment.new(mock_config) }
78
+ let(:puppetfile) { instance_double("R10K::Puppetfile", modules: []).as_null_object }
79
+
80
+ before do
81
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
82
+ expect(R10K::Puppetfile).to receive(:new).and_return(puppetfile).at_least(:once)
83
+ end
84
+
85
+ it "syncs the puppetfile when given the puppetfile flag" do
86
+ expect(puppetfile).to receive(:sync)
87
+ action = described_class.new({config: "/some/nonexistent/path", puppetfile: true}, [], {})
88
+ action.call
89
+ end
90
+
91
+ it "syncs the puppetfile when given the modules flag" do
92
+ expect(puppetfile).to receive(:sync)
93
+ action = described_class.new({config: "/some/nonexistent/path", modules: true}, [], {})
94
+ action.call
95
+ end
96
+
97
+ end
98
+
55
99
  describe "with an environment that doesn't exist" do
56
100
  let(:deployment) do
57
101
  R10K::Deployment.new(mock_config)
@@ -61,7 +105,7 @@ describe R10K::Action::Deploy::Environment do
61
105
  expect(R10K::Deployment).to receive(:new).and_return(deployment)
62
106
  end
63
107
 
64
- subject { described_class.new({config: "/some/nonexistent/path"}, %w[not_an_environment]) }
108
+ subject { described_class.new({config: "/some/nonexistent/path"}, %w[not_an_environment], {}) }
65
109
 
66
110
  it "logs that the environments can't be deployed and returns false" do
67
111
  expect(subject.logger).to receive(:error).with("Environment(s) 'not_an_environment' cannot be found in any source and will not be deployed.")
@@ -71,10 +115,10 @@ describe R10K::Action::Deploy::Environment do
71
115
  end
72
116
 
73
117
  describe "with no-force" do
74
- subject { described_class.new({ config: "/some/nonexistent/path", puppetfile: true, :'no-force' => true}, %w[first]) }
118
+ subject { described_class.new({ config: "/some/nonexistent/path", modules: true, :'no-force' => true}, %w[first], {}) }
75
119
 
76
120
  it "tries to preserve local modifications" do
77
- expect(subject.force).to equal(false)
121
+ expect(subject.settings[:overrides][:modules][:force]).to equal(false)
78
122
  end
79
123
  end
80
124
 
@@ -162,26 +206,73 @@ describe R10K::Action::Deploy::Environment do
162
206
  end
163
207
  end
164
208
 
209
+ describe "Purging white/allowlist" do
210
+
211
+ let(:settings) { { deploy: { purge_levels: [:environment], purge_allowlist: ['coolfile', 'coolfile2'] } } }
212
+ let(:overrides) { { environments: {}, modules: {}, purging: { purge_levels: [:environment], purge_allowlist: ['coolfile', 'coolfile2'] } } }
213
+ let(:deployment) do
214
+ R10K::Deployment.new(mock_config.merge(overrides))
215
+ end
216
+ before do
217
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
218
+ end
219
+
220
+ subject { described_class.new({ config: "/some/nonexistent/path", modules: true }, %w[PREFIX_first], settings) }
221
+
222
+ it "reads in the purge_allowlist setting and purges accordingly" do
223
+ expect(subject.logger).to receive(:debug).with(/purging unmanaged content for environment/i)
224
+ expect(subject.settings[:overrides][:purging][:purge_allowlist]).to eq(['coolfile', 'coolfile2'])
225
+ subject.call
226
+ end
227
+
228
+ describe "purge_whitelist" do
229
+ let (:settings) { { deploy: { purge_levels: [:environment], purge_whitelist: ['coolfile', 'coolfile2'] } } }
230
+
231
+ it "reads in the purge_whitelist setting and still sets it to purge_allowlist and purges accordingly" do
232
+ expect(subject.logger).to receive(:debug).with(/purging unmanaged content for environment/i)
233
+ expect(subject.settings[:overrides][:purging][:purge_allowlist]).to eq(['coolfile', 'coolfile2'])
234
+ subject.call
235
+ end
236
+ end
237
+ end
238
+
165
239
  describe "purge_levels" do
166
240
  let(:settings) { { deploy: { purge_levels: purge_levels } } }
241
+ let(:overrides) do
242
+ {
243
+ environments: {
244
+ requested_environments: ['PREFIX_first']
245
+ },
246
+ modules: {
247
+ deploy_modules: true
248
+ },
249
+ purging: {
250
+ purge_levels: purge_levels
251
+ }
252
+ }
253
+ end
167
254
 
168
255
  let(:deployment) do
169
- R10K::Deployment.new(mock_config.merge(settings))
256
+ R10K::Deployment.new(mock_config.merge({ overrides: overrides }))
170
257
  end
171
258
 
172
259
  before do
173
260
  expect(R10K::Deployment).to receive(:new).and_return(deployment)
174
261
  end
175
262
 
176
- subject { described_class.new({ config: "/some/nonexistent/path", puppetfile: true }, %w[PREFIX_first], settings) }
263
+ subject { described_class.new({ config: "/some/nonexistent/path", modules: true }, %w[PREFIX_first], settings) }
177
264
 
178
265
  describe "deployment purge level" do
179
266
  let(:purge_levels) { [:deployment] }
180
267
 
181
268
  it "only logs about purging deployment" do
269
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, env, &block|
270
+ expect(env.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
271
+ original.call(env)
272
+ end.at_least(:once)
273
+
182
274
  expect(subject.logger).to receive(:debug).with(/purging unmanaged environments for deployment/i)
183
275
  expect(subject.logger).to_not receive(:debug).with(/purging unmanaged content for environment/i)
184
- expect(subject.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
185
276
 
186
277
  subject.call
187
278
  end
@@ -191,15 +282,23 @@ describe R10K::Action::Deploy::Environment do
191
282
  let(:purge_levels) { [:environment] }
192
283
 
193
284
  it "only logs about purging environment" do
285
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, env, &block|
286
+ expect(env.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
287
+ original.call(env)
288
+ end.at_least(:once)
194
289
  expect(subject.logger).to receive(:debug).with(/purging unmanaged content for environment/i)
195
290
  expect(subject.logger).to_not receive(:debug).with(/purging unmanaged environments for deployment/i)
196
- expect(subject.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
197
291
 
198
292
  subject.call
199
293
  end
200
294
 
201
295
  it "logs that environment was not purged if deploy failed" do
202
- expect(subject).to receive(:visit_puppetfile) { subject.instance_variable_set(:@visit_ok, false) }
296
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, env, &block|
297
+ if env.name =~ /first/
298
+ expect(env).to receive(:deploy) { subject.instance_variable_set(:@visit_ok, false) }
299
+ end
300
+ original.call(env)
301
+ end.at_least(:once)
203
302
 
204
303
  expect(subject.logger).to receive(:debug).with(/not purging unmanaged content for environment/i)
205
304
 
@@ -211,7 +310,13 @@ describe R10K::Action::Deploy::Environment do
211
310
  let(:purge_levels) { [:puppetfile] }
212
311
 
213
312
  it "only logs about purging puppetfile" do
214
- expect(subject.logger).to receive(:debug).with(/purging unmanaged puppetfile content/i)
313
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, env, &block|
314
+ if env.name =~ /first/
315
+ expect(env.logger).to receive(:debug).with(/purging unmanaged puppetfile content/i)
316
+ end
317
+ original.call(env)
318
+ end.at_least(:once)
319
+
215
320
  expect(subject.logger).to_not receive(:debug).with(/purging unmanaged environments for deployment/i)
216
321
  expect(subject.logger).to_not receive(:debug).with(/purging unmanaged content for environment/i)
217
322
 
@@ -219,6 +324,7 @@ describe R10K::Action::Deploy::Environment do
219
324
  end
220
325
  end
221
326
  end
327
+
222
328
  describe "generate-types" do
223
329
  let(:deployment) do
224
330
  R10K::Deployment.new(
@@ -248,19 +354,22 @@ describe R10K::Action::Deploy::Environment do
248
354
  described_class.new(
249
355
  {
250
356
  config: '/some/nonexistent/path',
251
- puppetfile: true,
357
+ modules: true,
252
358
  'generate-types': true
253
359
  },
254
- %w[first second]
360
+ %w[first second],
361
+ {}
255
362
  )
256
363
  end
257
364
 
258
365
  it 'generate_types is true' do
259
- expect(subject.instance_variable_get(:@generate_types)).to eq(true)
366
+ expect(subject.settings[:overrides][:environments][:generate_types]).to eq(true)
260
367
  end
261
368
 
262
369
  it 'only calls puppet generate types on specified environment' do
263
- subject.instance_variable_set(:@argv, %w[first])
370
+ settings = subject.instance_variable_get(:@settings)
371
+ settings[:overrides][:environments][:requested_environments] = %w{first}
372
+ subject.instance_variable_set(:@settings, settings)
264
373
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
265
374
  if environment.dirname == 'first'
266
375
  expect(environment).to receive(:generate_types!)
@@ -273,8 +382,8 @@ describe R10K::Action::Deploy::Environment do
273
382
  end
274
383
 
275
384
  it 'does not call puppet generate types on puppetfile failure' do
276
- allow(subject).to receive(:visit_puppetfile) { subject.instance_variable_set(:@visit_ok, false) }
277
385
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
386
+ allow(environment).to receive(:deploy) { subject.instance_variable_set(:@visit_ok, false) }
278
387
  expect(environment).not_to receive(:generate_types!)
279
388
  original.call(environment, &block)
280
389
  end.twice
@@ -282,10 +391,11 @@ describe R10K::Action::Deploy::Environment do
282
391
  end
283
392
 
284
393
  it 'calls puppet generate types on previous puppetfile failure' do
285
- allow(subject).to receive(:visit_puppetfile) do |puppetfile|
286
- subject.instance_variable_set(:@visit_ok, false) if puppetfile.environment.dirname == 'first'
287
- end
288
394
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
395
+ allow(environment).to receive(:deploy) do
396
+ subject.instance_variable_set(:@visit_ok, false) if environment.dirname == 'first'
397
+ end
398
+
289
399
  if environment.dirname == 'second'
290
400
  expect(environment).to receive(:generate_types!)
291
401
  else
@@ -302,15 +412,16 @@ describe R10K::Action::Deploy::Environment do
302
412
  described_class.new(
303
413
  {
304
414
  config: '/some/nonexistent/path',
305
- puppetfile: true,
415
+ modules: true,
306
416
  'generate-types': false
307
417
  },
308
- %w[first]
418
+ %w[first],
419
+ {}
309
420
  )
310
421
  end
311
422
 
312
423
  it 'generate_types is false' do
313
- expect(subject.instance_variable_get(:@generate_types)).to eq(false)
424
+ expect(subject.settings[:overrides][:environments][:generate_types]).to eq(false)
314
425
  end
315
426
 
316
427
  it 'does not call puppet generate types' do
@@ -325,7 +436,7 @@ describe R10K::Action::Deploy::Environment do
325
436
 
326
437
  describe 'with puppet-path' do
327
438
 
328
- subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-path': '/nonexistent' }, []) }
439
+ subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-path': '/nonexistent' }, [], {}) }
329
440
 
330
441
  it 'sets puppet_path' do
331
442
  expect(subject.instance_variable_get(:@puppet_path)).to eq('/nonexistent')
@@ -334,12 +445,30 @@ describe R10K::Action::Deploy::Environment do
334
445
 
335
446
  describe 'with puppet-conf' do
336
447
 
337
- subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-conf': '/nonexistent' }, []) }
448
+ subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-conf': '/nonexistent' }, [], {}) }
338
449
 
339
450
  it 'sets puppet_conf' do
340
451
  expect(subject.instance_variable_get(:@puppet_conf)).to eq('/nonexistent')
341
452
  end
342
453
  end
454
+
455
+ describe 'with private-key' do
456
+
457
+ subject { described_class.new({ config: '/some/nonexistent/path', 'private-key': '/nonexistent' }, [], {}) }
458
+
459
+ it 'sets private_key' do
460
+ expect(subject.instance_variable_get(:@private_key)).to eq('/nonexistent')
461
+ end
462
+ end
463
+
464
+ describe 'with oauth-token' do
465
+
466
+ subject { described_class.new({ config: '/some/nonexistent/path', 'oauth-token': '/nonexistent' }, [], {}) }
467
+
468
+ it 'sets oauth_token' do
469
+ expect(subject.instance_variable_get(:@oauth_token)).to eq('/nonexistent')
470
+ end
471
+ end
343
472
  end
344
473
 
345
474
  describe "write_environment_info!" do
@@ -352,15 +481,31 @@ describe R10K::Action::Deploy::Environment do
352
481
  def initialize(path, info)
353
482
  @path = path
354
483
  @info = info
355
- @puppetfile = R10K::Puppetfile.new
484
+ @puppetfile = R10K::Puppetfile.new("", {})
356
485
  end
357
486
  end
358
487
 
359
488
  let(:mock_stateful_repo_1) { instance_double("R10K::Git::StatefulRepository", :head => "123456") }
360
489
  let(:mock_stateful_repo_2) { instance_double("R10K::Git::StatefulRepository", :head => "654321") }
361
- let(:mock_git_module_1) { instance_double("R10K::Module::Git", :name => "my_cool_module", :version => "1.0", :repo => mock_stateful_repo_1) }
362
- let(:mock_git_module_2) { instance_double("R10K::Module::Git", :name => "my_lame_module", :version => "0.0.1", :repo => mock_stateful_repo_2) }
363
- let(:mock_forge_module_1) { double(:name => "their_shiny_module", :version => "2.0.0") }
490
+ let(:mock_git_module_1) do
491
+ instance_double("R10K::Module::Git",
492
+ :name => "my_cool_module",
493
+ :properties => {
494
+ :type => :git,
495
+ :expected => "1.0",
496
+ :actual => mock_stateful_repo_1.head
497
+ })
498
+ end
499
+ let(:mock_git_module_2) do
500
+ instance_double("R10K::Module::Git",
501
+ :name => "my_uncool_module",
502
+ :properties => {
503
+ :type => :git,
504
+ :expected => "0.0.1",
505
+ :actual => mock_stateful_repo_2.head
506
+ })
507
+ end
508
+ let(:mock_forge_module_1) { double(:name => "their_shiny_module", :properties => { :expected => "2.0.0" }) }
364
509
  let(:mock_puppetfile) { instance_double("R10K::Puppetfile", :modules => [mock_git_module_1, mock_git_module_2, mock_forge_module_1]) }
365
510
 
366
511
  before(:all) do
@@ -373,9 +518,8 @@ describe R10K::Action::Deploy::Environment do
373
518
  Dir.delete(@tmp_path)
374
519
  end
375
520
 
376
- it "writes the .r10k-deploy file correctly" do
521
+ it "writes the .r10k-deploy file correctly if all goes well" do
377
522
  allow(R10K::Puppetfile).to receive(:new).and_return(mock_puppetfile)
378
- allow(mock_forge_module_1).to receive(:repo).and_raise(NoMethodError)
379
523
 
380
524
  fake_env = Fake_Environment.new(@tmp_path, {:name => "my_cool_environment", :signature => "pablo picasso"})
381
525
  allow(fake_env).to receive(:modules).and_return(mock_puppetfile.modules)
@@ -392,13 +536,30 @@ describe R10K::Action::Deploy::Environment do
392
536
  expect(r10k_deploy['module_deploys'][0]['name']).to eq("my_cool_module")
393
537
  expect(r10k_deploy['module_deploys'][0]['version']).to eq("1.0")
394
538
  expect(r10k_deploy['module_deploys'][0]['sha']).to eq("123456")
395
- expect(r10k_deploy['module_deploys'][1]['name']).to eq("my_lame_module")
539
+ expect(r10k_deploy['module_deploys'][1]['name']).to eq("my_uncool_module")
396
540
  expect(r10k_deploy['module_deploys'][1]['version']).to eq("0.0.1")
397
541
  expect(r10k_deploy['module_deploys'][1]['sha']).to eq("654321")
398
542
  expect(r10k_deploy['module_deploys'][2]['name']).to eq("their_shiny_module")
399
543
  expect(r10k_deploy['module_deploys'][2]['version']).to eq("2.0.0")
400
544
  expect(r10k_deploy['module_deploys'][2]['sha']).to eq(nil)
545
+ end
546
+
547
+ it "writes the .r10k-deploy file correctly if there's a failure" do
548
+ allow(R10K::Puppetfile).to receive(:new).and_return(mock_puppetfile)
549
+
550
+ fake_env = Fake_Environment.new(@tmp_path, {:name => "my_cool_environment", :signature => "pablo picasso"})
551
+ allow(fake_env).to receive(:modules).and_return(mock_puppetfile.modules)
552
+ allow(mock_forge_module_1).to receive(:properties).and_raise(StandardError)
553
+ subject.send(:write_environment_info!, fake_env, "2019-01-01 23:23:22 +0000", true)
554
+
555
+ file_contents = File.read("#{@tmp_path}/.r10k-deploy.json")
556
+ r10k_deploy = JSON.parse(file_contents)
401
557
 
558
+ expect(r10k_deploy['name']).to eq("my_cool_environment")
559
+ expect(r10k_deploy['signature']).to eq("pablo picasso")
560
+ expect(r10k_deploy['started_at']).to eq("2019-01-01 23:23:22 +0000")
561
+ expect(r10k_deploy['deploy_success']).to eq(true)
562
+ expect(r10k_deploy['module_deploys'].length).to eq(0)
402
563
  end
403
564
  end
404
565
  end