module Chef::Knife::Ec2Base
Public Class Methods
included(includer)
click to toggle source
@todo Would prefer to do this in a rational way, but can't be done b/c of Mixlib::CLI's design :(
# File lib/chef/knife/helpers/ec2_base.rb, line 29 def self.included(includer) includer.class_eval do deps do require "aws-sdk-ec2" require "chef/json_compat" require "chef/util/path_helper" end option :aws_credential_file, long: "--aws-credential-file FILE", description: "File containing AWS credentials as used by the AWS Command Line Interface." option :aws_config_file, long: "--aws-config-file FILE", description: "File containing AWS configurations as used by the AWS Command Line Interface." option :aws_profile, long: "--aws-profile PROFILE", description: "AWS profile, from AWS credential file and AWS config file, to use", default: "default" option :aws_access_key_id, short: "-A ID", long: "--aws-access-key-id KEY", description: "Your AWS Access Key ID" option :aws_secret_access_key, short: "-K SECRET", long: "--aws-secret-access-key SECRET", description: "Your AWS API Secret Access Key" option :aws_session_token, long: "--aws-session-token TOKEN", description: "Your AWS Session Token, for use with AWS STS Federation or Session Tokens" option :region, long: "--region REGION", description: "Your AWS region" option :use_iam_profile, long: "--use-iam-profile", description: "Use IAM profile assigned to current machine", boolean: true, default: false end end
Public Instance Methods
ami()
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 180 def ami @ami ||= fetch_ami(config[:image]) end
connection_string()
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 77 def connection_string conn = {} conn[:region] = config[:region] || "us-east-1" Chef::Log.debug "Using AWS region #{conn[:region]}" conn[:credentials] = if config[:use_iam_profile] Chef::Log.debug "Using iam profile for authentication as use_iam_profile set" Aws::InstanceProfileCredentials.new else 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])}" Aws::Credentials.new(config[:aws_access_key_id], config[:aws_secret_access_key], config[:aws_session_token]) end conn end
ec2_connection()
click to toggle source
@return [Aws::EC2::Client]
# File lib/chef/knife/helpers/ec2_base.rb, line 94 def ec2_connection @ec2_connection ||= Aws::EC2::Client.new(connection_string) end
fetch_ami(image_id)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 102 def fetch_ami(image_id) return nil unless image_id ec2_connection.describe_images({ image_ids: [image_id], }).images.first end
fetch_ec2_instance(instance_id)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 110 def fetch_ec2_instance(instance_id) instance = ec2_connection.describe_instances({ instance_ids: [ instance_id, ], }).reservations[0] normalize_server_data(server_hashes(instance)) end
fetch_network_interfaces(nic_id)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 119 def fetch_network_interfaces(nic_id) ec2_connection.describe_network_interfaces({ network_interface_ids: [nic_id], }).network_interfaces[0] end
fetch_password_data(server_id)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 125 def fetch_password_data(server_id) ec2_connection.get_password_data({ instance_id: server_id, }) end
fetch_region()
click to toggle source
@return [String]
# File lib/chef/knife/helpers/ec2_base.rb, line 132 def fetch_region ec2_connection.instance_variable_get(:@config).region end
fetch_subnet(subnet_id)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 136 def fetch_subnet(subnet_id) ec2_connection.describe_subnets({ subnet_ids: [subnet_id], }).subnets[0] end
find_name_tag(tags)
click to toggle source
Name tag value return. @return [String]
# File lib/chef/knife/helpers/ec2_base.rb, line 186 def find_name_tag(tags) name_tag = tags.find { |tag| tag[:key] == "Name" } name_tag ? name_tag[:value] : nil end
is_image_windows?()
click to toggle source
Platform value return for Windows AMIs; otherwise, it is blank. @return [Boolean]
# File lib/chef/knife/helpers/ec2_base.rb, line 193 def is_image_windows? ami && ami.platform == "windows" end
msg_pair(label, value, color = :cyan)
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 174 def msg_pair(label, value, color = :cyan) if value && !value.to_s.empty? ui.info("#{ui.color(label, color)}: #{value}") end end
normalize_server_data(server_hashes)
click to toggle source
@return [Struct]
# File lib/chef/knife/helpers/ec2_base.rb, line 169 def normalize_server_data(server_hashes) require "ostruct" unless defined?(OpenStruct) OpenStruct.new(server_hashes) end
server_hashes(server_obj)
click to toggle source
@return [Hash]
# File lib/chef/knife/helpers/ec2_base.rb, line 143 def server_hashes(server_obj) server_data = {} %w{ebs_optimized image_id instance_id instance_type key_name platform public_dns_name public_ip_address private_dns_name private_ip_address root_device_type}.each do |id| server_data[id] = server_obj.instances[0].send(id) end server_data["availability_zone"] = server_obj.instances[0].placement.availability_zone server_data["groups"] = server_obj.groups.map(&:group_name) unless vpc_mode? server_data["iam_instance_profile"] = ( server_obj.instances[0].iam_instance_profile.nil? ? nil : server_obj.instances[0].iam_instance_profile.arn[%r{instance-profile/(.*)}] ) server_data["id"] = server_data["instance_id"] tags = server_obj.instances[0].tags.map(&:value) server_data["name"] = find_name_tag(server_obj.instances[0].tags) server_data["placement_group"] = server_obj.instances[0].placement.group_name server_data["security_groups"] = server_obj.instances[0].security_groups.map(&:group_name) server_data["security_group_ids"] = server_obj.instances[0].security_groups.map(&:group_id) server_data["state"] = server_obj.instances[0].state.name server_data["subnet_id"] = server_obj.instances[0].network_interfaces[0].subnet_id if vpc_mode? server_data["source_dest_check"] = server_obj.instances[0].network_interfaces[0].source_dest_check if vpc_mode? server_data["tags"] = tags server_data["tenancy"] = server_obj.instances[0].placement.tenancy server_data["volume_id"] = server_obj.instances[0].block_device_mappings[0]&.ebs&.volume_id server_data["block_device_mappings"] = server_obj.instances[0].block_device_mappings server_data end
validate_aws_config!(keys = %i{aws_access_key_id aws_secret_access_key})
click to toggle source
validate the config options that were passed since some of them cannot be used together also validate the aws configuration file contents if present
# File lib/chef/knife/helpers/ec2_base.rb, line 199 def validate_aws_config!(keys = %i{aws_access_key_id aws_secret_access_key}) errors = [] # track all errors so we report on all of them validate_aws_config_file! if config[:aws_config_file] unless config[:use_iam_profile] # skip config file / key validation if we're using iam profile # validate the creds file if: # aws keys have not been passed in config / CLI and the default cred file location does exist # OR # the user passed aws_credential_file if (config.keys & %i{aws_access_key_id aws_secret_access_key}).empty? && aws_cred_file_location || config[:aws_credential_file] unless (config.keys & %i{aws_access_key_id aws_secret_access_key}).empty? errors << "Either provide a credentials file or the access key and secret keys but not both." end validate_aws_credential_file! end keys.each do |k| pretty_key = k.to_s.tr("_", " ").gsub(/\w+/) { |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize } if config[k].nil? errors << "You did not provide a valid '#{pretty_key}' value." end end if errors.each { |e| ui.error(e) }.any? exit 1 end end end
vpc_mode?()
click to toggle source
# File lib/chef/knife/helpers/ec2_base.rb, line 98 def vpc_mode? !!config[:subnet_id] end