knife-ec2 1.0.36 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/knife/ec2_ami_list.rb +8 -8
- data/lib/chef/knife/ec2_flavor_list.rb +1 -1
- data/lib/chef/knife/ec2_server_create.rb +151 -168
- data/lib/chef/knife/ec2_server_list.rb +2 -2
- data/lib/chef/knife/helpers/ec2_base.rb +28 -43
- data/lib/chef/knife/helpers/s3_source.rb +5 -5
- data/lib/knife-ec2/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe1ebf8d54dad92978109ce3af6069df518ccd163583dadff486b7492f798cf1
|
4
|
+
data.tar.gz: d8f036bc63ee4d7b30bd3656ebda5a8f4f2425b7e12b004e6603b9b909a23ae7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e5185a70b989ab3594cf73011e8c01f3cafb3449e22c64bc31012ab38d37cad35e7142e9b5070b80ad761f0fb38a623b374e26d20a25ee4ce9ef40eca7981cd
|
7
|
+
data.tar.gz: a93a5c8a752e0745c7c30dd2f42d20c718b83e21192da44a50920ed363e139d48f0bd2b36e511a17c3e8f33c8e6b7940d5ace38ff1d0426fefce0cd7a9a4369b
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Piyush Awasthi (<piyush.awasthi@msystechnologies.com>)
|
3
|
-
# Copyright:: Copyright (c)
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
# By default owner is aws-marketplace but you can specify following owner with the help of -o or --owner
|
28
28
|
# * self => Displays the list of AMIs created by the user
|
29
29
|
# * aws-marketplace => Displays all AMIs form trusted vendors like Ubuntu, Microsoft, SAP, Zend as well as many open source offering
|
30
|
-
# *
|
30
|
+
# * microsoft => Displays only Microsoft vendor AMIs
|
31
31
|
#
|
32
32
|
# == Platform
|
33
33
|
# By default all platform AMI's will display but you can filter your response
|
@@ -95,8 +95,8 @@ class Chef
|
|
95
95
|
all_data = {}
|
96
96
|
ec2_connection.describe_images(image_params).images.each do |v|
|
97
97
|
v_data = {}
|
98
|
-
if
|
99
|
-
next unless v.description.downcase.include?(
|
98
|
+
if config[:search]
|
99
|
+
next unless v.description.downcase.include?(config[:search].downcase)
|
100
100
|
end
|
101
101
|
|
102
102
|
%w{image_id platform description architecture}.each do |id|
|
@@ -112,16 +112,16 @@ class Chef
|
|
112
112
|
|
113
113
|
def image_params
|
114
114
|
params = {}
|
115
|
-
params["owners"] = [
|
115
|
+
params["owners"] = [config[:owner].to_s]
|
116
116
|
|
117
117
|
filters = []
|
118
|
-
if
|
118
|
+
if config[:platform]
|
119
119
|
filters << { name: "platform",
|
120
|
-
values: [
|
120
|
+
values: [config[:platform]] }
|
121
121
|
end
|
122
122
|
|
123
123
|
# TODO: Need to find substring to match in the description
|
124
|
-
# filters << { description:
|
124
|
+
# filters << { description: config[:search] } if config[:search]
|
125
125
|
|
126
126
|
if filters.length > 0
|
127
127
|
params["filters"] = filters
|
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
banner "knife ec2 flavor list (options) [DEPRECATED]"
|
28
28
|
|
29
29
|
def run
|
30
|
-
ui.error("knife ec2 flavor list has been deprecated as this functionality is not provided by the AWS API the previous
|
30
|
+
ui.error("knife ec2 flavor list has been deprecated as this functionality is not provided by the AWS API the previous implementation relied upon hardcoded values that were often incorrect. For an up to date list of instance types see https://www.ec2instances.info/")
|
31
31
|
exit 1
|
32
32
|
end
|
33
33
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
3
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
4
|
-
# Copyright:: Copyright (c)
|
4
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -28,9 +28,9 @@ class Chef
|
|
28
28
|
include Knife::Ec2Base
|
29
29
|
|
30
30
|
deps do
|
31
|
-
require "tempfile"
|
32
|
-
require "uri"
|
33
|
-
require "net/ssh"
|
31
|
+
require "tempfile" unless defined?(Tempfile)
|
32
|
+
require "uri" unless defined?(URI)
|
33
|
+
require "net/ssh" unless defined?(Net::SSH)
|
34
34
|
require "net/ssh/gateway"
|
35
35
|
Chef::Knife::Bootstrap.load_deps
|
36
36
|
end
|
@@ -43,14 +43,12 @@ class Chef
|
|
43
43
|
option :flavor,
|
44
44
|
short: "-f FLAVOR",
|
45
45
|
long: "--flavor FLAVOR",
|
46
|
-
description: "The flavor of server (m1.small, m1.medium, etc)"
|
47
|
-
proc: Proc.new { |f| Chef::Config[:knife][:flavor] = f }
|
46
|
+
description: "The flavor of server (m1.small, m1.medium, etc)"
|
48
47
|
|
49
48
|
option :image,
|
50
49
|
short: "-I IMAGE",
|
51
50
|
long: "--image IMAGE",
|
52
|
-
description: "The AMI for the server"
|
53
|
-
proc: Proc.new { |i| Chef::Config[:knife][:image] = i }
|
51
|
+
description: "The AMI for the server"
|
54
52
|
|
55
53
|
option :iam_instance_profile,
|
56
54
|
long: "--iam-profile NAME",
|
@@ -62,14 +60,14 @@ class Chef
|
|
62
60
|
description: "The security groups for this server; not allowed when using VPC",
|
63
61
|
proc: Proc.new { |groups| groups.split(",") }
|
64
62
|
|
65
|
-
option :
|
63
|
+
option :security_group_ids,
|
66
64
|
short: "-g SECURITY_GROUP_ID",
|
67
65
|
long: "--security-group-id ID",
|
68
66
|
description: "The security group id for this server; required when using VPC. Use the --security-group-id option multiple times when specifying multiple groups for e.g. -g sg-e985168d -g sg-e7f06383 -g sg-ec1b7e88.",
|
69
|
-
proc: Proc.new { |security_group_id|
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
proc: Proc.new { |security_group_id, accumulator|
|
68
|
+
accumulator ||= []
|
69
|
+
accumulator.push(security_group_id)
|
70
|
+
accumulator
|
73
71
|
}
|
74
72
|
|
75
73
|
option :associate_eip,
|
@@ -82,8 +80,7 @@ class Chef
|
|
82
80
|
|
83
81
|
option :placement_group,
|
84
82
|
long: "--placement-group PLACEMENT_GROUP",
|
85
|
-
description: "The placement group to place a cluster compute instance"
|
86
|
-
proc: Proc.new { |pg| Chef::Config[:knife][:placement_group] = pg }
|
83
|
+
description: "The placement group to place a cluster compute instance"
|
87
84
|
|
88
85
|
option :primary_eni,
|
89
86
|
long: "--primary-eni ENI_ID",
|
@@ -92,14 +89,12 @@ class Chef
|
|
92
89
|
option :availability_zone,
|
93
90
|
short: "-Z ZONE",
|
94
91
|
long: "--availability-zone ZONE",
|
95
|
-
description: "The Availability Zone"
|
96
|
-
proc: Proc.new { |key| Chef::Config[:knife][:availability_zone] = key }
|
92
|
+
description: "The Availability Zone"
|
97
93
|
|
98
94
|
option :ssh_key_name,
|
99
95
|
short: "-S KEY",
|
100
96
|
long: "--ssh-key KEY",
|
101
|
-
description: "The AWS SSH key id"
|
102
|
-
proc: Proc.new { |key| Chef::Config[:knife][:ssh_key_name] = key }
|
97
|
+
description: "The AWS SSH key id"
|
103
98
|
|
104
99
|
option :ebs_size,
|
105
100
|
long: "--ebs-size SIZE",
|
@@ -109,46 +104,41 @@ class Chef
|
|
109
104
|
long: "--ebs-optimized",
|
110
105
|
description: "Enabled optimized EBS I/O"
|
111
106
|
|
112
|
-
option :
|
113
|
-
long: "--ebs-
|
114
|
-
description: "
|
107
|
+
option :ebs_delete_on_term,
|
108
|
+
long: "--ebs-delete-on-term",
|
109
|
+
description: "Delete EBS volume on instance termination",
|
110
|
+
boolean: true,
|
111
|
+
default: true
|
115
112
|
|
116
113
|
option :secret,
|
117
114
|
long: "--secret ",
|
118
|
-
description: "The secret key to use to encrypt data bag item values"
|
119
|
-
proc: lambda { |s| Chef::Config[:knife][:secret] = s }
|
115
|
+
description: "The secret key to use to encrypt data bag item values"
|
120
116
|
|
121
117
|
option :secret_file,
|
122
118
|
long: "--secret-file SECRET_FILE",
|
123
|
-
description: "A file containing the secret key to use to encrypt data bag item values"
|
124
|
-
proc: lambda { |sf| Chef::Config[:knife][:secret_file] = sf }
|
119
|
+
description: "A file containing the secret key to use to encrypt data bag item values"
|
125
120
|
|
126
121
|
option :s3_secret,
|
127
122
|
long: "--s3-secret S3_SECRET_URL",
|
128
|
-
description: "S3 URL (e.g. s3://bucket/file) for the encrypted_data_bag_secret_file"
|
129
|
-
proc: lambda { |url| Chef::Config[:knife][:s3_secret] = url }
|
123
|
+
description: "S3 URL (e.g. s3://bucket/file) for the encrypted_data_bag_secret_file"
|
130
124
|
|
131
125
|
option :subnet_id,
|
132
126
|
long: "--subnet SUBNET-ID",
|
133
|
-
description: "create node in this Virtual Private Cloud Subnet ID (implies VPC mode)"
|
134
|
-
proc: Proc.new { |key| Chef::Config[:knife][:subnet_id] = key }
|
127
|
+
description: "create node in this Virtual Private Cloud Subnet ID (implies VPC mode)"
|
135
128
|
|
136
129
|
option :private_ip_address,
|
137
130
|
long: "--private-ip-address IP-ADDRESS",
|
138
|
-
description: "allows to specify the private IP address of the instance in VPC mode"
|
139
|
-
proc: Proc.new { |ip| Chef::Config[:knife][:private_ip_address] = ip }
|
131
|
+
description: "allows to specify the private IP address of the instance in VPC mode"
|
140
132
|
|
141
133
|
option :fqdn,
|
142
134
|
long: "--fqdn FQDN",
|
143
135
|
description: "Pre-defined FQDN. This is used for Kerberos Authentication purpose only",
|
144
|
-
proc: Proc.new { |key| Chef::Config[:knife][:fqdn] = key },
|
145
136
|
default: nil
|
146
137
|
|
147
138
|
option :aws_user_data,
|
148
139
|
long: "--user-data USER_DATA_FILE",
|
149
140
|
short: "-u USER_DATA_FILE",
|
150
141
|
description: "The EC2 User Data file to provision the instance with",
|
151
|
-
proc: Proc.new { |m| Chef::Config[:knife][:aws_user_data] = m },
|
152
142
|
default: nil
|
153
143
|
|
154
144
|
option :ephemeral,
|
@@ -172,19 +162,16 @@ class Chef
|
|
172
162
|
option :ebs_volume_type,
|
173
163
|
long: "--ebs-volume-type TYPE",
|
174
164
|
description: "Possible values are standard (magnetic) | io1 | gp2 | sc1 | st1. Default is gp2",
|
175
|
-
proc: Proc.new { |key| Chef::Config[:knife][:ebs_volume_type] = key },
|
176
165
|
default: "gp2"
|
177
166
|
|
178
167
|
option :ebs_provisioned_iops,
|
179
168
|
long: "--provisioned-iops IOPS",
|
180
169
|
description: "IOPS rate, only used when ebs volume type is 'io1'",
|
181
|
-
proc: Proc.new { |key| Chef::Config[:knife][:provisioned_iops] = key },
|
182
170
|
default: nil
|
183
171
|
|
184
172
|
option :validation_key_url,
|
185
173
|
long: "--validation-key-url URL",
|
186
|
-
description: "Path to the validation key"
|
187
|
-
proc: proc { |m| Chef::Config[:validation_key_url] = m }
|
174
|
+
description: "Path to the validation key"
|
188
175
|
|
189
176
|
option :ebs_encrypted,
|
190
177
|
long: "--ebs-encrypted",
|
@@ -213,7 +200,7 @@ class Chef
|
|
213
200
|
option :aws_connection_timeout,
|
214
201
|
long: "--aws-connection-timeout MINUTES",
|
215
202
|
description: "The maximum time in minutes to wait to for aws connection. Default is 10 min",
|
216
|
-
proc: proc { |t| t = t.to_i * 60
|
203
|
+
proc: proc { |t| t = t.to_i * 60 },
|
217
204
|
default: 600
|
218
205
|
|
219
206
|
option :create_ssl_listener,
|
@@ -261,19 +248,19 @@ class Chef
|
|
261
248
|
option :chef_tag,
|
262
249
|
long: "--chef-tag CHEF_TAG",
|
263
250
|
description: "Use to tag the node in chef server; Provide --chef-tag option multiple times when specifying multiple tags e.g. --chef-tag tag1 --chef-tag tag2.",
|
264
|
-
proc: Proc.new { |chef_tag|
|
265
|
-
|
266
|
-
|
267
|
-
|
251
|
+
proc: Proc.new { |chef_tag, accumulator|
|
252
|
+
accumulator ||= []
|
253
|
+
accumulator.push(chef_tag)
|
254
|
+
accumulator
|
268
255
|
}
|
269
256
|
|
270
257
|
option :aws_tag,
|
271
258
|
long: "--aws-tag AWS_TAG",
|
272
259
|
description: "AWS tag for this server; Use the --aws-tag option multiple times when specifying multiple tags e.g. --aws-tag key1=value1 --aws-tag key2=value2.",
|
273
|
-
proc: Proc.new { |aws_tag|
|
274
|
-
|
275
|
-
|
276
|
-
|
260
|
+
proc: Proc.new { |aws_tag, accumulator|
|
261
|
+
accumulator ||= []
|
262
|
+
accumulator.push(aws_tag)
|
263
|
+
accumulator
|
277
264
|
}
|
278
265
|
|
279
266
|
option :cpu_credits,
|
@@ -287,7 +274,7 @@ class Chef
|
|
287
274
|
# For VPC EIP assignment we need the allocation ID so fetch full EIP details
|
288
275
|
elastic_ip = ec2_connection.describe_addresses.addresses.detect { |addr| addr if addr.public_ip == requested_elastic_ip }
|
289
276
|
|
290
|
-
if
|
277
|
+
if config[:spot_price]
|
291
278
|
server_def = spot_instances_attributes
|
292
279
|
spot_request = ec2_connection.request_spot_instances(server_def)
|
293
280
|
msg_pair("Spot Request ID", spot_request.spot_instance_request_id)
|
@@ -340,7 +327,7 @@ class Chef
|
|
340
327
|
msg_pair("Security Groups", printed_security_groups) unless vpc_mode? || (server.groups && server.security_groups_ids)
|
341
328
|
msg_pair("Security Group Ids", printed_security_group_ids) if vpc_mode? || server.security_groups_ids
|
342
329
|
|
343
|
-
msg_pair("IAM Profile",
|
330
|
+
msg_pair("IAM Profile", config[:iam_instance_profile])
|
344
331
|
|
345
332
|
msg_pair("AWS Tags", printed_aws_tags)
|
346
333
|
msg_pair("Volume Tags", printed_volume_tags)
|
@@ -352,7 +339,7 @@ class Chef
|
|
352
339
|
# occasionally 'ready?' isn't, so retry a couple times if needed.
|
353
340
|
tries = 6
|
354
341
|
begin
|
355
|
-
disable_source_dest_check if vpc_mode? &&
|
342
|
+
disable_source_dest_check if vpc_mode? && config[:disable_source_dest_check]
|
356
343
|
|
357
344
|
create_tags(hashed_tags) unless hashed_tags.empty?
|
358
345
|
create_volume_tags(hashed_volume_tags) unless hashed_volume_tags.empty?
|
@@ -387,7 +374,7 @@ class Chef
|
|
387
374
|
end
|
388
375
|
msg_pair("Private IP Address", server.private_ip_address)
|
389
376
|
|
390
|
-
if
|
377
|
+
if config[:validation_key_url]
|
391
378
|
download_validation_key(validation_key_path)
|
392
379
|
Chef::Config[:validation_key] = validation_key_path
|
393
380
|
end
|
@@ -415,16 +402,16 @@ class Chef
|
|
415
402
|
|
416
403
|
fqdn = connection_host
|
417
404
|
if winrm?
|
418
|
-
if
|
405
|
+
if config[:kerberos_realm]
|
419
406
|
# Fetch AD/WINS based fqdn if any for Kerberos-based Auth
|
420
|
-
fqdn =
|
407
|
+
fqdn = config[:fqdn] || fetch_server_fqdn(server.private_ip_address)
|
421
408
|
end
|
422
409
|
config[:connection_password] = windows_password
|
423
410
|
end
|
424
411
|
@name_args = [fqdn]
|
425
412
|
|
426
|
-
if
|
427
|
-
config[:chef_node_name] = evaluate_node_name(
|
413
|
+
if config[:chef_node_name]
|
414
|
+
config[:chef_node_name] = evaluate_node_name(config[:chef_node_name])
|
428
415
|
else
|
429
416
|
config[:chef_node_name] = server.id
|
430
417
|
end
|
@@ -441,10 +428,10 @@ class Chef
|
|
441
428
|
msg_pair("Availability Zone", server.availability_zone)
|
442
429
|
msg_pair("Security Groups", printed_security_groups) unless vpc_mode? || (server.groups.nil? && server.security_group_ids)
|
443
430
|
msg_pair("Security Group Ids", printed_security_group_ids) if vpc_mode? || server.security_group_ids
|
444
|
-
msg_pair("IAM Profile",
|
445
|
-
msg_pair("Primary ENI",
|
431
|
+
msg_pair("IAM Profile", config[:iam_instance_profile]) if config[:iam_instance_profile]
|
432
|
+
msg_pair("Primary ENI", config[:primary_eni]) if config[:primary_eni]
|
446
433
|
msg_pair("AWS Tags", printed_aws_tags)
|
447
|
-
msg_pair("Chef Tags",
|
434
|
+
msg_pair("Chef Tags", config[:tags]) if config[:tags].any?
|
448
435
|
msg_pair("SSH Key", server.key_name)
|
449
436
|
msg_pair("Root Device Type", server.root_device_type)
|
450
437
|
msg_pair("Root Volume Tags", printed_volume_tags)
|
@@ -509,8 +496,8 @@ class Chef
|
|
509
496
|
|
510
497
|
def validation_key_path
|
511
498
|
@validation_key_path ||= begin
|
512
|
-
if URI(
|
513
|
-
URI(
|
499
|
+
if URI(config[:validation_key_url]).scheme == "file"
|
500
|
+
URI(config[:validation_key_url]).path
|
514
501
|
else
|
515
502
|
validation_key_tmpfile.path
|
516
503
|
end
|
@@ -524,10 +511,10 @@ class Chef
|
|
524
511
|
|
525
512
|
def download_validation_key(tempfile)
|
526
513
|
Chef::Log.debug "Downloading validation key " \
|
527
|
-
"<#{
|
514
|
+
"<#{config[:validation_key_url]}> to file " \
|
528
515
|
"<#{tempfile}>"
|
529
516
|
|
530
|
-
case URI(
|
517
|
+
case URI(config[:validation_key_url]).scheme
|
531
518
|
when "s3"
|
532
519
|
File.open(tempfile, "w") { |f| f.write(s3_validation_key) }
|
533
520
|
end
|
@@ -535,31 +522,31 @@ class Chef
|
|
535
522
|
|
536
523
|
def s3_validation_key
|
537
524
|
@s3_validation_key ||= begin
|
538
|
-
Chef::Knife::S3Source.fetch(
|
525
|
+
Chef::Knife::S3Source.fetch(config[:validation_key_url])
|
539
526
|
end
|
540
527
|
end
|
541
528
|
|
542
529
|
def s3_secret
|
543
530
|
@s3_secret ||= begin
|
544
|
-
return false unless
|
531
|
+
return false unless config[:s3_secret]
|
545
532
|
|
546
|
-
Chef::Knife::S3Source.fetch(
|
533
|
+
Chef::Knife::S3Source.fetch(config[:s3_secret])
|
547
534
|
end
|
548
535
|
end
|
549
536
|
|
550
537
|
def bootstrap_common_params
|
551
|
-
config[:encrypted_data_bag_secret] = s3_secret ||
|
552
|
-
config[:encrypted_data_bag_secret_file] =
|
538
|
+
config[:encrypted_data_bag_secret] = s3_secret || config[:secret]
|
539
|
+
config[:encrypted_data_bag_secret_file] = config[:secret_file]
|
553
540
|
# retrieving the secret from S3 is unique to knife-ec2, so we need to set "command line secret" to the value fetched from S3
|
554
541
|
# When linux vm is spawned, the chef's secret option proc function sets the value "command line secret" and this value is used by
|
555
542
|
# chef's code to check if secret option is passed through command line or not
|
556
|
-
|
557
|
-
config[:secret] = s3_secret ||
|
543
|
+
config[:cl_secret] = s3_secret if config[:s3_secret]
|
544
|
+
config[:secret] = s3_secret || config[:secret]
|
558
545
|
|
559
546
|
# Modify global configuration state to ensure hint gets set by
|
560
547
|
# knife-bootstrap
|
561
|
-
|
562
|
-
|
548
|
+
config[:hints] ||= {}
|
549
|
+
config[:hints]["ec2"] ||= {}
|
563
550
|
end
|
564
551
|
|
565
552
|
def fetch_server_fqdn(ip_addr)
|
@@ -570,7 +557,7 @@ class Chef
|
|
570
557
|
def vpc_mode?
|
571
558
|
# Amazon Virtual Private Cloud requires a subnet_id. If
|
572
559
|
# present, do a few things differently
|
573
|
-
!!
|
560
|
+
!!config[:subnet_id]
|
574
561
|
end
|
575
562
|
|
576
563
|
# When options connection_protocol and connection_port are not provided
|
@@ -586,17 +573,17 @@ class Chef
|
|
586
573
|
end
|
587
574
|
|
588
575
|
def plugin_validate_options!
|
589
|
-
if
|
590
|
-
|
591
|
-
|
576
|
+
if config.key?(:aws_ssh_key_id)
|
577
|
+
config[:ssh_key_name] = config[:aws_ssh_key_id] unless config[:ssh_key_name]
|
578
|
+
config.delete(:aws_ssh_key_id)
|
592
579
|
ui.warn("Use of aws_ssh_key_id option in knife.rb/config.rb config is deprecated, use ssh_key_name option instead.")
|
593
580
|
end
|
594
|
-
create_key_pair unless
|
581
|
+
create_key_pair unless config[:ssh_key_name]
|
595
582
|
|
596
|
-
validate_nics! if
|
583
|
+
validate_nics! if config[:network_interfaces]
|
597
584
|
|
598
585
|
if ami.nil?
|
599
|
-
ui.error("The provided AMI value '#{
|
586
|
+
ui.error("The provided AMI value '#{config[:image]}' could not be found. Is this AMI availble in the provided region #{config[:region]}?")
|
600
587
|
exit 1
|
601
588
|
end
|
602
589
|
|
@@ -639,19 +626,25 @@ class Chef
|
|
639
626
|
exit 1
|
640
627
|
end
|
641
628
|
|
642
|
-
if config[:ebs_volume_type] && ! %w{gp2 io1 standard}.include?(config[:ebs_volume_type])
|
643
|
-
ui.error("--ebs-volume-type must be 'standard' or 'io1' or 'gp2'")
|
629
|
+
if config[:ebs_volume_type] && ! %w{gp2 io1 standard st1 sc1}.include?(config[:ebs_volume_type])
|
630
|
+
ui.error("--ebs-volume-type must be 'standard' or 'io1' or 'gp2' or 'st1' or 'sc1'")
|
644
631
|
msg opt_parser
|
645
632
|
exit 1
|
646
633
|
end
|
647
634
|
|
635
|
+
# validation for ebs_size
|
636
|
+
if (%w{st1 sc1}.include?(config[:ebs_volume_type])) && ! config[:ebs_size].to_i.between?(500, 16384)
|
637
|
+
ui.error("--ebs-size should be in between 500-16384 for 'st1' or 'sc1' ebs volume type.")
|
638
|
+
exit 1
|
639
|
+
end
|
640
|
+
|
648
641
|
if config[:security_groups] && config[:security_groups].class == String
|
649
642
|
ui.error("Invalid value type for knife[:security_groups] in knife configuration file (i.e knife.rb/config.rb). Type should be array. e.g - knife[:security_groups] = ['sgroup1']")
|
650
643
|
exit 1
|
651
644
|
end
|
652
645
|
|
653
646
|
# Validation for security_group_ids passed through knife.rb/config.rb. It will raise error if values are not provided in Array.
|
654
|
-
if
|
647
|
+
if config[:security_group_ids] && config[:security_group_ids].class == String
|
655
648
|
ui.error("Invalid value type for knife[:security_group_ids] in knife configuration file (i.e knife.rb/config.rb). Type should be array. e.g - knife[:security_group_ids] = ['sgroup1']")
|
656
649
|
exit 1
|
657
650
|
end
|
@@ -666,14 +659,14 @@ class Chef
|
|
666
659
|
exit 1
|
667
660
|
end
|
668
661
|
|
669
|
-
if
|
662
|
+
if config[:ebs_encrypted]
|
670
663
|
error_message = ""
|
671
664
|
errors = []
|
672
665
|
# validation for flavor and ebs_encrypted
|
673
|
-
if !
|
666
|
+
if !config[:flavor]
|
674
667
|
ui.error("--ebs-encrypted option requires valid flavor to be specified.")
|
675
668
|
exit 1
|
676
|
-
elsif
|
669
|
+
elsif config[:ebs_encrypted] && ! %w{m3.medium m3.large m3.xlarge m3.2xlarge m4.large m4.xlarge
|
677
670
|
m4.2xlarge m4.4xlarge m4.10xlarge m4.16xlarge t2.nano t2.micro t2.small
|
678
671
|
t2.medium t2.large t2.xlarge t2.2xlarge d2.xlarge d2.2xlarge d2.4xlarge
|
679
672
|
d2.8xlarge c4.large c4.xlarge c4.2xlarge c4.4xlarge c4.8xlarge c3.large
|
@@ -681,19 +674,19 @@ class Chef
|
|
681
674
|
r3.2xlarge r3.4xlarge r3.8xlarge r4.large r4.xlarge r4.2xlarge r4.4xlarge
|
682
675
|
r4.8xlarge r4.16xlarge x1.16xlarge x1.32xlarge i2.xlarge i2.2xlarge i2.4xlarge
|
683
676
|
i2.8xlarge i3.large i3.xlarge i3.2xlarge i3.4xlarge i3.8xlarge i3.16xlarge
|
684
|
-
f1.2xlarge f1.16xlarge g2.2xlarge g2.8xlarge p2.xlarge p2.8xlarge p2.16xlarge}.include?(
|
685
|
-
ui.error("--ebs-encrypted option is not supported for #{
|
677
|
+
f1.2xlarge f1.16xlarge g2.2xlarge g2.8xlarge p2.xlarge p2.8xlarge p2.16xlarge}.include?(config[:flavor])
|
678
|
+
ui.error("--ebs-encrypted option is not supported for #{config[:flavor]} flavor.")
|
686
679
|
exit 1
|
687
680
|
end
|
688
681
|
|
689
682
|
# validation for ebs_size and ebs_volume_type and ebs_encrypted
|
690
|
-
if !
|
683
|
+
if !config[:ebs_size]
|
691
684
|
errors << "--ebs-encrypted option requires valid --ebs-size to be specified."
|
692
|
-
elsif (
|
685
|
+
elsif (config[:ebs_volume_type] == "gp2") && ! config[:ebs_size].to_i.between?(1, 16384)
|
693
686
|
errors << "--ebs-size should be in between 1-16384 for 'gp2' ebs volume type."
|
694
|
-
elsif (
|
687
|
+
elsif (config[:ebs_volume_type] == "io1") && ! config[:ebs_size].to_i.between?(4, 16384)
|
695
688
|
errors << "--ebs-size should be in between 4-16384 for 'io1' ebs volume type."
|
696
|
-
elsif (
|
689
|
+
elsif (config[:ebs_volume_type] == "standard") && ! config[:ebs_size].to_i.between?(1, 1024)
|
697
690
|
errors << "--ebs-size should be in between 1-1024 for 'standard' ebs volume type."
|
698
691
|
end
|
699
692
|
|
@@ -703,19 +696,19 @@ class Chef
|
|
703
696
|
end
|
704
697
|
end
|
705
698
|
|
706
|
-
if
|
699
|
+
if config[:spot_price] && config[:disable_api_termination]
|
707
700
|
ui.error("spot-price and disable-api-termination options cannot be passed together as 'Termination Protection' cannot be enabled for spot instances.")
|
708
701
|
exit 1
|
709
702
|
end
|
710
703
|
|
711
|
-
if
|
712
|
-
unless
|
704
|
+
if config[:spot_price].nil? && config[:spot_wait_mode]
|
705
|
+
unless config[:spot_wait_mode].casecmp("prompt") == 0
|
713
706
|
ui.error("spot-wait-mode option requires that a spot-price option is set.")
|
714
707
|
exit 1
|
715
708
|
end
|
716
709
|
end
|
717
710
|
|
718
|
-
volume_tags =
|
711
|
+
volume_tags = config[:volume_tags]
|
719
712
|
if !volume_tags.nil? && (volume_tags.length != volume_tags.to_s.count("="))
|
720
713
|
ui.error("Volume Tags should be entered in a key = value pair")
|
721
714
|
exit 1
|
@@ -723,27 +716,27 @@ class Chef
|
|
723
716
|
|
724
717
|
if winrm?
|
725
718
|
reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,40}$/
|
726
|
-
unless
|
719
|
+
unless config[:connection_password]&.match?(reg)
|
727
720
|
ui.error("Complexity requirements are not met. Password length should be 8-40 characters and include: 1 uppercase, 1 lowercase, 1 digit, and 1 special character")
|
728
721
|
exit 1
|
729
722
|
end
|
730
723
|
end
|
731
724
|
|
732
|
-
if
|
725
|
+
if config[:chef_tag]
|
733
726
|
# If --chef-tag is provided then it will be set in chef as single value e.g. --chef-tag "myTag"
|
734
727
|
# --tags has been removed from knife-ec2, now it's available in core
|
735
|
-
config[:tags] +=
|
728
|
+
config[:tags] += config[:chef_tag]
|
736
729
|
ui.warn("[DEPRECATED] --chef-tag option is deprecated and will be removed in future release. Use --tags TAGS option instead.")
|
737
730
|
end
|
738
731
|
|
739
|
-
if
|
732
|
+
if config[:cpu_credits] && !config[:flavor]
|
740
733
|
ui.error("Instance type should be specified and should be any of T2/T3 type.")
|
741
734
|
exit 1
|
742
735
|
end
|
743
736
|
end
|
744
737
|
|
745
738
|
def parse_aws_tags
|
746
|
-
tags =
|
739
|
+
tags = config[:aws_tag]
|
747
740
|
if !tags.nil? && (tags.length != tags.to_s.count("="))
|
748
741
|
ui.error("AWS Tags should be entered in a key = value pair")
|
749
742
|
exit 1
|
@@ -817,7 +810,7 @@ class Chef
|
|
817
810
|
end
|
818
811
|
|
819
812
|
def ssl_config_data_already_exist?
|
820
|
-
File.read(
|
813
|
+
File.read(config[:aws_user_data]).gsub(/\\\\/, "\\").include? ssl_config_user_data.strip
|
821
814
|
end
|
822
815
|
|
823
816
|
def process_user_data(script_lines)
|
@@ -841,7 +834,7 @@ class Chef
|
|
841
834
|
|
842
835
|
# base64-encoded text
|
843
836
|
def encode_data(text)
|
844
|
-
require "base64"
|
837
|
+
require "base64" unless defined?(Base64)
|
845
838
|
Base64.encode64(text)
|
846
839
|
end
|
847
840
|
|
@@ -849,34 +842,34 @@ class Chef
|
|
849
842
|
attributes = {
|
850
843
|
instance_count: 1,
|
851
844
|
launch_specification: server_attributes,
|
852
|
-
spot_price:
|
853
|
-
type:
|
845
|
+
spot_price: config[:spot_price],
|
846
|
+
type: config[:spot_request_type],
|
854
847
|
}
|
855
848
|
end
|
856
849
|
|
857
850
|
def server_attributes
|
858
851
|
attributes = {
|
859
|
-
image_id:
|
860
|
-
instance_type:
|
861
|
-
key_name:
|
852
|
+
image_id: config[:image],
|
853
|
+
instance_type: config[:flavor],
|
854
|
+
key_name: config[:ssh_key_name],
|
862
855
|
max_count: 1,
|
863
856
|
min_count: 1,
|
864
857
|
placement: {
|
865
|
-
availability_zone:
|
858
|
+
availability_zone: config[:availability_zone],
|
866
859
|
},
|
867
860
|
}
|
868
861
|
|
869
862
|
network_attrs = {}
|
870
|
-
if !!
|
871
|
-
network_attrs[:network_interface_id] =
|
863
|
+
if !!config[:primary_eni]
|
864
|
+
network_attrs[:network_interface_id] = config[:primary_eni]
|
872
865
|
elsif vpc_mode?
|
873
|
-
network_attrs[:subnet_id] =
|
866
|
+
network_attrs[:subnet_id] = config[:subnet_id]
|
874
867
|
end
|
875
868
|
|
876
869
|
if vpc_mode?
|
877
|
-
network_attrs[:groups] =
|
878
|
-
network_attrs[:private_ip_address] =
|
879
|
-
network_attrs[:associate_public_ip_address] =
|
870
|
+
network_attrs[:groups] = config[:security_group_ids] if !!config[:security_group_ids]
|
871
|
+
network_attrs[:private_ip_address] = config[:private_ip_address]
|
872
|
+
network_attrs[:associate_public_ip_address] = config[:associate_public_ip]
|
880
873
|
else
|
881
874
|
attributes[:security_groups] = config[:security_groups]
|
882
875
|
end
|
@@ -885,24 +878,24 @@ class Chef
|
|
885
878
|
network_attrs[:device_index] = 0
|
886
879
|
attributes[:network_interfaces] = [network_attrs]
|
887
880
|
else
|
888
|
-
attributes[:security_group_ids] =
|
881
|
+
attributes[:security_group_ids] = config[:security_group_ids]
|
889
882
|
end
|
890
883
|
|
891
|
-
attributes[:placement][:group_name] =
|
892
|
-
attributes[:placement][:tenancy] = "dedicated" if vpc_mode? &&
|
884
|
+
attributes[:placement][:group_name] = config[:placement_group]
|
885
|
+
attributes[:placement][:tenancy] = "dedicated" if vpc_mode? && config[:dedicated_instance]
|
893
886
|
attributes[:iam_instance_profile] = {}
|
894
|
-
attributes[:iam_instance_profile][:name] =
|
895
|
-
if
|
896
|
-
if
|
887
|
+
attributes[:iam_instance_profile][:name] = config[:iam_instance_profile]
|
888
|
+
if config[:winrm_ssl]
|
889
|
+
if config[:aws_user_data]
|
897
890
|
begin
|
898
|
-
user_data = File.readlines(
|
891
|
+
user_data = File.readlines(config[:aws_user_data])
|
899
892
|
if config[:create_ssl_listener]
|
900
893
|
user_data = process_user_data(user_data)
|
901
894
|
end
|
902
895
|
user_data = user_data.join
|
903
896
|
attributes.merge!(user_data: encode_data(user_data))
|
904
897
|
rescue
|
905
|
-
ui.warn("Cannot read #{
|
898
|
+
ui.warn("Cannot read #{config[:aws_user_data]}: #{$!.inspect}. Ignoring option.")
|
906
899
|
end
|
907
900
|
else
|
908
901
|
if config[:create_ssl_listener]
|
@@ -910,19 +903,19 @@ class Chef
|
|
910
903
|
end
|
911
904
|
end
|
912
905
|
else
|
913
|
-
if
|
906
|
+
if config[:aws_user_data]
|
914
907
|
begin
|
915
|
-
user_data = File.read(
|
908
|
+
user_data = File.read(config[:aws_user_data])
|
916
909
|
attributes.merge!(user_data: encode_data(user_data))
|
917
910
|
rescue
|
918
|
-
ui.warn("Cannot read #{
|
911
|
+
ui.warn("Cannot read #{config[:aws_user_data]}: #{$!.inspect}. Ignoring option.")
|
919
912
|
end
|
920
913
|
end
|
921
914
|
end
|
922
|
-
attributes[:ebs_optimized] = !!
|
915
|
+
attributes[:ebs_optimized] = !!config[:ebs_optimized]
|
923
916
|
|
924
917
|
if ami.root_device_type == "ebs"
|
925
|
-
if
|
918
|
+
if config[:ebs_encrypted] || %w{st1 sc1}.include?(config[:ebs_volume_type])
|
926
919
|
ami_map = ami.block_device_mappings[1]
|
927
920
|
else
|
928
921
|
ami_map = ami.block_device_mappings.first
|
@@ -939,11 +932,9 @@ class Chef
|
|
939
932
|
msg opt_parser
|
940
933
|
exit 1
|
941
934
|
end
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
ami_map.ebs.delete_on_termination if ami_map.ebs.respond_to?(:delete_on_termination)
|
946
|
-
end
|
935
|
+
|
936
|
+
delete_term = config[:ebs_delete_on_term]
|
937
|
+
|
947
938
|
iops_rate = begin
|
948
939
|
if config[:ebs_provisioned_iops]
|
949
940
|
Integer(config[:ebs_provisioned_iops]).to_s
|
@@ -966,7 +957,7 @@ class Chef
|
|
966
957
|
},
|
967
958
|
}]
|
968
959
|
attributes[:block_device_mappings][0][:ebs][:iops] = iops_rate unless iops_rate.nil? || iops_rate.empty?
|
969
|
-
attributes[:block_device_mappings][0][:ebs][:encrypted] = true if
|
960
|
+
attributes[:block_device_mappings][0][:ebs][:encrypted] = true if config[:ebs_encrypted]
|
970
961
|
end
|
971
962
|
|
972
963
|
if config[:ephemeral] && config[:ephemeral].length > 0
|
@@ -978,9 +969,9 @@ class Chef
|
|
978
969
|
end
|
979
970
|
|
980
971
|
## cannot pass disable_api_termination option to the API when using spot instances ##
|
981
|
-
attributes[:disable_api_termination] =
|
972
|
+
attributes[:disable_api_termination] = config[:disable_api_termination] if config[:spot_price].nil?
|
982
973
|
|
983
|
-
attributes[:instance_initiated_shutdown_behavior] =
|
974
|
+
attributes[:instance_initiated_shutdown_behavior] = config[:instance_initiated_shutdown_behavior]
|
984
975
|
|
985
976
|
if config[:cpu_credits]
|
986
977
|
attributes[:credit_specification] =
|
@@ -1016,8 +1007,8 @@ class Chef
|
|
1016
1007
|
delay = 15 # Default Delay for waiter
|
1017
1008
|
attempts = 40 # Default max attempts for waiter
|
1018
1009
|
|
1019
|
-
if
|
1020
|
-
attempts = (
|
1010
|
+
if config[:aws_connection_timeout]
|
1011
|
+
attempts = (config[:aws_connection_timeout].to_f / delay).to_i
|
1021
1012
|
end
|
1022
1013
|
attempts
|
1023
1014
|
end
|
@@ -1102,7 +1093,7 @@ class Chef
|
|
1102
1093
|
|
1103
1094
|
# Use the keys specificed on the command line if available (overrides SSH Config)
|
1104
1095
|
if config[:ssh_gateway_identity]
|
1105
|
-
gateway_keys = Array(
|
1096
|
+
gateway_keys = Array(config[:ssh_gateway_identity])
|
1106
1097
|
end
|
1107
1098
|
|
1108
1099
|
unless gateway_keys.nil?
|
@@ -1194,8 +1185,8 @@ class Chef
|
|
1194
1185
|
file_path = File.join(Config.config_dir, "#{key_pair.key_name}.pem")
|
1195
1186
|
file = File.open(file_path, "w+") { |f| f << key_pair.key_material }
|
1196
1187
|
|
1197
|
-
|
1198
|
-
|
1188
|
+
config[:ssh_key_name] = key_pair.key_name
|
1189
|
+
config[:ssh_identity_file] = file.path
|
1199
1190
|
puts "\nGenerated keypair file: #{file.path}"
|
1200
1191
|
end
|
1201
1192
|
|
@@ -1222,7 +1213,7 @@ class Chef
|
|
1222
1213
|
|
1223
1214
|
interfaces = ec2_connection.describe_network_interfaces(params)
|
1224
1215
|
valid_nic_ids = interfaces.network_interfaces.map(&:network_interface_id)
|
1225
|
-
invalid_nic_ids =
|
1216
|
+
invalid_nic_ids = config[:network_interfaces] - valid_nic_ids
|
1226
1217
|
|
1227
1218
|
return true if invalid_nic_ids.empty?
|
1228
1219
|
|
@@ -1232,14 +1223,14 @@ class Chef
|
|
1232
1223
|
end
|
1233
1224
|
|
1234
1225
|
def vpc_id
|
1235
|
-
@vpc_id ||= fetch_subnet(
|
1226
|
+
@vpc_id ||= fetch_subnet(config[:subnet_id]).vpc_id
|
1236
1227
|
end
|
1237
1228
|
|
1238
1229
|
def wait_for_nic_attachment
|
1239
1230
|
attached_nics_count = 0
|
1240
|
-
until attached_nics_count ==
|
1231
|
+
until attached_nics_count == config[:network_interfaces].count
|
1241
1232
|
attachment_nics =
|
1242
|
-
|
1233
|
+
config[:network_interfaces].map do |nic_id|
|
1243
1234
|
fetch_network_interfaces(nic_id).attachment.status
|
1244
1235
|
end
|
1245
1236
|
attached_nics_count = attachment_nics.grep("attached").count
|
@@ -1336,12 +1327,11 @@ class Chef
|
|
1336
1327
|
end
|
1337
1328
|
|
1338
1329
|
def decrypt_admin_password(encoded_password, key)
|
1339
|
-
require "base64"
|
1340
|
-
require "openssl"
|
1330
|
+
require "base64" unless defined?(Base64)
|
1331
|
+
require "openssl" unless defined?(OpenSSL)
|
1341
1332
|
private_key = OpenSSL::PKey::RSA.new(key)
|
1342
1333
|
encrypted_password = Base64.decode64(encoded_password)
|
1343
|
-
|
1344
|
-
password
|
1334
|
+
private_key.private_decrypt(encrypted_password)
|
1345
1335
|
end
|
1346
1336
|
|
1347
1337
|
def check_windows_password_available(server_id)
|
@@ -1353,23 +1343,23 @@ class Chef
|
|
1353
1343
|
end
|
1354
1344
|
|
1355
1345
|
def windows_password
|
1356
|
-
if not
|
1357
|
-
if
|
1346
|
+
if not config[:connection_password]
|
1347
|
+
if config[:ssh_identity_file]
|
1358
1348
|
if server
|
1359
1349
|
print "\n#{ui.color("Waiting for Windows Admin password to be available: ", :magenta)}"
|
1360
1350
|
print(".") until check_windows_password_available(server.id) { puts("done") }
|
1361
1351
|
response = fetch_password_data(server.id)
|
1362
|
-
data = File.read(
|
1352
|
+
data = File.read(config[:ssh_identity_file])
|
1363
1353
|
config[:connection_password] = decrypt_admin_password(response.password_data, data)
|
1364
1354
|
else
|
1365
|
-
print "\n#{ui.color("
|
1355
|
+
print "\n#{ui.color("Fetching instance details: \n", :magenta)}"
|
1366
1356
|
end
|
1367
1357
|
else
|
1368
1358
|
ui.error("Cannot find SSH Identity file, required to fetch dynamically generated password")
|
1369
1359
|
exit 1
|
1370
1360
|
end
|
1371
1361
|
else
|
1372
|
-
|
1362
|
+
config[:connection_password]
|
1373
1363
|
end
|
1374
1364
|
end
|
1375
1365
|
|
@@ -1381,7 +1371,7 @@ class Chef
|
|
1381
1371
|
|
1382
1372
|
# TODO: connection_protocol and connection_port used to choose winrm/ssh or 5985/22 based on the image chosen
|
1383
1373
|
def connection_port
|
1384
|
-
port =
|
1374
|
+
port = config[:connection_port] || config[knife_key_for_protocol(:port)]
|
1385
1375
|
return port if port
|
1386
1376
|
|
1387
1377
|
assign_default_port
|
@@ -1392,7 +1382,7 @@ class Chef
|
|
1392
1382
|
# @return [Integer]
|
1393
1383
|
def assign_default_port
|
1394
1384
|
if winrm?
|
1395
|
-
|
1385
|
+
config[:winrm_ssl] ? 5986 : 5985
|
1396
1386
|
else
|
1397
1387
|
22
|
1398
1388
|
end
|
@@ -1405,23 +1395,16 @@ class Chef
|
|
1405
1395
|
|
1406
1396
|
default_protocol = is_image_windows? ? "winrm" : "ssh"
|
1407
1397
|
from_url = host_descriptor =~ %r{^(.*)://} ? $1 : nil
|
1408
|
-
|
1409
|
-
|
1410
|
-
@connection_protocol_ec2 = from_url || from_cli || from_knife || default_protocol
|
1398
|
+
from_config = config[:connection_protocol]
|
1399
|
+
@connection_protocol_ec2 = from_url || from_config || default_protocol
|
1411
1400
|
end
|
1412
1401
|
|
1413
1402
|
def connection_user
|
1414
|
-
@connection_user ||=
|
1403
|
+
@connection_user ||= config[:connection_user] || config[knife_key_for_protocol(:user)]
|
1415
1404
|
end
|
1416
1405
|
|
1417
1406
|
def server_name
|
1418
|
-
|
1419
|
-
|
1420
|
-
if !server.public_dns_name.empty?
|
1421
|
-
server.public_dns_name
|
1422
|
-
else
|
1423
|
-
server.private_ip_address
|
1424
|
-
end
|
1407
|
+
server ? connection_host : nil
|
1425
1408
|
end
|
1426
1409
|
|
1427
1410
|
alias host_descriptor server_name
|
@@ -1448,7 +1431,7 @@ class Chef
|
|
1448
1431
|
|
1449
1432
|
def hashed_volume_tags
|
1450
1433
|
hvt = {}
|
1451
|
-
volume_tags =
|
1434
|
+
volume_tags = config[:volume_tags]
|
1452
1435
|
volume_tags.map { |t| key, val = t.split("="); hvt[key] = val } unless volume_tags.nil?
|
1453
1436
|
|
1454
1437
|
hvt
|
@@ -1464,8 +1447,8 @@ class Chef
|
|
1464
1447
|
|
1465
1448
|
# Always set the Name tag
|
1466
1449
|
unless ht.key?("Name")
|
1467
|
-
if
|
1468
|
-
ht["Name"] = evaluate_node_name(
|
1450
|
+
if config[:chef_node_name]
|
1451
|
+
ht["Name"] = evaluate_node_name(config[:chef_node_name])
|
1469
1452
|
else
|
1470
1453
|
ht["Name"] = server.id
|
1471
1454
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
3
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
4
|
-
# Copyright:: Copyright (c)
|
4
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -122,7 +122,7 @@ class Chef
|
|
122
122
|
|
123
123
|
output_column_count = servers_list.length
|
124
124
|
|
125
|
-
|
125
|
+
unless config[:region]
|
126
126
|
ui.warn "No region was specified in knife.rb/config.rb or as an argument. The default region, us-east-1, will be used:"
|
127
127
|
end
|
128
128
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
#
|
3
3
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
4
|
-
# Copyright:: Copyright (c)
|
4
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -51,46 +51,41 @@ class Chef
|
|
51
51
|
option :aws_access_key_id,
|
52
52
|
short: "-A ID",
|
53
53
|
long: "--aws-access-key-id KEY",
|
54
|
-
description: "Your AWS Access Key ID"
|
55
|
-
proc: Proc.new { |key| Chef::Config[:knife][:aws_access_key_id] = key }
|
54
|
+
description: "Your AWS Access Key ID"
|
56
55
|
|
57
56
|
option :aws_secret_access_key,
|
58
57
|
short: "-K SECRET",
|
59
58
|
long: "--aws-secret-access-key SECRET",
|
60
|
-
description: "Your AWS API Secret Access Key"
|
61
|
-
proc: Proc.new { |key| Chef::Config[:knife][:aws_secret_access_key] = key }
|
59
|
+
description: "Your AWS API Secret Access Key"
|
62
60
|
|
63
61
|
option :aws_session_token,
|
64
62
|
long: "--aws-session-token TOKEN",
|
65
|
-
description: "Your AWS Session Token, for use with AWS STS Federation or Session Tokens"
|
66
|
-
proc: Proc.new { |key| Chef::Config[:knife][:aws_session_token] = key }
|
63
|
+
description: "Your AWS Session Token, for use with AWS STS Federation or Session Tokens"
|
67
64
|
|
68
65
|
option :region,
|
69
66
|
long: "--region REGION",
|
70
|
-
description: "Your AWS region"
|
71
|
-
proc: Proc.new { |key| Chef::Config[:knife][:region] = key }
|
67
|
+
description: "Your AWS region"
|
72
68
|
|
73
69
|
option :use_iam_profile,
|
74
70
|
long: "--use-iam-profile",
|
75
71
|
description: "Use IAM profile assigned to current machine",
|
76
72
|
boolean: true,
|
77
|
-
default: false
|
78
|
-
proc: Proc.new { |key| Chef::Config[:knife][:use_iam_profile] = key }
|
73
|
+
default: false
|
79
74
|
end
|
80
75
|
end
|
81
76
|
|
82
77
|
def connection_string
|
83
78
|
conn = {}
|
84
|
-
conn[:region] =
|
79
|
+
conn[:region] = config[:region] || "us-east-1"
|
85
80
|
Chef::Log.debug "Using AWS region #{conn[:region]}"
|
86
81
|
conn[:credentials] =
|
87
|
-
if
|
82
|
+
if config[:use_iam_profile]
|
88
83
|
Chef::Log.debug "Using iam profile for authentication as use_iam_profile set"
|
89
84
|
Aws::InstanceProfileCredentials.new
|
90
85
|
else
|
91
|
-
Chef::Log.debug "Setting up AWS connection using aws_access_key_id: #{mask(
|
86
|
+
Chef::Log.debug "Setting up AWS connection using aws_access_key_id: #{mask(config[:aws_access_key_id])} aws_secret_access_key: #{mask(config[:aws_secret_access_key])} aws_session_token: #{mask(config[:aws_session_token])}"
|
92
87
|
|
93
|
-
Aws::Credentials.new(
|
88
|
+
Aws::Credentials.new(config[:aws_access_key_id], config[:aws_secret_access_key], config[:aws_session_token])
|
94
89
|
end
|
95
90
|
conn
|
96
91
|
end
|
@@ -101,7 +96,7 @@ class Chef
|
|
101
96
|
end
|
102
97
|
|
103
98
|
def vpc_mode?
|
104
|
-
!!
|
99
|
+
!!config[:subnet_id]
|
105
100
|
end
|
106
101
|
|
107
102
|
def fetch_ami(image_id)
|
@@ -176,16 +171,6 @@ class Chef
|
|
176
171
|
OpenStruct.new(server_hashes)
|
177
172
|
end
|
178
173
|
|
179
|
-
# @return [String]
|
180
|
-
def locate_config_value(key)
|
181
|
-
key = key.to_sym
|
182
|
-
if defined?(config_value) # Inherited by bootstrap
|
183
|
-
config_value(key) || default_config[key]
|
184
|
-
else
|
185
|
-
config[key] || Chef::Config[:knife][key] || default_config[key]
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
174
|
def msg_pair(label, value, color = :cyan)
|
190
175
|
if value && !value.to_s.empty?
|
191
176
|
ui.info("#{ui.color(label, color)}: #{value}")
|
@@ -193,7 +178,7 @@ class Chef
|
|
193
178
|
end
|
194
179
|
|
195
180
|
def ami
|
196
|
-
@ami ||= fetch_ami(
|
181
|
+
@ami ||= fetch_ami(config[:image])
|
197
182
|
end
|
198
183
|
|
199
184
|
# Platform value return for Windows AMIs; otherwise, it is blank.
|
@@ -207,16 +192,16 @@ class Chef
|
|
207
192
|
def validate_aws_config!(keys = %i{aws_access_key_id aws_secret_access_key})
|
208
193
|
errors = [] # track all errors so we report on all of them
|
209
194
|
|
210
|
-
validate_aws_config_file! if
|
211
|
-
unless
|
195
|
+
validate_aws_config_file! if config[:aws_config_file]
|
196
|
+
unless config[:use_iam_profile] # skip config file / key validation if we're using iam profile
|
212
197
|
# validate the creds file if:
|
213
198
|
# aws keys have not been passed in config / CLI and the default cred file location does exist
|
214
199
|
# OR
|
215
200
|
# the user passed aws_credential_file
|
216
|
-
if (
|
217
|
-
|
201
|
+
if (config.keys & %i{aws_access_key_id aws_secret_access_key}).empty? && aws_cred_file_location ||
|
202
|
+
config[:aws_credential_file]
|
218
203
|
|
219
|
-
unless (
|
204
|
+
unless (config.keys & %i{aws_access_key_id aws_secret_access_key}).empty?
|
220
205
|
errors << "Either provide a credentials file or the access key and secret keys but not both."
|
221
206
|
end
|
222
207
|
|
@@ -225,7 +210,7 @@ class Chef
|
|
225
210
|
|
226
211
|
keys.each do |k|
|
227
212
|
pretty_key = k.to_s.tr("_", " ").gsub(/\w+/) { |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
|
228
|
-
if
|
213
|
+
if config[k].nil?
|
229
214
|
errors << "You did not provide a valid '#{pretty_key}' value."
|
230
215
|
end
|
231
216
|
end
|
@@ -243,8 +228,8 @@ class Chef
|
|
243
228
|
# @return [String, nil] location to aws credentials file or nil if none exists
|
244
229
|
def aws_cred_file_location
|
245
230
|
@cred_file ||= begin
|
246
|
-
if !
|
247
|
-
|
231
|
+
if !config[:aws_credential_file].nil?
|
232
|
+
config[:aws_credential_file]
|
248
233
|
else
|
249
234
|
Chef::Util::PathHelper.home(".aws", "credentials") if ::File.exist?(Chef::Util::PathHelper.home(".aws", "credentials"))
|
250
235
|
end
|
@@ -288,7 +273,7 @@ class Chef
|
|
288
273
|
|
289
274
|
# Custom Warning
|
290
275
|
def custom_warnings!
|
291
|
-
|
276
|
+
unless config[:region]
|
292
277
|
ui.warn "No region was specified in knife.rb/config.rb or as an argument. The default region, us-east-1, will be used:"
|
293
278
|
end
|
294
279
|
end
|
@@ -298,18 +283,18 @@ class Chef
|
|
298
283
|
# validate the contents of the aws configuration file
|
299
284
|
# @return [void]
|
300
285
|
def validate_aws_config_file!
|
301
|
-
config_file =
|
286
|
+
config_file = config[:aws_config_file]
|
302
287
|
Chef::Log.debug "Using AWS config file at #{config_file}"
|
303
288
|
|
304
289
|
raise ArgumentError, "The provided --aws_config_file (#{config_file}) cannot be found on disk." unless File.exist?(config_file)
|
305
290
|
|
306
291
|
aws_config = ini_parse(File.read(config_file))
|
307
|
-
profile_key =
|
292
|
+
profile_key = config[:aws_profile]
|
308
293
|
profile_key = "profile #{profile_key}" if profile_key != "default"
|
309
294
|
|
310
295
|
unless aws_config.values.empty?
|
311
296
|
if aws_config[profile_key]
|
312
|
-
|
297
|
+
config[:region] = aws_config[profile_key]["region"]
|
313
298
|
else
|
314
299
|
raise ArgumentError, "The provided --aws-profile '#{profile_key}' is invalid."
|
315
300
|
end
|
@@ -330,7 +315,7 @@ class Chef
|
|
330
315
|
# aws_access_key_id = somethingsomethingdarkside
|
331
316
|
# aws_secret_access_key = somethingsomethingdarkside
|
332
317
|
aws_creds = ini_parse(File.read(aws_cred_file_location))
|
333
|
-
profile =
|
318
|
+
profile = config[:aws_profile]
|
334
319
|
Chef::Log.debug "Using AWS profile #{profile}"
|
335
320
|
entries = if aws_creds.values.first.key?("AWSAccessKeyId")
|
336
321
|
aws_creds.values.first
|
@@ -339,9 +324,9 @@ class Chef
|
|
339
324
|
end
|
340
325
|
|
341
326
|
if entries
|
342
|
-
|
343
|
-
|
344
|
-
|
327
|
+
config[:aws_access_key_id] = entries["AWSAccessKeyId"] || entries["aws_access_key_id"]
|
328
|
+
config[:aws_secret_access_key] = entries["AWSSecretKey"] || entries["aws_secret_access_key"]
|
329
|
+
config[:aws_session_token] = entries["AWSSessionToken"] || entries["aws_session_token"]
|
345
330
|
else
|
346
331
|
raise ArgumentError, "The provided --aws-profile '#{profile}' is invalid. Does the credential file at '#{aws_cred_file_location}' contain this profile?"
|
347
332
|
end
|
@@ -60,15 +60,15 @@ class Chef
|
|
60
60
|
|
61
61
|
def connection_string
|
62
62
|
conn = {}
|
63
|
-
conn[:region] =
|
63
|
+
conn[:region] = config[:region]
|
64
64
|
conn[:credentials] =
|
65
|
-
if
|
65
|
+
if config[:use_iam_profile]
|
66
66
|
Aws::InstanceProfileCredentials.new
|
67
67
|
else
|
68
68
|
Aws::Credentials.new(
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
config[:aws_access_key_id],
|
70
|
+
config[:aws_secret_access_key],
|
71
|
+
config[:aws_session_token]
|
72
72
|
)
|
73
73
|
end
|
74
74
|
conn
|
data/lib/knife-ec2/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-ec2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chef Software, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '15.
|
19
|
+
version: '15.11'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '15.
|
26
|
+
version: '15.11'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: aws-sdk-s3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
85
85
|
- - ">="
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '2.
|
87
|
+
version: '2.6'
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
89
|
requirements:
|
90
90
|
- - ">="
|