Class: Bosh::Director::DeploymentPlan::NetworkSubnet

Inherits:
Object
  • Object
show all
Includes:
Bosh::Director::DnsHelper, IpUtil, ValidationHelper
Defined in:
lib/bosh/director/deployment_plan/network_subnet.rb

Constant Summary

Constants included from Bosh::Director::DnsHelper

Bosh::Director::DnsHelper::SOA, Bosh::Director::DnsHelper::TTL_4H, Bosh::Director::DnsHelper::TTL_5M

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValidationHelper

#invalid_type, #safe_property

Methods included from IpUtil

#each_ip, #format_ip, #ip_to_i, #ip_to_netaddr, #process_range

Methods included from Bosh::Director::DnsHelper

#add_default_dns_server, #canonical, #default_dns_server, #delete_dns_records, #delete_empty_domain, #dns_domain_name, #dns_ns_record, #dns_servers, #invalid_dns, #reverse_domain, #reverse_host, #update_dns_a_record, #update_dns_ptr_record

Constructor Details

#initialize(network, subnet_spec) ⇒ NetworkSubnet



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 30

def initialize(network, subnet_spec)
  @network = network

  range_property = safe_property(subnet_spec, "range", :class => String)
  @range = NetAddr::CIDR.create(range_property)

  if @range.size <= 1
    raise NetworkInvalidRange,
          "Invalid network range `#{range_property}', " +
          "should include at least 2 IPs"
  end

  @netmask = @range.wildcard_mask
  network_id = @range.network(:Objectify => true)
  broadcast = @range.broadcast(:Objectify => true)

  gateway_property = safe_property(subnet_spec, "gateway",
                                   :class => String, :optional => true)
  if gateway_property
    @gateway = NetAddr::CIDR.create(gateway_property)
    unless @gateway.size == 1
      invalid_gateway("must be a single IP")
    end
    unless @range.contains?(@gateway)
      invalid_gateway("must be inside the range")
    end
    if @gateway == network_id
      invalid_gateway("can't be the network id")
    end
    if @gateway == broadcast
      invalid_gateway("can't be the broadcast IP")
    end
  end

  @dns = dns_servers(@network.name, subnet_spec)

  @cloud_properties = safe_property(subnet_spec, "cloud_properties",
                                    :class => Hash)

  @available_dynamic_ips = Set.new
  @available_static_ips = Set.new

  first_ip = @range.first(:Objectify => true)
  last_ip = @range.last(:Objectify => true)

  (first_ip.to_i .. last_ip.to_i).each do |ip|
    @available_dynamic_ips << ip
  end

  @available_dynamic_ips.delete(@gateway.to_i) if @gateway
  @available_dynamic_ips.delete(network_id.to_i)
  @available_dynamic_ips.delete(broadcast.to_i)

  reserved_ips = safe_property(subnet_spec, "reserved", :optional => true)
  static_ips = safe_property(subnet_spec, "static", :optional => true)

  each_ip(reserved_ips) do |ip|
    unless @available_dynamic_ips.delete?(ip)
      raise NetworkReservedIpOutOfRange,
            "Reserved IP `#{format_ip(ip)}' is out of " +
            "network `#{@network.name}' range"
    end
  end

  each_ip(static_ips) do |ip|
    unless @available_dynamic_ips.delete?(ip)
      raise NetworkStaticIpOutOfRange,
            "Static IP `#{format_ip(ip)}' is out of " +
            "network `#{@network.name}' range"
    end
    @available_static_ips.add(ip)
  end

  # Keeping track of initial pools to understand
  # where to release no longer needed IPs
  @dynamic_ip_pool = @available_dynamic_ips.dup
  @static_ip_pool = @available_static_ips.dup
end

Instance Attribute Details

#cloud_propertiesHash (readonly)



23
24
25
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 23

def cloud_properties
  @cloud_properties
end

#dnsArray<String> (readonly)



20
21
22
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 20

def dns
  @dns
end

#gatewayNetAddr::CIDR (readonly)



17
18
19
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 17

def gateway
  @gateway
end

#netmaskString (readonly)



26
27
28
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 26

def netmask
  @netmask
end

#networkDeploymentPlan::Network (readonly)



11
12
13
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 11

def network
  @network
end

#rangeNetAddr::CIDR (readonly)



14
15
16
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 14

def range
  @range
end

Instance Method Details

#allocate_dynamic_ipObject



140
141
142
143
144
145
146
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 140

def allocate_dynamic_ip
  ip = @available_dynamic_ips.first
  if ip
    @available_dynamic_ips.delete(ip)
  end
  ip
end

#dynamic_ips_countObject



148
149
150
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 148

def dynamic_ips_count
  @available_dynamic_ips.size
end

#overlaps?(subnet) ⇒ Boolean



109
110
111
112
113
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 109

def overlaps?(subnet)
  @range == subnet.range ||
    @range.contains?(subnet.range) ||
    subnet.range.contains?(@range)
end

#release_ip(ip) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 126

def release_ip(ip)
  ip = ip.to_i
  if @dynamic_ip_pool.include?(ip)
    @available_dynamic_ips.add(ip)
  elsif @static_ip_pool.include?(ip)
    @available_static_ips.add(ip)
  else
    raise NetworkReservationIpNotOwned,
          "Can't release IP `#{format_ip(ip)}' " +
          "back to `#{@network.name}' network: " +
          "it's' neither in dynamic nor in static pool"
  end
end

#reserve_ip(ip) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 115

def reserve_ip(ip)
  ip = ip.to_i
  if @available_static_ips.delete?(ip)
    :static
  elsif @available_dynamic_ips.delete?(ip)
    :dynamic
  else
    nil
  end
end

#static_ips_countObject



152
153
154
# File 'lib/bosh/director/deployment_plan/network_subnet.rb', line 152

def static_ips_count
  @available_static_ips.size
end