knife-ec2 0.12.0 → 0.13.0
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/.gitignore +41 -41
- data/.travis.yml +7 -1
- data/CHANGELOG.md +40 -4
- data/CONTRIBUTING.md +216 -71
- data/CONTRIBUTIONS.md +3 -6
- data/DOC_CHANGES.md +25 -50
- data/Gemfile +4 -1
- data/LICENSE +201 -201
- data/README.md +138 -83
- data/RELEASE_NOTES.md +20 -36
- data/Rakefile +56 -56
- data/knife-ec2.gemspec +4 -3
- data/lib/chef/knife/ec2_base.rb +45 -12
- data/lib/chef/knife/ec2_flavor_list.rb +53 -53
- data/lib/chef/knife/ec2_server_create.rb +251 -45
- data/lib/chef/knife/ec2_server_delete.rb +140 -140
- data/lib/chef/knife/ec2_server_list.rb +52 -83
- data/lib/chef/knife/s3_source.rb +49 -49
- data/lib/knife-ec2/version.rb +6 -6
- data/spec/spec_helper.rb +18 -18
- data/spec/unit/ec2_server_create_spec.rb +930 -19
- data/spec/unit/ec2_server_delete_spec.rb +141 -141
- data/spec/unit/ec2_server_list_spec.rb +131 -0
- data/spec/unit/s3_source_deps_spec.rb +24 -24
- data/spec/unit/s3_source_spec.rb +75 -75
- metadata +25 -15
data/lib/chef/knife/s3_source.rb
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
class Chef
|
2
|
-
class Knife
|
3
|
-
class S3Source
|
4
|
-
attr_accessor :url
|
5
|
-
|
6
|
-
def self.fetch(url)
|
7
|
-
source = Chef::Knife::S3Source.new
|
8
|
-
source.url = url
|
9
|
-
source.body
|
10
|
-
end
|
11
|
-
|
12
|
-
def body
|
13
|
-
bucket_obj.files.get(path).body
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def bucket_obj
|
19
|
-
@bucket_obj ||= fog.directories.get(bucket)
|
20
|
-
end
|
21
|
-
|
22
|
-
def bucket
|
23
|
-
uri = URI(@url)
|
24
|
-
if uri.scheme == "s3"
|
25
|
-
URI(@url).host
|
26
|
-
else
|
27
|
-
URI(@url).path.split("/")[1]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def path
|
32
|
-
uri = URI(@url)
|
33
|
-
if uri.scheme == "s3"
|
34
|
-
URI(@url).path.sub(/^\//, '')
|
35
|
-
else
|
36
|
-
URI(@url).path.split(bucket).last.sub(/^\//, '')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def fog
|
41
|
-
require 'fog' # lazy load the fog library to speed up the knife run
|
42
|
-
@fog ||= Fog::Storage::AWS.new(
|
43
|
-
aws_access_key_id: Chef::Config[:knife][:aws_access_key_id],
|
44
|
-
aws_secret_access_key: Chef::Config[:knife][:aws_secret_access_key]
|
45
|
-
)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
1
|
+
class Chef
|
2
|
+
class Knife
|
3
|
+
class S3Source
|
4
|
+
attr_accessor :url
|
5
|
+
|
6
|
+
def self.fetch(url)
|
7
|
+
source = Chef::Knife::S3Source.new
|
8
|
+
source.url = url
|
9
|
+
source.body
|
10
|
+
end
|
11
|
+
|
12
|
+
def body
|
13
|
+
bucket_obj.files.get(path).body
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def bucket_obj
|
19
|
+
@bucket_obj ||= fog.directories.get(bucket)
|
20
|
+
end
|
21
|
+
|
22
|
+
def bucket
|
23
|
+
uri = URI(@url)
|
24
|
+
if uri.scheme == "s3"
|
25
|
+
URI(@url).host
|
26
|
+
else
|
27
|
+
URI(@url).path.split("/")[1]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def path
|
32
|
+
uri = URI(@url)
|
33
|
+
if uri.scheme == "s3"
|
34
|
+
URI(@url).path.sub(/^\//, '')
|
35
|
+
else
|
36
|
+
URI(@url).path.split(bucket).last.sub(/^\//, '')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def fog
|
41
|
+
require 'fog/aws' # lazy load the fog library to speed up the knife run
|
42
|
+
@fog ||= Fog::Storage::AWS.new(
|
43
|
+
aws_access_key_id: Chef::Config[:knife][:aws_access_key_id],
|
44
|
+
aws_secret_access_key: Chef::Config[:knife][:aws_secret_access_key]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/knife-ec2/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
module Knife
|
2
|
-
module Ec2
|
3
|
-
VERSION = "0.
|
4
|
-
MAJOR, MINOR, TINY = VERSION.split('.')
|
5
|
-
end
|
6
|
-
end
|
1
|
+
module Knife
|
2
|
+
module Ec2
|
3
|
+
VERSION = "0.13.0"
|
4
|
+
MAJOR, MINOR, TINY = VERSION.split('.')
|
5
|
+
end
|
6
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'chef'
|
3
|
-
require 'chef/knife/winrm_base'
|
4
|
-
require 'chef/knife/ec2_server_create'
|
5
|
-
require 'chef/knife/ec2_server_delete'
|
6
|
-
require 'chef/knife/ec2_server_list'
|
7
|
-
|
8
|
-
# Clear config between each example
|
9
|
-
# to avoid dependencies between examples
|
10
|
-
RSpec.configure do |c|
|
11
|
-
c.raise_errors_for_deprecations!
|
12
|
-
c.filter_run_excluding :exclude => true
|
13
|
-
c.before(:each) do
|
14
|
-
Chef::Config.reset
|
15
|
-
Chef::Config[:knife] ={}
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
1
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'chef'
|
3
|
+
require 'chef/knife/winrm_base'
|
4
|
+
require 'chef/knife/ec2_server_create'
|
5
|
+
require 'chef/knife/ec2_server_delete'
|
6
|
+
require 'chef/knife/ec2_server_list'
|
7
|
+
|
8
|
+
# Clear config between each example
|
9
|
+
# to avoid dependencies between examples
|
10
|
+
RSpec.configure do |c|
|
11
|
+
c.raise_errors_for_deprecations!
|
12
|
+
c.filter_run_excluding :exclude => true
|
13
|
+
c.before(:each) do
|
14
|
+
Chef::Config.reset
|
15
|
+
Chef::Config[:knife] ={}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -20,7 +20,7 @@ require File.expand_path('../../spec_helper', __FILE__)
|
|
20
20
|
require 'net/ssh/proxy/http'
|
21
21
|
require 'net/ssh/proxy/command'
|
22
22
|
require 'net/ssh/gateway'
|
23
|
-
require 'fog'
|
23
|
+
require 'fog/aws'
|
24
24
|
require 'chef/knife/bootstrap'
|
25
25
|
require 'chef/knife/bootstrap_windows_winrm'
|
26
26
|
require 'chef/knife/bootstrap_windows_ssh'
|
@@ -35,11 +35,15 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
35
35
|
:image => 'image',
|
36
36
|
:ssh_key_name => 'ssh_key_name',
|
37
37
|
:aws_access_key_id => 'aws_access_key_id',
|
38
|
-
:aws_secret_access_key => 'aws_secret_access_key'
|
38
|
+
:aws_secret_access_key => 'aws_secret_access_key',
|
39
|
+
:network_interfaces => ['eni-12345678',
|
40
|
+
'eni-87654321']
|
39
41
|
}.each do |key, value|
|
40
42
|
Chef::Config[:knife][key] = value
|
41
43
|
end
|
42
44
|
|
45
|
+
@my_vpc = 'vpc-12345678'
|
46
|
+
|
43
47
|
@ec2_connection = double(Fog::Compute::AWS)
|
44
48
|
allow(@ec2_connection).to receive(:tags).and_return double('create', :create => true)
|
45
49
|
allow(@ec2_connection).to receive_message_chain(:images, :get).and_return double('ami', :root_device_type => 'not_ebs', :platform => 'linux')
|
@@ -49,6 +53,11 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
49
53
|
:server_id => nil,
|
50
54
|
:allocation_id => ''})]
|
51
55
|
|
56
|
+
allow(@ec2_connection).to receive(:subnets).and_return [@subnet_1, @subnet_2]
|
57
|
+
allow(@ec2_connection).to receive_message_chain(:network_interfaces, :all).and_return [
|
58
|
+
double('network_interfaces', network_interface_id: 'eni-12345678'),
|
59
|
+
double('network_interfaces', network_interface_id: 'eni-87654321')
|
60
|
+
]
|
52
61
|
|
53
62
|
@ec2_servers = double()
|
54
63
|
@new_ec2_server = double()
|
@@ -98,6 +107,8 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
98
107
|
@validation_key_url = 's3://bucket/foo/bar'
|
99
108
|
@validation_key_file = '/tmp/a_good_temp_file'
|
100
109
|
@validation_key_body = "TEST VALIDATION KEY\n"
|
110
|
+
@vpc_id = "vpc-1a2b3c4d"
|
111
|
+
@vpc_security_group_ids = ["sg-1a2b3c4d"]
|
101
112
|
end
|
102
113
|
|
103
114
|
describe "Spot Instance creation" do
|
@@ -162,6 +173,66 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
162
173
|
expect(@new_ec2_server).to receive(:wait_for).and_return(true)
|
163
174
|
@knife_ec2_create.run
|
164
175
|
end
|
176
|
+
|
177
|
+
context 'spot-wait-mode option' do
|
178
|
+
context 'when spot-price is not given' do
|
179
|
+
context 'spot-wait-mode option is not given' do
|
180
|
+
before do
|
181
|
+
@knife_ec2_create.config.delete(:spot_price)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'does not raise error' do
|
185
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
186
|
+
'spot-wait-mode option requires that a spot-price option is set.'
|
187
|
+
)
|
188
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'spot-wait-mode option is given' do
|
193
|
+
before do
|
194
|
+
@knife_ec2_create.config.delete(:spot_price)
|
195
|
+
@knife_ec2_create.config[:spot_wait_mode] = 'wait'
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'raises error' do
|
199
|
+
expect(@knife_ec2_create.ui).to receive(:error).with(
|
200
|
+
'spot-wait-mode option requires that a spot-price option is set.'
|
201
|
+
)
|
202
|
+
expect { @knife_ec2_create.validate! }.to raise_error(SystemExit)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'when spot-price is given' do
|
208
|
+
context 'spot-wait-mode option is not given' do
|
209
|
+
before do
|
210
|
+
@knife_ec2_create.config[:spot_price] = 0.001
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'does not raise error' do
|
214
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
215
|
+
'spot-wait-mode option requires that a spot-price option is set.'
|
216
|
+
)
|
217
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'spot-wait-mode option is given' do
|
222
|
+
before do
|
223
|
+
@knife_ec2_create.config[:spot_price] = 0.001
|
224
|
+
@knife_ec2_create.config[:spot_wait_mode] = 'exit'
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'does not raise error' do
|
228
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
229
|
+
'spot-wait-mode option requires that a spot-price option is set.'
|
230
|
+
)
|
231
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
165
236
|
end
|
166
237
|
|
167
238
|
describe "run" do
|
@@ -258,6 +329,17 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
258
329
|
expect(@knife_ec2_create.server).to_not be_nil
|
259
330
|
end
|
260
331
|
|
332
|
+
it "creates an EC2 instance, enables ClassicLink and bootstraps it" do
|
333
|
+
@knife_ec2_create.config[:classic_link_vpc_id] = @vpc_id
|
334
|
+
@knife_ec2_create.config[:classic_link_vpc_security_group_ids] = @vpc_security_group_ids
|
335
|
+
|
336
|
+
expect(@ec2_connection).to receive(:attach_classic_link_vpc).with(@ec2_server_attribs[:id], @vpc_id, @vpc_security_group_ids)
|
337
|
+
expect(@new_ec2_server).to receive(:wait_for).and_return(true)
|
338
|
+
|
339
|
+
@knife_ec2_create.run
|
340
|
+
expect(@knife_ec2_create.server).to_not be_nil
|
341
|
+
end
|
342
|
+
|
261
343
|
it "retries if it receives Fog::Compute::AWS::NotFound" do
|
262
344
|
expect(@new_ec2_server).to receive(:wait_for).and_return(true)
|
263
345
|
expect(@knife_ec2_create).to receive(:create_tags).and_raise(Fog::Compute::AWS::NotFound)
|
@@ -269,10 +351,8 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
269
351
|
|
270
352
|
it 'actually writes to the validation key tempfile' do
|
271
353
|
expect(@new_ec2_server).to receive(:wait_for).and_return(true)
|
272
|
-
Chef::Config[:knife][:validation_key_url] =
|
273
|
-
|
274
|
-
@knife_ec2_create.config[:validation_key_url] =
|
275
|
-
@validation_key_url
|
354
|
+
Chef::Config[:knife][:validation_key_url] = @validation_key_url
|
355
|
+
@knife_ec2_create.config[:validation_key_url] = @validation_key_url
|
276
356
|
|
277
357
|
allow(@knife_ec2_create).to receive_message_chain(:validation_key_tmpfile, :path).and_return(@validation_key_file)
|
278
358
|
allow(Chef::Knife::S3Source).to receive(:fetch).with(@validation_key_url).and_return(@validation_key_body)
|
@@ -423,6 +503,10 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
423
503
|
expect(bootstrap.config[:secret]).to eql("sys-knife-secret")
|
424
504
|
end
|
425
505
|
|
506
|
+
it "sets encrypted_data_bag_secret" do
|
507
|
+
expect(bootstrap.config[:encrypted_data_bag_secret]).to eql("sys-knife-secret")
|
508
|
+
end
|
509
|
+
|
426
510
|
it "prefers using a provided value instead of the knife confiuration" do
|
427
511
|
subject.config[:secret] = "cli-provided-secret"
|
428
512
|
expect(bootstrap.config[:secret]).to eql("cli-provided-secret")
|
@@ -438,6 +522,10 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
438
522
|
expect(bootstrap.config[:secret_file]).to eql("sys-knife-secret-file")
|
439
523
|
end
|
440
524
|
|
525
|
+
it "sets encrypted_data_bag_secret_file" do
|
526
|
+
expect(bootstrap.config[:encrypted_data_bag_secret_file]).to eql("sys-knife-secret-file")
|
527
|
+
end
|
528
|
+
|
441
529
|
it "prefers using a provided value instead of the knife confiuration" do
|
442
530
|
subject.config[:secret_file] = "cli-provided-secret-file"
|
443
531
|
expect(bootstrap.config[:secret_file]).to eql("cli-provided-secret-file")
|
@@ -458,12 +546,41 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
458
546
|
end
|
459
547
|
end
|
460
548
|
|
549
|
+
describe 'S3 secret test cases' do
|
550
|
+
before do
|
551
|
+
Chef::Config[:knife][:s3_secret] =
|
552
|
+
's3://test.bucket/folder/encrypted_data_bag_secret'
|
553
|
+
@knife_ec2_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
|
554
|
+
@secret_content = "TEST DATA BAG SECRET\n"
|
555
|
+
allow(@knife_ec2_create).to receive(:s3_secret).and_return(@secret_content)
|
556
|
+
allow(Chef::Knife).to receive(:Bootstrap)
|
557
|
+
@bootstrap = @knife_ec2_create.bootstrap_for_linux_node(@new_ec2_server, @new_ec2_server.dns_name)
|
558
|
+
end
|
559
|
+
|
560
|
+
context 'when s3 secret option is passed' do
|
561
|
+
it 'sets the s3 secret value to cl_secret key' do
|
562
|
+
@knife_ec2_create.bootstrap_common_params(@bootstrap)
|
563
|
+
expect(Chef::Config[:knife][:cl_secret]).to eql(@secret_content)
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
context 'when s3 secret option is not passed' do
|
568
|
+
it 'sets the cl_secret value to nil' do
|
569
|
+
Chef::Config[:knife].delete(:s3_secret)
|
570
|
+
Chef::Config[:knife].delete(:cl_secret)
|
571
|
+
@knife_ec2_create.bootstrap_common_params(@bootstrap)
|
572
|
+
expect(Chef::Config[:knife][:cl_secret]).to eql(nil)
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
461
577
|
context "when deprecated aws_ssh_key_id option is used in knife config and no ssh-key is supplied on the CLI" do
|
462
578
|
before do
|
463
579
|
Chef::Config[:knife][:aws_ssh_key_id] = "mykey"
|
464
580
|
Chef::Config[:knife].delete(:ssh_key_name)
|
465
581
|
@aws_key = Chef::Config[:knife][:aws_ssh_key_id]
|
466
582
|
allow(@knife_ec2_create).to receive(:ami).and_return(false)
|
583
|
+
allow(@knife_ec2_create).to receive(:validate_nics!).and_return(true)
|
467
584
|
end
|
468
585
|
|
469
586
|
it "gives warning message and creates the attribute with the required name" do
|
@@ -478,6 +595,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
478
595
|
Chef::Config[:knife][:aws_ssh_key_id] = "mykey"
|
479
596
|
@aws_key = Chef::Config[:knife][:aws_ssh_key_id]
|
480
597
|
allow(@knife_ec2_create).to receive(:ami).and_return(false)
|
598
|
+
allow(@knife_ec2_create).to receive(:validate_nics!).and_return(true)
|
481
599
|
end
|
482
600
|
|
483
601
|
it "gives warning message and gives preference to CLI value over knife config's value" do
|
@@ -491,6 +609,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
491
609
|
before do
|
492
610
|
Chef::Config[:knife][:ssh_key_name] = "mykey"
|
493
611
|
allow(@knife_ec2_create).to receive(:ami).and_return(false)
|
612
|
+
allow(@knife_ec2_create).to receive(:validate_nics!).and_return(true)
|
494
613
|
end
|
495
614
|
|
496
615
|
it "does nothing" do
|
@@ -521,7 +640,9 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
521
640
|
@knife_ec2_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb'
|
522
641
|
@knife_ec2_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
|
523
642
|
@knife_ec2_create.config[:run_list] = ['role[base]']
|
524
|
-
@knife_ec2_create.config[:
|
643
|
+
@knife_ec2_create.config[:first_boot_attributes] = "{'my_attributes':{'foo':'bar'}"
|
644
|
+
@knife_ec2_create.config[:first_boot_attributes_from_file] = "{'my_attributes':{'foo':'bar'}"
|
645
|
+
|
525
646
|
|
526
647
|
@bootstrap = @knife_ec2_create.bootstrap_for_linux_node(@new_ec2_server, @new_ec2_server.dns_name)
|
527
648
|
end
|
@@ -539,6 +660,10 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
539
660
|
expect(@bootstrap.config[:first_boot_attributes]).to eq("{'my_attributes':{'foo':'bar'}")
|
540
661
|
end
|
541
662
|
|
663
|
+
it "should set the bootstrap 'first_boot_attributes_from_file' correctly" do
|
664
|
+
expect(@bootstrap.config[:first_boot_attributes_from_file]).to eq("{'my_attributes':{'foo':'bar'}")
|
665
|
+
end
|
666
|
+
|
542
667
|
it "configures sets the bootstrap's run_list" do
|
543
668
|
expect(@bootstrap.config[:run_list]).to eq(['role[base]'])
|
544
669
|
end
|
@@ -613,7 +738,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
613
738
|
expect(@bootstrap.config[:forward_agent]).to eq(true)
|
614
739
|
end
|
615
740
|
end
|
616
|
-
|
741
|
+
|
617
742
|
describe "when configuring the winrm bootstrap process for windows" do
|
618
743
|
before do
|
619
744
|
allow(@knife_ec2_create).to receive(:fetch_server_fqdn).and_return("SERVERNAME")
|
@@ -628,8 +753,8 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
628
753
|
@knife_ec2_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb'
|
629
754
|
@knife_ec2_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
|
630
755
|
@knife_ec2_create.config[:run_list] = ['role[base]']
|
631
|
-
@knife_ec2_create.config[:
|
632
|
-
@knife_ec2_create.config[:winrm_ssl_verify_mode] = '
|
756
|
+
@knife_ec2_create.config[:first_boot_attributes] = "{'my_attributes':{'foo':'bar'}"
|
757
|
+
@knife_ec2_create.config[:winrm_ssl_verify_mode] = 'verify_peer'
|
633
758
|
@knife_ec2_create.config[:msi_url] = 'https://opscode-omnibus-packages.s3.amazonaws.com/windows/2008r2/x86_64/chef-client-12.3.0-1.msi'
|
634
759
|
@knife_ec2_create.config[:install_as_service] = true
|
635
760
|
@knife_ec2_create.config[:session_timeout] = "90"
|
@@ -679,7 +804,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
679
804
|
end
|
680
805
|
|
681
806
|
it "should set the bootstrap 'winrm_ssl_verify_mode' correctly" do
|
682
|
-
expect(@bootstrap.config[:winrm_ssl_verify_mode]).to eq("
|
807
|
+
expect(@bootstrap.config[:winrm_ssl_verify_mode]).to eq("verify_peer")
|
683
808
|
end
|
684
809
|
|
685
810
|
it "should set the bootstrap 'msi_url' correctly" do
|
@@ -764,7 +889,75 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
764
889
|
@knife_ec2_create.validate!
|
765
890
|
expect(Chef::Config[:knife][:aws_access_key_id]).to eq(@access_key_id)
|
766
891
|
expect(Chef::Config[:knife][:aws_secret_access_key]).to eq(@secret_key)
|
767
|
-
end
|
892
|
+
end
|
893
|
+
|
894
|
+
context "when invalid --aws-profile is given" do
|
895
|
+
it "raises exception" do
|
896
|
+
Chef::Config[:knife][:aws_profile] = 'xyz'
|
897
|
+
allow(File).to receive(:read).and_return("[default]\naws_access_key_id=TESTKEY\r\naws_secret_access_key=TESTSECRET")
|
898
|
+
expect{ @knife_ec2_create.validate! }.to raise_error("The provided --aws-profile 'xyz' is invalid.")
|
899
|
+
end
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
|
904
|
+
describe "when reading aws_config_file" do
|
905
|
+
before do
|
906
|
+
Chef::Config[:knife][:aws_config_file] = '/apple/pear'
|
907
|
+
@region = 'region'
|
908
|
+
end
|
909
|
+
|
910
|
+
it "reads UNIX Line endings" do
|
911
|
+
allow(File).to receive(:read).
|
912
|
+
and_return("[default]\r\nregion=#{@region}")
|
913
|
+
@knife_ec2_create.validate!
|
914
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
915
|
+
end
|
916
|
+
|
917
|
+
it "reads DOS Line endings" do
|
918
|
+
allow(File).to receive(:read).
|
919
|
+
and_return("[default]\r\nregion=#{@region}")
|
920
|
+
@knife_ec2_create.validate!
|
921
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
922
|
+
end
|
923
|
+
it "reads UNIX Line endings for new format" do
|
924
|
+
allow(File).to receive(:read).
|
925
|
+
and_return("[default]\nregion=#{@region}")
|
926
|
+
@knife_ec2_create.validate!
|
927
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
928
|
+
end
|
929
|
+
|
930
|
+
it "reads DOS Line endings for new format" do
|
931
|
+
allow(File).to receive(:read).
|
932
|
+
and_return("[default]\nregion=#{@region}")
|
933
|
+
@knife_ec2_create.validate!
|
934
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
935
|
+
end
|
936
|
+
|
937
|
+
it "loads the correct profile" do
|
938
|
+
Chef::Config[:knife][:aws_profile] = 'other'
|
939
|
+
allow(File).to receive(:read).
|
940
|
+
and_return("[default]\nregion=TESTREGION\n\n[profile other]\nregion=#{@region}")
|
941
|
+
@knife_ec2_create.validate!
|
942
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
943
|
+
end
|
944
|
+
|
945
|
+
context "when invalid --aws-profile is given" do
|
946
|
+
it "raises exception" do
|
947
|
+
Chef::Config[:knife][:aws_profile] = 'xyz'
|
948
|
+
allow(File).to receive(:read).and_return("[default]\nregion=TESTREGION")
|
949
|
+
expect{ @knife_ec2_create.validate! }.to raise_error("The provided --aws-profile 'profile xyz' is invalid.")
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
context "when aws_profile is passed a 'default' from CLI or knife.rb file" do
|
954
|
+
it 'loads the default profile successfully' do
|
955
|
+
Chef::Config[:knife][:aws_profile] = 'default'
|
956
|
+
allow(File).to receive(:read).and_return("[default]\nregion=#{@region}\n\n[profile other]\nregion=TESTREGION")
|
957
|
+
@knife_ec2_create.validate!
|
958
|
+
expect(Chef::Config[:knife][:region]).to eq(@region)
|
959
|
+
end
|
960
|
+
end
|
768
961
|
end
|
769
962
|
|
770
963
|
it 'understands that file:// validation key URIs are just paths' do
|
@@ -782,10 +975,33 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
782
975
|
end
|
783
976
|
|
784
977
|
it "disallows security group names when using a VPC" do
|
785
|
-
@knife_ec2_create.config[:subnet_id] =
|
978
|
+
@knife_ec2_create.config[:subnet_id] = @subnet_1_id
|
979
|
+
@knife_ec2_create.config[:security_group_ids] = 'sg-aabbccdd'
|
980
|
+
@knife_ec2_create.config[:security_groups] = 'groupname'
|
981
|
+
|
982
|
+
allow(@ec2_connection).to receive_message_chain(:subnets, :get).with(@subnet_1_id).and_return(@subnet_1)
|
983
|
+
|
984
|
+
expect { @knife_ec2_create.validate! }.to raise_error(SystemExit)
|
985
|
+
end
|
986
|
+
|
987
|
+
it 'disallows invalid network interface ids' do
|
988
|
+
@knife_ec2_create.config[:network_interfaces] = ['INVALID_ID']
|
989
|
+
|
990
|
+
expect { @knife_ec2_create.validate! }.to raise_error(SystemExit)
|
991
|
+
end
|
992
|
+
|
993
|
+
it 'disallows network interfaces not in the right VPC' do
|
994
|
+
@knife_ec2_create.config[:subnet_id] = @subnet_1_id
|
786
995
|
@knife_ec2_create.config[:security_group_ids] = 'sg-aabbccdd'
|
787
996
|
@knife_ec2_create.config[:security_groups] = 'groupname'
|
788
997
|
|
998
|
+
allow(@ec2_connection).to receive_message_chain(:subnets, :get).with(@subnet_1_id).and_return(@subnet_1)
|
999
|
+
|
1000
|
+
allow(@ec2_connection).to receive_message_chain(:network_interfaces, :all).and_return [
|
1001
|
+
double('network_interfaces', network_interface_id: 'eni-12345678', vpc_id: 'another_vpc'),
|
1002
|
+
double('network_interfaces', network_interface_id: 'eni-87654321', vpc_id: @my_vpc)
|
1003
|
+
]
|
1004
|
+
|
789
1005
|
expect { @knife_ec2_create.validate! }.to raise_error SystemExit
|
790
1006
|
end
|
791
1007
|
|
@@ -809,6 +1025,23 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
809
1025
|
expect { @knife_ec2_create.validate! }.to raise_error SystemExit
|
810
1026
|
end
|
811
1027
|
|
1028
|
+
it "disallows setting only one of the two ClassicLink options" do
|
1029
|
+
@knife_ec2_create.config[:classic_link_vpc_id] = @vpc_id
|
1030
|
+
@knife_ec2_create.config[:classic_link_vpc_security_group_ids] = nil
|
1031
|
+
|
1032
|
+
expect { @knife_ec2_create.validate! }.to raise_error SystemExit
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
it "disallows ClassicLink with VPC" do
|
1036
|
+
@knife_ec2_create.config[:subnet_id] = 'subnet-1a2b3c4d'
|
1037
|
+
@knife_ec2_create.config[:classic_link_vpc_id] = @vpc_id
|
1038
|
+
@knife_ec2_create.config[:classic_link_vpc_security_group_ids] = @vpc_security_group_ids
|
1039
|
+
|
1040
|
+
allow(@knife_ec2_create).to receive(:validate_nics!).and_return(true)
|
1041
|
+
|
1042
|
+
expect { @knife_ec2_create.validate! }.to raise_error SystemExit
|
1043
|
+
end
|
1044
|
+
|
812
1045
|
it "disallows ebs provisioned iops option when not using ebs volume type" do
|
813
1046
|
@knife_ec2_create.config[:ebs_provisioned_iops] = "123"
|
814
1047
|
@knife_ec2_create.config[:ebs_volume_type] = nil
|
@@ -1151,8 +1384,8 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
1151
1384
|
describe "ssh_connect_host" do
|
1152
1385
|
before(:each) do
|
1153
1386
|
allow(@new_ec2_server).to receive_messages(
|
1154
|
-
:dns_name => '
|
1155
|
-
:private_ip_address => '
|
1387
|
+
:dns_name => 'public.example.org',
|
1388
|
+
:private_ip_address => '192.168.1.100',
|
1156
1389
|
:custom => 'custom',
|
1157
1390
|
:public_ip_address => '111.111.111.111'
|
1158
1391
|
)
|
@@ -1161,7 +1394,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
1161
1394
|
|
1162
1395
|
describe "by default" do
|
1163
1396
|
it 'should use public dns name' do
|
1164
|
-
expect(@knife_ec2_create.ssh_connect_host).to eq('
|
1397
|
+
expect(@knife_ec2_create.ssh_connect_host).to eq('public.example.org')
|
1165
1398
|
end
|
1166
1399
|
end
|
1167
1400
|
|
@@ -1172,10 +1405,29 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
1172
1405
|
end
|
1173
1406
|
end
|
1174
1407
|
|
1175
|
-
|
1176
|
-
|
1408
|
+
context "when vpc_mode? is true" do
|
1409
|
+
before do
|
1177
1410
|
allow(@knife_ec2_create).to receive_messages(:vpc_mode? => true)
|
1178
|
-
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
context "--associate-public-ip is specified" do
|
1414
|
+
it "uses the dns_name or public_ip_address" do
|
1415
|
+
@knife_ec2_create.config[:associate_public_ip] = true
|
1416
|
+
expect(@knife_ec2_create.ssh_connect_host).to eq('public.example.org')
|
1417
|
+
end
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
context "--associate-eip is specified" do
|
1421
|
+
it "uses the dns_name or public_ip_address" do
|
1422
|
+
@knife_ec2_create.config[:associate_eip] = '111.111.111.111'
|
1423
|
+
expect(@knife_ec2_create.ssh_connect_host).to eq('public.example.org')
|
1424
|
+
end
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
context "with no other ip flags" do
|
1428
|
+
it 'uses private_ip_address' do
|
1429
|
+
expect(@knife_ec2_create.ssh_connect_host).to eq('192.168.1.100')
|
1430
|
+
end
|
1179
1431
|
end
|
1180
1432
|
end
|
1181
1433
|
|
@@ -1278,4 +1530,663 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
1278
1530
|
expect(@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22)).to be_falsey
|
1279
1531
|
end
|
1280
1532
|
end
|
1533
|
+
|
1534
|
+
describe 'ssl_config_user_data' do
|
1535
|
+
before do
|
1536
|
+
@knife_ec2_create.config[:winrm_password] = "ec2@123"
|
1537
|
+
end
|
1538
|
+
|
1539
|
+
context 'For domain user' do
|
1540
|
+
before do
|
1541
|
+
@knife_ec2_create.config[:winrm_user] = "domain\\ec2"
|
1542
|
+
@ssl_config_data = <<-EOH
|
1543
|
+
|
1544
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1545
|
+
winrm quickconfig -q
|
1546
|
+
}
|
1547
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1548
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1549
|
+
}
|
1550
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1551
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1552
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1553
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1554
|
+
iex $create_listener_cmd
|
1555
|
+
|
1556
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1557
|
+
|
1558
|
+
EOH
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
it 'gets ssl config user data' do
|
1562
|
+
expect(@knife_ec2_create.ssl_config_user_data).to be == @ssl_config_data
|
1563
|
+
end
|
1564
|
+
end
|
1565
|
+
|
1566
|
+
context 'For local user' do
|
1567
|
+
before do
|
1568
|
+
@knife_ec2_create.config[:winrm_user] = ".\\ec2"
|
1569
|
+
@ssl_config_data = <<-EOH
|
1570
|
+
net user /add ec2 ec2@123;
|
1571
|
+
net localgroup Administrators /add ec2;
|
1572
|
+
|
1573
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1574
|
+
winrm quickconfig -q
|
1575
|
+
}
|
1576
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1577
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1578
|
+
}
|
1579
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1580
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1581
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1582
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1583
|
+
iex $create_listener_cmd
|
1584
|
+
|
1585
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1586
|
+
|
1587
|
+
EOH
|
1588
|
+
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
it 'gets ssl config user data' do
|
1592
|
+
expect(@knife_ec2_create.ssl_config_user_data).to be == @ssl_config_data
|
1593
|
+
end
|
1594
|
+
end
|
1595
|
+
end
|
1596
|
+
|
1597
|
+
describe 'ssl_config_data_already_exist?' do
|
1598
|
+
|
1599
|
+
before(:each) do
|
1600
|
+
@user_user_data = 'user_user_data.ps1'
|
1601
|
+
@knife_ec2_create.config[:winrm_user] = "domain\\ec2"
|
1602
|
+
@knife_ec2_create.config[:winrm_password] = "ec2@123"
|
1603
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
context 'ssl config data does not exist in user supplied user_data' do
|
1607
|
+
before do
|
1608
|
+
File.open(@user_user_data,"w+") do |f|
|
1609
|
+
f.write <<-EOH
|
1610
|
+
user_command_1\\\\user_command_2\\\\user_command_3
|
1611
|
+
user_command_4
|
1612
|
+
EOH
|
1613
|
+
end
|
1614
|
+
end
|
1615
|
+
|
1616
|
+
it 'returns false' do
|
1617
|
+
expect(@knife_ec2_create.ssl_config_data_already_exist?).to eq(false)
|
1618
|
+
end
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
context 'ssl config data already exist in user supplied user_data' do
|
1622
|
+
before do
|
1623
|
+
File.open(@user_user_data,"w+") do |f|
|
1624
|
+
f.write <<-EOH
|
1625
|
+
user_command_1
|
1626
|
+
user_command_2
|
1627
|
+
|
1628
|
+
<powershell>
|
1629
|
+
|
1630
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1631
|
+
winrm quickconfig -q
|
1632
|
+
}
|
1633
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1634
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1635
|
+
}
|
1636
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1637
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1638
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1639
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1640
|
+
iex $create_listener_cmd
|
1641
|
+
|
1642
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1643
|
+
|
1644
|
+
</powershell>
|
1645
|
+
|
1646
|
+
EOH
|
1647
|
+
end
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
it 'returns false' do
|
1651
|
+
expect(@knife_ec2_create.ssl_config_data_already_exist?).to eq(true)
|
1652
|
+
end
|
1653
|
+
end
|
1654
|
+
|
1655
|
+
after(:each) do
|
1656
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1657
|
+
FileUtils.rm_rf @user_user_data
|
1658
|
+
end
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
describe 'attach ssl config into user data when transport is ssl' do
|
1662
|
+
before(:each) do
|
1663
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
1664
|
+
Chef::Config[:knife][:ssh_key_name] = "mykey"
|
1665
|
+
@knife_ec2_create.config[:ssh_key_name] = "ssh_key_name"
|
1666
|
+
@knife_ec2_create.config[:winrm_transport] = "ssl"
|
1667
|
+
@knife_ec2_create.config[:create_ssl_listener] = true
|
1668
|
+
@knife_ec2_create.config[:winrm_user] = "domain\\ec2"
|
1669
|
+
@knife_ec2_create.config[:winrm_password] = "ec2@123"
|
1670
|
+
end
|
1671
|
+
|
1672
|
+
context 'when user_data script provided by user contains only <script> section' do
|
1673
|
+
before do
|
1674
|
+
@user_user_data = 'user_user_data.ps1'
|
1675
|
+
File.open(@user_user_data,"w+") do |f|
|
1676
|
+
f.write <<-EOH
|
1677
|
+
<script>
|
1678
|
+
|
1679
|
+
ipconfig > c:\\ipconfig_data.txt
|
1680
|
+
|
1681
|
+
</script>
|
1682
|
+
EOH
|
1683
|
+
end
|
1684
|
+
@server_def_user_data = <<-EOH
|
1685
|
+
<script>
|
1686
|
+
|
1687
|
+
ipconfig > c:\\ipconfig_data.txt
|
1688
|
+
|
1689
|
+
</script>
|
1690
|
+
|
1691
|
+
|
1692
|
+
<powershell>
|
1693
|
+
|
1694
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1695
|
+
winrm quickconfig -q
|
1696
|
+
}
|
1697
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1698
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1699
|
+
}
|
1700
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1701
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1702
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1703
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1704
|
+
iex $create_listener_cmd
|
1705
|
+
|
1706
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1707
|
+
|
1708
|
+
</powershell>
|
1709
|
+
EOH
|
1710
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
it "appends ssl config to user supplied user_data after <script> tag section" do
|
1714
|
+
server_def = @knife_ec2_create.create_server_def
|
1715
|
+
|
1716
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
after do
|
1720
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1721
|
+
FileUtils.rm_rf @user_user_data
|
1722
|
+
end
|
1723
|
+
end
|
1724
|
+
|
1725
|
+
context 'when user_data script provided by user contains <powershell> section' do
|
1726
|
+
before do
|
1727
|
+
@user_user_data = 'user_user_data.ps1'
|
1728
|
+
File.open(@user_user_data,"w+") do |f|
|
1729
|
+
f.write <<-EOH
|
1730
|
+
<powershell>
|
1731
|
+
|
1732
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1733
|
+
</powershell>
|
1734
|
+
EOH
|
1735
|
+
end
|
1736
|
+
@server_def_user_data = <<-EOH
|
1737
|
+
<powershell>
|
1738
|
+
|
1739
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1740
|
+
|
1741
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1742
|
+
winrm quickconfig -q
|
1743
|
+
}
|
1744
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1745
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1746
|
+
}
|
1747
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1748
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1749
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1750
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1751
|
+
iex $create_listener_cmd
|
1752
|
+
|
1753
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1754
|
+
|
1755
|
+
</powershell>
|
1756
|
+
EOH
|
1757
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1758
|
+
end
|
1759
|
+
|
1760
|
+
it "appends ssl config to user supplied user_data at the end of <powershell> tag section" do
|
1761
|
+
server_def = @knife_ec2_create.create_server_def
|
1762
|
+
|
1763
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1764
|
+
end
|
1765
|
+
|
1766
|
+
after do
|
1767
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1768
|
+
FileUtils.rm_rf @user_user_data
|
1769
|
+
end
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
context 'when user_data script provided by user already contains ssl config code' do
|
1773
|
+
before do
|
1774
|
+
@user_user_data = 'user_user_data.ps1'
|
1775
|
+
File.open(@user_user_data,"w+") do |f|
|
1776
|
+
f.write <<-EOH
|
1777
|
+
<powershell>
|
1778
|
+
|
1779
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1780
|
+
|
1781
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1782
|
+
winrm quickconfig -q
|
1783
|
+
}
|
1784
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1785
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1786
|
+
}
|
1787
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1788
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1789
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1790
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1791
|
+
iex $create_listener_cmd
|
1792
|
+
|
1793
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1794
|
+
|
1795
|
+
</powershell>
|
1796
|
+
EOH
|
1797
|
+
end
|
1798
|
+
@server_def_user_data = <<-EOH
|
1799
|
+
<powershell>
|
1800
|
+
|
1801
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1802
|
+
|
1803
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1804
|
+
winrm quickconfig -q
|
1805
|
+
}
|
1806
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1807
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1808
|
+
}
|
1809
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1810
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1811
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1812
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1813
|
+
iex $create_listener_cmd
|
1814
|
+
|
1815
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1816
|
+
|
1817
|
+
</powershell>
|
1818
|
+
EOH
|
1819
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1820
|
+
end
|
1821
|
+
|
1822
|
+
it "does no modifications and passes user_data as it is to server_def" do
|
1823
|
+
server_def = @knife_ec2_create.create_server_def
|
1824
|
+
|
1825
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1826
|
+
end
|
1827
|
+
|
1828
|
+
after do
|
1829
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1830
|
+
FileUtils.rm_rf @user_user_data
|
1831
|
+
end
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
context 'when user_data script provided by user has invalid syntax' do
|
1835
|
+
before do
|
1836
|
+
@user_user_data = 'user_user_data.ps1'
|
1837
|
+
File.open(@user_user_data,"w+") do |f|
|
1838
|
+
f.write <<-EOH
|
1839
|
+
<powershell>
|
1840
|
+
|
1841
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1842
|
+
|
1843
|
+
<script>
|
1844
|
+
|
1845
|
+
ipconfig > c:\\ipconfig_data.txt
|
1846
|
+
|
1847
|
+
</script>
|
1848
|
+
EOH
|
1849
|
+
end
|
1850
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
it "gives error and exits" do
|
1854
|
+
expect(@knife_ec2_create.ui).to receive(:error).with("Provided user_data file is invalid.")
|
1855
|
+
expect { @knife_ec2_create.create_server_def }.to raise_error SystemExit
|
1856
|
+
end
|
1857
|
+
|
1858
|
+
after do
|
1859
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1860
|
+
FileUtils.rm_rf @user_user_data
|
1861
|
+
end
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
context 'when user_data script provided by user has <powershell> and <script> tag sections' do
|
1865
|
+
before do
|
1866
|
+
@user_user_data = 'user_user_data.ps1'
|
1867
|
+
File.open(@user_user_data,"w+") do |f|
|
1868
|
+
f.write <<-EOH
|
1869
|
+
<powershell>
|
1870
|
+
|
1871
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1872
|
+
|
1873
|
+
</powershell>
|
1874
|
+
<script>
|
1875
|
+
|
1876
|
+
ipconfig > c:\\ipconfig_data.txt
|
1877
|
+
|
1878
|
+
</script>
|
1879
|
+
EOH
|
1880
|
+
end
|
1881
|
+
@server_def_user_data = <<-EOH
|
1882
|
+
<powershell>
|
1883
|
+
|
1884
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1885
|
+
|
1886
|
+
|
1887
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1888
|
+
winrm quickconfig -q
|
1889
|
+
}
|
1890
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1891
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1892
|
+
}
|
1893
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1894
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1895
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1896
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1897
|
+
iex $create_listener_cmd
|
1898
|
+
|
1899
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1900
|
+
|
1901
|
+
</powershell>
|
1902
|
+
<script>
|
1903
|
+
|
1904
|
+
ipconfig > c:\\ipconfig_data.txt
|
1905
|
+
|
1906
|
+
</script>
|
1907
|
+
EOH
|
1908
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
it "appends ssl config to user supplied user_data at the end of <powershell> tag section" do
|
1912
|
+
server_def = @knife_ec2_create.create_server_def
|
1913
|
+
|
1914
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
after do
|
1918
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1919
|
+
FileUtils.rm_rf @user_user_data
|
1920
|
+
end
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
context "when user_data is not supplied by user on cli" do
|
1924
|
+
before do
|
1925
|
+
@server_def_user_data = <<-EOH
|
1926
|
+
<powershell>
|
1927
|
+
|
1928
|
+
If (-Not (Get-Service WinRM | Where-Object {$_.status -eq "Running"})) {
|
1929
|
+
winrm quickconfig -q
|
1930
|
+
}
|
1931
|
+
If (winrm e winrm/config/listener | Select-String -Pattern " Transport = HTTP\\b" -Quiet) {
|
1932
|
+
winrm delete winrm/config/listener?Address=*+Transport=HTTP
|
1933
|
+
}
|
1934
|
+
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
|
1935
|
+
New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
|
1936
|
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
|
1937
|
+
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
|
1938
|
+
iex $create_listener_cmd
|
1939
|
+
|
1940
|
+
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes
|
1941
|
+
|
1942
|
+
</powershell>
|
1943
|
+
EOH
|
1944
|
+
end
|
1945
|
+
|
1946
|
+
it "creates user_data only with default ssl configuration" do
|
1947
|
+
server_def = @knife_ec2_create.create_server_def
|
1948
|
+
|
1949
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1950
|
+
end
|
1951
|
+
end
|
1952
|
+
|
1953
|
+
context "when user has specified --no-create-ssl-listener along with his/her own user_data on cli" do
|
1954
|
+
before do
|
1955
|
+
@knife_ec2_create.config[:create_ssl_listener] = false
|
1956
|
+
@user_user_data = 'user_user_data.ps1'
|
1957
|
+
File.open(@user_user_data,"w+") do |f|
|
1958
|
+
f.write <<-EOH
|
1959
|
+
<powershell>
|
1960
|
+
|
1961
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1962
|
+
|
1963
|
+
</powershell>
|
1964
|
+
<script>
|
1965
|
+
|
1966
|
+
ipconfig > c:\\ipconfig_data.txt
|
1967
|
+
|
1968
|
+
</script>
|
1969
|
+
EOH
|
1970
|
+
end
|
1971
|
+
@server_def_user_data = <<-EOH
|
1972
|
+
<powershell>
|
1973
|
+
|
1974
|
+
Get-DscLocalConfigurationManager > c:\\dsc_data.txt
|
1975
|
+
|
1976
|
+
</powershell>
|
1977
|
+
<script>
|
1978
|
+
|
1979
|
+
ipconfig > c:\\ipconfig_data.txt
|
1980
|
+
|
1981
|
+
</script>
|
1982
|
+
EOH
|
1983
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
it "does not attach ssl config into the user_data supplied by user on cli" do
|
1987
|
+
server_def = @knife_ec2_create.create_server_def
|
1988
|
+
|
1989
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
1990
|
+
end
|
1991
|
+
|
1992
|
+
after do
|
1993
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
1994
|
+
FileUtils.rm_rf @user_user_data
|
1995
|
+
end
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
context "when user has specified --no-create-ssl-listener with no user_data on cli" do
|
1999
|
+
before do
|
2000
|
+
@knife_ec2_create.config[:create_ssl_listener] = false
|
2001
|
+
@server_def_user_data = nil
|
2002
|
+
end
|
2003
|
+
|
2004
|
+
it "creates nil or empty user_data" do
|
2005
|
+
server_def = @knife_ec2_create.create_server_def
|
2006
|
+
|
2007
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
2008
|
+
end
|
2009
|
+
end
|
2010
|
+
|
2011
|
+
after(:each) do
|
2012
|
+
@knife_ec2_create.config.delete(:ssh_key_name)
|
2013
|
+
Chef::Config[:knife].delete(:ssh_key_name)
|
2014
|
+
@knife_ec2_create.config.delete(:winrm_transport)
|
2015
|
+
@knife_ec2_create.config.delete(:create_ssl_listener)
|
2016
|
+
end
|
2017
|
+
end
|
2018
|
+
|
2019
|
+
describe "do not attach ssl config into user data when transport is plaintext" do
|
2020
|
+
before(:each) do
|
2021
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2022
|
+
Chef::Config[:knife][:ssh_key_name] = "mykey"
|
2023
|
+
@knife_ec2_create.config[:ssh_key_name] = "ssh_key_name"
|
2024
|
+
@knife_ec2_create.config[:winrm_transport] = "plaintext"
|
2025
|
+
end
|
2026
|
+
|
2027
|
+
context "when user_data is supplied on cli" do
|
2028
|
+
before do
|
2029
|
+
@user_user_data = 'user_user_data.ps1'
|
2030
|
+
File.open(@user_user_data,"w+") do |f|
|
2031
|
+
f.write <<-EOH
|
2032
|
+
<script>
|
2033
|
+
|
2034
|
+
ipconfig > c:\\ipconfig_data.txt
|
2035
|
+
netstat > c:\\netstat_data.txt
|
2036
|
+
|
2037
|
+
</script>
|
2038
|
+
EOH
|
2039
|
+
end
|
2040
|
+
@knife_ec2_create.config[:aws_user_data] = @user_user_data
|
2041
|
+
@server_def_user_data = <<-EOH
|
2042
|
+
<script>
|
2043
|
+
|
2044
|
+
ipconfig > c:\\ipconfig_data.txt
|
2045
|
+
netstat > c:\\netstat_data.txt
|
2046
|
+
|
2047
|
+
</script>
|
2048
|
+
EOH
|
2049
|
+
end
|
2050
|
+
|
2051
|
+
it "user_data is created only with user's user_data" do
|
2052
|
+
server_def = @knife_ec2_create.create_server_def
|
2053
|
+
|
2054
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
2055
|
+
end
|
2056
|
+
|
2057
|
+
after do
|
2058
|
+
@knife_ec2_create.config.delete(:aws_user_data)
|
2059
|
+
FileUtils.rm_rf @user_user_data
|
2060
|
+
end
|
2061
|
+
end
|
2062
|
+
|
2063
|
+
context "when user_data is not supplied on cli" do
|
2064
|
+
before do
|
2065
|
+
@server_def_user_data = nil
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
it "creates nil or empty user_data" do
|
2069
|
+
server_def = @knife_ec2_create.create_server_def
|
2070
|
+
|
2071
|
+
expect(server_def[:user_data]).to eq(@server_def_user_data)
|
2072
|
+
end
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
after(:each) do
|
2076
|
+
@knife_ec2_create.config.delete(:ssh_key_name)
|
2077
|
+
Chef::Config[:knife].delete(:ssh_key_name)
|
2078
|
+
@knife_ec2_create.config.delete(:winrm_transport)
|
2079
|
+
end
|
2080
|
+
end
|
2081
|
+
|
2082
|
+
describe 'disable_api_termination option' do
|
2083
|
+
context 'spot instance' do
|
2084
|
+
context 'disable_api_termination is not passed on CLI or in knife config' do
|
2085
|
+
before do
|
2086
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2087
|
+
@knife_ec2_create.config[:spot_price] = 0.001
|
2088
|
+
end
|
2089
|
+
|
2090
|
+
it "does not set disable_api_termination option in server_def" do
|
2091
|
+
server_def = @knife_ec2_create.create_server_def
|
2092
|
+
expect(server_def[:disable_api_termination]).to be == nil
|
2093
|
+
end
|
2094
|
+
|
2095
|
+
it "does not raise error" do
|
2096
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
2097
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2098
|
+
)
|
2099
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
2100
|
+
end
|
2101
|
+
end
|
2102
|
+
|
2103
|
+
context 'disable_api_termination is passed on CLI' do
|
2104
|
+
before do
|
2105
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2106
|
+
@knife_ec2_create.config[:spot_price] = 0.001
|
2107
|
+
@knife_ec2_create.config[:disable_api_termination] = true
|
2108
|
+
end
|
2109
|
+
|
2110
|
+
it "raises error" do
|
2111
|
+
expect(@knife_ec2_create.ui).to receive(:error).with(
|
2112
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2113
|
+
)
|
2114
|
+
expect { @knife_ec2_create.validate! }.to raise_error(SystemExit)
|
2115
|
+
end
|
2116
|
+
end
|
2117
|
+
|
2118
|
+
context 'disable_api_termination is passed in knife config' do
|
2119
|
+
before do
|
2120
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2121
|
+
@knife_ec2_create.config[:spot_price] = 0.001
|
2122
|
+
Chef::Config[:knife][:disable_api_termination] = true
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
it "raises error" do
|
2126
|
+
expect(@knife_ec2_create.ui).to receive(:error).with(
|
2127
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2128
|
+
)
|
2129
|
+
expect { @knife_ec2_create.validate! }.to raise_error(SystemExit)
|
2130
|
+
end
|
2131
|
+
end
|
2132
|
+
end
|
2133
|
+
|
2134
|
+
context 'non-spot instance' do
|
2135
|
+
context 'when disable_api_termination option is not passed on the CLI or in the knife config' do
|
2136
|
+
before do
|
2137
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2138
|
+
end
|
2139
|
+
|
2140
|
+
it "sets disable_api_termination option in server_def with value as false" do
|
2141
|
+
server_def = @knife_ec2_create.create_server_def
|
2142
|
+
expect(server_def[:disable_api_termination]).to be == false
|
2143
|
+
end
|
2144
|
+
|
2145
|
+
it "does not raise error" do
|
2146
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
2147
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2148
|
+
)
|
2149
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
2150
|
+
end
|
2151
|
+
end
|
2152
|
+
|
2153
|
+
context "when disable_api_termination option is passed on the CLI" do
|
2154
|
+
before do
|
2155
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2156
|
+
@knife_ec2_create.config[:disable_api_termination] = true
|
2157
|
+
end
|
2158
|
+
|
2159
|
+
it "sets disable_api_termination option in server_def with value as true" do
|
2160
|
+
server_def = @knife_ec2_create.create_server_def
|
2161
|
+
expect(server_def[:disable_api_termination]).to be == true
|
2162
|
+
end
|
2163
|
+
|
2164
|
+
it "does not raise error" do
|
2165
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
2166
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2167
|
+
)
|
2168
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
2169
|
+
end
|
2170
|
+
end
|
2171
|
+
|
2172
|
+
context "when disable_api_termination option is passed in the knife config" do
|
2173
|
+
before do
|
2174
|
+
allow(Fog::Compute::AWS).to receive(:new).and_return(@ec2_connection)
|
2175
|
+
Chef::Config[:knife][:disable_api_termination] = true
|
2176
|
+
end
|
2177
|
+
|
2178
|
+
it "sets disable_api_termination option in server_def with value as true" do
|
2179
|
+
server_def = @knife_ec2_create.create_server_def
|
2180
|
+
expect(server_def[:disable_api_termination]).to be == true
|
2181
|
+
end
|
2182
|
+
|
2183
|
+
it "does not raise error" do
|
2184
|
+
expect(@knife_ec2_create.ui).to_not receive(:error).with(
|
2185
|
+
"spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances."
|
2186
|
+
)
|
2187
|
+
expect { @knife_ec2_create.validate! }.to_not raise_error
|
2188
|
+
end
|
2189
|
+
end
|
2190
|
+
end
|
2191
|
+
end
|
1281
2192
|
end
|