berkshelf 3.0.0.beta9 → 3.0.0.rc1
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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +69 -48
- data/berkshelf.gemspec +3 -3
- data/features/commands/update.feature +41 -1
- data/features/commands/upload.feature +61 -11
- data/features/lifecycle.feature +93 -0
- data/generator_files/CHANGELOG.md.erb +8 -4
- data/generator_files/gitignore.erb +7 -2
- data/generator_files/metadata.rb.erb +2 -2
- data/lib/berkshelf.rb +2 -0
- data/lib/berkshelf/base_generator.rb +18 -0
- data/lib/berkshelf/berksfile.rb +11 -103
- data/lib/berkshelf/cli.rb +6 -4
- data/lib/berkshelf/cookbook_generator.rb +20 -9
- data/lib/berkshelf/formatters/base.rb +2 -2
- data/lib/berkshelf/formatters/human.rb +3 -3
- data/lib/berkshelf/formatters/json.rb +2 -2
- data/lib/berkshelf/init_generator.rb +1 -7
- data/lib/berkshelf/installer.rb +2 -1
- data/lib/berkshelf/lockfile.rb +88 -40
- data/lib/berkshelf/logger.rb +2 -2
- data/lib/berkshelf/resolver.rb +4 -1
- data/lib/berkshelf/uploader.rb +122 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +18 -169
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/base_spec.rb +1 -1
- data/spec/unit/berkshelf/ui_spec.rb +6 -7
- data/spec/unit/berkshelf/uploader_spec.rb +190 -0
- metadata +13 -11
- data/gem_graph.png +0 -0
data/lib/berkshelf/logger.rb
CHANGED
@@ -11,8 +11,8 @@ module Berkshelf
|
|
11
11
|
#
|
12
12
|
# @param [Exception] ex
|
13
13
|
def exception(ex)
|
14
|
-
|
15
|
-
|
14
|
+
fatal("#{ex.class}: #{ex}")
|
15
|
+
fatal(ex.backtrace.join("\n")) unless ex.backtrace.nil?
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/berkshelf/resolver.rb
CHANGED
@@ -57,7 +57,10 @@ module Berkshelf
|
|
57
57
|
#
|
58
58
|
# @return [Array<String, String>]
|
59
59
|
def demand_array
|
60
|
-
demands.collect
|
60
|
+
demands.collect do |demand|
|
61
|
+
constraint = demand.locked_version || demand.version_constraint
|
62
|
+
[demand.name, constraint]
|
63
|
+
end
|
61
64
|
end
|
62
65
|
|
63
66
|
# Finds a solution for the currently added dependencies and their dependencies and
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Berkshelf
|
2
|
+
class Uploader
|
3
|
+
attr_reader :berksfile
|
4
|
+
attr_reader :lockfile
|
5
|
+
attr_reader :options
|
6
|
+
attr_reader :names
|
7
|
+
|
8
|
+
def initialize(berksfile, *args)
|
9
|
+
@berksfile = berksfile
|
10
|
+
@lockfile = berksfile.lockfile
|
11
|
+
|
12
|
+
@options = {
|
13
|
+
force: false,
|
14
|
+
freeze: true,
|
15
|
+
halt_on_frozen: false,
|
16
|
+
validate: true,
|
17
|
+
}.merge(args.last.is_a?(Hash) ? args.pop : {})
|
18
|
+
|
19
|
+
@names = Array(args).flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
Berkshelf.log.info "Uploading cookbooks"
|
24
|
+
|
25
|
+
cookbooks = if names.empty?
|
26
|
+
Berkshelf.log.debug " No names given, using all cookbooks"
|
27
|
+
filtered_cookbooks
|
28
|
+
else
|
29
|
+
Berkshelf.log.debug " Names given (#{names.join(', ')})"
|
30
|
+
names.map { |name| lockfile.retrieve(name) }
|
31
|
+
end
|
32
|
+
|
33
|
+
# Perform all validations first to prevent partially uploaded cookbooks
|
34
|
+
cookbooks.each { |cookbook| validate_files!(cookbook) }
|
35
|
+
|
36
|
+
upload(cookbooks)
|
37
|
+
cookbooks
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Upload the list of cookbooks to the Chef Server, with some exception
|
43
|
+
# wrapping.
|
44
|
+
#
|
45
|
+
# @param [Array<String>] cookbooks
|
46
|
+
def upload(cookbooks)
|
47
|
+
Berkshelf.log.info "Starting upload"
|
48
|
+
|
49
|
+
Berkshelf.ridley_connection(options) do |connection|
|
50
|
+
cookbooks.each do |cookbook|
|
51
|
+
Berkshelf.log.debug " Uploading #{cookbook}"
|
52
|
+
|
53
|
+
begin
|
54
|
+
connection.cookbook.upload(cookbook.path,
|
55
|
+
name: cookbook.cookbook_name,
|
56
|
+
force: options[:force],
|
57
|
+
freeze: options[:freeze],
|
58
|
+
validate: options[:validate],
|
59
|
+
)
|
60
|
+
|
61
|
+
Berkshelf.formatter.uploaded(cookbook, connection)
|
62
|
+
rescue Ridley::Errors::FrozenCookbook
|
63
|
+
if options[:halt_on_frozen]
|
64
|
+
raise FrozenCookbook.new(cookbook)
|
65
|
+
end
|
66
|
+
|
67
|
+
Berkshelf.formatter.skipping(cookbook, connection)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Filter cookbooks based off the list of dependencies in the Berksfile.
|
74
|
+
#
|
75
|
+
# This method is secretly recursive. It iterates over each dependency in
|
76
|
+
# the Berksfile (using {Berksfile#dependencies} to account for filters)
|
77
|
+
# and retrieves that cookbook, it's dependencies, and the recusive
|
78
|
+
# dependencies, but iteratively.
|
79
|
+
#
|
80
|
+
# @return [Array<CachedCookbook>]
|
81
|
+
#
|
82
|
+
def filtered_cookbooks
|
83
|
+
# Create a copy of the dependencies. We need to make a copy, or else
|
84
|
+
# we would be adding dependencies directly to the Berksfile object, and
|
85
|
+
# that would be a bad idea...
|
86
|
+
dependencies = berksfile.dependencies.map(&:name)
|
87
|
+
|
88
|
+
checked = {}
|
89
|
+
cookbooks = {}
|
90
|
+
|
91
|
+
dependencies.each do |dependency|
|
92
|
+
next if checked[dependency]
|
93
|
+
|
94
|
+
lockfile.graph.find(dependency).dependencies.each do |name, _|
|
95
|
+
cookbooks[name] ||= lockfile.retrieve(name)
|
96
|
+
dependencies << name
|
97
|
+
end
|
98
|
+
|
99
|
+
checked[dependency] = true
|
100
|
+
cookbooks[dependency] ||= lockfile.retrieve(dependency)
|
101
|
+
end
|
102
|
+
|
103
|
+
cookbooks.values.sort
|
104
|
+
end
|
105
|
+
|
106
|
+
# Validate that the given cookbook does not have "bad" files. Currently
|
107
|
+
# this means including spaces in filenames (such as recipes)
|
108
|
+
#
|
109
|
+
# @param [CachedCookbook] cookbook
|
110
|
+
# the Cookbook to validate
|
111
|
+
def validate_files!(cookbook)
|
112
|
+
path = cookbook.path.to_s
|
113
|
+
|
114
|
+
files = Dir.glob(File.join(path, '**', '*.rb')).select do |f|
|
115
|
+
parent = Pathname.new(path).dirname.to_s
|
116
|
+
f.gsub(parent, '') =~ /[[:space:]]/
|
117
|
+
end
|
118
|
+
|
119
|
+
raise InvalidCookbookFiles.new(cookbook, files) unless files.empty?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/lib/berkshelf/version.rb
CHANGED
@@ -320,187 +320,36 @@ describe Berkshelf::Berksfile do
|
|
320
320
|
end
|
321
321
|
|
322
322
|
describe '#upload' do
|
323
|
-
let(:
|
324
|
-
let(:lockfile) { double(present?: true, trusted?: true, graph: graph) }
|
323
|
+
let(:uploader) { double(Berkshelf::Uploader, run: nil) }
|
325
324
|
|
326
325
|
before do
|
327
|
-
|
328
|
-
subject.stub(:
|
329
|
-
|
330
|
-
|
331
|
-
let(:options) { Hash.new }
|
332
|
-
let(:chef_config) do
|
333
|
-
double('chef-config',
|
334
|
-
node_name: 'fake-client',
|
335
|
-
client_key: 'client-key',
|
336
|
-
chef_server_url: 'http://configured-chef-server/',
|
337
|
-
validation_client_name: 'validator',
|
338
|
-
validation_key: 'validator.pem',
|
339
|
-
cookbook_copyright: 'user',
|
340
|
-
cookbook_email: 'user@example.com',
|
341
|
-
cookbook_license: 'apachev2',
|
342
|
-
)
|
343
|
-
end
|
344
|
-
let(:berkshelf_config) { double('berkshelf-config', ssl: double(verify: true), chef: chef_config) }
|
345
|
-
let(:default_ridley_options) do
|
346
|
-
{
|
347
|
-
client_name: 'fake-client',
|
348
|
-
client_key: 'client-key',
|
349
|
-
ssl: {
|
350
|
-
verify: true
|
351
|
-
}
|
352
|
-
}
|
353
|
-
end
|
354
|
-
|
355
|
-
let(:upload) { subject.upload(options) }
|
356
|
-
|
357
|
-
context 'when there is no value for :chef_server_url' do
|
358
|
-
before { chef_config.stub(chef_server_url: nil) }
|
359
|
-
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.server_url' }
|
360
|
-
|
361
|
-
it 'raises an error' do
|
362
|
-
expect { upload }.to raise_error(Berkshelf::ChefConnectionError, message)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
context 'when there is no value for :client_name' do
|
367
|
-
before { chef_config.stub(node_name: nil) }
|
368
|
-
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.node_name' }
|
369
|
-
|
370
|
-
it 'raises an error' do
|
371
|
-
expect { upload }.to raise_error(Berkshelf::ChefConnectionError, message)
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
context 'when there is no value for :client_key' do
|
376
|
-
before { chef_config.stub(client_key: nil) }
|
377
|
-
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.client_key' }
|
378
|
-
|
379
|
-
it 'raises an error' do
|
380
|
-
expect {
|
381
|
-
upload
|
382
|
-
}.to raise_error(Berkshelf::ChefConnectionError, message)
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
context 'when a Chef Server url is not passed as an option' do
|
387
|
-
let(:ridley_options) do
|
388
|
-
{ server_url: 'http://configured-chef-server/' }.merge(default_ridley_options)
|
389
|
-
end
|
390
|
-
|
391
|
-
it 'uses Berkshelf::Config configured server_url' do
|
392
|
-
Ridley.should_receive(:open).with(ridley_options)
|
393
|
-
upload
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
context 'when a Chef Server url is passed as an option' do
|
398
|
-
let(:options) do
|
399
|
-
{
|
400
|
-
server_url: 'http://fake-chef-server.com/'
|
401
|
-
}
|
402
|
-
end
|
403
|
-
let(:ridley_options) do
|
404
|
-
{ server_url: 'http://fake-chef-server.com/'}.merge(default_ridley_options)
|
405
|
-
end
|
406
|
-
|
407
|
-
it 'uses the passed in :server_url' do
|
408
|
-
Ridley.should_receive(:open).with(ridley_options)
|
409
|
-
upload
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
context 'when a client name is passed as an option' do
|
414
|
-
let(:options) do
|
415
|
-
{
|
416
|
-
client_name: 'passed-in-client-name'
|
417
|
-
}
|
418
|
-
end
|
419
|
-
let(:ridley_options) do
|
420
|
-
default_ridley_options.merge(
|
421
|
-
{ server_url: 'http://configured-chef-server/', client_name: 'passed-in-client-name'})
|
422
|
-
end
|
423
|
-
|
424
|
-
it 'uses the passed in :client_name' do
|
425
|
-
Ridley.should_receive(:open).with(ridley_options)
|
426
|
-
upload
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
context 'when a client key is passed as an option' do
|
431
|
-
let(:options) do
|
432
|
-
{
|
433
|
-
client_key: 'passed-in-client-key'
|
434
|
-
}
|
435
|
-
end
|
436
|
-
let(:ridley_options) do
|
437
|
-
default_ridley_options.merge(
|
438
|
-
{ server_url: 'http://configured-chef-server/', client_key: 'passed-in-client-key'})
|
439
|
-
end
|
326
|
+
subject.stub(:validate_lockfile_present!)
|
327
|
+
subject.stub(:validate_lockfile_trusted!)
|
328
|
+
subject.stub(:validate_dependencies_installed!)
|
440
329
|
|
441
|
-
|
442
|
-
Ridley.should_receive(:open).with(ridley_options)
|
443
|
-
upload
|
444
|
-
end
|
330
|
+
Berkshelf::Uploader.stub(:new).and_return(uploader)
|
445
331
|
end
|
446
332
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
let(:options) do
|
452
|
-
{
|
453
|
-
force: false,
|
454
|
-
freeze: true,
|
455
|
-
validate: false,
|
456
|
-
name: mysql_cookbook.cookbook_name
|
457
|
-
}
|
458
|
-
end
|
459
|
-
let(:ridley_options) do
|
460
|
-
default_ridley_options.merge({ server_url: 'http://configured-chef-server/'})
|
461
|
-
end
|
462
|
-
let(:conn) { double('conn') }
|
463
|
-
|
464
|
-
before do
|
465
|
-
subject.stub(:dependencies).and_return([mysql_dependency])
|
466
|
-
graph.stub(:find).with(mysql_dependency).and_return(mysql_dependency)
|
467
|
-
lockfile.stub(:retrieve).with(mysql_dependency).and_return(mysql_cookbook)
|
468
|
-
end
|
469
|
-
|
470
|
-
it 'uses the passed in :validate' do
|
471
|
-
expect(Ridley).to receive(:open).and_yield(conn)
|
472
|
-
expect(conn).to receive(:cookbook).and_return(mysql_cookbook)
|
473
|
-
expect(mysql_cookbook).to receive(:upload).with('path', options)
|
474
|
-
subject.upload('mysql', options)
|
475
|
-
end
|
333
|
+
it 'validates the lockfile is present' do
|
334
|
+
expect(subject).to receive(:validate_lockfile_present!).once
|
335
|
+
subject.upload
|
476
336
|
end
|
477
|
-
end
|
478
|
-
|
479
|
-
describe '#validate_files!' do
|
480
|
-
before { described_class.send(:public, :validate_files!) }
|
481
|
-
let(:cookbook) { double('cookbook', cookbook_name: 'cookbook', path: 'path') }
|
482
337
|
|
483
|
-
it '
|
484
|
-
|
485
|
-
|
486
|
-
subject.validate_files!(cookbook)
|
487
|
-
}.to raise_error
|
338
|
+
it 'validates the lockfile is trusted' do
|
339
|
+
expect(subject).to receive(:validate_lockfile_trusted!).once
|
340
|
+
subject.upload
|
488
341
|
end
|
489
342
|
|
490
|
-
it '
|
491
|
-
|
492
|
-
|
493
|
-
subject.validate_files!(cookbook)
|
494
|
-
}.to_not raise_error
|
343
|
+
it 'validates the dependencies are installed' do
|
344
|
+
expect(subject).to receive(:validate_dependencies_installed!).once
|
345
|
+
subject.upload
|
495
346
|
end
|
496
347
|
|
497
|
-
it '
|
498
|
-
|
499
|
-
|
348
|
+
it 'creates a new Uploader' do
|
349
|
+
expect(Berkshelf::Uploader).to receive(:new).with(subject)
|
350
|
+
expect(uploader).to receive(:run)
|
500
351
|
|
501
|
-
|
502
|
-
subject.validate_files!(cookbook)
|
503
|
-
}.to_not raise_error
|
352
|
+
subject.upload
|
504
353
|
end
|
505
354
|
end
|
506
355
|
end
|
@@ -47,8 +47,8 @@ describe Berkshelf::CookbookGenerator do
|
|
47
47
|
contains 'Author:: YOUR_NAME (<YOUR_EMAIL>)'
|
48
48
|
end
|
49
49
|
file 'CHANGELOG.md' do
|
50
|
-
contains '#
|
51
|
-
contains "
|
50
|
+
contains '# 0.1.0'
|
51
|
+
contains "Initial release of sparkle_motion"
|
52
52
|
end
|
53
53
|
file 'metadata.rb' do
|
54
54
|
contains "name 'sparkle_motion'"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Thor::Base.shell do
|
4
|
-
let(:stdout) { double('stdout') }
|
4
|
+
let(:stdout) { double('stdout', tty?: true) }
|
5
5
|
let(:stderr) { double('stderr') }
|
6
6
|
|
7
7
|
before do
|
@@ -30,7 +30,7 @@ describe Thor::Base.shell do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'does not output anything', :not_supported_on_windows do
|
33
|
-
stdout.should_not_receive(:
|
33
|
+
stdout.should_not_receive(:print)
|
34
34
|
subject.say 'message'
|
35
35
|
end
|
36
36
|
end
|
@@ -41,7 +41,7 @@ describe Thor::Base.shell do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'prints to stdout' do
|
44
|
-
stdout.should_receive(:
|
44
|
+
stdout.should_receive(:print).once
|
45
45
|
stdout.should_receive(:flush).with(no_args())
|
46
46
|
subject.say 'message'
|
47
47
|
end
|
@@ -66,7 +66,7 @@ describe Thor::Base.shell do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'prints to stdout' do
|
69
|
-
stdout.should_receive(:
|
69
|
+
stdout.should_receive(:print).once
|
70
70
|
stdout.should_receive(:flush).with(no_args())
|
71
71
|
subject.say_status 5, 'message'
|
72
72
|
end
|
@@ -80,7 +80,7 @@ describe Thor::Base.shell do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'does not output anything' do
|
83
|
-
stdout.should_not_receive(:
|
83
|
+
stdout.should_not_receive(:print)
|
84
84
|
subject.warn 'warning'
|
85
85
|
end
|
86
86
|
end
|
@@ -91,8 +91,7 @@ describe Thor::Base.shell do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'calls #say with yellow coloring' do
|
94
|
-
stdout.
|
95
|
-
stdout.should_receive(:puts).with("warning")
|
94
|
+
stdout.should_receive(:print)
|
96
95
|
stdout.should_receive(:flush).with(no_args())
|
97
96
|
subject.warn 'warning'
|
98
97
|
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
describe Uploader do
|
5
|
+
let(:berksfile) do
|
6
|
+
double(Berksfile,
|
7
|
+
lockfile: lockfile,
|
8
|
+
dependencies: [],
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:lockfile) do
|
13
|
+
double(Lockfile,
|
14
|
+
graph: graph
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:graph) { double(Lockfile::Graph, locks: {}) }
|
19
|
+
|
20
|
+
subject { Uploader.new(berksfile) }
|
21
|
+
|
22
|
+
describe '#initialize' do
|
23
|
+
it 'saves the berksfile' do
|
24
|
+
instance = Uploader.new(berksfile)
|
25
|
+
expect(instance.berksfile).to be(berksfile)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'saves the lockfile' do
|
29
|
+
instance = Uploader.new(berksfile)
|
30
|
+
expect(instance.lockfile).to be(lockfile)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'saves the options' do
|
34
|
+
instance = Uploader.new(berksfile, force: true, validate: false)
|
35
|
+
options = instance.options
|
36
|
+
expect(options[:force]).to be_true
|
37
|
+
expect(options[:validate]).to be_false
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'saves the names' do
|
41
|
+
instance = Uploader.new(berksfile, 'cookbook_1', 'cookbook_2')
|
42
|
+
expect(instance.names).to eq(['cookbook_1', 'cookbook_2'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#validate_files!' do
|
47
|
+
before { Uploader.send(:public, :validate_files!) }
|
48
|
+
|
49
|
+
let(:cookbook) { double('cookbook', cookbook_name: 'cookbook', path: 'path') }
|
50
|
+
|
51
|
+
it 'raises an error when the cookbook has spaces in the files' do
|
52
|
+
Dir.stub(:glob).and_return(['/there are/spaces/in this/recipes/default.rb'])
|
53
|
+
expect {
|
54
|
+
subject.validate_files!(cookbook)
|
55
|
+
}.to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does not raise an error when the cookbook is valid' do
|
59
|
+
Dir.stub(:glob).and_return(['/there-are/no-spaces/in-this/recipes/default.rb'])
|
60
|
+
expect {
|
61
|
+
subject.validate_files!(cookbook)
|
62
|
+
}.to_not raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not raise an exception with spaces in the path' do
|
66
|
+
Dir.stub(:glob).and_return(['/there are/spaces/in this/recipes/default.rb'])
|
67
|
+
Pathname.any_instance.stub(:dirname).and_return('/there are/spaces/in this')
|
68
|
+
|
69
|
+
expect {
|
70
|
+
subject.validate_files!(cookbook)
|
71
|
+
}.to_not raise_error
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#run' do
|
76
|
+
let(:options) { Hash.new }
|
77
|
+
|
78
|
+
let(:chef_config) do
|
79
|
+
double(Ridley::Chef::Config,
|
80
|
+
node_name: 'fake-client',
|
81
|
+
client_key: 'client-key',
|
82
|
+
chef_server_url: 'http://configured-chef-server/',
|
83
|
+
validation_client_name: 'validator',
|
84
|
+
validation_key: 'validator.pem',
|
85
|
+
cookbook_copyright: 'user',
|
86
|
+
cookbook_email: 'user@example.com',
|
87
|
+
cookbook_license: 'apachev2',
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:berkshelf_config) do
|
92
|
+
double(Config,
|
93
|
+
ssl: double(verify: true),
|
94
|
+
chef: chef_config,
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
let(:default_ridley_options) do
|
99
|
+
{
|
100
|
+
client_name: 'fake-client',
|
101
|
+
client_key: 'client-key',
|
102
|
+
ssl: {
|
103
|
+
verify: true
|
104
|
+
}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
before do
|
109
|
+
Berkshelf.stub(:config).and_return(berkshelf_config)
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when there is no value for :chef_server_url' do
|
113
|
+
before { chef_config.stub(chef_server_url: nil) }
|
114
|
+
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.server_url' }
|
115
|
+
|
116
|
+
it 'raises an error' do
|
117
|
+
expect { subject.run }.to raise_error(Berkshelf::ChefConnectionError, message)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when there is no value for :client_name' do
|
122
|
+
before { chef_config.stub(node_name: nil) }
|
123
|
+
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.node_name' }
|
124
|
+
|
125
|
+
it 'raises an error' do
|
126
|
+
expect { subject.run }.to raise_error(Berkshelf::ChefConnectionError, message)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when there is no value for :client_key' do
|
131
|
+
before { chef_config.stub(client_key: nil) }
|
132
|
+
let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.client_key' }
|
133
|
+
|
134
|
+
it 'raises an error' do
|
135
|
+
expect {
|
136
|
+
subject.run
|
137
|
+
}.to raise_error(Berkshelf::ChefConnectionError, message)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'when no options are given' do
|
142
|
+
let(:ridley_options) do
|
143
|
+
{ server_url: 'http://configured-chef-server/' }.merge(default_ridley_options)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'uses the Berkshelf::Config options' do
|
147
|
+
expect(Ridley).to receive(:open).with(
|
148
|
+
server_url: chef_config.chef_server_url,
|
149
|
+
client_name: chef_config.node_name,
|
150
|
+
client_key: chef_config.client_key,
|
151
|
+
ssl: {
|
152
|
+
verify: berkshelf_config.ssl.verify
|
153
|
+
}
|
154
|
+
)
|
155
|
+
subject.run
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'when a Chef Server url is passed as an option' do
|
160
|
+
subject { Uploader.new(berksfile, server_url: 'http://custom') }
|
161
|
+
|
162
|
+
it 'uses the passed in :server_url' do
|
163
|
+
expect(Ridley).to receive(:open)
|
164
|
+
.with(include(server_url: 'http://custom'))
|
165
|
+
subject.run
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when a client name is passed as an option' do
|
170
|
+
subject { Uploader.new(berksfile, client_name: 'custom') }
|
171
|
+
|
172
|
+
it 'uses the passed in :client_name' do
|
173
|
+
expect(Ridley).to receive(:open)
|
174
|
+
.with(include(client_name: 'custom'))
|
175
|
+
subject.run
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'when a client key is passed as an option' do
|
180
|
+
subject { Uploader.new(berksfile, client_key: 'custom') }
|
181
|
+
|
182
|
+
it 'uses the passed in :client_key' do
|
183
|
+
expect(Ridley).to receive(:open)
|
184
|
+
.with(include(client_key: 'custom'))
|
185
|
+
subject.run
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|