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, #flush_dns_cache, #invalid_dns, #reverse_domain, #reverse_host, #update_dns_a_record, #update_dns_ptr_record

Constructor Details

#initialize(network, subnet_spec) ⇒ NetworkSubnet

Returns a new instance of NetworkSubnet.

Parameters:



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
# 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)

  ignore_missing_gateway = Bosh::Director::Config.ignore_missing_gateway
  gateway_property = safe_property(subnet_spec, "gateway", class: String, optional: ignore_missing_gateway)
  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, default: {})

  @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)

Returns Subnet cloud properties (VLAN etc.).

Returns:

  • (Hash)

    Subnet cloud properties (VLAN etc.)



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

def cloud_properties
  @cloud_properties
end

#dnsArray<String> (readonly)

Returns Subnet DNS IP addresses.

Returns:

  • (Array<String>)

    Subnet DNS IP addresses



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

def dns
  @dns
end

#gatewayNetAddr::CIDR (readonly)

Returns Subnet gateway IP address.

Returns:

  • (NetAddr::CIDR)

    Subnet gateway IP address



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

def gateway
  @gateway
end

#netmaskString (readonly)

Returns Subnet netmask.

Returns:

  • (String)

    Subnet netmask



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

def netmask
  @netmask
end

#networkDeploymentPlan::Network (readonly)

Returns Network this subnet belongs to.

Returns:



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

def network
  @network
end

#rangeNetAddr::CIDR (readonly)

Returns Subnet range.

Returns:

  • (NetAddr::CIDR)

    Subnet range



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

def range
  @range
end

Instance Method Details

#allocate_dynamic_ipObject



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

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

#dynamic_ips_countObject



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

def dynamic_ips_count
  @available_dynamic_ips.size
end

#overlaps?(subnet) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#release_ip(ip) ⇒ Object



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

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



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

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



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

def static_ips_count
  @available_static_ips.size
end