bosh-director 1.5.0.pre.1113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +34 -0
- data/bin/bosh-director +36 -0
- data/bin/bosh-director-console +84 -0
- data/bin/bosh-director-drain-workers +42 -0
- data/bin/bosh-director-migrate +58 -0
- data/bin/bosh-director-scheduler +27 -0
- data/bin/bosh-director-worker +76 -0
- data/db/migrations/README +1 -0
- data/db/migrations/director/20110209010747_initial.rb +118 -0
- data/db/migrations/director/20110406055800_add_task_user.rb +9 -0
- data/db/migrations/director/20110518225809_remove_cid_constrain.rb +13 -0
- data/db/migrations/director/20110617211923_add_deployments_release_versions.rb +32 -0
- data/db/migrations/director/20110622212607_add_task_checkpoint_timestamp.rb +9 -0
- data/db/migrations/director/20110628023039_add_state_to_instances.rb +21 -0
- data/db/migrations/director/20110709012332_add_disk_size_to_instances.rb +9 -0
- data/db/migrations/director/20110906183441_add_log_bundles.rb +11 -0
- data/db/migrations/director/20110907194830_add_logs_json_to_templates.rb +9 -0
- data/db/migrations/director/20110915205610_add_persistent_disks.rb +51 -0
- data/db/migrations/director/20111005180929_add_properties.rb +14 -0
- data/db/migrations/director/20111110024617_add_deployment_problems.rb +24 -0
- data/db/migrations/director/20111216214145_recreate_support_for_vms.rb +9 -0
- data/db/migrations/director/20120102084027_add_credentials_to_vms.rb +7 -0
- data/db/migrations/director/20120427235217_allow_multiple_releases_per_deployment.rb +36 -0
- data/db/migrations/director/20120524175805_add_task_type.rb +44 -0
- data/db/migrations/director/20120614001930_delete_redundant_deployment_release_relation.rb +34 -0
- data/db/migrations/director/20120822004528_add_fingerprint_to_templates_and_packages.rb +17 -0
- data/db/migrations/director/20120830191244_add_properties_to_templates.rb +9 -0
- data/db/migrations/director/20121106190739_persist_vm_env.rb +9 -0
- data/db/migrations/director/20130222232131_add_sha1_to_stemcells.rb +9 -0
- data/db/migrations/director/20130312211407_add_commit_hash_to_release_versions.rb +19 -0
- data/db/migrations/director/20130409235338_snapshot.rb +15 -0
- data/db/migrations/director/20130530164918_add_paused_flag_to_instance.rb +14 -0
- data/db/migrations/director/20130531172604_add_director_attributes.rb +13 -0
- data/db/migrations/dns/20120123234908_initial.rb +27 -0
- data/lib/bosh/director.rb +133 -0
- data/lib/bosh/director/agent_client.rb +78 -0
- data/lib/bosh/director/api.rb +29 -0
- data/lib/bosh/director/api/api_helper.rb +81 -0
- data/lib/bosh/director/api/backup_manager.rb +15 -0
- data/lib/bosh/director/api/controller.rb +639 -0
- data/lib/bosh/director/api/controller_helpers.rb +34 -0
- data/lib/bosh/director/api/deployment_lookup.rb +13 -0
- data/lib/bosh/director/api/deployment_manager.rb +60 -0
- data/lib/bosh/director/api/http_constants.rb +16 -0
- data/lib/bosh/director/api/instance_lookup.rb +44 -0
- data/lib/bosh/director/api/instance_manager.rb +63 -0
- data/lib/bosh/director/api/problem_manager.rb +40 -0
- data/lib/bosh/director/api/property_manager.rb +69 -0
- data/lib/bosh/director/api/release_manager.rb +59 -0
- data/lib/bosh/director/api/resource_manager.rb +69 -0
- data/lib/bosh/director/api/resurrector_manager.rb +15 -0
- data/lib/bosh/director/api/snapshot_manager.rb +94 -0
- data/lib/bosh/director/api/stemcell_manager.rb +50 -0
- data/lib/bosh/director/api/task_helper.rb +46 -0
- data/lib/bosh/director/api/task_manager.rb +64 -0
- data/lib/bosh/director/api/user_manager.rb +72 -0
- data/lib/bosh/director/api/vm_state_manager.rb +11 -0
- data/lib/bosh/director/app.rb +35 -0
- data/lib/bosh/director/blob_util.rb +87 -0
- data/lib/bosh/director/blobstores.rb +29 -0
- data/lib/bosh/director/client.rb +156 -0
- data/lib/bosh/director/cloudcheck_helper.rb +204 -0
- data/lib/bosh/director/compile_task.rb +157 -0
- data/lib/bosh/director/config.rb +370 -0
- data/lib/bosh/director/configuration_hasher.rb +114 -0
- data/lib/bosh/director/cycle_helper.rb +36 -0
- data/lib/bosh/director/db_backup.rb +22 -0
- data/lib/bosh/director/db_backup/adapter.rb +3 -0
- data/lib/bosh/director/db_backup/adapter/mysql2.rb +27 -0
- data/lib/bosh/director/db_backup/adapter/postgres.rb +36 -0
- data/lib/bosh/director/db_backup/adapter/sqlite.rb +17 -0
- data/lib/bosh/director/db_backup/error.rb +10 -0
- data/lib/bosh/director/deployment_plan.rb +26 -0
- data/lib/bosh/director/deployment_plan/assembler.rb +430 -0
- data/lib/bosh/director/deployment_plan/compilation_config.rb +54 -0
- data/lib/bosh/director/deployment_plan/compiled_package.rb +35 -0
- data/lib/bosh/director/deployment_plan/dynamic_network.rb +91 -0
- data/lib/bosh/director/deployment_plan/idle_vm.rb +109 -0
- data/lib/bosh/director/deployment_plan/instance.rb +413 -0
- data/lib/bosh/director/deployment_plan/job.rb +470 -0
- data/lib/bosh/director/deployment_plan/manual_network.rb +137 -0
- data/lib/bosh/director/deployment_plan/network.rb +74 -0
- data/lib/bosh/director/deployment_plan/network_subnet.rb +167 -0
- data/lib/bosh/director/deployment_plan/planner.rb +288 -0
- data/lib/bosh/director/deployment_plan/preparer.rb +52 -0
- data/lib/bosh/director/deployment_plan/release.rb +126 -0
- data/lib/bosh/director/deployment_plan/resource_pool.rb +143 -0
- data/lib/bosh/director/deployment_plan/resource_pools.rb +68 -0
- data/lib/bosh/director/deployment_plan/stemcell.rb +56 -0
- data/lib/bosh/director/deployment_plan/template.rb +94 -0
- data/lib/bosh/director/deployment_plan/update_config.rb +80 -0
- data/lib/bosh/director/deployment_plan/updater.rb +55 -0
- data/lib/bosh/director/deployment_plan/vip_network.rb +79 -0
- data/lib/bosh/director/dns_helper.rb +204 -0
- data/lib/bosh/director/download_helper.rb +44 -0
- data/lib/bosh/director/duration.rb +36 -0
- data/lib/bosh/director/encryption_helper.rb +10 -0
- data/lib/bosh/director/errors.rb +198 -0
- data/lib/bosh/director/event_log.rb +136 -0
- data/lib/bosh/director/ext.rb +64 -0
- data/lib/bosh/director/hash_string_vals.rb +13 -0
- data/lib/bosh/director/instance_deleter.rb +109 -0
- data/lib/bosh/director/instance_updater.rb +506 -0
- data/lib/bosh/director/ip_util.rb +67 -0
- data/lib/bosh/director/job_queue.rb +16 -0
- data/lib/bosh/director/job_runner.rb +162 -0
- data/lib/bosh/director/job_updater.rb +121 -0
- data/lib/bosh/director/jobs/backup.rb +86 -0
- data/lib/bosh/director/jobs/base_job.rb +66 -0
- data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +46 -0
- data/lib/bosh/director/jobs/cloud_check/scan.rb +38 -0
- data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +73 -0
- data/lib/bosh/director/jobs/create_snapshot.rb +23 -0
- data/lib/bosh/director/jobs/delete_deployment.rb +183 -0
- data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +34 -0
- data/lib/bosh/director/jobs/delete_release.rb +219 -0
- data/lib/bosh/director/jobs/delete_snapshots.rb +23 -0
- data/lib/bosh/director/jobs/delete_stemcell.rb +102 -0
- data/lib/bosh/director/jobs/fetch_logs.rb +99 -0
- data/lib/bosh/director/jobs/scheduled_backup.rb +38 -0
- data/lib/bosh/director/jobs/snapshot_deployment.rb +61 -0
- data/lib/bosh/director/jobs/snapshot_deployments.rb +23 -0
- data/lib/bosh/director/jobs/snapshot_self.rb +43 -0
- data/lib/bosh/director/jobs/ssh.rb +59 -0
- data/lib/bosh/director/jobs/update_deployment.rb +110 -0
- data/lib/bosh/director/jobs/update_release.rb +672 -0
- data/lib/bosh/director/jobs/update_stemcell.rb +109 -0
- data/lib/bosh/director/jobs/vm_state.rb +89 -0
- data/lib/bosh/director/lock.rb +133 -0
- data/lib/bosh/director/lock_helper.rb +92 -0
- data/lib/bosh/director/models.rb +29 -0
- data/lib/bosh/director/models/compiled_package.rb +33 -0
- data/lib/bosh/director/models/deployment.rb +22 -0
- data/lib/bosh/director/models/deployment_problem.rb +49 -0
- data/lib/bosh/director/models/deployment_property.rb +21 -0
- data/lib/bosh/director/models/director_attribute.rb +9 -0
- data/lib/bosh/director/models/dns.rb +9 -0
- data/lib/bosh/director/models/dns/domain.rb +9 -0
- data/lib/bosh/director/models/dns/record.rb +7 -0
- data/lib/bosh/director/models/helpers/model_helper.rb +7 -0
- data/lib/bosh/director/models/instance.rb +28 -0
- data/lib/bosh/director/models/log_bundle.rb +10 -0
- data/lib/bosh/director/models/package.rb +30 -0
- data/lib/bosh/director/models/persistent_disk.rb +13 -0
- data/lib/bosh/director/models/release.rb +17 -0
- data/lib/bosh/director/models/release_version.rb +16 -0
- data/lib/bosh/director/models/snapshot.rb +13 -0
- data/lib/bosh/director/models/stemcell.rb +18 -0
- data/lib/bosh/director/models/task.rb +10 -0
- data/lib/bosh/director/models/template.rb +44 -0
- data/lib/bosh/director/models/user.rb +11 -0
- data/lib/bosh/director/models/vm.rb +42 -0
- data/lib/bosh/director/nats_rpc.rb +54 -0
- data/lib/bosh/director/network_reservation.rb +121 -0
- data/lib/bosh/director/next_rebase_version.rb +20 -0
- data/lib/bosh/director/package_compiler.rb +423 -0
- data/lib/bosh/director/problem_handlers/base.rb +153 -0
- data/lib/bosh/director/problem_handlers/inactive_disk.rb +112 -0
- data/lib/bosh/director/problem_handlers/invalid_problem.rb +28 -0
- data/lib/bosh/director/problem_handlers/missing_vm.rb +34 -0
- data/lib/bosh/director/problem_handlers/mount_info_mismatch.rb +62 -0
- data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +64 -0
- data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +85 -0
- data/lib/bosh/director/problem_handlers/unresponsive_agent.rb +78 -0
- data/lib/bosh/director/problem_resolver.rb +103 -0
- data/lib/bosh/director/problem_scanner.rb +268 -0
- data/lib/bosh/director/resource_pool_updater.rb +216 -0
- data/lib/bosh/director/scheduler.rb +57 -0
- data/lib/bosh/director/sequel.rb +13 -0
- data/lib/bosh/director/tar_gzipper.rb +47 -0
- data/lib/bosh/director/task_result_file.rb +19 -0
- data/lib/bosh/director/thread_pool.rb +8 -0
- data/lib/bosh/director/validation_helper.rb +55 -0
- data/lib/bosh/director/version.rb +7 -0
- data/lib/bosh/director/vm_creator.rb +80 -0
- data/lib/bosh/director/vm_data.rb +63 -0
- data/lib/bosh/director/vm_metadata_updater.rb +29 -0
- data/lib/bosh/director/vm_reuser.rb +63 -0
- data/lib/cloud/dummy.rb +149 -0
- metadata +664 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Director
|
|
4
|
+
module DeploymentPlan
|
|
5
|
+
class Template
|
|
6
|
+
|
|
7
|
+
attr_reader :name
|
|
8
|
+
attr_reader :release
|
|
9
|
+
|
|
10
|
+
attr_reader :model
|
|
11
|
+
attr_reader :package_models
|
|
12
|
+
|
|
13
|
+
# @param [DeploymentPlan::Release] release Release
|
|
14
|
+
# @param [String] name Template name
|
|
15
|
+
def initialize(release, name)
|
|
16
|
+
@release = release
|
|
17
|
+
@name = name
|
|
18
|
+
@model = nil
|
|
19
|
+
@package_models = []
|
|
20
|
+
@logger = Config.logger
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Looks up template model and its package models in DB
|
|
24
|
+
# @return [void]
|
|
25
|
+
def bind_models
|
|
26
|
+
@model = @release.get_template_model_by_name(@name)
|
|
27
|
+
|
|
28
|
+
if @model.nil?
|
|
29
|
+
raise DeploymentUnknownTemplate, "Can't find template `#{@name}'"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@package_models = @model.package_names.map do |name|
|
|
33
|
+
@release.get_package_model_by_name(name)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Downloads template blob to a given path
|
|
38
|
+
# @return [String] Path to downloaded blob
|
|
39
|
+
def download_blob
|
|
40
|
+
uuid = SecureRandom.uuid
|
|
41
|
+
path = File.join(Dir.tmpdir, "template-#{uuid}")
|
|
42
|
+
|
|
43
|
+
@logger.debug("Downloading template `#{@name}' (#{blobstore_id})...")
|
|
44
|
+
t1 = Time.now
|
|
45
|
+
|
|
46
|
+
File.open(path, "w") do |f|
|
|
47
|
+
App.instance.blobstores.blobstore.get(blobstore_id, f)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
@logger.debug("Template `#{@name}' downloaded to #{path} " +
|
|
51
|
+
"(took #{Time.now - t1}s)")
|
|
52
|
+
|
|
53
|
+
path
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [String]
|
|
57
|
+
def version
|
|
58
|
+
present_model.version
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @return [String]
|
|
62
|
+
def sha1
|
|
63
|
+
present_model.sha1
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @return [String]
|
|
67
|
+
def blobstore_id
|
|
68
|
+
present_model.blobstore_id
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @return [Array]
|
|
72
|
+
def logs
|
|
73
|
+
present_model.logs
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return [Hash]
|
|
77
|
+
def properties
|
|
78
|
+
present_model.properties
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Returns model only if it's present, fails otherwise
|
|
84
|
+
# @return [Models::Template]
|
|
85
|
+
def present_model
|
|
86
|
+
if @model.nil?
|
|
87
|
+
raise DirectorError, "Template `#{@name}' model is unbound"
|
|
88
|
+
end
|
|
89
|
+
@model
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Director
|
|
4
|
+
module DeploymentPlan
|
|
5
|
+
class UpdateConfig
|
|
6
|
+
include ValidationHelper
|
|
7
|
+
|
|
8
|
+
attr_accessor :canaries
|
|
9
|
+
attr_accessor :max_in_flight
|
|
10
|
+
|
|
11
|
+
attr_accessor :min_canary_watch_time
|
|
12
|
+
attr_accessor :max_canary_watch_time
|
|
13
|
+
|
|
14
|
+
attr_accessor :min_update_watch_time
|
|
15
|
+
attr_accessor :max_update_watch_time
|
|
16
|
+
|
|
17
|
+
# @param [Hash] update_config Raw update config from deployment manifest
|
|
18
|
+
# @param [optional, Hash] default_update_config Default update config
|
|
19
|
+
def initialize(update_config, default_update_config = nil)
|
|
20
|
+
optional = !default_update_config.nil?
|
|
21
|
+
|
|
22
|
+
@canaries = safe_property(update_config, "canaries",
|
|
23
|
+
:class => Integer, :optional => optional)
|
|
24
|
+
|
|
25
|
+
@max_in_flight = safe_property(update_config, "max_in_flight",
|
|
26
|
+
:class => Integer, :optional => optional,
|
|
27
|
+
:min => 1)
|
|
28
|
+
|
|
29
|
+
canary_watch_times = safe_property(update_config, "canary_watch_time",
|
|
30
|
+
:class => String,
|
|
31
|
+
:optional => optional)
|
|
32
|
+
update_watch_times = safe_property(update_config, "update_watch_time",
|
|
33
|
+
:class => String,
|
|
34
|
+
:optional => optional)
|
|
35
|
+
|
|
36
|
+
if canary_watch_times
|
|
37
|
+
@min_canary_watch_time, @max_canary_watch_time =
|
|
38
|
+
parse_watch_times(canary_watch_times)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if update_watch_times
|
|
42
|
+
@min_update_watch_time, @max_update_watch_time =
|
|
43
|
+
parse_watch_times(update_watch_times)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if optional
|
|
47
|
+
@canaries ||= default_update_config.canaries
|
|
48
|
+
|
|
49
|
+
@min_canary_watch_time ||= default_update_config.min_canary_watch_time
|
|
50
|
+
@max_canary_watch_time ||= default_update_config.max_canary_watch_time
|
|
51
|
+
|
|
52
|
+
@min_update_watch_time ||= default_update_config.min_update_watch_time
|
|
53
|
+
@max_update_watch_time ||= default_update_config.max_update_watch_time
|
|
54
|
+
|
|
55
|
+
@max_in_flight ||= default_update_config.max_in_flight
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def parse_watch_times(value)
|
|
60
|
+
value = value.to_s
|
|
61
|
+
|
|
62
|
+
if value =~ /^\s*(\d+)\s*\-\s*(\d+)\s*$/
|
|
63
|
+
result = [$1.to_i, $2.to_i]
|
|
64
|
+
elsif value =~ /^\s*(\d+)\s*$/
|
|
65
|
+
result = [$1.to_i, $1.to_i]
|
|
66
|
+
else
|
|
67
|
+
raise UpdateConfigInvalidWatchTime,
|
|
68
|
+
"Watch time should be an integer or a range of two integers"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if result[0] > result[1]
|
|
72
|
+
raise UpdateConfigInvalidWatchTime,
|
|
73
|
+
"Min watch time cannot be greater than max watch time"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Bosh::Director
|
|
2
|
+
module DeploymentPlan
|
|
3
|
+
class Updater
|
|
4
|
+
def initialize(job, event_log, resource_pools, assembler, deployment_plan)
|
|
5
|
+
@job = job
|
|
6
|
+
@logger = job.logger
|
|
7
|
+
@event_log = event_log
|
|
8
|
+
@resource_pools = resource_pools
|
|
9
|
+
@assembler = assembler
|
|
10
|
+
@deployment_plan = deployment_plan
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def update
|
|
14
|
+
event_log.begin_stage('Preparing DNS', 1)
|
|
15
|
+
job.track_and_log('Binding DNS') do
|
|
16
|
+
if Config.dns_enabled?
|
|
17
|
+
assembler.bind_dns
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
logger.info('Updating resource pools')
|
|
22
|
+
resource_pools.update
|
|
23
|
+
job.task_checkpoint
|
|
24
|
+
|
|
25
|
+
logger.info('Binding instance VMs')
|
|
26
|
+
assembler.bind_instance_vms
|
|
27
|
+
|
|
28
|
+
event_log.begin_stage('Preparing configuration', 1)
|
|
29
|
+
job.track_and_log('Binding configuration') do
|
|
30
|
+
assembler.bind_configuration
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
logger.info('Deleting no longer needed VMs')
|
|
34
|
+
assembler.delete_unneeded_vms
|
|
35
|
+
|
|
36
|
+
logger.info('Deleting no longer needed instances')
|
|
37
|
+
assembler.delete_unneeded_instances
|
|
38
|
+
|
|
39
|
+
logger.info('Updating jobs')
|
|
40
|
+
deployment_plan.jobs.each do |bosh_job|
|
|
41
|
+
job.task_checkpoint
|
|
42
|
+
logger.info("Updating job: #{bosh_job.name}")
|
|
43
|
+
JobUpdater.new(deployment_plan, bosh_job).update
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
logger.info('Refilling resource pools')
|
|
47
|
+
resource_pools.refill
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
attr_reader :job, :event_log, :resource_pools, :logger, :assembler, :deployment_plan
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Director
|
|
4
|
+
module DeploymentPlan
|
|
5
|
+
class VipNetwork < Network
|
|
6
|
+
include IpUtil
|
|
7
|
+
|
|
8
|
+
# @return [Hash] Network cloud properties
|
|
9
|
+
attr_reader :cloud_properties
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Creates a new network.
|
|
13
|
+
#
|
|
14
|
+
# @param [DeploymentPlan] deployment associated deployment plan
|
|
15
|
+
# @param [Hash] network_spec parsed deployment manifest network section
|
|
16
|
+
def initialize(deployment, network_spec)
|
|
17
|
+
super
|
|
18
|
+
@cloud_properties = safe_property(network_spec, "cloud_properties",
|
|
19
|
+
:class => Hash)
|
|
20
|
+
@reserved_ips = Set.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Reserves a network resource.
|
|
25
|
+
#
|
|
26
|
+
# This is either an already used reservation being verified or a new one
|
|
27
|
+
# waiting to be fulfilled.
|
|
28
|
+
# @param [NetworkReservation] reservation
|
|
29
|
+
# @return [Boolean] true if the reservation was fulfilled
|
|
30
|
+
def reserve(reservation)
|
|
31
|
+
reservation.reserved = false
|
|
32
|
+
if reservation.ip.nil?
|
|
33
|
+
raise NetworkReservationIpMissing,
|
|
34
|
+
"Must have IP for static reservations"
|
|
35
|
+
elsif reservation.dynamic?
|
|
36
|
+
reservation.error = NetworkReservation::WRONG_TYPE
|
|
37
|
+
elsif @reserved_ips.include?(reservation.ip)
|
|
38
|
+
reservation.error = NetworkReservation::USED
|
|
39
|
+
else
|
|
40
|
+
reservation.reserved = true
|
|
41
|
+
reservation.type = NetworkReservation::STATIC
|
|
42
|
+
@reserved_ips.add(reservation.ip)
|
|
43
|
+
end
|
|
44
|
+
reservation.reserved?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# Releases a previous reservation that had been fulfilled.
|
|
49
|
+
# @param [NetworkReservation] reservation
|
|
50
|
+
# @return [void]
|
|
51
|
+
def release(reservation)
|
|
52
|
+
unless reservation.ip
|
|
53
|
+
raise NetworkReservationIpMissing,
|
|
54
|
+
"Can't release reservation without an IP"
|
|
55
|
+
end
|
|
56
|
+
@reserved_ips.delete(reservation.ip)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Returns the network settings for the specific reservation.
|
|
61
|
+
#
|
|
62
|
+
# @param [NetworkReservation] reservation
|
|
63
|
+
# @param [Array<String>] default_properties
|
|
64
|
+
# @return [Hash] network settings that will be passed to the BOSH Agent
|
|
65
|
+
def network_settings(reservation, default_properties = VALID_DEFAULTS)
|
|
66
|
+
if default_properties && !default_properties.empty?
|
|
67
|
+
raise NetworkReservationVipDefaultProvided,
|
|
68
|
+
"Can't provide any defaults since this is a VIP network"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
"type" => "vip",
|
|
73
|
+
"ip" => ip_to_netaddr(reservation.ip).ip,
|
|
74
|
+
"cloud_properties" => @cloud_properties
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Director
|
|
4
|
+
module DnsHelper
|
|
5
|
+
|
|
6
|
+
# primary_ns contact serial refresh retry expire minimum
|
|
7
|
+
SOA = "localhost hostmaster@localhost 0 10800 604800 30"
|
|
8
|
+
TTL_5M = 300
|
|
9
|
+
TTL_4H = 3600 * 4
|
|
10
|
+
|
|
11
|
+
# @param [String] ip IP address
|
|
12
|
+
# @return [String] reverse dns domain name for an IP
|
|
13
|
+
def reverse_domain(ip)
|
|
14
|
+
reverse(ip, 2)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param [String] ip IP address
|
|
18
|
+
# @return [String] reverse dns name for an IP used for a PTR record
|
|
19
|
+
def reverse_host(ip)
|
|
20
|
+
reverse(ip, 3)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def canonical(string)
|
|
24
|
+
# a-z, 0-9, -, case insensitive, and must start with a letter
|
|
25
|
+
string = string.downcase.gsub(/_/, "-").gsub(/[^a-z0-9-]/, "")
|
|
26
|
+
if string =~ /^(\d|-)/
|
|
27
|
+
raise DnsInvalidCanonicalName,
|
|
28
|
+
"Invalid DNS canonical name `#{string}', must begin with a letter"
|
|
29
|
+
end
|
|
30
|
+
if string =~ /-$/
|
|
31
|
+
raise DnsInvalidCanonicalName,
|
|
32
|
+
"Invalid DNS canonical name `#{string}', can't end with a hyphen"
|
|
33
|
+
end
|
|
34
|
+
string
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# build a list of dns servers to use
|
|
38
|
+
def dns_servers(network, spec, add_default_dns = true)
|
|
39
|
+
servers = nil
|
|
40
|
+
dns_property = safe_property(spec, "dns",
|
|
41
|
+
:class => Array, :optional => true)
|
|
42
|
+
if dns_property
|
|
43
|
+
servers = []
|
|
44
|
+
dns_property.each do |dns|
|
|
45
|
+
dns = NetAddr::CIDR.create(dns)
|
|
46
|
+
unless dns.size == 1
|
|
47
|
+
invalid_dns(network, "must be a single IP")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
servers << dns.ip
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
return servers unless add_default_dns
|
|
55
|
+
|
|
56
|
+
add_default_dns_server(servers)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# returns the default DNS server
|
|
60
|
+
def default_dns_server
|
|
61
|
+
Config.dns["server"] if Config.dns
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# add default dns server to an array of dns servers
|
|
65
|
+
def add_default_dns_server(servers)
|
|
66
|
+
return servers unless Config.dns_enabled?
|
|
67
|
+
|
|
68
|
+
default_server = default_dns_server
|
|
69
|
+
if default_server && default_server != "127.0.0.1"
|
|
70
|
+
(servers ||= []) << default_server
|
|
71
|
+
servers.uniq!
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
servers
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# returns the DNS domain name
|
|
78
|
+
def dns_domain_name
|
|
79
|
+
Config.dns_domain_name
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# returns the DNS name server record
|
|
83
|
+
def dns_ns_record
|
|
84
|
+
"ns.#{dns_domain_name}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# create/update DNS A record
|
|
88
|
+
def update_dns_a_record(domain, name, ip_address)
|
|
89
|
+
record = Models::Dns::Record.find(:domain_id => domain.id,
|
|
90
|
+
:name => name)
|
|
91
|
+
if record.nil?
|
|
92
|
+
record = Models::Dns::Record.new(:domain_id => domain.id,
|
|
93
|
+
:name => name, :type => "A",
|
|
94
|
+
:ttl => TTL_5M)
|
|
95
|
+
end
|
|
96
|
+
record.content = ip_address
|
|
97
|
+
record.change_date = Time.now.to_i
|
|
98
|
+
record.save
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# create/update DNS PTR records (for reverse lookups)
|
|
102
|
+
def update_dns_ptr_record(name, ip_address)
|
|
103
|
+
reverse_domain = reverse_domain(ip_address)
|
|
104
|
+
reverse_host = reverse_host(ip_address)
|
|
105
|
+
|
|
106
|
+
rdomain = Models::Dns::Domain.safe_find_or_create(:name => reverse_domain,
|
|
107
|
+
:type => "NATIVE")
|
|
108
|
+
Models::Dns::Record.find_or_create(:domain_id => rdomain.id,
|
|
109
|
+
:name => reverse_domain,
|
|
110
|
+
:type =>'SOA', :content => SOA,
|
|
111
|
+
:ttl => TTL_4H)
|
|
112
|
+
|
|
113
|
+
Models::Dns::Record.find_or_create(:domain_id => rdomain.id,
|
|
114
|
+
:name => reverse_domain,
|
|
115
|
+
:type =>'NS', :ttl => TTL_4H,
|
|
116
|
+
:content => dns_ns_record)
|
|
117
|
+
|
|
118
|
+
record = Models::Dns::Record.find(:content => name, :type =>'PTR')
|
|
119
|
+
|
|
120
|
+
# delete the record if the IP address changed
|
|
121
|
+
if record && record.name != reverse_host
|
|
122
|
+
id = record.domain_id
|
|
123
|
+
record.destroy
|
|
124
|
+
record = nil
|
|
125
|
+
|
|
126
|
+
# delete the domain if the domain id changed and it's empty
|
|
127
|
+
if id != rdomain.id
|
|
128
|
+
delete_empty_domain(Models::Dns::Domain[id])
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
unless record
|
|
133
|
+
record = Models::Dns::Record.new(:domain_id => rdomain.id,
|
|
134
|
+
:name => reverse_host,
|
|
135
|
+
:type =>'PTR', :ttl => TTL_5M)
|
|
136
|
+
end
|
|
137
|
+
record.content = name
|
|
138
|
+
record.change_date = Time.now.to_i
|
|
139
|
+
record.save
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# deletes all DNS records matching the pattern
|
|
143
|
+
# @param [String] record_pattern SQL pattern
|
|
144
|
+
# @param [Integer] domain_id domain record id
|
|
145
|
+
def delete_dns_records(record_pattern, domain_id=nil)
|
|
146
|
+
records = Models::Dns::Record.filter(:name.like(record_pattern))
|
|
147
|
+
if domain_id
|
|
148
|
+
records = records.filter(:domain_id => domain_id)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# delete A records and collect all IPs for later
|
|
152
|
+
ips = []
|
|
153
|
+
records.each do |record|
|
|
154
|
+
ips << record.content
|
|
155
|
+
@logger.info("Deleting DNS record: #{record.name}")
|
|
156
|
+
record.destroy
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# delete PTR records from IP list
|
|
160
|
+
ips.each do |ip|
|
|
161
|
+
records = Models::Dns::Record.filter(:name.like(reverse_host(ip)))
|
|
162
|
+
records.each do |record|
|
|
163
|
+
@logger.info("Deleting reverse DNS record: #{record.name}")
|
|
164
|
+
record.destroy
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# see if any of the reverse domains are empty and should be deleted
|
|
169
|
+
ips.each do |ip|
|
|
170
|
+
reverse = reverse_domain(ip)
|
|
171
|
+
rdomain = Models::Dns::Domain.filter(:name => reverse,
|
|
172
|
+
:type => "NATIVE")
|
|
173
|
+
rdomain.each do |domain|
|
|
174
|
+
delete_empty_domain(domain)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# if the count is 2, it means we only have the NS & SOA record
|
|
180
|
+
# and the domain is "empty" and can be deleted
|
|
181
|
+
def delete_empty_domain(domain)
|
|
182
|
+
if domain.records.size == 2
|
|
183
|
+
@logger.info("Deleting empty reverse domain #{domain.name}")
|
|
184
|
+
domain.destroy # cascaded - all records are removed
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @param [String] network name
|
|
189
|
+
# @param [String] reason
|
|
190
|
+
# @raise NetworkInvalidDns
|
|
191
|
+
def invalid_dns(network, reason)
|
|
192
|
+
raise NetworkInvalidDns,
|
|
193
|
+
"Invalid DNS for network `#{network}': #{reason}"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
|
|
198
|
+
def reverse(ip, n)
|
|
199
|
+
octets = ip.split(/\./)
|
|
200
|
+
"#{octets[0..n].reverse.join(".")}.in-addr.arpa"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
end
|
|
204
|
+
end
|