Skip to content

Commit

Permalink
Merge pull request #174 from fmoehler/enable-dual-stack-with-single-nic
Browse files Browse the repository at this point in the history
Enable dual stack with single nic
  • Loading branch information
lnguyen authored Jan 16, 2025
2 parents 6d331ab + 463ff5e commit ba8ccd9
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 122 deletions.
2 changes: 1 addition & 1 deletion src/bosh_aws_cpi/lib/cloud/aws/instance_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def initialize(ec2, logger)
@imds_v2_enable = {}

security_group_mapper = SecurityGroupMapper.new(@ec2)
@param_mapper = InstanceParamMapper.new(security_group_mapper)
@param_mapper = InstanceParamMapper.new(security_group_mapper, logger)
end

def create(stemcell_id, vm_cloud_props, networks_cloud_props, disk_locality, default_security_groups, block_device_mappings, user_data, tags, metadata_options)
Expand Down
70 changes: 57 additions & 13 deletions src/bosh_aws_cpi/lib/cloud/aws/instance_param_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ module Bosh::AwsCloud
class InstanceParamMapper
attr_accessor :manifest_params

def initialize(security_group_mapper)
def initialize(security_group_mapper, logger)
@manifest_params = {}
@logger = logger
@security_group_mapper = security_group_mapper
end

Expand Down Expand Up @@ -92,12 +93,34 @@ def instance_params
nic[:groups] = sg unless sg.nil? || sg.empty?
nic[:subnet_id] = subnet_id if subnet_id

# only supporting one ip address for now (either ipv4 or ipv6)
if private_ip_address
if ipv6_address?(private_ip_address)
nic[:ipv_6_addresses] = [{ipv_6_address: private_ip_address}]
if dual_stack_mode?
ipv6_count = ipv4_count = 0
private_ip_addresses.each do |private_ip|
if ipv6_address?(private_ip)
nic[:ipv_6_addresses] = [{ipv_6_address: private_ip}]
ipv6_count += 1
else
nic[:private_ip_address] = private_ip
ipv4_count += 1
end
end
if ipv4_count == 1 && ipv6_count == 1
@logger.info("Running in dual stack mode")
else
nic[:private_ip_address] = private_ip_address
if ipv4_count == 0
raise Bosh::Clouds::CloudError, "Dual Stack Mode: No ipv4 address assigned"
elsif ipv6_count == 0
raise Bosh::Clouds::CloudError, "Dual Stack Mode: No ipv6 address assigned"
end
end
else
private_ip_address = private_ip_addresses.first
if private_ip_address
if ipv6_address?(private_ip_address)
nic[:ipv_6_addresses] = [{ipv_6_address: private_ip_address}]
else
nic[:private_ip_address] = private_ip_address
end
end
end

Expand Down Expand Up @@ -147,19 +170,40 @@ def ipv6_address?(addr)
addr.to_s.include?(':')
end

def private_ip_address
first_manual_network = networks_cloud_props.filter('manual').first
first_manual_network.ip unless first_manual_network.nil?
def private_ip_addresses
manual_subnets = subnets.select {|subnet| subnet.type == 'manual' }
ips = manual_subnets.map { |subnet_network| subnet_network.ip }

ips unless ips.nil?
end

# NOTE: do NOT lookup the subnet (from EC2 client) anymore. We just need to
# pass along the subnet_id anyway, and we have that.
def subnet_id
subnet_network_spec = networks_cloud_props.filter('manual', 'dynamic').reject do |net|
def subnets
subnet_network_specs = networks_cloud_props.filter('manual', 'dynamic').reject do |net|
net.subnet.nil?
end.first
end

subnet_network_specs unless subnet_network_specs.nil?
end

subnet_network_spec.subnet unless subnet_network_spec.nil?
def subnet_id
subnet_ids.first
end

def subnet_ids
subnets.map { |subnet_network| subnet_network.subnet }
end

def dual_stack_mode?
dual_stack_mode = false
if subnets.length == 2 && subnets.find {|subnet| subnet.type == 'dynamic'}.nil?
# if two manual networks refer to the same subnet we assume dual stack mode
if subnet_ids[0] == subnet_ids[1]
dual_stack_mode = true
end
end
dual_stack_mode
end

def availability_zone
Expand Down
Loading

0 comments on commit ba8ccd9

Please sign in to comment.