mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Add pretend networking and interface association to the network interface mocking
This commit is contained in:
parent
911ec7c5a8
commit
421bc0adb7
9 changed files with 200 additions and 64 deletions
12
fog.gemspec
12
fog.gemspec
|
@ -44,10 +44,14 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency("fog-core", "~> 1.21", ">= 1.21.1")
|
||||
s.add_dependency("fog-json")
|
||||
|
||||
s.add_dependency('nokogiri', '~> 1.5', '>= 1.5.11')
|
||||
|
||||
# Modular providers
|
||||
s.add_dependency("fog-brightbox")
|
||||
s.add_dependency('builder')
|
||||
s.add_dependency('excon', '~>0.31.0')
|
||||
s.add_dependency('formatador', '~>0.2.0')
|
||||
s.add_dependency('ipaddress', '~>0.5')
|
||||
s.add_dependency('mime-types')
|
||||
s.add_dependency('net-scp', '~>1.1')
|
||||
s.add_dependency('net-ssh', '>=2.1.3')
|
||||
s.add_dependency('nokogiri', '>=1.5.11')
|
||||
|
||||
## List your development dependencies here. Development dependencies are
|
||||
## those that are only needed during development
|
||||
|
|
|
@ -35,10 +35,17 @@ module Fog
|
|||
|
||||
def attach_network_interface(nic_id, instance_id, device_index)
|
||||
response = Excon::Response.new
|
||||
if self.data[:network_interfaces][nic_id]
|
||||
if ! self.data[:instances].find{ |i,i_conf|
|
||||
i_conf['instanceId'] == instance_id
|
||||
}
|
||||
raise Fog::Compute::AWS::NotFound.new("The instance ID '#{instance_id}' does not exist")
|
||||
elsif self.data[:network_interfaces].find{ |ni,ni_conf| ni_conf['attachment']['instanceId'] == instance_id && ni_conf['attachment']['deviceIndex'] == device_index }
|
||||
raise Fog::Compute::AWS::Error.new("InvalidParameterValue => Instance '#{instance_id}' already has an interface attached at device index '#{device_index}'.")
|
||||
elsif self.data[:network_interfaces][nic_id]
|
||||
attachment = self.data[:network_interfaces][nic_id]['attachment']
|
||||
attachment['attachmentId'] = Fog::AWS::Mock.request_id
|
||||
attachment['instanceId'] = instance_id
|
||||
attachment['deviceIndex'] = device_index
|
||||
|
||||
response.status = 200
|
||||
response.body = {
|
||||
|
|
|
@ -65,45 +65,63 @@ module Fog
|
|||
def create_network_interface(subnetId, options = {})
|
||||
response = Excon::Response.new
|
||||
if subnetId
|
||||
id = Fog::AWS::Mock.network_interface_id
|
||||
subnet = self.data[:subnets].find{ |s| s['subnetId'] == subnetId }
|
||||
if subnet.nil?
|
||||
raise Fog::Compute::AWS::Error.new("Unknown subnet '#{subnetId}' specified")
|
||||
else
|
||||
id = Fog::AWS::Mock.network_interface_id
|
||||
cidr_block = IPAddress.parse(subnet['cidrBlock'])
|
||||
|
||||
groups = {}
|
||||
if options['GroupSet']
|
||||
options['GroupSet'].each do |group_id|
|
||||
name = self.data[:security_groups].select { |k,v| v['groupId'] == group_id }.first
|
||||
if name.nil?
|
||||
raise Fog::Compute::AWS::Error.new("Unknown security group '#{group_id}' specified")
|
||||
groups = {}
|
||||
if options['GroupSet']
|
||||
options['GroupSet'].each do |group_id|
|
||||
name = self.data[:security_groups].select { |k,v| v['groupId'] == group_id } .first.first
|
||||
if name.nil?
|
||||
raise Fog::Compute::AWS::Error.new("Unknown security group '#{group_id}' specified")
|
||||
end
|
||||
groups[group_id] = name
|
||||
end
|
||||
groups[group_id] = name
|
||||
end
|
||||
end
|
||||
if options['PrivateIpAddress'].nil?
|
||||
options['PrivateIpAddress'] = "10.0.0.2"
|
||||
end
|
||||
|
||||
data = {
|
||||
'networkInterfaceId' => id,
|
||||
'subnetId' => subnetId,
|
||||
'vpcId' => 'mock-vpc-id',
|
||||
'availabilityZone' => 'mock-zone',
|
||||
'description' => options['Description'],
|
||||
'ownerId' => '',
|
||||
'requesterManaged' => 'false',
|
||||
'status' => 'available',
|
||||
'macAddress' => '00:11:22:33:44:55',
|
||||
'privateIpAddress' => options['PrivateIpAddress'],
|
||||
'sourceDestCheck' => true,
|
||||
'groupSet' => groups,
|
||||
'attachment' => {},
|
||||
'association' => {},
|
||||
'tagSet' => {}
|
||||
}
|
||||
self.data[:network_interfaces][id] = data
|
||||
response.body = {
|
||||
'requestId' => Fog::AWS::Mock.request_id,
|
||||
'networkInterface' => data
|
||||
}
|
||||
response
|
||||
if options['PrivateIpAddress'].nil?
|
||||
# Here we try to act like a DHCP server and pick the first
|
||||
# available IP (not including the first in the cidr block,
|
||||
# which is typically reserved for the gateway).
|
||||
cidr_block.each_host do |p_ip|
|
||||
unless self.data[:network_interfaces].map{ |ni, ni_conf| ni_conf['privateIpAddress'] }.include?p_ip.to_s ||
|
||||
cidr_block.first == p_ip
|
||||
options['PrivateIpAddress'] = p_ip.to_s
|
||||
break
|
||||
end
|
||||
end
|
||||
elsif self.data[:network_interfaces].map{ |ni,ni_conf| ni_conf['privateIpAddress'] }.include?options['PrivateIpAddress']
|
||||
raise Fog::Compute::AWS::Error.new("InUse => The specified address is already in use.")
|
||||
end
|
||||
|
||||
data = {
|
||||
'networkInterfaceId' => id,
|
||||
'subnetId' => subnetId,
|
||||
'vpcId' => 'mock-vpc-id',
|
||||
'availabilityZone' => 'mock-zone',
|
||||
'description' => options['Description'],
|
||||
'ownerId' => '',
|
||||
'requesterManaged' => 'false',
|
||||
'status' => 'available',
|
||||
'macAddress' => '00:11:22:33:44:55',
|
||||
'privateIpAddress' => options['PrivateIpAddress'],
|
||||
'sourceDestCheck' => true,
|
||||
'groupSet' => groups,
|
||||
'attachment' => {},
|
||||
'association' => {},
|
||||
'tagSet' => {}
|
||||
}
|
||||
self.data[:network_interfaces][id] = data
|
||||
response.body = {
|
||||
'requestId' => Fog::AWS::Mock.request_id,
|
||||
'networkInterface' => data
|
||||
}
|
||||
response
|
||||
end
|
||||
else
|
||||
response.status = 400
|
||||
response.body = {
|
||||
|
|
|
@ -3,6 +3,7 @@ module Fog
|
|||
class AWS
|
||||
class Real
|
||||
|
||||
require 'ipaddress'
|
||||
require 'fog/aws/parsers/compute/create_subnet'
|
||||
|
||||
# Creates a Subnet with the CIDR block you specify.
|
||||
|
@ -44,7 +45,20 @@ module Fog
|
|||
def create_subnet(vpcId, cidrBlock, options = {})
|
||||
av_zone = options['AvailabilityZone'].nil? ? 'us-east-1c' : options['AvailabilityZone']
|
||||
Excon::Response.new.tap do |response|
|
||||
if cidrBlock && vpcId
|
||||
if cidrBlock && vpcId
|
||||
vpc = self.data[:vpcs].find{ |v| v['vpcId'] == vpcId }
|
||||
if vpc.nil?
|
||||
raise Fog::Compute::AWS::NotFound.new("The vpc ID '#{vpcId}' does not exist")
|
||||
end
|
||||
if ! ::IPAddress.parse(vpc['cidrBlock']).include?(::IPAddress.parse(cidrBlock))
|
||||
raise Fog::Compute::AWS::Error.new("Range => The CIDR '#{cidrBlock}' is invalid.")
|
||||
end
|
||||
self.data[:subnets].each do |subnet|
|
||||
if ::IPAddress.parse(subnet['cidrBlock']).include?(::IPAddress.parse(cidrBlock))
|
||||
raise Fog::Compute::AWS::Error.new("Conflict => The CIDR '#{cidrBlock}' conflicts with another subnet")
|
||||
end
|
||||
end
|
||||
|
||||
response.status = 200
|
||||
data = {
|
||||
'subnetId' => Fog::AWS::Mock.subnet_id,
|
||||
|
|
|
@ -184,8 +184,6 @@ module Fog
|
|||
instance['ipAddress'] = Fog::AWS::Mock.ip_address
|
||||
instance['originalIpAddress'] = instance['ipAddress']
|
||||
instance['dnsName'] = Fog::AWS::Mock.dns_name_for(instance['ipAddress'])
|
||||
instance['privateIpAddress'] = Fog::AWS::Mock.private_ip_address
|
||||
instance['privateDnsName'] = Fog::AWS::Mock.private_dns_name_for(instance['privateIpAddress'])
|
||||
instance['instanceState'] = { 'code' => 16, 'name' => 'running' }
|
||||
end
|
||||
when 'rebooting'
|
||||
|
@ -209,18 +207,30 @@ module Fog
|
|||
|
||||
if self.data[:instances][instance['instanceId']]
|
||||
|
||||
instance['networkInterfaces'] = self.data[:network_interfaces].select{|ni,ni_conf|
|
||||
ni_conf['attachment']['instanceId'] == instance['instanceId']
|
||||
}.map{|ni,ni_conf|
|
||||
{
|
||||
'ownerId' => ni_conf['ownerId'],
|
||||
'subnetId' => ni_conf['subnetId'],
|
||||
'vpcId' => ni_conf['vpcId'],
|
||||
'networkInterfaceId' => ni_conf['networkInterfaceId'],
|
||||
'groupSet' => ni_conf['groupSet'],
|
||||
'attachmentId' => ni_conf['attachment']['attachmentId']
|
||||
}
|
||||
nics = self.data[:network_interfaces].select{|ni,ni_conf|
|
||||
ni_conf['attachment']['instanceId'] == instance['instanceId']
|
||||
}
|
||||
instance['networkInterfaces'] = nics.map{|ni,ni_conf|
|
||||
{
|
||||
'ownerId' => ni_conf['ownerId'],
|
||||
'subnetId' => ni_conf['subnetId'],
|
||||
'vpcId' => ni_conf['vpcId'],
|
||||
'networkInterfaceId' => ni_conf['networkInterfaceId'],
|
||||
'groupSet' => ni_conf['groupSet'],
|
||||
'attachmentId' => ni_conf['attachment']['attachmentId']
|
||||
}
|
||||
}
|
||||
if nics.count > 0
|
||||
|
||||
instance['privateIpAddress'] = nics.sort_by {|ni, ni_conf|
|
||||
ni_conf['attachment']['deviceIndex']
|
||||
}.map{ |ni, ni_conf| ni_conf['privateIpAddress'] }.first
|
||||
|
||||
instance['privateDnsName'] = Fog::AWS::Mock.private_dns_name_for(instance['privateIpAddress'])
|
||||
else
|
||||
instance['privateIpAddress'] = ''
|
||||
instance['privateDnsName'] = ''
|
||||
end
|
||||
|
||||
reservation_set[instance['reservationId']] ||= {
|
||||
'groupSet' => instance['groupSet'],
|
||||
|
|
|
@ -184,6 +184,16 @@ module Fog
|
|||
}
|
||||
end
|
||||
|
||||
if options['SubnetId']
|
||||
if options['PrivateIpAddress']
|
||||
ni_options = {'PrivateIpAddress' => options['PrivateIpAddress']}
|
||||
else
|
||||
ni_options = {}
|
||||
end
|
||||
|
||||
network_interface_id = create_network_interface(options['SubnetId'], ni_options).body['networkInterface']['networkInterfaceId']
|
||||
end
|
||||
|
||||
network_interfaces = (options['NetworkInterfaces'] || []).inject([]) do |mapping, device|
|
||||
device_index = device.fetch("DeviceIndex", 0)
|
||||
subnet_id = device.fetch("SubnetId", options[:subnet_id] || Fog::AWS::Mock.subnet_id)
|
||||
|
@ -238,12 +248,15 @@ module Fog
|
|||
'groupIds' => [],
|
||||
'groupSet' => group_set,
|
||||
'iamInstanceProfile' => {},
|
||||
'networkInterfaces' => [],
|
||||
'ownerId' => self.data[:owner_id],
|
||||
'privateIpAddress' => nil,
|
||||
'reservationId' => reservation_id,
|
||||
'stateReason' => {}
|
||||
})
|
||||
|
||||
if options['SubnetId']
|
||||
attachment_id = attach_network_interface(network_interface_id, instance_id, 0).data[:body]['attachmentId']
|
||||
modify_network_interface_attribute(network_interface_id, 'attachment', {'attachmentId' => attachment_id, 'deleteOnTermination' => 'true'})
|
||||
end
|
||||
end
|
||||
response.body = {
|
||||
'groupSet' => group_set,
|
||||
|
|
|
@ -204,11 +204,15 @@ Shindo.tests('Fog::Compute[:aws] | instance requests', ['aws']) do
|
|||
|
||||
# Test network interface attachment
|
||||
tests('#describe_instances networkInterfaces') do
|
||||
data = Fog::Compute[:aws].create_network_interface('subnet-12345678').body
|
||||
vpc = Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/16')
|
||||
subnet = Fog::Compute[:aws].subnets.create('vpc_id' => vpc.id, 'cidr_block' => '10.0.10.0/16')
|
||||
data = Fog::Compute[:aws].create_network_interface(subnet.subnet_id).body
|
||||
@network_interface_id = data['networkInterface']['networkInterfaceId']
|
||||
Fog::Compute[:aws].attach_network_interface(@network_interface_id, @instance_id, 1)
|
||||
Fog::Compute[:aws].attach_network_interface(@network_interface_id, @instance_id, '1')
|
||||
body = Fog::Compute[:aws].describe_instances('instance-id' => "#{@instance_id}").body
|
||||
tests("returns 1 attachment").returns(1) { body['reservationSet'].first['instancesSet'].first['networkInterfaces'].size }
|
||||
subnet.destroy
|
||||
vpc.destroy
|
||||
end
|
||||
|
||||
another_server.destroy
|
||||
|
@ -269,6 +273,9 @@ Shindo.tests('Fog::Compute[:aws] | instance requests', ['aws']) do
|
|||
|
||||
tests('failure') do
|
||||
|
||||
tests("#run_instances(nil, 1, 1, {'SubnetId'=>'subnet-00000000'}").raises(::Fog::Compute::AWS::Error) do
|
||||
Fog::Compute[:aws].run_instances(nil, 1, 1, {'SubnetId' => 'subnet-000000'})
|
||||
end
|
||||
tests("#get_console_output('i-00000000')").raises(Fog::Compute::AWS::NotFound) do
|
||||
Fog::Compute[:aws].get_console_output('i-00000000')
|
||||
end
|
||||
|
|
|
@ -120,11 +120,12 @@ Shindo.tests('Fog::Compute[:aws] | network interface requests', ['aws']) do
|
|||
|
||||
@server = Fog::Compute[:aws].servers.create({:flavor_id => 'm1.small', :subnet_id => @subnet_id })
|
||||
@server.wait_for { ready? }
|
||||
@instance_id=@server.id
|
||||
@instance_id=@server.id
|
||||
|
||||
# attach
|
||||
# attach
|
||||
@device_index = 1
|
||||
tests('#attach_network_interface').formats(@attach_network_interface_format) do
|
||||
data = Fog::Compute[:aws].attach_network_interface(@nic_id, @instance_id, 1).body
|
||||
data = Fog::Compute[:aws].attach_network_interface(@nic_id, @instance_id, @device_index).body
|
||||
@attachment_id = data['attachmentId']
|
||||
data
|
||||
end
|
||||
|
@ -201,4 +202,48 @@ Shindo.tests('Fog::Compute[:aws] | network interface requests', ['aws']) do
|
|||
@subnet.destroy
|
||||
@vpc.destroy
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
|
||||
# Attempt to attach a nonexistent interface
|
||||
tests("#attach_network_interface('eni-00000000', 'i-00000000', '1')").raises(::Fog::Compute::AWS::NotFound) do
|
||||
Fog::Compute[:aws].attach_network_interface('eni-00000000', 'i-00000000', '1')
|
||||
end
|
||||
|
||||
# Create environment
|
||||
@vpc = Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||
@subnet = Fog::Compute[:aws].subnets.create('vpc_id' => @vpc.id, 'cidr_block' => '10.0.10.16/28')
|
||||
|
||||
@subnet_id = @subnet.subnet_id
|
||||
|
||||
data = Fog::Compute[:aws].create_network_interface(@subnet_id).body
|
||||
@nic_id = data['networkInterface']['networkInterfaceId']
|
||||
|
||||
# Attempt to re-use an existing IP for another ENI
|
||||
tests("#create_network_interface('#{@subnet_id}', {'PrivateIpAddress' => '#{data['networkInterface']['privateIpAddress']}'}").raises(::Fog::Compute::AWS::Error) do
|
||||
Fog::Compute[:aws].create_network_interface(@subnet_id, {'PrivateIpAddress' => data['networkInterface']['privateIpAddress']})
|
||||
end
|
||||
|
||||
# Attempt to attach a valid ENI to a nonexistent instance.
|
||||
tests("#attach_network_interface('#{@nic_id}', 'i-00000000', '0')").raises(::Fog::Compute::AWS::NotFound) do
|
||||
Fog::Compute[:aws].attach_network_interface(@nic_id, 'i-00000000', '0')
|
||||
end
|
||||
|
||||
@server = Fog::Compute[:aws].servers.create({:flavor_id => 'm1.small', :subnet_id => @subnet_id })
|
||||
@server.wait_for { ready? }
|
||||
@instance_id=@server.id
|
||||
@device_index = 1
|
||||
data = Fog::Compute[:aws].attach_network_interface(@nic_id, @instance_id, @device_index).body
|
||||
|
||||
# Attempt to attach two ENIs to the same instance with the same device
|
||||
# index.
|
||||
tests("#attach_network_interface('#{@nic_id}', '#{@instance_id}', '#{@device_index}')").raises(::Fog::Compute::AWS::Error) do
|
||||
Fog::Compute[:aws].attach_network_interface(@nic_id, @instance_id, @device_index)
|
||||
end
|
||||
|
||||
@server.destroy
|
||||
@subnet.destroy
|
||||
@vpc.destroy
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,9 +20,10 @@ Shindo.tests('Fog::Compute[:aws] | subnet requests', ['aws']) do
|
|||
'requestId' => String
|
||||
}
|
||||
|
||||
@vpc=Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||
@vpc_id = @vpc.id
|
||||
|
||||
tests('success') do
|
||||
@vpc=Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||
@vpc_id = @vpc.id
|
||||
@subnet_id = nil
|
||||
|
||||
tests('#create_subnet').formats(@single_subnet_format) do
|
||||
|
@ -38,6 +39,23 @@ Shindo.tests('Fog::Compute[:aws] | subnet requests', ['aws']) do
|
|||
tests("#delete_subnet('#{@subnet_id}')").formats(AWS::Compute::Formats::BASIC) do
|
||||
Fog::Compute[:aws].delete_subnet(@subnet_id).body
|
||||
end
|
||||
@vpc.destroy
|
||||
end
|
||||
|
||||
tests('failure') do
|
||||
tests("#create_subnet('vpc-00000000', '10.0.10.0/16')").raises(Fog::Compute::AWS::NotFound) do
|
||||
Fog::Compute[:aws].create_subnet('vpc-00000000', '10.0.10.0/16')
|
||||
end
|
||||
|
||||
tests("#create_subnet('#{@vpc_id}', '10.0.9.16/28')").raises(Fog::Compute::AWS::Error) do
|
||||
Fog::Compute[:aws].create_subnet(@vpc_id, '10.0.9.16/28')
|
||||
end
|
||||
|
||||
# Attempt to create two subnets with conflicting CIDRs
|
||||
tests("#create_subnet('#{@vpc_id}', '10.0.10.64/26')").raises(::Fog::Compute::AWS::Error) do
|
||||
Fog::Compute[:aws].create_subnet(@vpc_id, '10.0.10.0/24')
|
||||
Fog::Compute[:aws].create_subnet(@vpc_id, '10.0.10.64/26')
|
||||
end
|
||||
end
|
||||
|
||||
@vpc.destroy
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue