lib/chef/knife/ec2_server_create.rb in knife-ec2-0.15.0 vs lib/chef/knife/ec2_server_create.rb in knife-ec2-0.16.0
- old
+ new
@@ -440,10 +440,21 @@
:long => "--disable-api-termination",
:description => "Disable termination of the instance using the Amazon EC2 console, CLI and API.",
:boolean => true,
:default => false
+ option :volume_tags,
+ :long => "--volume-tags Tag=Value[,Tag=Value...]",
+ :description => "Tag the Root volume",
+ :proc => Proc.new { |volume_tags| volume_tags.split(',') }
+
+ option :tag_node_in_chef,
+ :long => "--tag-node-in-chef",
+ :description => "Flag for tagging node in ec2 and chef both",
+ :boolean => true,
+ :default => false
+
def run
$stdout.sync = true
validate!
requested_elastic_ip = config[:associate_eip] if config[:associate_eip]
@@ -487,10 +498,11 @@
@server = connection.servers.get(spot_request.instance_id)
else
begin
@server = connection.servers.create(create_server_def)
rescue => error
+ error.message.sub("download completed, but downloaded file not found", "Verify that you have public internet access.")
ui.error error.message
Chef::Log.debug("#{error.backtrace.join("\n")}")
exit
end
end
@@ -507,10 +519,15 @@
end
end
printed_tags = hashed_tags.map{ |tag, val| "#{tag}: #{val}" }.join(", ")
+ hashed_volume_tags={}
+ volume_tags = locate_config_value(:volume_tags)
+ volume_tags.map{ |t| key,val=t.split('='); hashed_volume_tags[key]=val} unless volume_tags.nil?
+ printed_volume_tags = hashed_volume_tags.map{ |tag, val| "#{tag}: #{val}" }.join(", ")
+
msg_pair("Instance ID", @server.id)
msg_pair("Flavor", @server.flavor_id)
msg_pair("Image", @server.image_id)
msg_pair("Region", connection.instance_variable_get(:@region))
msg_pair("Availability Zone", @server.availability_zone)
@@ -528,10 +545,11 @@
msg_pair("Security Group Ids", printed_security_group_ids) if vpc_mode? or @server.security_group_ids
msg_pair("IAM Profile", locate_config_value(:iam_instance_profile))
msg_pair("Tags", printed_tags)
+ msg_pair("Volume Tags", printed_volume_tags)
msg_pair("SSH Key", @server.key_name)
print "\n#{ui.color("Waiting for EC2 to create the instance", :magenta)}"
# wait for instance to come up before acting against it
@@ -541,10 +559,11 @@
# occasionally 'ready?' isn't, so retry a couple times if needed.
tries = 6
begin
create_tags(hashed_tags) unless hashed_tags.empty?
+ create_volume_tags(hashed_volume_tags) unless hashed_volume_tags.empty?
associate_eip(elastic_ip) if config[:associate_eip]
enable_classic_link(config[:classic_link_vpc_id], config[:classic_link_vpc_security_group_ids]) if config[:classic_link_vpc_id]
rescue Fog::Compute::AWS::NotFound, Fog::Errors::Error
raise if (tries -= 1) <= 0
ui.warn("server not ready, retrying tag application (retries left: #{tries})")
@@ -614,10 +633,11 @@
msg_pair("Security Group Ids", printed_security_group_ids) if vpc_mode? or @server.security_group_ids
msg_pair("IAM Profile", locate_config_value(:iam_instance_profile)) if locate_config_value(:iam_instance_profile)
msg_pair("Tags", printed_tags)
msg_pair("SSH Key", @server.key_name)
msg_pair("Root Device Type", @server.root_device_type)
+ msg_pair("Root Volume Tags", printed_volume_tags)
if @server.root_device_type == "ebs"
device_map = @server.block_device_mapping.first
msg_pair("Root Volume ID", device_map['volumeId'])
msg_pair("Root Device Name", device_map['deviceName'])
msg_pair("Root Device Delete on Terminate", device_map['deleteOnTermination'])
@@ -783,11 +803,12 @@
end
bootstrap.name_args = [fqdn]
bootstrap.config[:msi_url] = locate_config_value(:msi_url)
bootstrap.config[:install_as_service] = locate_config_value(:install_as_service)
bootstrap.config[:session_timeout] = locate_config_value(:session_timeout)
- bootstrap.config[:tags] = config[:tags]
+ bootstrap.config[:tags] = config[:tags] if locate_config_value(:tag_node_in_chef)
+
if locate_config_value(:chef_node_name)
bootstrap.config[:chef_node_name] = evaluate_node_name(locate_config_value(:chef_node_name))
else
bootstrap.config[:chef_node_name] = server.id
end
@@ -800,11 +821,12 @@
bootstrap.config[:ssh_user] = config[:ssh_user]
bootstrap.config[:ssh_password] = locate_config_value(:ssh_password)
bootstrap.config[:ssh_port] = config[:ssh_port]
bootstrap.config[:ssh_gateway] = config[:ssh_gateway]
bootstrap.config[:identity_file] = config[:identity_file]
- bootstrap.config[:tags] = config[:tags]
+ bootstrap.config[:tags] = config[:tags] if locate_config_value(:tag_node_in_chef)
+
if locate_config_value(:chef_node_name)
bootstrap.config[:chef_node_name] = evaluate_node_name(locate_config_value(:chef_node_name))
else
bootstrap.config[:chef_node_name] = server.id
end
@@ -912,15 +934,18 @@
# validation for flavor and ebs_encrypted
if !locate_config_value(:flavor)
ui.error("--ebs-encrypted option requires valid flavor to be specified.")
exit 1
elsif (locate_config_value(:ebs_encrypted) and ! %w(m3.medium m3.large m3.xlarge m3.2xlarge m4.large m4.xlarge
- m4.2xlarge m4.4xlarge m4.10xlarge t2.micro t2.small t2.medium t2.large
- d2.xlarge d2.2xlarge d2.4xlarge d2.8xlarge c4.large c4.xlarge
- c4.2xlarge c4.4xlarge c4.8xlarge c3.large c3.xlarge c3.2xlarge
- c3.4xlarge c3.8xlarge cr1.8xlarge r3.large r3.xlarge r3.2xlarge
- r3.4xlarge r3.8xlarge i2.xlarge i2.2xlarge i2.4xlarge i2.8xlarge g2.2xlarge g2.8xlarge).include?(locate_config_value(:flavor)))
+ m4.2xlarge m4.4xlarge m4.10xlarge m4.16xlarge t2.nano t2.micro t2.small
+ t2.medium t2.large t2.xlarge t2.2xlarge d2.xlarge d2.2xlarge d2.4xlarge
+ d2.8xlarge c4.large c4.xlarge c4.2xlarge c4.4xlarge c4.8xlarge c3.large
+ c3.xlarge c3.2xlarge c3.4xlarge c3.8xlarge cr1.8xlarge r3.large r3.xlarge
+ r3.2xlarge r3.4xlarge r3.8xlarge r4.large r4.xlarge r4.2xlarge r4.4xlarge
+ r4.8xlarge r4.16xlarge x1.16xlarge x1.32xlarge i2.xlarge i2.2xlarge i2.4xlarge
+ i2.8xlarge i3.large i3.xlarge i3.2xlarge i3.4xlarge i3.8xlarge i3.16xlarge
+ f1.2xlarge f1.16xlarge g2.2xlarge g2.8xlarge p2.xlarge p2.8xlarge p2.16xlarge).include?(locate_config_value(:flavor)))
ui.error("--ebs-encrypted option is not supported for #{locate_config_value(:flavor)} flavor.")
exit 1
end
# validation for ebs_size and ebs_volume_type and ebs_encrypted
@@ -948,10 +973,28 @@
if locate_config_value(:spot_price).nil? && locate_config_value(:spot_wait_mode).downcase != 'prompt'
ui.error('spot-wait-mode option requires that a spot-price option is set.')
exit 1
end
+ volume_tags = locate_config_value(:volume_tags)
+ if !volume_tags.nil? and volume_tags.length != volume_tags.to_s.count('=')
+ ui.error("Volume Tags should be entered in a key = value pair")
+ exit 1
+ end
+
+ if (locate_config_value(:winrm_password).to_s.length > 14 )
+ ui.warn("The password provided is longer than 14 characters. Computers with Windows prior to Windows 2000 will not be able to use this account. Do you want to continue this operation? (Y/N):")
+ password_promt = STDIN.gets.chomp.upcase
+ if (password_promt == "N")
+ raise "Exiting as operation with password greater than 14 characters not accepted"
+ elsif (password_promt == "Y")
+ @allow_long_password = "/yes"
+ else
+ raise "The input provided is incorrect."
+ end
+ end
+
end
def tags
tags = locate_config_value(:tags)
if !tags.nil? and tags.length != tags.to_s.count('=')
@@ -972,11 +1015,11 @@
def ssl_config_user_data
user_related_commands = ""
winrm_user = locate_config_value(:winrm_user).split("\\")
if (winrm_user[0] == ".") || (winrm_user[0] == "") ||(winrm_user.length == 1)
user_related_commands = <<-EOH
-net user /add #{locate_config_value(:winrm_user).delete('.\\')} #{windows_password};
+net user /add #{locate_config_value(:winrm_user).delete('.\\')} #{windows_password} #{@allow_long_password};
net localgroup Administrators /add #{locate_config_value(:winrm_user).delete('.\\')};
EOH
end
<<-EOH
#{user_related_commands}
@@ -988,17 +1031,43 @@
}
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/public-ipv4
If (-Not $vm_name) {
$vm_name = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/local-ipv4
}
-New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -dnsname $vm_name
+
+$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
+$name.Encode("CN=$vm_name", 0)
+$key = new-object -com "X509Enrollment.CX509PrivateKey.1"
+$key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
+$key.KeySpec = 1
+$key.Length = 2048
+$key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
+$key.MachineContext = 1
+$key.Create()
+$serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
+$serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
+$ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
+$ekuoids.add($serverauthoid)
+$ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
+$ekuext.InitializeEncode($ekuoids)
+$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
+$cert.InitializeFromPrivateKey(2, $key, "")
+$cert.Subject = $name
+$cert.Issuer = $cert.Subject
+$cert.NotBefore = get-date
+$cert.NotAfter = $cert.NotBefore.AddYears(10)
+$cert.X509Extensions.Add($ekuext)
+$cert.Encode()
+$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
+$enrollment.InitializeFromRequest($cert)
+$certdata = $enrollment.CreateRequest(0)
+$enrollment.InstallResponse(2, $certdata, 0, "")
+
$thumbprint = (Get-ChildItem -Path cert:\\localmachine\\my | Where-Object {$_.Subject -match "$vm_name"}).Thumbprint;
$create_listener_cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname=`"$vm_name`";CertificateThumbprint=`"$thumbprint`"}'"
iex $create_listener_cmd
-
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
-
EOH
end
def ssl_config_data_already_exist?
File.read(locate_config_value(:aws_user_data)).gsub(/\\\\/,"\\").include? ssl_config_user_data.strip
@@ -1440,9 +1509,15 @@
#Returns the name of node after evaluation of server id if %s is present.
#Eg: "Test-%s" will return "Test-i-12345" in case the instance id is i-12345
def evaluate_node_name(node_name)
return node_name%server.id
+ end
+
+ def create_volume_tags(hashed_volume_tags)
+ hashed_volume_tags.each_pair do |key,val|
+ connection.tags.create :key => key, :value => val, :resource_id => @server.block_device_mapping.first['volumeId']
+ end
end
end
end
end