bosh-director 1.3160.0 → 1.3163.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bosh-director-worker +2 -14
  3. data/db/migrations/director/20150513225143_ip_addresses.rb +11 -0
  4. data/db/migrations/director/20150702004608_add_links.rb +8 -0
  5. data/db/migrations/director/20150708231924_add_link_spec.rb +7 -0
  6. data/db/migrations/director/20150724183256_add_debugging_to_ip_addresses.rb +8 -0
  7. data/db/migrations/director/20150730225029_add_uuid_to_instances.rb +16 -0
  8. data/db/migrations/director/20150803215805_add_availabililty_zone_and_cloud_properties_to_instances.rb +8 -0
  9. data/db/migrations/director/20150804211419_add_compilation_flag_to_instance.rb +7 -0
  10. data/db/migrations/director/20150918003455_add_bootstrap_node_to_instance.rb +7 -0
  11. data/db/migrations/director/20151008232214_add_dns_records.rb +7 -0
  12. data/db/migrations/director/20151015172551_add_orphan_disks_and_snapshots.rb +29 -0
  13. data/db/migrations/director/20151030222853_add_templates_to_instance.rb +10 -0
  14. data/db/migrations/director/20151031001039_add_spec_to_instance.rb +19 -0
  15. data/db/migrations/director/20151109190602_rename_orphan_columns.rb +13 -0
  16. data/lib/bosh/director.rb +19 -9
  17. data/lib/bosh/director/agent_client.rb +0 -17
  18. data/lib/bosh/director/api/cloud_config_manager.rb +7 -5
  19. data/lib/bosh/director/api/controllers/base_controller.rb +3 -2
  20. data/lib/bosh/director/api/controllers/cleanup_controller.rb +15 -0
  21. data/lib/bosh/director/api/controllers/deployments_controller.rb +38 -26
  22. data/lib/bosh/director/api/controllers/disks_controller.rb +20 -0
  23. data/lib/bosh/director/api/controllers/info_controller.rb +2 -2
  24. data/lib/bosh/director/api/controllers/releases_controller.rb +1 -16
  25. data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -9
  26. data/lib/bosh/director/api/deployment_manager.rb +2 -1
  27. data/lib/bosh/director/api/instance_lookup.rb +17 -0
  28. data/lib/bosh/director/api/instance_manager.rb +20 -10
  29. data/lib/bosh/director/api/release_manager.rb +28 -8
  30. data/lib/bosh/director/api/resurrector_manager.rb +9 -2
  31. data/lib/bosh/director/api/route_configuration.rb +2 -0
  32. data/lib/bosh/director/api/snapshot_manager.rb +9 -5
  33. data/lib/bosh/director/api/stemcell_manager.rb +50 -0
  34. data/lib/bosh/director/app.rb +1 -1
  35. data/lib/bosh/director/cloudcheck_helper.rb +119 -132
  36. data/lib/bosh/director/compile_task.rb +1 -1
  37. data/lib/bosh/director/compile_task_generator.rb +2 -2
  38. data/lib/bosh/director/config.rb +21 -12
  39. data/lib/bosh/director/deployment_deleter.rb +69 -0
  40. data/lib/bosh/director/deployment_plan.rb +35 -4
  41. data/lib/bosh/director/deployment_plan/agent_state_migrator.rb +47 -0
  42. data/lib/bosh/director/deployment_plan/assembler.rb +115 -241
  43. data/lib/bosh/director/deployment_plan/availability_zone.rb +27 -0
  44. data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +144 -35
  45. data/lib/bosh/director/deployment_plan/compilation_config.rb +21 -19
  46. data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +169 -0
  47. data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -8
  48. data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +13 -1
  49. data/lib/bosh/director/deployment_plan/deployment_validator.rb +17 -0
  50. data/lib/bosh/director/deployment_plan/desired_instance.rb +15 -0
  51. data/lib/bosh/director/deployment_plan/{disk_pool.rb → disk_type.rb} +14 -19
  52. data/lib/bosh/director/deployment_plan/dynamic_network.rb +105 -53
  53. data/lib/bosh/director/deployment_plan/dynamic_network_subnet.rb +13 -0
  54. data/lib/bosh/director/deployment_plan/env.rb +18 -0
  55. data/lib/bosh/director/deployment_plan/global_network_resolver.rb +77 -0
  56. data/lib/bosh/director/deployment_plan/instance.rb +222 -390
  57. data/lib/bosh/director/deployment_plan/instance_network_reservations.rb +71 -0
  58. data/lib/bosh/director/deployment_plan/instance_plan.rb +336 -0
  59. data/lib/bosh/director/deployment_plan/instance_plan_factory.rb +54 -0
  60. data/lib/bosh/director/deployment_plan/instance_plan_sorter.rb +61 -0
  61. data/lib/bosh/director/deployment_plan/instance_planner.rb +101 -0
  62. data/lib/bosh/director/deployment_plan/instance_repository.rb +36 -0
  63. data/lib/bosh/director/deployment_plan/instance_spec.rb +154 -0
  64. data/lib/bosh/director/deployment_plan/ip_provider/database_ip_repo.rb +136 -0
  65. data/lib/bosh/director/deployment_plan/ip_provider/in_memory_ip_repo.rb +81 -0
  66. data/lib/bosh/director/deployment_plan/ip_provider/ip_provider.rb +153 -0
  67. data/lib/bosh/director/deployment_plan/ip_provider/ip_provider_factory.rb +22 -0
  68. data/lib/bosh/director/deployment_plan/job.rb +116 -53
  69. data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +49 -0
  70. data/lib/bosh/director/deployment_plan/job_migrator.rb +90 -0
  71. data/lib/bosh/director/deployment_plan/job_network.rb +42 -0
  72. data/lib/bosh/director/deployment_plan/job_network_parser.rb +118 -0
  73. data/lib/bosh/director/deployment_plan/job_spec_parser.rb +123 -126
  74. data/lib/bosh/director/deployment_plan/links/link.rb +30 -0
  75. data/lib/bosh/director/deployment_plan/links/link_lookup.rb +66 -0
  76. data/lib/bosh/director/deployment_plan/links/link_path.rb +27 -0
  77. data/lib/bosh/director/deployment_plan/links/links_resolver.rb +70 -0
  78. data/lib/bosh/director/deployment_plan/links/template_link.rb +21 -0
  79. data/lib/bosh/director/deployment_plan/manifest_migrator.rb +3 -17
  80. data/lib/bosh/director/deployment_plan/manifest_validator.rb +46 -0
  81. data/lib/bosh/director/deployment_plan/manual_network.rb +70 -97
  82. data/lib/bosh/director/deployment_plan/manual_network_subnet.rb +148 -0
  83. data/lib/bosh/director/deployment_plan/network.rb +50 -39
  84. data/lib/bosh/director/deployment_plan/network_planner.rb +4 -0
  85. data/lib/bosh/director/deployment_plan/network_planner/plan.rb +26 -0
  86. data/lib/bosh/director/deployment_plan/network_planner/planner.rb +21 -0
  87. data/lib/bosh/director/deployment_plan/network_planner/reservation_reconciler.rb +81 -0
  88. data/lib/bosh/director/deployment_plan/network_planner/vip_static_ips_planner.rb +50 -0
  89. data/lib/bosh/director/deployment_plan/network_settings.rb +65 -0
  90. data/lib/bosh/director/deployment_plan/options/skip_drain.rb +7 -0
  91. data/lib/bosh/director/deployment_plan/package_validator.rb +79 -0
  92. data/lib/bosh/director/deployment_plan/placement_planner.rb +8 -0
  93. data/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb +90 -0
  94. data/lib/bosh/director/deployment_plan/placement_planner/bruteforce_ip_allocation.rb +124 -0
  95. data/lib/bosh/director/deployment_plan/placement_planner/index_assigner.rb +32 -0
  96. data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +125 -0
  97. data/lib/bosh/director/deployment_plan/placement_planner/placed_desired_instances.rb +40 -0
  98. data/lib/bosh/director/deployment_plan/placement_planner/plan.rb +42 -0
  99. data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb +237 -0
  100. data/lib/bosh/director/deployment_plan/placement_planner/unplaced_existing_instances.rb +53 -0
  101. data/lib/bosh/director/deployment_plan/planner.rb +186 -74
  102. data/lib/bosh/director/deployment_plan/planner_factory.rb +30 -147
  103. data/lib/bosh/director/deployment_plan/release_version.rb +3 -3
  104. data/lib/bosh/director/deployment_plan/resource_pool.rb +2 -174
  105. data/lib/bosh/director/deployment_plan/stemcell.rb +57 -14
  106. data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +28 -135
  107. data/lib/bosh/director/deployment_plan/steps/update_step.rb +23 -44
  108. data/lib/bosh/director/deployment_plan/template.rb +15 -4
  109. data/lib/bosh/director/deployment_plan/vip_network.rb +14 -42
  110. data/lib/bosh/director/deployment_plan/vm.rb +1 -99
  111. data/lib/bosh/director/deployment_plan/vm_type.rb +27 -0
  112. data/lib/bosh/director/disk_manager.rb +268 -0
  113. data/lib/bosh/director/dns/canonicalizer.rb +28 -0
  114. data/lib/bosh/director/dns/dns_manager.rb +163 -0
  115. data/lib/bosh/director/dns/local_dns_repo.rb +20 -0
  116. data/lib/bosh/director/dns/powerdns.rb +170 -0
  117. data/lib/bosh/director/errand/job_manager.rb +18 -29
  118. data/lib/bosh/director/error_ignorer.rb +16 -0
  119. data/lib/bosh/director/errors.rb +51 -20
  120. data/lib/bosh/director/event_log.rb +6 -0
  121. data/lib/bosh/director/instance_deleter.rb +53 -81
  122. data/lib/bosh/director/instance_reuser.rb +89 -0
  123. data/lib/bosh/director/instance_updater.rb +139 -281
  124. data/lib/bosh/director/instance_updater/preparer.rb +8 -5
  125. data/lib/bosh/director/instance_updater/state_applier.rb +21 -0
  126. data/lib/bosh/director/ip_util.rb +46 -26
  127. data/lib/bosh/director/job_renderer.rb +22 -10
  128. data/lib/bosh/director/job_runner.rb +1 -4
  129. data/lib/bosh/director/job_updater.rb +47 -35
  130. data/lib/bosh/director/job_updater_factory.rb +5 -4
  131. data/lib/bosh/director/jobs/base_job.rb +8 -0
  132. data/lib/bosh/director/jobs/cleanup_artifacts.rb +93 -0
  133. data/lib/bosh/director/jobs/delete_deployment.rb +10 -154
  134. data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +1 -1
  135. data/lib/bosh/director/jobs/delete_orphan_disks.rb +44 -0
  136. data/lib/bosh/director/jobs/delete_release.rb +19 -196
  137. data/lib/bosh/director/jobs/delete_stemcell.rb +10 -76
  138. data/lib/bosh/director/jobs/export_release.rb +41 -121
  139. data/lib/bosh/director/jobs/fetch_logs.rb +0 -6
  140. data/lib/bosh/director/jobs/helpers.rb +10 -0
  141. data/lib/bosh/director/jobs/helpers/blob_deleter.rb +24 -0
  142. data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +24 -0
  143. data/lib/bosh/director/jobs/helpers/name_version_release_deleter.rb +48 -0
  144. data/lib/bosh/director/jobs/helpers/package_deleter.rb +33 -0
  145. data/lib/bosh/director/jobs/helpers/release_deleter.rb +52 -0
  146. data/lib/bosh/director/jobs/helpers/release_version_deleter.rb +115 -0
  147. data/lib/bosh/director/jobs/helpers/releases_to_delete_picker.rb +31 -0
  148. data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +61 -0
  149. data/lib/bosh/director/jobs/helpers/stemcells_to_delete_picker.rb +30 -0
  150. data/lib/bosh/director/jobs/helpers/template_deleter.rb +20 -0
  151. data/lib/bosh/director/jobs/release/release_job.rb +18 -7
  152. data/lib/bosh/director/jobs/run_errand.rb +57 -36
  153. data/lib/bosh/director/jobs/scheduled_orphan_cleanup.rb +46 -0
  154. data/lib/bosh/director/jobs/ssh.rb +50 -17
  155. data/lib/bosh/director/jobs/update_deployment.rb +29 -11
  156. data/lib/bosh/director/jobs/update_release.rb +25 -4
  157. data/lib/bosh/director/jobs/vm_state.rb +23 -32
  158. data/lib/bosh/director/lock.rb +13 -8
  159. data/lib/bosh/director/logs_fetcher.rb +1 -1
  160. data/lib/bosh/director/models.rb +3 -0
  161. data/lib/bosh/director/models/compiled_package.rb +3 -3
  162. data/lib/bosh/director/models/deployment.rb +10 -0
  163. data/lib/bosh/director/models/instance.rb +77 -1
  164. data/lib/bosh/director/models/ip_address.rb +26 -0
  165. data/lib/bosh/director/models/orphan_disk.rb +23 -0
  166. data/lib/bosh/director/models/orphan_snapshot.rb +14 -0
  167. data/lib/bosh/director/models/template.rb +32 -9
  168. data/lib/bosh/director/models/vm.rb +5 -8
  169. data/lib/bosh/director/network_reservation.rb +69 -99
  170. data/lib/bosh/director/problem_handlers/inactive_disk.rb +5 -20
  171. data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -13
  172. data/lib/bosh/director/problem_resolver.rb +2 -2
  173. data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +2 -21
  174. data/lib/bosh/director/scheduler.rb +23 -6
  175. data/lib/bosh/director/{instance_updater/stopper.rb → stopper.rb} +24 -18
  176. data/lib/bosh/director/tagged_logger.rb +30 -0
  177. data/lib/bosh/director/transactor.rb +9 -0
  178. data/lib/bosh/director/version.rb +1 -1
  179. data/lib/bosh/director/vm_creator.rb +91 -19
  180. data/lib/bosh/director/vm_deleter.rb +25 -0
  181. data/lib/bosh/director/vm_recreator.rb +15 -0
  182. data/lib/cloud/dummy.rb +381 -94
  183. metadata +110 -30
  184. data/lib/bosh/director/deployment_plan/dns_binder.rb +0 -45
  185. data/lib/bosh/director/deployment_plan/instance_vm_binder.rb +0 -37
  186. data/lib/bosh/director/deployment_plan/network_subnet.rb +0 -166
  187. data/lib/bosh/director/deployment_plan/resource_pools.rb +0 -68
  188. data/lib/bosh/director/dns_helper.rb +0 -223
  189. data/lib/bosh/director/instance_updater/network_updater.rb +0 -110
  190. data/lib/bosh/director/instance_updater/vm_updater.rb +0 -189
  191. data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +0 -64
  192. data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +0 -85
  193. data/lib/bosh/director/resource_pool_updater.rb +0 -174
  194. data/lib/bosh/director/vm_data.rb +0 -63
  195. data/lib/bosh/director/vm_reuser.rb +0 -63
@@ -0,0 +1,148 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ class ManualNetworkSubnet
4
+ extend ValidationHelper
5
+ extend IpUtil
6
+
7
+ attr_reader :network_name, :range, :gateway, :dns, :cloud_properties,
8
+ :netmask, :availability_zone_names, :restricted_ips, :static_ips
9
+
10
+ def self.parse(network_name, subnet_spec, availability_zones, legacy_reserved_ranges)
11
+ @logger = Config.logger
12
+
13
+ @logger.debug("reserved ranges #{legacy_reserved_ranges.inspect}")
14
+ range_property = safe_property(subnet_spec, "range", :class => String)
15
+ range = NetAddr::CIDR.create(range_property)
16
+
17
+ if range.size <= 1
18
+ raise NetworkInvalidRange,
19
+ "Invalid network range `#{range_property}', " +
20
+ "should include at least 2 IPs"
21
+ end
22
+
23
+ netmask = range.wildcard_mask
24
+ network_id = range.network(:Objectify => true)
25
+ broadcast = range.broadcast(:Objectify => true)
26
+
27
+ ignore_missing_gateway = Bosh::Director::Config.ignore_missing_gateway
28
+ gateway_property = safe_property(subnet_spec, "gateway", class: String, optional: ignore_missing_gateway)
29
+ if gateway_property
30
+ gateway = NetAddr::CIDR.create(gateway_property)
31
+ unless gateway.size == 1
32
+ invalid_gateway(network_name, "must be a single IP")
33
+ end
34
+ unless range.contains?(gateway)
35
+ invalid_gateway(network_name, "must be inside the range")
36
+ end
37
+ if gateway == network_id
38
+ invalid_gateway(network_name, "can't be the network id")
39
+ end
40
+ if gateway == broadcast
41
+ invalid_gateway(network_name, "can't be the broadcast IP")
42
+ end
43
+ end
44
+
45
+ dns_manager = DnsManager.create
46
+ dns_spec = safe_property(subnet_spec, 'dns', :class => Array, :optional => true)
47
+ dns = dns_manager.dns_servers(network_name, dns_spec)
48
+
49
+ availability_zone_names = parse_availability_zones(subnet_spec, network_name, availability_zones)
50
+
51
+ cloud_properties = safe_property(subnet_spec, "cloud_properties", class: Hash, default: {})
52
+
53
+ reserved_property = safe_property(subnet_spec, "reserved", :optional => true)
54
+ static_property = safe_property(subnet_spec, "static", :optional => true)
55
+
56
+ restricted_ips = Set.new
57
+ restricted_ips.add(gateway.to_i) if gateway
58
+ restricted_ips.add(network_id.to_i)
59
+ restricted_ips.add(broadcast.to_i)
60
+
61
+ each_ip(reserved_property) do |ip|
62
+ unless range.contains?(ip)
63
+ raise NetworkReservedIpOutOfRange,
64
+ "Reserved IP `#{format_ip(ip)}' is out of " +
65
+ "network `#{network_name}' range"
66
+ end
67
+ restricted_ips.add(ip)
68
+ end
69
+
70
+ static_ips = Set.new
71
+ each_ip(static_property) do |ip|
72
+ unless range.contains?(ip) && !restricted_ips.include?(ip)
73
+ raise NetworkStaticIpOutOfRange,
74
+ "Static IP `#{format_ip(ip)}' is out of " +
75
+ "network `#{network_name}' range"
76
+ end
77
+ static_ips.add(ip)
78
+ end
79
+
80
+ legacy_reserved_ranges.each do |cidr_range|
81
+ cidr_range.range(0, nil, Objectify: true).each do |ip|
82
+ restricted_ips.add(ip.to_i) unless static_ips.include?(ip.to_i)
83
+ end
84
+ end
85
+
86
+ new(network_name, range, gateway, dns, cloud_properties, netmask, availability_zone_names, restricted_ips, static_ips)
87
+ end
88
+
89
+ def initialize(network_name, range, gateway, dns, cloud_properties, netmask, availability_zone_names, restricted_ips, static_ips)
90
+ @network_name = network_name
91
+ @range = range
92
+ @gateway = gateway
93
+ @dns = dns
94
+ @cloud_properties = cloud_properties
95
+ @netmask = netmask
96
+ @availability_zone_names = availability_zone_names
97
+ @restricted_ips = restricted_ips
98
+ @static_ips = static_ips
99
+ end
100
+
101
+ def overlaps?(subnet)
102
+ range == subnet.range ||
103
+ range.contains?(subnet.range) ||
104
+ subnet.range.contains?(range)
105
+ end
106
+
107
+ def is_reservable?(ip)
108
+ range.contains?(ip) && !restricted_ips.include?(ip.to_i)
109
+ end
110
+
111
+ private
112
+
113
+ def self.parse_availability_zones(subnet_spec, network_name, availability_zones)
114
+ has_availability_zones_key = subnet_spec.has_key?('azs')
115
+ has_availability_zone_key = subnet_spec.has_key?('az')
116
+ if has_availability_zones_key && has_availability_zone_key
117
+ raise Bosh::Director::NetworkInvalidProperty, "Network '#{network_name}' contains both 'az' and 'azs'. Choose one."
118
+ end
119
+
120
+ if has_availability_zones_key
121
+ zones = safe_property(subnet_spec, 'azs', class: Array, optional: true)
122
+ if zones.empty?
123
+ raise Bosh::Director::NetworkInvalidProperty, "Network '#{network_name}' refers to an empty 'azs' array"
124
+ end
125
+ zones.each do |zone|
126
+ check_validity_of_subnet_availability_zone(zone, availability_zones, network_name)
127
+ end
128
+ zones
129
+ else
130
+ availability_zone_name = safe_property(subnet_spec, 'az', class: String, optional: true)
131
+ check_validity_of_subnet_availability_zone(availability_zone_name, availability_zones, network_name)
132
+ availability_zone_name.nil? ? nil : [availability_zone_name]
133
+ end
134
+ end
135
+
136
+ def self.invalid_gateway(network_name, reason)
137
+ raise NetworkInvalidGateway,
138
+ "Invalid gateway for network `#{network_name}': #{reason}"
139
+ end
140
+
141
+ def self.check_validity_of_subnet_availability_zone(availability_zone_name, availability_zones, network_name)
142
+ unless availability_zone_name.nil? || availability_zones.any? { |az| az.name == availability_zone_name }
143
+ raise Bosh::Director::NetworkSubnetUnknownAvailabilityZone, "Network '#{network_name}' refers to an unknown availability zone '#{availability_zone_name}'"
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -5,14 +5,10 @@ module Bosh::Director
5
5
  ##
6
6
  # Represents a logical deployment network.
7
7
  class Network
8
- include DnsHelper
9
8
  include ValidationHelper
10
9
 
11
10
  VALID_DEFAULTS = %w(dns gateway).sort
12
11
 
13
- # @return [DeploymentPlan] associated deployment
14
- attr_accessor :deployment
15
-
16
12
  # @return [String] network name
17
13
  attr_accessor :name
18
14
 
@@ -24,39 +20,10 @@ module Bosh::Director
24
20
  #
25
21
  # @param [DeploymentPlan] deployment associated deployment plan
26
22
  # @param [Hash] network_spec parsed deployment manifest network section
27
- def initialize(deployment, network_spec)
28
- @deployment = deployment
29
- @name = safe_property(network_spec, "name", :class => String)
30
- @canonical_name = canonical(@name)
31
- end
32
-
33
- ##
34
- # Reserves a network resource, raises an error if reservation failed
35
- # @param [NetworkReservation] reservation Network reservation
36
- # @param [String] origin Whoever is reserving
37
- def reserve!(reservation, origin)
38
- reserve(reservation)
39
- unless reservation.reserved?
40
- reservation.handle_error(origin)
41
- end
42
- end
43
-
44
- ##
45
- # Reserves a network resource.
46
- #
47
- # Will update the passed in reservation if it can be fulfilled.
48
- # @param [NetworkReservation] reservation
49
- # @return [Boolean] true if the reservation was fulfilled
50
- def reserve(reservation)
51
- raise NotImplementedError, "#reserve not implemented for #{self.class}"
52
- end
53
-
54
- ##
55
- # Releases a previous reservation that had been fulfilled.
56
- # @param [NetworkReservation] reservation
57
- # @return [void]
58
- def release(reservation)
59
- raise NotImplementedError, "#release not implemented for #{self.class}"
23
+ def initialize(name, logger)
24
+ @name = name
25
+ @canonical_name = Canonicalizer.canonicalize(@name)
26
+ @logger = logger
60
27
  end
61
28
 
62
29
  ##
@@ -65,10 +32,54 @@ module Bosh::Director
65
32
  # @param [NetworkReservation] reservation
66
33
  # @param [Array<String>] default_properties
67
34
  # @return [Hash] network settings that will be passed to the BOSH Agent
68
- def network_settings(reservation, default_properties = VALID_DEFAULTS)
35
+ def network_settings(reservation, default_properties = VALID_DEFAULTS, availability_zone = nil)
69
36
  raise NotImplementedError,
70
37
  "#network_settings not implemented for #{self.class}"
71
38
  end
39
+
40
+ def has_azs?(az_names)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ def find_az_names_for_ip(ip)
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def validate_reference_from_job!(job_network_spec, job_name)
49
+ end
50
+
51
+ def supports_azs?
52
+ false
53
+ end
54
+
55
+ def manual?
56
+ false
57
+ end
58
+ end
59
+
60
+ class NetworkWithSubnets < Network
61
+ def has_azs?(az_names)
62
+ az_names = [az_names].flatten
63
+
64
+ if az_names.compact.empty? && availability_zones.empty?
65
+ return true
66
+ end
67
+
68
+ unreferenced_zones = az_names - availability_zones
69
+ if unreferenced_zones.empty?
70
+ return true
71
+ end
72
+
73
+ false
74
+ end
75
+
76
+ def supports_azs?
77
+ true
78
+ end
79
+
80
+ def availability_zones
81
+ @subnets.map(&:availability_zone_names).flatten.uniq
82
+ end
72
83
  end
73
84
  end
74
- end
85
+ end
@@ -0,0 +1,4 @@
1
+ require 'bosh/director/deployment_plan/network_planner/plan'
2
+ require 'bosh/director/deployment_plan/network_planner/planner'
3
+ require 'bosh/director/deployment_plan/network_planner/reservation_reconciler'
4
+ require 'bosh/director/deployment_plan/network_planner/vip_static_ips_planner'
@@ -0,0 +1,26 @@
1
+ module Bosh::Director::DeploymentPlan
2
+ module NetworkPlanner
3
+ class Plan
4
+ def initialize(attrs)
5
+ @reservation = attrs.fetch(:reservation)
6
+ @obsolete = attrs.fetch(:obsolete, false)
7
+ @existing = attrs.fetch(:existing, false)
8
+ end
9
+
10
+ attr_reader :reservation
11
+ attr_accessor :existing
12
+
13
+ def obsolete?
14
+ !!@obsolete
15
+ end
16
+
17
+ def desired?
18
+ !existing? && !obsolete?
19
+ end
20
+
21
+ def existing?
22
+ !!@existing
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ module Bosh::Director::DeploymentPlan
2
+ module NetworkPlanner
3
+ class Planner
4
+ def initialize(logger)
5
+ @logger = logger
6
+ end
7
+
8
+ def network_plan_with_dynamic_reservation(instance_plan, job_network)
9
+ reservation = Bosh::Director::DesiredNetworkReservation.new_dynamic(instance_plan.instance, job_network.deployment_network)
10
+ @logger.debug("Creating new dynamic reservation #{reservation} for instance '#{instance_plan.instance}'")
11
+ Plan.new(reservation: reservation)
12
+ end
13
+
14
+ def network_plan_with_static_reservation(instance_plan, job_network, static_ip)
15
+ reservation = Bosh::Director::DesiredNetworkReservation.new_static(instance_plan.instance, job_network.deployment_network, static_ip)
16
+ @logger.debug("Creating new static reservation #{reservation} for instance '#{instance_plan.instance}'")
17
+ Plan.new(reservation: reservation)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+ module Bosh::Director::DeploymentPlan
2
+ module NetworkPlanner
3
+ class ReservationReconciler
4
+ def initialize(instance_plan, logger)
5
+ @instance_plan = instance_plan
6
+ @logger = logger
7
+ end
8
+
9
+ def reconcile(existing_reservations)
10
+ unplaced_existing_reservations = Set.new(existing_reservations)
11
+ existing_network_plans = []
12
+ desired_reservations = @instance_plan.network_plans.map{ |np| np.reservation }
13
+
14
+ desired_network_plans = desired_reservations.map do |reservation|
15
+ Plan.new(reservation: reservation)
16
+ end
17
+
18
+ existing_reservations.each do |existing_reservation|
19
+ unless az_is_desired(existing_reservation)
20
+ @logger.debug("Can't reuse reservation #{existing_reservation}, existing reservation az does not match desired az '#{@instance_plan.desired_instance.availability_zone}'")
21
+ next
22
+ end
23
+
24
+ desired_reservation = desired_reservations.find do |reservation|
25
+ reservation.network == existing_reservation.network &&
26
+ (reservation.dynamic? || reservation.ip == existing_reservation.ip)
27
+ end
28
+
29
+ if desired_reservation && existing_reservation.reserved?
30
+ @logger.debug("For desired reservation #{desired_reservation} found existing reservation on the same network #{existing_reservation}")
31
+
32
+ if both_are_dynamic_reservations(existing_reservation, desired_reservation) ||
33
+ both_are_static_reservations_with_same_ip(existing_reservation, desired_reservation)
34
+
35
+ @logger.debug("Reusing existing reservation #{existing_reservation} for '#{desired_reservation}'")
36
+ existing_network_plans << Plan.new(reservation: existing_reservation, existing: true)
37
+ unplaced_existing_reservations.delete(existing_reservation)
38
+ desired_network_plans.delete_if { |plan| plan.reservation == desired_reservation }
39
+ else
40
+ @logger.debug("Can't reuse reservation #{existing_reservation} for #{desired_reservation}")
41
+ end
42
+ else
43
+ @logger.debug("Unneeded reservation #{existing_reservation}")
44
+ end
45
+ end
46
+
47
+ obsolete_network_plans = unplaced_existing_reservations.map do |reservation|
48
+ Plan.new(reservation: reservation, obsolete: true)
49
+ end
50
+
51
+ existing_network_plans + desired_network_plans + obsolete_network_plans
52
+ end
53
+
54
+ private
55
+
56
+ def both_are_dynamic_reservations(existing_reservation, reservation)
57
+ existing_reservation.type == reservation.type &&
58
+ reservation.dynamic?
59
+ end
60
+
61
+ def both_are_static_reservations_with_same_ip(existing_reservation, reservation)
62
+ existing_reservation.type == reservation.type &&
63
+ reservation.static? &&
64
+ reservation.ip == existing_reservation.ip
65
+ end
66
+
67
+ def az_is_desired(existing_reservation)
68
+ return true unless existing_reservation.network.supports_azs?
69
+
70
+ ip_az_names = existing_reservation.network.find_az_names_for_ip(existing_reservation.ip)
71
+ @logger.debug("Reservation #{existing_reservation} belongs to azs: #{ip_az_names}")
72
+
73
+ desired_az = @instance_plan.desired_instance.az
74
+ return true if ip_az_names.to_a.compact.empty? && desired_az.nil?
75
+ return false if desired_az.nil?
76
+
77
+ ip_az_names.to_a.include?(desired_az.name)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,50 @@
1
+ module Bosh::Director::DeploymentPlan
2
+ module NetworkPlanner
3
+ class VipStaticIpsPlanner
4
+ def initialize(network_planner, logger)
5
+ @network_planner = network_planner
6
+ @logger = logger
7
+ end
8
+
9
+ def add_vip_network_plans(instance_plans, vip_networks)
10
+ vip_networks.each do |vip_network|
11
+ static_ips = vip_network.static_ips.dup
12
+
13
+ unplaced_instance_plans = []
14
+ instance_plans.each do |instance_plan|
15
+ static_ip = get_instance_static_ip(instance_plan.existing_instance, vip_network.name, static_ips)
16
+ if static_ip
17
+ instance_plan.network_plans << @network_planner.network_plan_with_static_reservation(instance_plan, vip_network, static_ip)
18
+ else
19
+ unplaced_instance_plans << instance_plan
20
+ end
21
+ end
22
+
23
+ unplaced_instance_plans.each do |instance_plan|
24
+ static_ip = static_ips.shift
25
+ instance_plan.network_plans << @network_planner.network_plan_with_static_reservation(instance_plan, vip_network, static_ip)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def get_instance_static_ip(existing_instance, network_name, static_ips)
33
+ if existing_instance
34
+ existing_instance_ip = find_ip_for_network(existing_instance, network_name)
35
+ if existing_instance_ip && static_ips.include?(existing_instance_ip)
36
+ static_ips.delete(existing_instance_ip)
37
+ return existing_instance_ip
38
+ end
39
+ end
40
+ end
41
+
42
+ def find_ip_for_network(existing_instance, network_name)
43
+ ip_address = existing_instance.ip_addresses.find do |ip_address|
44
+ ip_address.network_name == network_name
45
+ end
46
+ ip_address.address if ip_address
47
+ end
48
+ end
49
+ end
50
+ end