Skip to content

Commit a3a16f8

Browse files
committed
introduce new prefix column in ip addresses table
1 parent 1e123e3 commit a3a16f8

File tree

7 files changed

+43
-88
lines changed

7 files changed

+43
-88
lines changed

src/bosh-director/lib/bosh/director/deployment_plan/instance_network_reservations.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def self.create_from_db(instance_model, deployment, logger)
1717
deployment,
1818
ip_address.network_name,
1919
ip_address.address,
20-
'not-dynamic')
20+
'not-dynamic',
21+
ip_address.prefix)
2122
end
2223

2324
unless instance_model.spec.nil?
@@ -54,9 +55,9 @@ def delete(reservation)
5455
@reservations.delete(reservation)
5556
end
5657

57-
def add_existing(instance_model, deployment, network_name, ip, existing_network_type)
58+
def add_existing(instance_model, deployment, network_name, ip, existing_network_type, prefix)
5859
network = find_network(deployment, ip, network_name, instance_model)
59-
reservation = ExistingNetworkReservation.new(instance_model, network, ip, existing_network_type)
60+
reservation = ExistingNetworkReservation.new(instance_model, network, ip, existing_network_type, prefix)
6061
deployment.ip_provider.reserve_existing_ips(reservation)
6162
@reservations << reservation
6263
end

src/bosh-director/lib/bosh/director/deployment_plan/ip_provider/ip_provider.rb

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,8 @@ def reserve_manual(reservation)
6565
@logger.debug("Allocating dynamic ip for manual network '#{reservation.network.name}'")
6666

6767
filter_subnet_by_instance_az(reservation).each do |subnet|
68-
ip = if reservation.is_prefix_reservation
69-
@ip_repo.allocate_dynamic_prefix(reservation, subnet)
70-
else
71-
@ip_repo.allocate_dynamic_ip(reservation, subnet)
72-
end
73-
74-
@logger.debug("Reserving dynamic IP/prefix '#{ip}' for manual network '#{reservation.network.name}'")
75-
76-
if ip
68+
if (ip = @ip_repo.allocate_dynamic_ip(reservation, subnet))
69+
@logger.debug("Reserving dynamic IP '#{ip}' for manual network '#{reservation.network.name}'")
7770
reservation.resolve_ip(ip)
7871
reservation.resolve_type(:dynamic)
7972
break
@@ -82,7 +75,7 @@ def reserve_manual(reservation)
8275

8376
if reservation.ip.nil?
8477
raise NetworkReservationNotEnoughCapacity,
85-
"Failed to reserve IP/Prefix for '#{reservation.instance_model}' for manual network '#{reservation.network.name}': no more available"
78+
"Failed to reserve IP for '#{reservation.instance_model}' for manual network '#{reservation.network.name}': no more available"
8679
end
8780
else
8881
@logger.debug("Reserving #{reservation.desc} for manual network '#{reservation.network.name}'")

src/bosh-director/lib/bosh/director/deployment_plan/ip_provider/ip_repo.rb

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,6 @@ def allocate_dynamic_ip(reservation, subnet)
5454
ip_address.to_i
5555
end
5656

57-
def allocate_dynamic_prefix(reservation, subnet)
58-
begin
59-
cidr = try_to_allocate_dynamic_prefix(reservation, subnet)
60-
rescue NoMoreIPsAvailableAndStopRetrying
61-
@logger.debug('Failed to allocate dynamic prefix: no more available')
62-
return nil
63-
rescue IpFoundInDatabaseAndCanBeRetried
64-
@logger.debug('Retrying to allocate dynamic prefix: probably a race condition with another deployment')
65-
# IP can be taken by other deployment that runs in parallel
66-
# retry until succeeds or out of range
67-
retry
68-
end
69-
70-
@logger.debug("Allocated dynamic cidr '#{cidr}' for #{reservation.network.name}")
71-
cidr.to_i
72-
end
73-
7457
def allocate_vip_ip(reservation, subnet)
7558
begin
7659
ip_address = try_to_allocate_vip_ip(reservation, subnet)
@@ -112,33 +95,6 @@ def try_to_allocate_dynamic_ip(reservation, subnet)
11295
ip_address
11396
end
11497

115-
def try_to_allocate_dynamic_prefix(reservation, subnet)
116-
@logger.debug("Allocating dynamic prefix for #{reservation.network.name}")
117-
addresses_in_use = Set.new(all_ip_addresses)
118-
119-
first_range_address = subnet.range.to_range.first.to_i - 1
120-
addresses_we_cant_allocate = addresses_in_use
121-
addresses_we_cant_allocate << first_range_address
122-
123-
addresses_we_cant_allocate.merge(subnet.restricted_ips.to_a) unless subnet.restricted_ips.empty?
124-
addresses_we_cant_allocate.merge(subnet.static_ips.to_a) unless subnet.static_ips.empty?
125-
126-
addr = Bosh::Director::IpAddrOrCidr.new(find_first_available_address(addresses_we_cant_allocate, first_range_address)).to_s
127-
cidr_string = get_first_available_prefix(addr, subnet.prefix)
128-
129-
@logger.debug("FIRST AVAILABLE PREFIX '#{cidr_string}' for #{reservation.network.name}")
130-
131-
cidr = Bosh::Director::IpAddrOrCidr.new(cidr_string)
132-
133-
unless subnet.range == cidr || subnet.range.include?(cidr)
134-
raise NoMoreIPsAvailableAndStopRetrying
135-
end
136-
137-
save_ip(cidr, reservation, false)
138-
139-
cidr
140-
end
141-
14298
def find_first_available_address(addresses_we_cant_allocate, first_address)
14399
last_address_we_cant_use = addresses_we_cant_allocate
144100
.to_a
@@ -204,15 +160,18 @@ def validate_instance_and_update_reservation_type(instance_model, ip, ip_address
204160
end
205161

206162
def save_ip(ip, reservation, is_static)
163+
@logger.debug("Adding IP Address: #{ip} from reservation: #{reservation}")
207164
ip_address = Bosh::Director::Models::IpAddress.new(
208165
address_str: ip.to_i.to_s,
209166
network_name: reservation.network.name,
210167
task_id: Bosh::Director::Config.current_job.task_id,
211168
static: is_static,
169+
prefix: reservation.prefix
212170
)
213171
reservation.instance_model.add_ip_address(ip_address)
214172
rescue Sequel::ValidationFailed, Sequel::DatabaseError => e
215173
error_message = e.message.downcase
174+
@logger.debug("ERROR!!! #{error_message}")
216175
if error_message.include?('unique') || error_message.include?('duplicate')
217176
raise IpFoundInDatabaseAndCanBeRetried, e.inspect
218177
else

src/bosh-director/lib/bosh/director/deployment_plan/network_planner/planner.rb

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,21 @@ def initialize(logger)
66
end
77

88
def network_plan_with_dynamic_reservation(instance_plan, job_network)
9-
plans = []
10-
reservation = Bosh::Director::DesiredNetworkReservation.new_dynamic(instance_plan.instance.model, job_network.deployment_network)
11-
@logger.debug("Creating new dynamic reservation #{reservation} for instance '#{instance_plan.instance}'")
12-
plans << Plan.new(reservation: reservation)
13-
job_network.deployment_network.subnets.each do |subnet|
14-
unless subnet.prefix.nil?
15-
prefix_reservation = Bosh::Director::DesiredNetworkReservation.new_dynamic(instance_plan.instance.model, job_network.deployment_network, true)
16-
plans << Plan.new(reservation: prefix_reservation)
17-
end
9+
prefix = job_network.deployment_network.subnets.each do |subnet|
10+
subnet.prefix
1811
end
19-
plans
12+
reservation = Bosh::Director::DesiredNetworkReservation.new_dynamic(instance_plan.instance.model, job_network.deployment_network, prefix)
13+
@logger.debug("Creating new dynamic reservation #{reservation} for instance '#{instance_plan.instance}'")
14+
Plan.new(reservation: reservation)
2015
end
2116

2217
def network_plan_with_static_reservation(instance_plan, job_network, static_ip)
23-
plans = []
24-
reservation = Bosh::Director::DesiredNetworkReservation.new_static(instance_plan.instance.model, job_network.deployment_network, static_ip)
25-
@logger.debug("Creating new static reservation #{reservation} for instance '#{instance_plan.instance}'")
26-
plans << Plan.new(reservation: reservation)
27-
job_network.deployment_network.subnets.each do |subnet|
28-
unless subnet.prefix.nil?
29-
prefix_reservation = Bosh::Director::DesiredNetworkReservation.new_dynamic(instance_plan.instance.model, job_network.deployment_network, true)
30-
plans << Plan.new(reservation: prefix_reservation)
31-
end
18+
prefix = job_network.deployment_network.subnets.each do |subnet|
19+
subnet.prefix
3220
end
33-
plans
21+
reservation = Bosh::Director::DesiredNetworkReservation.new_static(instance_plan.instance.model, job_network.deployment_network, static_ip, prefix)
22+
@logger.debug("Creating new static reservation #{reservation} for instance '#{instance_plan.instance}'")
23+
Plan.new(reservation: reservation)
3424
end
3525
end
3626
end

src/bosh-director/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def desired_new_instance_plans(new_desired_instances)
123123

124124
def populate_network_plans(instance_plan)
125125
@networks.each do |network|
126-
@network_planner.network_plan_with_dynamic_reservation(instance_plan, network).each {|plan| instance_plan.network_plans << plan }
126+
instance_plan.network_plans << @network_planner.network_plan_with_dynamic_reservation(instance_plan, network)
127127
end
128128
end
129129

src/bosh-director/lib/bosh/director/models/ip_address.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def validate
1111
validates_presence :orphaned_vm_id, allow_nil: true
1212
validates_presence :task_id
1313
validates_presence :address_str
14-
validates_unique :address_str
14+
validates_unique([:address_str, :prefix])
1515
raise 'Invalid type for address_str column' unless address_str.is_a?(String)
1616
end
1717

@@ -48,6 +48,18 @@ def address
4848
address_str.to_i
4949
end
5050

51+
def ip_prefix
52+
if prefix.nil?
53+
if Bosh::Director::IpAddrOrCidr.new(address).ipv6?
54+
128
55+
else
56+
32
57+
end
58+
else
59+
prefix
60+
end
61+
end
62+
5163
def to_s
5264
info
5365
end

src/bosh-director/lib/bosh/director/network_reservation.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Bosh::Director
22
class NetworkReservation
3-
attr_reader :ip, :instance_model, :network, :type, :is_prefix_reservation
3+
attr_reader :ip, :instance_model, :network, :type, :prefix
44

55
def initialize(instance_model, network)
66
@instance_model = instance_model
@@ -26,10 +26,10 @@ def formatted_ip
2626
class ExistingNetworkReservation < NetworkReservation
2727
attr_reader :network_type, :obsolete
2828

29-
def initialize(instance_model, network, ip, network_type)
29+
def initialize(instance_model, network, ip, network_type, prefix)
3030
super(instance_model, network)
3131
@ip = IpAddrOrCidr.new(ip).to_i if ip
32-
@is_prefix_reservation = IpAddrOrCidr.new(ip).prefix != 32
32+
@prefix = prefix
3333
@network_type = network_type
3434
@obsolete = network.instance_of? Bosh::Director::DeploymentPlan::Network
3535
end
@@ -48,19 +48,19 @@ def to_s
4848
end
4949

5050
class DesiredNetworkReservation < NetworkReservation
51-
def self.new_dynamic(instance_model, network, prefix_reservation = false)
52-
new(instance_model, network, nil, :dynamic, prefix_reservation)
51+
def self.new_dynamic(instance_model, network, prefix)
52+
new(instance_model, network, nil, :dynamic, prefix)
5353
end
5454

55-
def self.new_static(instance_model, network, ip)
56-
new(instance_model, network, ip, :static)
55+
def self.new_static(instance_model, network, ip, prefix)
56+
new(instance_model, network, ip, :static, prefix)
5757
end
5858

59-
def initialize(instance_model, network, ip, type, prefix_reservation)
59+
def initialize(instance_model, network, ip, type, prefix)
6060
super(instance_model, network)
6161
@ip = IpAddrOrCidr.new(ip).to_i if ip
6262
@type = type
63-
@is_prefix_reservation = prefix_reservation
63+
@prefix = prefix
6464
end
6565

6666
def resolve_ip(ip)

0 commit comments

Comments
 (0)