Class: Bosh::Director::DeploymentPlan::PlacementPlanner::NetworksToStaticIps

Inherits:
Object
  • Object
show all
Extended by:
IpUtil
Includes:
IpUtil
Defined in:
lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb

Defined Under Namespace

Classes: StaticIpToAzs

Class Method Summary collapse

Instance Method Summary collapse

Methods included from IpUtil

each_ip, format_ip, ip_to_i, ip_to_netaddr

Constructor Details

#initialize(networks_to_static_ips, job_name) ⇒ NetworksToStaticIps

Returns a new instance of NetworksToStaticIps.



35
36
37
38
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 35

def initialize(networks_to_static_ips, job_name)
  @networks_to_static_ips = networks_to_static_ips
  @job_name = job_name
end

Class Method Details

.create(job_networks, desired_azs, job_name) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 9

def self.create(job_networks, desired_azs, job_name)
  networks_to_static_ips = {}

  desired_az_names = desired_azs.nil? ? [nil] : desired_azs.to_a.map(&:name)

  job_networks.each do |job_network|
    next unless job_network.static?
    subnets = job_network.deployment_network.subnets

    job_network.static_ips.each do |static_ip|
      subnet_for_ip = subnets.find { |subnet| subnet.static_ips.include?(static_ip) }
      if subnet_for_ip.nil?
        raise JobNetworkInstanceIpMismatch,
          "Instance group '#{job_name}' with network '#{job_network.name}' declares static ip '#{format_ip(static_ip)}', " +
            "which belongs to no subnet"
      end
      az_names = subnet_for_ip.availability_zone_names.nil? ? [nil] : subnet_for_ip.availability_zone_names
      filtered_az_names = az_names.select { |static_ip_az_name| desired_az_names.include?(static_ip_az_name) }.uniq
      networks_to_static_ips[job_network.name] ||= []
      networks_to_static_ips[job_network.name] << StaticIpToAzs.new(static_ip, filtered_az_names)
    end
  end

  new(networks_to_static_ips, job_name)
end

Instance Method Details

#azs_to_networksObject



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 67

def azs_to_networks
  result = {}
  @networks_to_static_ips.each do |network_name, static_ips_to_azs|
    static_ips_to_azs.each do |static_ip_to_azs|
      static_ip_to_azs.az_names.each do |az_name|
        result[az_name][network_name] ||= []
        result[az_name][network_name] << static_ip_to_azs.ip
      end
    end
  end
end

#claim_in_az(ip, az_name) ⇒ Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 91

def claim_in_az(ip, az_name)
  @networks_to_static_ips.each do |_, static_ips_to_azs|
    static_ips_to_azs.each do |static_ip_to_azs|
      if static_ip_to_azs.ip == ip
        static_ip_to_azs.claimed = true
        static_ip_to_azs.az_names = [az_name]
      end
    end
  end
end

#delete(ip) ⇒ Object



102
103
104
105
106
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 102

def delete(ip)
  @networks_to_static_ips.each do |_, static_ip_to_azs|
    static_ip_to_azs.delete_if { |static_ip_to_az| static_ip_to_az.ip == ip }
  end
end

#distribute_evenly_per_zoneObject



79
80
81
82
83
84
85
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 79

def distribute_evenly_per_zone
  best_combination = BruteForceIpAllocation.new(@networks_to_static_ips).find_best_combination
  if best_combination.nil?
    raise JobNetworkInstanceIpMismatch, "Failed to evenly distribute static IPs between zones for instance group '#{@job_name}'"
  end
  @networks_to_static_ips = best_combination
end

#find_by_network_and_az(network, az_name) ⇒ Object



112
113
114
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 112

def find_by_network_and_az(network, az_name)
  unclaimed_networks_to_static_ips[network.name].find { |static_ip_to_azs| static_ip_to_azs.az_names.include?(az_name) }
end

#find_by_network_and_ip(network, ip) ⇒ Object



108
109
110
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 108

def find_by_network_and_ip(network, ip)
  unclaimed_networks_to_static_ips[network.name].find { |static_ip_to_azs| static_ip_to_azs.ip == ip }
end

#next_ip_for_network(network) ⇒ Object



87
88
89
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 87

def next_ip_for_network(network)
  unclaimed_networks_to_static_ips[network.name].first
end

#unclaimed_networks_to_static_ipsObject



116
117
118
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 116

def unclaimed_networks_to_static_ips
  Hash[@networks_to_static_ips.map { |network_name, static_ips_to_azs| [network_name, static_ips_to_azs.reject(&:claimed)] }]
end

#validate_azs_are_declared_in_job_and_subnets(desired_azs) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 40

def validate_azs_are_declared_in_job_and_subnets(desired_azs)
  if desired_azs.nil? &&
    @networks_to_static_ips.any? do |_, static_ips_to_az|
      static_ips_to_az.any? { |static_ip_to_az| !static_ip_to_az.az_names.any?(&:nil?) }
    end

    raise JobInvalidAvailabilityZone,
      "Instance group '#{@job_name}' subnets declare availability zones and the instance group does not"
  end
end

#validate_ips_are_in_desired_azs(desired_azs) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb', line 51

def validate_ips_are_in_desired_azs(desired_azs)
  return if desired_azs.to_a.empty?

  desired_az_names = desired_azs.to_a.map(&:name)
  @networks_to_static_ips.each do |_, static_ips_to_az|
    non_desired_ip_to_az = static_ips_to_az.find do |static_ip_to_az|
      !(desired_az_names & static_ip_to_az.az_names).any?
    end

    if non_desired_ip_to_az
      raise JobStaticIpsFromInvalidAvailabilityZone,
        "Instance group '#{@job_name}' declares static ip '#{format_ip(non_desired_ip_to_az.ip)}' which does not belong to any of the instance group's availability zones."
    end
  end
end