knife-ec2 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|