lib/beaker/hypervisor/aws_sdk.rb in beaker-aws-0.5.0 vs lib/beaker/hypervisor/aws_sdk.rb in beaker-aws-0.6.0
- old
+ new
@@ -263,10 +263,12 @@
# @api private
def create_instance(host, ami_spec, subnet_id)
amitype = host['vmname'] || host['platform']
amisize = host['amisize'] || 'm1.small'
vpc_id = host['vpc_id'] || @options['vpc_id'] || nil
+ host['sg_cidr_ips'] = host['sg_cidr_ips'] || '0.0.0.0/0';
+ sg_cidr_ips = host['sg_cidr_ips'].split(',')
if vpc_id && !subnet_id
raise RuntimeError, "A subnet_id must be provided with a vpc_id"
end
@@ -322,13 +324,13 @@
}
}
end
end
- security_group = ensure_group(vpc || region, Beaker::EC2Helper.amiports(host))
+ security_group = ensure_group(vpc || region, Beaker::EC2Helper.amiports(host), sg_cidr_ips)
#check if ping is enabled
- ping_security_group = ensure_ping_group(vpc || region)
+ ping_security_group = ensure_ping_group(vpc || region, sg_cidr_ips)
msg = "aws-sdk: launching %p on %p using %p/%p%s" %
[host.name, amitype, amisize, image_type,
subnet_id ? ("in %p" % subnet_id) : '']
@logger.notify(msg)
@@ -338,11 +340,11 @@
:image_id => image_id,
:monitoring => {
:enabled => true,
},
:key_name => ensure_key_pair(region).key_pairs.first.key_name,
- :security_groups => [security_group.group_name, ping_security_group.group_name],
+ :security_group_ids => [security_group.group_id, ping_security_group.group_id],
:instance_type => amisize,
:disable_api_termination => false,
:instance_initiated_shutdown_behavior => "terminate",
:subnet_id => subnet_id,
}
@@ -476,11 +478,11 @@
# Here we keep waiting for the machine state to reach 'running' with an
# exponential backoff for each poll.
# TODO: should probably be a in a shared method somewhere
for tries in 1..10
refreshed_instance = instance_by_id(instance.instance_id)
-
+
if refreshed_instance.nil?
@logger.debug("Instance #{name} not yet available (#{e})")
else
if block_given?
test_result = yield refreshed_instance
@@ -713,11 +715,11 @@
if host['vmname'] =~ /^amazon/
# Amazon Linux requires this to preserve host name changes across reboots.
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-hostname.html
# Also note that without an elastic ip set, while this will
# preserve the hostname across a full shutdown/startup of the vm
- # (as opposed to a reboot) -- the ip address will have changed.
+ # (as opposed to a reboot) -- the ip address will have changed.
host.exec(Command.new("sed -ie '/^HOSTNAME/ s/=.*/=#{host.name}/' /etc/sysconfig/network"))
end
end
end
else
@@ -906,24 +908,25 @@
# Return an existing group, or create new one
#
# Accepts a VPC as input for checking & creation.
#
# @param vpc [Aws::EC2::VPC] the AWS vpc control object
+ # @param sg_cidr_ips [Array<String>] CIDRs used for outbound security group rule
# @return [Aws::EC2::SecurityGroup] created security group
# @api private
- def ensure_ping_group(vpc)
+ def ensure_ping_group(vpc, sg_cidr_ips = ['0.0.0.0/0'])
@logger.notify("aws-sdk: Ensure security group exists that enables ping, create if not")
group = client.describe_security_groups(
:filters => [
{ :name => 'group-name', :values => [PING_SECURITY_GROUP_NAME] },
{ :name => 'vpc-id', :values => [vpc.vpc_id] },
]
).security_groups.first
if group.nil?
- group = create_ping_group(vpc)
+ group = create_ping_group(vpc, sg_cidr_ips)
end
group
end
@@ -931,13 +934,14 @@
#
# Accepts a VPC as input for checking & creation.
#
# @param vpc [Aws::EC2::VPC] the AWS vpc control object
# @param ports [Array<Number>] an array of port numbers
+ # @param sg_cidr_ips [Array<String>] CIDRs used for outbound security group rule
# @return [Aws::EC2::SecurityGroup] created security group
# @api private
- def ensure_group(vpc, ports)
+ def ensure_group(vpc, ports, sg_cidr_ips = ['0.0.0.0/0'])
@logger.notify("aws-sdk: Ensure security group exists for ports #{ports.to_s}, create if not")
name = group_id(ports)
group = client.describe_security_groups(
:filters => [
@@ -945,24 +949,25 @@
{ :name => 'vpc-id', :values => [vpc.vpc_id] },
]
).security_groups.first
if group.nil?
- group = create_group(vpc, ports)
+ group = create_group(vpc, ports, sg_cidr_ips)
end
group
end
# Create a new ping enabled security group
#
# Accepts a region or VPC for group creation.
#
- # @param rv [Aws::EC2::Region, Aws::EC2::VPC] the AWS region or vpc control object
+ # @param region_or_vpc [Aws::EC2::Region, Aws::EC2::VPC] the AWS region or vpc control object
+ # @param sg_cidr_ips [Array<String>] CIDRs used for outbound security group rule
# @return [Aws::EC2::SecurityGroup] created security group
# @api private
- def create_ping_group(region_or_vpc)
+ def create_ping_group(region_or_vpc, sg_cidr_ips = ['0.0.0.0/0'])
@logger.notify("aws-sdk: Creating group #{PING_SECURITY_GROUP_NAME}")
cl = region_or_vpc.is_a?(String) ? client(region_or_vpc) : client
params = {
:description => 'Custom Beaker security group to enable ping',
@@ -970,56 +975,80 @@
}
params[:vpc_id] = region_or_vpc.vpc_id if region_or_vpc.is_a?(Aws::EC2::Types::Vpc)
group = cl.create_security_group(params)
- cl.authorize_security_group_ingress(
- :cidr_ip => '0.0.0.0/0',
- :ip_protocol => 'icmp',
- :from_port => '8', # 8 == ICMPv4 ECHO request
- :to_port => '-1', # -1 == All ICMP codes
- :group_id => group.group_id,
- )
+ sg_cidr_ips.each do |cidr_ip|
+ add_ingress_rule(
+ cl,
+ group,
+ cidr_ip,
+ '8', # 8 == ICMPv4 ECHO request
+ '-1', # -1 == All ICMP codes
+ 'icmp',
+ )
+ end
group
end
# Create a new security group
#
# Accepts a region or VPC for group creation.
#
- # @param rv [Aws::EC2::Region, Aws::EC2::VPC] the AWS region or vpc control object
+ # @param region_or_vpc [Aws::EC2::Region, Aws::EC2::VPC] the AWS region or vpc control object
# @param ports [Array<Number>] an array of port numbers
+ # @param sg_cidr_ips [Array<String>] CIDRs used for outbound security group rule
# @return [Aws::EC2::SecurityGroup] created security group
# @api private
- def create_group(region_or_vpc, ports)
+ def create_group(region_or_vpc, ports, sg_cidr_ips = ['0.0.0.0/0'])
name = group_id(ports)
@logger.notify("aws-sdk: Creating group #{name} for ports #{ports.to_s}")
+ @logger.notify("aws-sdk: Creating group #{name} with CIDR IPs #{sg_cidr_ips.to_s}")
cl = region_or_vpc.is_a?(String) ? client(region_or_vpc) : client
- group = cl.create_security_group(
+ params = {
+ :description => "Custom Beaker security group for #{ports.to_a}",
:group_name => name,
- :description => "Custom Beaker security group for #{ports.to_a}"
- )
+ }
+ params[:vpc_id] = region_or_vpc.vpc_id if region_or_vpc.is_a?(Aws::EC2::Types::Vpc)
+
+ group = cl.create_security_group(params)
+
unless ports.is_a? Set
ports = Set.new(ports)
end
- ports.each do |port|
- cl.authorize_security_group_ingress(
- :cidr_ip => '0.0.0.0/0',
- :ip_protocol => 'tcp',
- :from_port => port,
- :to_port => port,
- :group_id => group.group_id,
- )
+ sg_cidr_ips.each do |cidr_ip|
+ ports.each do |port|
+ add_ingress_rule(cl, group, cidr_ip, port, port)
+ end
end
group
end
+ # Authorizes connections from certain CIDR to a range of ports
+ #
+ # @param cl [Aws::EC2::Client]
+ # @param sg_group [Aws::EC2::SecurityGroup] the AWS security group
+ # @param cidr_ip [String] CIDR used for outbound security group rule
+ # @param from_port [String] Starting Port number in the range
+ # @param to_port [String] Ending Port number in the range
+ # @return [void]
+ # @api private
+ def add_ingress_rule(cl, sg_group, cidr_ip, from_port, to_port, protocol = 'tcp')
+ cl.authorize_security_group_ingress(
+ :cidr_ip => cidr_ip,
+ :ip_protocol => protocol,
+ :from_port => from_port,
+ :to_port => to_port,
+ :group_id => sg_group.group_id,
+ )
+ end
+
# Return a hash containing AWS credentials
#
# @return [Hash<Symbol, String>] AWS credentials
# @api private
def load_credentials
@@ -1044,11 +1073,10 @@
#
# @param dot_fog [String] dot fog path
# @return [Aws::Credentials] ec2 credentials
# @api private
def load_fog_credentials(dot_fog = '.fog')
- fog = YAML.load_file( dot_fog )
- default = fog[:default]
+ default = get_fog_credentials(dot_fog)
raise "You must specify an aws_access_key_id in your .fog file (#{dot_fog}) for ec2 instances!" unless default[:aws_access_key_id]
raise "You must specify an aws_secret_access_key in your .fog file (#{dot_fog}) for ec2 instances!" unless default[:aws_secret_access_key]
Aws::Credentials.new(