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.
- checksums.yaml +4 -4
- data/bin/bosh-director-worker +2 -14
- data/db/migrations/director/20150513225143_ip_addresses.rb +11 -0
- data/db/migrations/director/20150702004608_add_links.rb +8 -0
- data/db/migrations/director/20150708231924_add_link_spec.rb +7 -0
- data/db/migrations/director/20150724183256_add_debugging_to_ip_addresses.rb +8 -0
- data/db/migrations/director/20150730225029_add_uuid_to_instances.rb +16 -0
- data/db/migrations/director/20150803215805_add_availabililty_zone_and_cloud_properties_to_instances.rb +8 -0
- data/db/migrations/director/20150804211419_add_compilation_flag_to_instance.rb +7 -0
- data/db/migrations/director/20150918003455_add_bootstrap_node_to_instance.rb +7 -0
- data/db/migrations/director/20151008232214_add_dns_records.rb +7 -0
- data/db/migrations/director/20151015172551_add_orphan_disks_and_snapshots.rb +29 -0
- data/db/migrations/director/20151030222853_add_templates_to_instance.rb +10 -0
- data/db/migrations/director/20151031001039_add_spec_to_instance.rb +19 -0
- data/db/migrations/director/20151109190602_rename_orphan_columns.rb +13 -0
- data/lib/bosh/director.rb +19 -9
- data/lib/bosh/director/agent_client.rb +0 -17
- data/lib/bosh/director/api/cloud_config_manager.rb +7 -5
- data/lib/bosh/director/api/controllers/base_controller.rb +3 -2
- data/lib/bosh/director/api/controllers/cleanup_controller.rb +15 -0
- data/lib/bosh/director/api/controllers/deployments_controller.rb +38 -26
- data/lib/bosh/director/api/controllers/disks_controller.rb +20 -0
- data/lib/bosh/director/api/controllers/info_controller.rb +2 -2
- data/lib/bosh/director/api/controllers/releases_controller.rb +1 -16
- data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -9
- data/lib/bosh/director/api/deployment_manager.rb +2 -1
- data/lib/bosh/director/api/instance_lookup.rb +17 -0
- data/lib/bosh/director/api/instance_manager.rb +20 -10
- data/lib/bosh/director/api/release_manager.rb +28 -8
- data/lib/bosh/director/api/resurrector_manager.rb +9 -2
- data/lib/bosh/director/api/route_configuration.rb +2 -0
- data/lib/bosh/director/api/snapshot_manager.rb +9 -5
- data/lib/bosh/director/api/stemcell_manager.rb +50 -0
- data/lib/bosh/director/app.rb +1 -1
- data/lib/bosh/director/cloudcheck_helper.rb +119 -132
- data/lib/bosh/director/compile_task.rb +1 -1
- data/lib/bosh/director/compile_task_generator.rb +2 -2
- data/lib/bosh/director/config.rb +21 -12
- data/lib/bosh/director/deployment_deleter.rb +69 -0
- data/lib/bosh/director/deployment_plan.rb +35 -4
- data/lib/bosh/director/deployment_plan/agent_state_migrator.rb +47 -0
- data/lib/bosh/director/deployment_plan/assembler.rb +115 -241
- data/lib/bosh/director/deployment_plan/availability_zone.rb +27 -0
- data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +144 -35
- data/lib/bosh/director/deployment_plan/compilation_config.rb +21 -19
- data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +169 -0
- data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -8
- data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +13 -1
- data/lib/bosh/director/deployment_plan/deployment_validator.rb +17 -0
- data/lib/bosh/director/deployment_plan/desired_instance.rb +15 -0
- data/lib/bosh/director/deployment_plan/{disk_pool.rb → disk_type.rb} +14 -19
- data/lib/bosh/director/deployment_plan/dynamic_network.rb +105 -53
- data/lib/bosh/director/deployment_plan/dynamic_network_subnet.rb +13 -0
- data/lib/bosh/director/deployment_plan/env.rb +18 -0
- data/lib/bosh/director/deployment_plan/global_network_resolver.rb +77 -0
- data/lib/bosh/director/deployment_plan/instance.rb +222 -390
- data/lib/bosh/director/deployment_plan/instance_network_reservations.rb +71 -0
- data/lib/bosh/director/deployment_plan/instance_plan.rb +336 -0
- data/lib/bosh/director/deployment_plan/instance_plan_factory.rb +54 -0
- data/lib/bosh/director/deployment_plan/instance_plan_sorter.rb +61 -0
- data/lib/bosh/director/deployment_plan/instance_planner.rb +101 -0
- data/lib/bosh/director/deployment_plan/instance_repository.rb +36 -0
- data/lib/bosh/director/deployment_plan/instance_spec.rb +154 -0
- data/lib/bosh/director/deployment_plan/ip_provider/database_ip_repo.rb +136 -0
- data/lib/bosh/director/deployment_plan/ip_provider/in_memory_ip_repo.rb +81 -0
- data/lib/bosh/director/deployment_plan/ip_provider/ip_provider.rb +153 -0
- data/lib/bosh/director/deployment_plan/ip_provider/ip_provider_factory.rb +22 -0
- data/lib/bosh/director/deployment_plan/job.rb +116 -53
- data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +49 -0
- data/lib/bosh/director/deployment_plan/job_migrator.rb +90 -0
- data/lib/bosh/director/deployment_plan/job_network.rb +42 -0
- data/lib/bosh/director/deployment_plan/job_network_parser.rb +118 -0
- data/lib/bosh/director/deployment_plan/job_spec_parser.rb +123 -126
- data/lib/bosh/director/deployment_plan/links/link.rb +30 -0
- data/lib/bosh/director/deployment_plan/links/link_lookup.rb +66 -0
- data/lib/bosh/director/deployment_plan/links/link_path.rb +27 -0
- data/lib/bosh/director/deployment_plan/links/links_resolver.rb +70 -0
- data/lib/bosh/director/deployment_plan/links/template_link.rb +21 -0
- data/lib/bosh/director/deployment_plan/manifest_migrator.rb +3 -17
- data/lib/bosh/director/deployment_plan/manifest_validator.rb +46 -0
- data/lib/bosh/director/deployment_plan/manual_network.rb +70 -97
- data/lib/bosh/director/deployment_plan/manual_network_subnet.rb +148 -0
- data/lib/bosh/director/deployment_plan/network.rb +50 -39
- data/lib/bosh/director/deployment_plan/network_planner.rb +4 -0
- data/lib/bosh/director/deployment_plan/network_planner/plan.rb +26 -0
- data/lib/bosh/director/deployment_plan/network_planner/planner.rb +21 -0
- data/lib/bosh/director/deployment_plan/network_planner/reservation_reconciler.rb +81 -0
- data/lib/bosh/director/deployment_plan/network_planner/vip_static_ips_planner.rb +50 -0
- data/lib/bosh/director/deployment_plan/network_settings.rb +65 -0
- data/lib/bosh/director/deployment_plan/options/skip_drain.rb +7 -0
- data/lib/bosh/director/deployment_plan/package_validator.rb +79 -0
- data/lib/bosh/director/deployment_plan/placement_planner.rb +8 -0
- data/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb +90 -0
- data/lib/bosh/director/deployment_plan/placement_planner/bruteforce_ip_allocation.rb +124 -0
- data/lib/bosh/director/deployment_plan/placement_planner/index_assigner.rb +32 -0
- data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +125 -0
- data/lib/bosh/director/deployment_plan/placement_planner/placed_desired_instances.rb +40 -0
- data/lib/bosh/director/deployment_plan/placement_planner/plan.rb +42 -0
- data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb +237 -0
- data/lib/bosh/director/deployment_plan/placement_planner/unplaced_existing_instances.rb +53 -0
- data/lib/bosh/director/deployment_plan/planner.rb +186 -74
- data/lib/bosh/director/deployment_plan/planner_factory.rb +30 -147
- data/lib/bosh/director/deployment_plan/release_version.rb +3 -3
- data/lib/bosh/director/deployment_plan/resource_pool.rb +2 -174
- data/lib/bosh/director/deployment_plan/stemcell.rb +57 -14
- data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +28 -135
- data/lib/bosh/director/deployment_plan/steps/update_step.rb +23 -44
- data/lib/bosh/director/deployment_plan/template.rb +15 -4
- data/lib/bosh/director/deployment_plan/vip_network.rb +14 -42
- data/lib/bosh/director/deployment_plan/vm.rb +1 -99
- data/lib/bosh/director/deployment_plan/vm_type.rb +27 -0
- data/lib/bosh/director/disk_manager.rb +268 -0
- data/lib/bosh/director/dns/canonicalizer.rb +28 -0
- data/lib/bosh/director/dns/dns_manager.rb +163 -0
- data/lib/bosh/director/dns/local_dns_repo.rb +20 -0
- data/lib/bosh/director/dns/powerdns.rb +170 -0
- data/lib/bosh/director/errand/job_manager.rb +18 -29
- data/lib/bosh/director/error_ignorer.rb +16 -0
- data/lib/bosh/director/errors.rb +51 -20
- data/lib/bosh/director/event_log.rb +6 -0
- data/lib/bosh/director/instance_deleter.rb +53 -81
- data/lib/bosh/director/instance_reuser.rb +89 -0
- data/lib/bosh/director/instance_updater.rb +139 -281
- data/lib/bosh/director/instance_updater/preparer.rb +8 -5
- data/lib/bosh/director/instance_updater/state_applier.rb +21 -0
- data/lib/bosh/director/ip_util.rb +46 -26
- data/lib/bosh/director/job_renderer.rb +22 -10
- data/lib/bosh/director/job_runner.rb +1 -4
- data/lib/bosh/director/job_updater.rb +47 -35
- data/lib/bosh/director/job_updater_factory.rb +5 -4
- data/lib/bosh/director/jobs/base_job.rb +8 -0
- data/lib/bosh/director/jobs/cleanup_artifacts.rb +93 -0
- data/lib/bosh/director/jobs/delete_deployment.rb +10 -154
- data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +1 -1
- data/lib/bosh/director/jobs/delete_orphan_disks.rb +44 -0
- data/lib/bosh/director/jobs/delete_release.rb +19 -196
- data/lib/bosh/director/jobs/delete_stemcell.rb +10 -76
- data/lib/bosh/director/jobs/export_release.rb +41 -121
- data/lib/bosh/director/jobs/fetch_logs.rb +0 -6
- data/lib/bosh/director/jobs/helpers.rb +10 -0
- data/lib/bosh/director/jobs/helpers/blob_deleter.rb +24 -0
- data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +24 -0
- data/lib/bosh/director/jobs/helpers/name_version_release_deleter.rb +48 -0
- data/lib/bosh/director/jobs/helpers/package_deleter.rb +33 -0
- data/lib/bosh/director/jobs/helpers/release_deleter.rb +52 -0
- data/lib/bosh/director/jobs/helpers/release_version_deleter.rb +115 -0
- data/lib/bosh/director/jobs/helpers/releases_to_delete_picker.rb +31 -0
- data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +61 -0
- data/lib/bosh/director/jobs/helpers/stemcells_to_delete_picker.rb +30 -0
- data/lib/bosh/director/jobs/helpers/template_deleter.rb +20 -0
- data/lib/bosh/director/jobs/release/release_job.rb +18 -7
- data/lib/bosh/director/jobs/run_errand.rb +57 -36
- data/lib/bosh/director/jobs/scheduled_orphan_cleanup.rb +46 -0
- data/lib/bosh/director/jobs/ssh.rb +50 -17
- data/lib/bosh/director/jobs/update_deployment.rb +29 -11
- data/lib/bosh/director/jobs/update_release.rb +25 -4
- data/lib/bosh/director/jobs/vm_state.rb +23 -32
- data/lib/bosh/director/lock.rb +13 -8
- data/lib/bosh/director/logs_fetcher.rb +1 -1
- data/lib/bosh/director/models.rb +3 -0
- data/lib/bosh/director/models/compiled_package.rb +3 -3
- data/lib/bosh/director/models/deployment.rb +10 -0
- data/lib/bosh/director/models/instance.rb +77 -1
- data/lib/bosh/director/models/ip_address.rb +26 -0
- data/lib/bosh/director/models/orphan_disk.rb +23 -0
- data/lib/bosh/director/models/orphan_snapshot.rb +14 -0
- data/lib/bosh/director/models/template.rb +32 -9
- data/lib/bosh/director/models/vm.rb +5 -8
- data/lib/bosh/director/network_reservation.rb +69 -99
- data/lib/bosh/director/problem_handlers/inactive_disk.rb +5 -20
- data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -13
- data/lib/bosh/director/problem_resolver.rb +2 -2
- data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +2 -21
- data/lib/bosh/director/scheduler.rb +23 -6
- data/lib/bosh/director/{instance_updater/stopper.rb → stopper.rb} +24 -18
- data/lib/bosh/director/tagged_logger.rb +30 -0
- data/lib/bosh/director/transactor.rb +9 -0
- data/lib/bosh/director/version.rb +1 -1
- data/lib/bosh/director/vm_creator.rb +91 -19
- data/lib/bosh/director/vm_deleter.rb +25 -0
- data/lib/bosh/director/vm_recreator.rb +15 -0
- data/lib/cloud/dummy.rb +381 -94
- metadata +110 -30
- data/lib/bosh/director/deployment_plan/dns_binder.rb +0 -45
- data/lib/bosh/director/deployment_plan/instance_vm_binder.rb +0 -37
- data/lib/bosh/director/deployment_plan/network_subnet.rb +0 -166
- data/lib/bosh/director/deployment_plan/resource_pools.rb +0 -68
- data/lib/bosh/director/dns_helper.rb +0 -223
- data/lib/bosh/director/instance_updater/network_updater.rb +0 -110
- data/lib/bosh/director/instance_updater/vm_updater.rb +0 -189
- data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +0 -64
- data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +0 -85
- data/lib/bosh/director/resource_pool_updater.rb +0 -174
- data/lib/bosh/director/vm_data.rb +0 -63
- data/lib/bosh/director/vm_reuser.rb +0 -63
@@ -0,0 +1,49 @@
|
|
1
|
+
module Bosh::Director
|
2
|
+
module DeploymentPlan
|
3
|
+
class JobAvailabilityZoneParser
|
4
|
+
include ValidationHelper
|
5
|
+
|
6
|
+
def parse(job_spec, job, deployment, networks)
|
7
|
+
az_names = safe_property(job_spec, 'azs', class: Array, optional: true)
|
8
|
+
check_contains(az_names, networks, job)
|
9
|
+
|
10
|
+
return nil if az_names.nil?
|
11
|
+
check_validity_of(az_names, job.name)
|
12
|
+
look_up_from_deployment(az_names, deployment, job.name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_contains(az_names, networks, job)
|
16
|
+
networks.each do |network|
|
17
|
+
unless network.has_azs?(az_names)
|
18
|
+
raise JobNetworkMissingRequiredAvailabilityZone,
|
19
|
+
"Job '#{job.name}' must specify availability zone that matches availability zones of network '#{network.name}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_validity_of(az_names, job_name)
|
25
|
+
if az_names.empty?
|
26
|
+
raise JobMissingAvailabilityZones, "Job '#{job_name}' has empty availability zones"
|
27
|
+
end
|
28
|
+
|
29
|
+
az_names.each do |name|
|
30
|
+
unless name.is_a?(String)
|
31
|
+
raise JobInvalidAvailabilityZone, "Job '#{job_name}' has invalid availability zone '#{name}', string expected"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def look_up_from_deployment(az_names, deployment, job_name)
|
37
|
+
az_names.map do |name|
|
38
|
+
az = deployment.availability_zone(name)
|
39
|
+
if az.nil?
|
40
|
+
raise JobUnknownAvailabilityZone, "Job '#{job_name}' references unknown availability zone '#{name}'"
|
41
|
+
end
|
42
|
+
az
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Bosh::Director
|
2
|
+
class DeploymentPlan::MigratedFromJob < Struct.new(:name, :availability_zone); end
|
3
|
+
|
4
|
+
class DeploymentPlan::JobMigrator
|
5
|
+
def initialize(deployment_plan, logger)
|
6
|
+
@deployment_plan = deployment_plan
|
7
|
+
@logger = logger
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_existing_instances(desired_job)
|
11
|
+
instances = []
|
12
|
+
existing_instances = @deployment_plan.instance_models.select { |model| model.job == desired_job.name }
|
13
|
+
existing_instances.each do |existing_instance|
|
14
|
+
instances << existing_instance
|
15
|
+
end
|
16
|
+
|
17
|
+
unless desired_job.migrated_from.to_a.empty?
|
18
|
+
migrated_from_instances = all_migrated_from_instances(
|
19
|
+
desired_job.migrated_from,
|
20
|
+
desired_job
|
21
|
+
)
|
22
|
+
|
23
|
+
instances += migrated_from_instances
|
24
|
+
end
|
25
|
+
|
26
|
+
instances
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def all_migrated_from_instances(migrated_from_jobs, desired_job)
|
32
|
+
desired_job_name = desired_job.name
|
33
|
+
migrated_from_instances = []
|
34
|
+
|
35
|
+
migrated_from_jobs.each do |migrated_from_job|
|
36
|
+
if @deployment_plan.job(migrated_from_job.name)
|
37
|
+
raise DeploymentInvalidMigratedFromJob,
|
38
|
+
"Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}'. " +
|
39
|
+
'A deployment can not migrate a job and also specify it. ' +
|
40
|
+
"Please remove job '#{migrated_from_job.name}'."
|
41
|
+
end
|
42
|
+
|
43
|
+
other_jobs = @deployment_plan.jobs.reject { |job| job.name == desired_job_name }
|
44
|
+
|
45
|
+
migrate_to_multiple_jobs = other_jobs.any? do |job|
|
46
|
+
job.migrated_from.any? do |other_migrated_from_job|
|
47
|
+
other_migrated_from_job.name == migrated_from_job.name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if migrate_to_multiple_jobs
|
52
|
+
raise DeploymentInvalidMigratedFromJob,
|
53
|
+
"Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}'. A job may be migrated to only one job."
|
54
|
+
end
|
55
|
+
|
56
|
+
migrated_from_job_instances = []
|
57
|
+
|
58
|
+
@deployment_plan.existing_instances.each do |instance|
|
59
|
+
if instance.job == migrated_from_job.name
|
60
|
+
if instance.availability_zone.nil? &&
|
61
|
+
migrated_from_job.availability_zone.nil? &&
|
62
|
+
desired_job.availability_zones.to_a.compact.any?
|
63
|
+
raise DeploymentInvalidMigratedFromJob,
|
64
|
+
"Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}', availability zone of '#{migrated_from_job.name}' is not specified"
|
65
|
+
end
|
66
|
+
|
67
|
+
if !migrated_from_job.availability_zone.nil? && !instance.availability_zone.nil?
|
68
|
+
if migrated_from_job.availability_zone != instance.availability_zone
|
69
|
+
raise DeploymentInvalidMigratedFromJob,
|
70
|
+
"Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}', '#{migrated_from_job.name}' belongs to availability zone '#{instance.availability_zone}' and manifest specifies '#{migrated_from_job.availability_zone}'"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
if instance.availability_zone.nil?
|
75
|
+
instance.update(availability_zone: migrated_from_job.availability_zone)
|
76
|
+
end
|
77
|
+
|
78
|
+
migrated_from_job_instances << instance
|
79
|
+
|
80
|
+
@logger.debug("Migrating job '#{migrated_from_job.name}/#{instance.uuid} (#{instance.index})' to '#{desired_job.name}/#{instance.uuid} (#{instance.index})'")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
migrated_from_instances += migrated_from_job_instances
|
85
|
+
end
|
86
|
+
|
87
|
+
migrated_from_instances
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Bosh::Director
|
2
|
+
module DeploymentPlan
|
3
|
+
class JobNetwork
|
4
|
+
attr_reader :name, :static_ips, :deployment_network
|
5
|
+
|
6
|
+
def initialize(name, static_ips, default_for, deployment_network)
|
7
|
+
@name = name
|
8
|
+
@static_ips = static_ips
|
9
|
+
@default_for = default_for
|
10
|
+
@deployment_network = deployment_network
|
11
|
+
end
|
12
|
+
|
13
|
+
def availability_zones
|
14
|
+
@deployment_network.availability_zones
|
15
|
+
end
|
16
|
+
|
17
|
+
def properties_for_which_the_network_is_the_default
|
18
|
+
@default_for
|
19
|
+
end
|
20
|
+
|
21
|
+
def static?
|
22
|
+
!!@static_ips
|
23
|
+
end
|
24
|
+
|
25
|
+
def vip?
|
26
|
+
deployment_network.kind_of?(VipNetwork)
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_for?(property)
|
30
|
+
properties_for_which_the_network_is_the_default.include?(property)
|
31
|
+
end
|
32
|
+
|
33
|
+
def make_default_for(defaults)
|
34
|
+
@default_for = defaults
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_azs?(az_names)
|
38
|
+
@deployment_network.has_azs?(az_names)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'bosh/director/deployment_plan/job_network'
|
2
|
+
|
3
|
+
module Bosh::Director
|
4
|
+
module DeploymentPlan
|
5
|
+
class JobNetworksParser
|
6
|
+
include ValidationHelper
|
7
|
+
include IpUtil
|
8
|
+
|
9
|
+
def initialize(properties_that_require_defaults)
|
10
|
+
@properties_that_require_defaults = properties_that_require_defaults
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse(job_spec, job_name, manifest_networks)
|
14
|
+
networks = parse_networks(job_spec, job_name, manifest_networks)
|
15
|
+
networks.each do |network|
|
16
|
+
validate_default_properties(network, job_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
validate_default_networks(networks, job_name)
|
20
|
+
|
21
|
+
networks
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_networks(job_spec, job_name, manifest_networks)
|
27
|
+
network_specs = safe_property(job_spec, "networks", :class => Array)
|
28
|
+
if network_specs.empty?
|
29
|
+
raise JobMissingNetwork, "Job `#{job_name}' must specify at least one network"
|
30
|
+
end
|
31
|
+
network_specs.map do |network_spec|
|
32
|
+
network_name = safe_property(network_spec, "name", :class => String)
|
33
|
+
default_for = safe_property(network_spec, "default", :class => Array, :default => [])
|
34
|
+
static_ips = parse_static_ips(network_spec['static_ips'], job_name)
|
35
|
+
|
36
|
+
deployment_network = look_up_deployment_network(manifest_networks, job_name, network_name)
|
37
|
+
deployment_network.validate_reference_from_job!(network_spec, job_name)
|
38
|
+
|
39
|
+
JobNetwork.new(network_name, static_ips, default_for, deployment_network)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def look_up_deployment_network(manifest_networks, job_name, network_name)
|
44
|
+
deployment_network = manifest_networks.find{ |network| network.name == network_name }
|
45
|
+
if deployment_network.nil?
|
46
|
+
raise JobUnknownNetwork, "Job '#{job_name}' references an unknown network '#{network_name}'"
|
47
|
+
end
|
48
|
+
deployment_network
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_static_ips(static_ips_raw, job_name)
|
52
|
+
static_ips = nil
|
53
|
+
if static_ips_raw
|
54
|
+
static_ips = []
|
55
|
+
each_ip(static_ips_raw) do |ip|
|
56
|
+
if static_ips.include?(ip)
|
57
|
+
raise JobInvalidStaticIPs, "Job '#{job_name}' specifies static IP '#{format_ip(ip)}' more than once"
|
58
|
+
end
|
59
|
+
|
60
|
+
static_ips.push(ip)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
static_ips
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate_default_properties(network, job_name)
|
67
|
+
network.properties_for_which_the_network_is_the_default.each do |property|
|
68
|
+
unless @properties_that_require_defaults.include?(property)
|
69
|
+
raise JobNetworkInvalidDefault,
|
70
|
+
"Job `#{job_name}' specified an invalid default network property `#{property}', " +
|
71
|
+
"valid properties are: " + @properties_that_require_defaults.join(", ")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def validate_default_networks(networks, job_name)
|
77
|
+
networks.first.make_default_for(@properties_that_require_defaults) if networks.count == 1
|
78
|
+
|
79
|
+
default_networks_for_properties = default_networks_for_properties(networks)
|
80
|
+
validate_only_one_default_network(default_networks_for_properties, job_name)
|
81
|
+
validate_default_network_for_each_property(default_networks_for_properties, job_name)
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_default_network_for_each_property(default_networks_for_properties, job_name)
|
85
|
+
missing_default_properties = default_networks_for_properties.select { |_, networks|
|
86
|
+
networks.empty?
|
87
|
+
}.map { |property, _|
|
88
|
+
property
|
89
|
+
}
|
90
|
+
unless missing_default_properties.empty?
|
91
|
+
raise JobNetworkMissingDefault,
|
92
|
+
"Job `#{job_name}' must specify which network is default for " +
|
93
|
+
missing_default_properties.sort.join(", ") + ", since it has more than one network configured"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def validate_only_one_default_network(default_networks_for_properties, job_name)
|
98
|
+
multiple_defaults = default_networks_for_properties.select { |_, networks|
|
99
|
+
networks.count > 1
|
100
|
+
}
|
101
|
+
unless multiple_defaults.empty?
|
102
|
+
message_for_each_property = multiple_defaults.map do |property, networks|
|
103
|
+
quoted_network_names = networks.map { |network| "'#{network.name}'" }.join(', ')
|
104
|
+
"'#{property}' has default networks: #{quoted_network_names}."
|
105
|
+
end
|
106
|
+
raise JobNetworkMultipleDefaults,
|
107
|
+
"Job `#{job_name}' specified more than one network to contain default. #{message_for_each_property.join(' ')}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def default_networks_for_properties(networks)
|
112
|
+
@properties_that_require_defaults.inject({}) do |defaults, property|
|
113
|
+
defaults.merge(property => networks.select { |network| network.default_for?(property) })
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -3,7 +3,6 @@ require 'bosh/template/property_helper'
|
|
3
3
|
module Bosh::Director
|
4
4
|
module DeploymentPlan
|
5
5
|
class JobSpecParser
|
6
|
-
include DnsHelper
|
7
6
|
include ValidationHelper
|
8
7
|
include Bosh::Template::PropertyHelper
|
9
8
|
include IpUtil
|
@@ -19,24 +18,34 @@ module Bosh::Director
|
|
19
18
|
# @return [DeploymentPlan::Job] Job as build from job_spec
|
20
19
|
def parse(job_spec)
|
21
20
|
@job_spec = job_spec
|
22
|
-
@job = Job.new(@
|
21
|
+
@job = Job.new(@logger)
|
23
22
|
|
24
23
|
parse_name
|
25
24
|
parse_lifecycle
|
26
25
|
|
27
26
|
parse_release
|
27
|
+
validate_templates
|
28
|
+
|
28
29
|
parse_template
|
29
30
|
parse_templates
|
30
31
|
|
31
|
-
validate_templates
|
32
|
-
|
33
32
|
check_template_uniqueness
|
34
33
|
parse_disk
|
35
34
|
parse_properties
|
36
35
|
parse_resource_pool
|
37
36
|
parse_update_config
|
38
|
-
|
39
|
-
|
37
|
+
|
38
|
+
networks = JobNetworksParser.new(Network::VALID_DEFAULTS).parse(@job_spec, @job.name, @deployment.networks)
|
39
|
+
@job.networks = networks
|
40
|
+
assign_default_networks(networks)
|
41
|
+
|
42
|
+
availability_zones = JobAvailabilityZoneParser.new.parse(@job_spec, @job, @deployment, networks)
|
43
|
+
@job.availability_zones = availability_zones
|
44
|
+
|
45
|
+
parse_migrated_from
|
46
|
+
|
47
|
+
desired_instances = parse_desired_instances(availability_zones, networks)
|
48
|
+
@job.desired_instances = desired_instances
|
40
49
|
|
41
50
|
@job
|
42
51
|
end
|
@@ -45,7 +54,7 @@ module Bosh::Director
|
|
45
54
|
|
46
55
|
def parse_name
|
47
56
|
@job.name = safe_property(@job_spec, "name", :class => String)
|
48
|
-
@job.canonical_name =
|
57
|
+
@job.canonical_name = Canonicalizer.canonicalize(@job.name)
|
49
58
|
end
|
50
59
|
|
51
60
|
def parse_lifecycle
|
@@ -100,7 +109,7 @@ module Bosh::Director
|
|
100
109
|
end
|
101
110
|
|
102
111
|
Array(template_names).each do |template_name|
|
103
|
-
@job.templates << @job.release.
|
112
|
+
@job.templates << @job.release.get_or_create_template(template_name)
|
104
113
|
end
|
105
114
|
end
|
106
115
|
end
|
@@ -109,11 +118,9 @@ module Bosh::Director
|
|
109
118
|
templates = safe_property(@job_spec, 'templates', class: Array, optional: true)
|
110
119
|
|
111
120
|
if templates
|
112
|
-
templates.each do |
|
113
|
-
template_name = safe_property(
|
114
|
-
release_name = safe_property(
|
115
|
-
|
116
|
-
release = nil
|
121
|
+
templates.each do |template_spec|
|
122
|
+
template_name = safe_property(template_spec, 'name', class: String)
|
123
|
+
release_name = safe_property(template_spec, 'release', class: String, optional: true)
|
117
124
|
|
118
125
|
if release_name
|
119
126
|
release = @deployment.release(release_name)
|
@@ -128,7 +135,15 @@ module Bosh::Director
|
|
128
135
|
end
|
129
136
|
end
|
130
137
|
|
131
|
-
@job.templates << release.
|
138
|
+
@job.templates << release.get_or_create_template(template_name)
|
139
|
+
|
140
|
+
links = safe_property(template_spec, 'links', class: Hash, optional: true)
|
141
|
+
@logger.debug("Parsing template links: #{links.inspect}")
|
142
|
+
|
143
|
+
links.to_a.each do |name, path|
|
144
|
+
link_path = LinkPath.parse(@deployment.name, path, @logger)
|
145
|
+
@job.add_link_path(template_name, name, link_path)
|
146
|
+
end
|
132
147
|
end
|
133
148
|
end
|
134
149
|
end
|
@@ -146,30 +161,45 @@ module Bosh::Director
|
|
146
161
|
|
147
162
|
def parse_disk
|
148
163
|
disk_size = safe_property(@job_spec, 'persistent_disk', :class => Integer, :optional => true)
|
164
|
+
disk_type_name = safe_property(@job_spec, 'persistent_disk_type', :class => String, :optional => true)
|
149
165
|
disk_pool_name = safe_property(@job_spec, 'persistent_disk_pool', :class => String, :optional => true)
|
150
166
|
|
151
|
-
if
|
167
|
+
if disk_type_name && disk_pool_name
|
152
168
|
raise JobInvalidPersistentDisk,
|
153
|
-
"Job `#{@job.name}'
|
154
|
-
"
|
169
|
+
"Job `#{@job.name}' specifies both 'disk_types' and 'disk_pools', only one key is allowed. " +
|
170
|
+
"'disk_pools' key will be DEPRECATED in the future."
|
171
|
+
end
|
172
|
+
|
173
|
+
if disk_type_name
|
174
|
+
disk_name = disk_type_name
|
175
|
+
disk_source = 'type'
|
176
|
+
else
|
177
|
+
disk_name = disk_pool_name
|
178
|
+
disk_source = 'pool'
|
179
|
+
end
|
180
|
+
|
181
|
+
if disk_size && disk_name
|
182
|
+
raise JobInvalidPersistentDisk,
|
183
|
+
"Job `#{@job.name}' references both a persistent disk size `#{disk_size}' " +
|
184
|
+
"and a persistent disk #{disk_source} `#{disk_name}'"
|
155
185
|
end
|
156
186
|
|
157
187
|
if disk_size
|
158
188
|
if disk_size < 0
|
159
189
|
raise JobInvalidPersistentDisk,
|
160
|
-
"Job `#{@job.name}' references an invalid
|
190
|
+
"Job `#{@job.name}' references an invalid persistent disk size `#{disk_size}'"
|
161
191
|
else
|
162
192
|
@job.persistent_disk = disk_size
|
163
193
|
end
|
164
194
|
end
|
165
195
|
|
166
|
-
if
|
167
|
-
|
168
|
-
if
|
169
|
-
raise
|
170
|
-
"Job `#{@job.name}' references an unknown disk
|
196
|
+
if disk_name
|
197
|
+
disk_type = @deployment.disk_type(disk_name)
|
198
|
+
if disk_type.nil?
|
199
|
+
raise JobUnknownDiskType,
|
200
|
+
"Job `#{@job.name}' references an unknown disk #{disk_source} `#{disk_name}'"
|
171
201
|
else
|
172
|
-
@job.
|
202
|
+
@job.persistent_disk_type = disk_type
|
173
203
|
end
|
174
204
|
end
|
175
205
|
end
|
@@ -195,11 +225,46 @@ module Bosh::Director
|
|
195
225
|
end
|
196
226
|
|
197
227
|
def parse_resource_pool
|
198
|
-
|
199
|
-
@job.
|
200
|
-
|
201
|
-
|
202
|
-
|
228
|
+
job_env_hash = safe_property(@job_spec, 'env', class: Hash, :default => {})
|
229
|
+
@job.env = Env.new(job_env_hash)
|
230
|
+
|
231
|
+
resource_pool_name = safe_property(@job_spec, "resource_pool", class: String, optional: true)
|
232
|
+
if resource_pool_name
|
233
|
+
resource_pool = @deployment.resource_pool(resource_pool_name)
|
234
|
+
if resource_pool.nil?
|
235
|
+
raise JobUnknownResourcePool,
|
236
|
+
"Job `#{@job.name}' references an unknown resource pool `#{resource_pool_name}'"
|
237
|
+
end
|
238
|
+
|
239
|
+
@job.vm_type = VmType.new({
|
240
|
+
'name' => resource_pool.name,
|
241
|
+
'cloud_properties' => resource_pool.cloud_properties
|
242
|
+
})
|
243
|
+
|
244
|
+
@job.stemcell = resource_pool.stemcell
|
245
|
+
|
246
|
+
if !job_env_hash.empty? && !resource_pool.env.empty?
|
247
|
+
raise JobAmbiguousEnv,
|
248
|
+
"Job '#{@job.name}' and resource pool: '#{resource_pool_name}' both declare env properties"
|
249
|
+
end
|
250
|
+
|
251
|
+
@job.env = Env.new(resource_pool.env)
|
252
|
+
|
253
|
+
return
|
254
|
+
end
|
255
|
+
|
256
|
+
vm_type_name = safe_property(@job_spec, 'vm_type', class: String)
|
257
|
+
@job.vm_type = @deployment.vm_type(vm_type_name)
|
258
|
+
if @job.vm_type.nil?
|
259
|
+
raise JobUnknownVmType,
|
260
|
+
"Job `#{@job.name}' references an unknown vm type `#{vm_type_name}'"
|
261
|
+
end
|
262
|
+
|
263
|
+
stemcell_name = safe_property(@job_spec, 'stemcell', class: String)
|
264
|
+
@job.stemcell = @deployment.stemcell(stemcell_name)
|
265
|
+
if @job.stemcell.nil?
|
266
|
+
raise JobUnknownStemcell,
|
267
|
+
"Job `#{@job.name}' references an unknown stemcell `#{stemcell_name}'"
|
203
268
|
end
|
204
269
|
end
|
205
270
|
|
@@ -208,30 +273,26 @@ module Bosh::Director
|
|
208
273
|
@job.update = UpdateConfig.new(update_spec, @deployment.update)
|
209
274
|
end
|
210
275
|
|
211
|
-
def
|
276
|
+
def parse_desired_instances(availability_zones, networks)
|
212
277
|
@job.state = safe_property(@job_spec, "state", class: String, optional: true)
|
213
278
|
job_size = safe_property(@job_spec, "instances", class: Integer)
|
214
279
|
instance_states = safe_property(@job_spec, "instance_states", class: Hash, default: {})
|
215
280
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
"Invalid job index `#{index}', integer expected"
|
222
|
-
end
|
223
|
-
|
224
|
-
unless (0...job_size).include?(index)
|
225
|
-
raise JobInvalidInstanceIndex,
|
226
|
-
"`#{@job.name}/#{index}' is outside of (0..#{job_size-1}) range"
|
281
|
+
networks.each do |network|
|
282
|
+
static_ips = network.static_ips
|
283
|
+
if static_ips && static_ips.size != job_size
|
284
|
+
raise JobNetworkInstanceIpMismatch,
|
285
|
+
"Job `#{@job.name}' has #{job_size} instances but was allocated #{static_ips.size} static IPs"
|
227
286
|
end
|
287
|
+
end
|
228
288
|
|
289
|
+
instance_states.each_pair do |index_or_id, state|
|
229
290
|
unless Job::VALID_JOB_STATES.include?(state)
|
230
291
|
raise JobInvalidInstanceState,
|
231
|
-
"Invalid state `#{state}' for `#{@job.name}/#{
|
292
|
+
"Invalid state `#{state}' for `#{@job.name}/#{index_or_id}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
|
232
293
|
end
|
233
294
|
|
234
|
-
@job.instance_states[
|
295
|
+
@job.instance_states[index_or_id] = state
|
235
296
|
end
|
236
297
|
|
237
298
|
if @job.state && !Job::VALID_JOB_STATES.include?(@job.state)
|
@@ -239,93 +300,22 @@ module Bosh::Director
|
|
239
300
|
"Invalid state `#{@job.state}' for `#{@job.name}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
|
240
301
|
end
|
241
302
|
|
242
|
-
|
243
|
-
@job.resource_pool.reserve_errand_capacity(job_size)
|
244
|
-
else
|
245
|
-
@job.resource_pool.reserve_capacity(job_size)
|
246
|
-
end
|
247
|
-
job_size.times do |index|
|
248
|
-
@job.instances[index] = Instance.new(@job, index, @logger)
|
249
|
-
end
|
303
|
+
job_size.times.map { DesiredInstance.new(@job, @deployment) }
|
250
304
|
end
|
251
305
|
|
252
|
-
def
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
network_name = safe_property(network_spec, "name", :class => String)
|
263
|
-
network = @deployment.network(network_name)
|
264
|
-
if network.nil?
|
265
|
-
raise JobUnknownNetwork,
|
266
|
-
"Job `#{@job.name}' references an unknown network `#{network_name}'"
|
267
|
-
end
|
268
|
-
|
269
|
-
static_ips = nil
|
270
|
-
if network_spec["static_ips"]
|
271
|
-
static_ips = []
|
272
|
-
each_ip(network_spec["static_ips"]) do |ip|
|
273
|
-
static_ips << ip
|
274
|
-
end
|
275
|
-
if static_ips.size != @job.instances.size
|
276
|
-
raise JobNetworkInstanceIpMismatch,
|
277
|
-
"Job `#{@job.name}' has #{@job.instances.size} instances but was allocated #{static_ips.size} static IPs"
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
default_network = safe_property(network_spec, "default", :class => Array, :optional => true)
|
282
|
-
if default_network
|
283
|
-
default_network.each do |property|
|
284
|
-
unless Network::VALID_DEFAULTS.include?(property)
|
285
|
-
raise JobNetworkInvalidDefault,
|
286
|
-
"Job `#{@job.name}' specified an invalid default network property `#{property}', " +
|
287
|
-
"valid properties are: " + Network::VALID_DEFAULTS.join(", ")
|
288
|
-
end
|
289
|
-
|
290
|
-
if @job.default_network[property]
|
291
|
-
raise JobNetworkMultipleDefaults,
|
292
|
-
"Job `#{@job.name}' specified more than one network to contain default #{property}"
|
293
|
-
else
|
294
|
-
@job.default_network[property] = network_name
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
@job.instances.each_with_index do |instance, index|
|
300
|
-
reservation = NetworkReservation.new
|
301
|
-
if static_ips
|
302
|
-
reservation.ip = static_ips[index]
|
303
|
-
reservation.type = NetworkReservation::STATIC
|
304
|
-
else
|
305
|
-
reservation.type = NetworkReservation::DYNAMIC
|
306
|
+
def parse_migrated_from
|
307
|
+
migrated_from = safe_property(@job_spec, 'migrated_from', class: Array, optional: true, :default => [])
|
308
|
+
migrated_from.each do |migrated_from_job_spec|
|
309
|
+
name = safe_property(migrated_from_job_spec, 'name', class: String)
|
310
|
+
az = safe_property(migrated_from_job_spec, 'az', class: String, optional: true)
|
311
|
+
unless az.nil?
|
312
|
+
unless @job.availability_zones.to_a.map(&:name).include?(az)
|
313
|
+
raise DeploymentInvalidMigratedFromJob,
|
314
|
+
"Job '#{name}' specified for migration to job '#{@job.name}' refers to availability zone '#{az}'. " +
|
315
|
+
"Az '#{az}' is not in the list of availability zones of job '#{@job.name}'."
|
306
316
|
end
|
307
|
-
instance.add_network_reservation(network_name, reservation)
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
if network_specs.size > 1
|
312
|
-
missing_default_properties = Network::VALID_DEFAULTS.dup
|
313
|
-
@job.default_network.each_key do |key|
|
314
|
-
missing_default_properties.delete(key)
|
315
|
-
end
|
316
|
-
|
317
|
-
unless missing_default_properties.empty?
|
318
|
-
raise JobNetworkMissingDefault,
|
319
|
-
"Job `#{@job.name}' must specify which network is default for " +
|
320
|
-
missing_default_properties.sort.join(", ") + ", since it has more than one network configured"
|
321
|
-
end
|
322
|
-
else
|
323
|
-
# Set the default network to the one and only available network
|
324
|
-
# (if not specified already)
|
325
|
-
network = safe_property(network_specs[0], "name", :class => String)
|
326
|
-
Network::VALID_DEFAULTS.each do |property|
|
327
|
-
@job.default_network[property] ||= network
|
328
317
|
end
|
318
|
+
@job.migrated_from << MigratedFromJob.new(name, az)
|
329
319
|
end
|
330
320
|
end
|
331
321
|
|
@@ -343,6 +333,13 @@ module Bosh::Director
|
|
343
333
|
"Job `#{@job.name}' does not specify template or templates keys, one is required"
|
344
334
|
end
|
345
335
|
end
|
336
|
+
|
337
|
+
def assign_default_networks(networks)
|
338
|
+
Network::VALID_DEFAULTS.each do |property|
|
339
|
+
network = networks.find { |network| network.default_for?(property) }
|
340
|
+
@job.default_network[property] = network.name if network
|
341
|
+
end
|
342
|
+
end
|
346
343
|
end
|
347
344
|
end
|
348
345
|
end
|