bosh-director 1.3202.0 → 1.3213.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrations/director/20151223172000_rename_requires_json.rb +7 -0
  3. data/db/migrations/director/20160106162749_runtime_configs.rb +19 -0
  4. data/db/migrations/director/20160106163433_add_runtime_configs_to_deployments.rb +7 -0
  5. data/db/migrations/director/20160202162216_add_post_start_completed_to_instance.rb +7 -0
  6. data/db/migrations/director/20160210201838_denormalize_compiled_package_stemcell_id_to_stemcell_name_and_version.rb +57 -0
  7. data/db/migrations/director/20160219175840_add_column_teams_to_deployments.rb +8 -0
  8. data/db/migrations/director/20160224222508_add_deployment_name_to_task.rb +7 -0
  9. data/db/migrations/director/20160225182206_rename_post_start_completed.rb +8 -0
  10. data/lib/bosh/director.rb +9 -0
  11. data/lib/bosh/director/api.rb +1 -1
  12. data/lib/bosh/director/api/api_helper.rb +27 -0
  13. data/lib/bosh/director/api/controllers/base_controller.rb +28 -5
  14. data/lib/bosh/director/api/controllers/cloud_configs_controller.rb +4 -3
  15. data/lib/bosh/director/api/controllers/deployments_controller.rb +165 -81
  16. data/lib/bosh/director/api/controllers/locks_controller.rb +1 -1
  17. data/lib/bosh/director/api/controllers/packages_controller.rb +4 -35
  18. data/lib/bosh/director/api/controllers/releases_controller.rb +6 -4
  19. data/lib/bosh/director/api/controllers/runtime_configs_controller.rb +41 -0
  20. data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -1
  21. data/lib/bosh/director/api/controllers/tasks_controller.rb +72 -5
  22. data/lib/bosh/director/api/deployment_manager.rb +10 -42
  23. data/lib/bosh/director/api/extensions/scoping.rb +11 -24
  24. data/lib/bosh/director/api/instance_lookup.rb +10 -22
  25. data/lib/bosh/director/api/instance_manager.rb +27 -15
  26. data/lib/bosh/director/api/local_identity_provider.rb +0 -8
  27. data/lib/bosh/director/api/problem_manager.rb +7 -19
  28. data/lib/bosh/director/api/property_manager.rb +12 -21
  29. data/lib/bosh/director/api/resurrector_manager.rb +4 -4
  30. data/lib/bosh/director/api/route_configuration.rb +1 -0
  31. data/lib/bosh/director/api/runtime_config_manager.rb +35 -0
  32. data/lib/bosh/director/api/snapshot_manager.rb +2 -2
  33. data/lib/bosh/director/api/task_helper.rb +2 -1
  34. data/lib/bosh/director/api/task_manager.rb +2 -8
  35. data/lib/bosh/director/api/uaa_identity_provider.rb +0 -16
  36. data/lib/bosh/director/blob_util.rb +3 -2
  37. data/lib/bosh/director/cloudcheck_helper.rb +17 -3
  38. data/lib/bosh/director/compile_task.rb +53 -24
  39. data/lib/bosh/director/compile_task_generator.rb +6 -6
  40. data/lib/bosh/director/compiled_package_group.rb +4 -3
  41. data/lib/bosh/director/compiled_release.rb +6 -0
  42. data/lib/bosh/director/compiled_release/manifest.rb +30 -0
  43. data/lib/bosh/director/compiled_release_manifest.rb +3 -3
  44. data/lib/bosh/director/config.rb +11 -1
  45. data/lib/bosh/director/deployment_plan.rb +1 -0
  46. data/lib/bosh/director/deployment_plan/assembler.rb +6 -2
  47. data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +26 -10
  48. data/lib/bosh/director/deployment_plan/compilation_config.rb +43 -7
  49. data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +10 -3
  50. data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -10
  51. data/lib/bosh/director/deployment_plan/dynamic_network.rb +1 -1
  52. data/lib/bosh/director/deployment_plan/instance.rb +36 -17
  53. data/lib/bosh/director/deployment_plan/instance_plan.rb +13 -2
  54. data/lib/bosh/director/deployment_plan/instance_spec.rb +12 -4
  55. data/lib/bosh/director/deployment_plan/job.rb +73 -39
  56. data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +4 -4
  57. data/lib/bosh/director/deployment_plan/job_migrator.rb +7 -7
  58. data/lib/bosh/director/deployment_plan/job_network_parser.rb +6 -6
  59. data/lib/bosh/director/deployment_plan/job_spec_parser.rb +91 -33
  60. data/lib/bosh/director/deployment_plan/links/link.rb +9 -4
  61. data/lib/bosh/director/deployment_plan/links/link_lookup.rb +23 -15
  62. data/lib/bosh/director/deployment_plan/links/link_path.rb +168 -15
  63. data/lib/bosh/director/deployment_plan/links/links_resolver.rb +34 -32
  64. data/lib/bosh/director/deployment_plan/links/template_link.rb +28 -8
  65. data/lib/bosh/director/deployment_plan/manifest_validator.rb +1 -1
  66. data/lib/bosh/director/deployment_plan/network_settings.rb +27 -13
  67. data/lib/bosh/director/deployment_plan/package_validator.rb +9 -5
  68. data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +4 -4
  69. data/lib/bosh/director/deployment_plan/planner.rb +31 -7
  70. data/lib/bosh/director/deployment_plan/planner_factory.rb +147 -6
  71. data/lib/bosh/director/deployment_plan/runtime_manifest_parser.rb +142 -0
  72. data/lib/bosh/director/deployment_plan/stemcell.rb +2 -2
  73. data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +3 -2
  74. data/lib/bosh/director/deployment_plan/template.rb +93 -8
  75. data/lib/bosh/director/deployment_plan/update_config.rb +10 -0
  76. data/lib/bosh/director/deployment_plan/vm_extension.rb +27 -0
  77. data/lib/bosh/director/errand/runner.rb +1 -1
  78. data/lib/bosh/director/errors.rb +11 -1
  79. data/lib/bosh/director/instance_updater.rb +46 -57
  80. data/lib/bosh/director/instance_updater/instance_state.rb +9 -0
  81. data/lib/bosh/director/instance_updater/state_applier.rb +18 -5
  82. data/lib/bosh/director/job_queue.rb +2 -2
  83. data/lib/bosh/director/job_renderer.rb +2 -2
  84. data/lib/bosh/director/job_updater.rb +7 -1
  85. data/lib/bosh/director/jobs/attach_disk.rb +2 -2
  86. data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +6 -1
  87. data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +14 -3
  88. data/lib/bosh/director/jobs/export_release.rb +1 -1
  89. data/lib/bosh/director/jobs/fetch_logs.rb +1 -4
  90. data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +1 -2
  91. data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +0 -16
  92. data/lib/bosh/director/jobs/release/release_job.rb +7 -7
  93. data/lib/bosh/director/jobs/run_errand.rb +5 -5
  94. data/lib/bosh/director/jobs/ssh.rb +3 -3
  95. data/lib/bosh/director/jobs/update_deployment.rb +41 -5
  96. data/lib/bosh/director/jobs/update_release.rb +78 -82
  97. data/lib/bosh/director/jobs/update_stemcell.rb +1 -1
  98. data/lib/bosh/director/jobs/vm_state.rb +34 -21
  99. data/lib/bosh/director/key_generator.rb +54 -0
  100. data/lib/bosh/director/lock.rb +2 -2
  101. data/lib/bosh/director/log_bundles_cleaner.rb +1 -0
  102. data/lib/bosh/director/manifest/changeset.rb +39 -22
  103. data/lib/bosh/director/manifest/diff_lines.rb +1 -27
  104. data/lib/bosh/director/manifest/manifest.rb +22 -7
  105. data/lib/bosh/director/manifest/redactor.rb +44 -0
  106. data/lib/bosh/director/models.rb +1 -0
  107. data/lib/bosh/director/models/compiled_package.rb +21 -15
  108. data/lib/bosh/director/models/deployment.rb +10 -0
  109. data/lib/bosh/director/models/instance.rb +2 -1
  110. data/lib/bosh/director/models/release_version.rb +0 -16
  111. data/lib/bosh/director/models/runtime_config.rb +19 -0
  112. data/lib/bosh/director/models/template.rb +4 -4
  113. data/lib/bosh/director/package_dependencies_manager.rb +22 -0
  114. data/lib/bosh/director/password_helper.rb +18 -0
  115. data/lib/bosh/director/permission_authorizer.rb +50 -30
  116. data/lib/bosh/director/post_deployment_script_runner.rb +40 -0
  117. data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -2
  118. data/lib/bosh/director/problem_resolver.rb +8 -2
  119. data/lib/bosh/director/problem_scanner/scanner.rb +1 -1
  120. data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +1 -1
  121. data/lib/bosh/director/validation_helper.rb +5 -5
  122. data/lib/bosh/director/version.rb +1 -1
  123. data/lib/bosh/director/vm_creator.rb +8 -0
  124. data/lib/cloud/dummy.rb +1 -0
  125. metadata +51 -19
  126. data/lib/bosh/director/api/vm_state_manager.rb +0 -9
  127. data/lib/bosh/director/compiled_package/blob_sha_mismatch_error.rb +0 -5
  128. data/lib/bosh/director/compiled_package/compiled_package.rb +0 -30
@@ -61,7 +61,7 @@ module Bosh::Director
61
61
  stemcell_manifest = Psych.load_file(stemcell_manifest_file)
62
62
 
63
63
  @name = safe_property(stemcell_manifest, "name", :class => String)
64
- @operating_system = safe_property(stemcell_manifest, "operating_system", :class => String, :optional => true)
64
+ @operating_system = safe_property(stemcell_manifest, "operating_system", :class => String, :optional => true, :default => @name)
65
65
  @version = safe_property(stemcell_manifest, "version", :class => String)
66
66
  @cloud_properties = safe_property(stemcell_manifest, "cloud_properties", :class => Hash, :optional => true)
67
67
  @sha1 = safe_property(stemcell_manifest, "sha1", :class => String)
@@ -9,13 +9,15 @@ module Bosh::Director
9
9
  :vms
10
10
  end
11
11
 
12
- def initialize(deployment_id, format)
12
+ def initialize(deployment_id, format, state_for_missing_vms = false)
13
13
  @deployment_id = deployment_id
14
14
  @format = format
15
+ @state_for_missing_vms = state_for_missing_vms
15
16
  end
16
17
 
17
18
  def perform
18
- instances = Models::Instance.filter(:deployment_id => @deployment_id).exclude(vm_cid: nil)
19
+ instances = Models::Instance.filter(:deployment_id => @deployment_id)
20
+ instances = instances.exclude(vm_cid: nil) unless @state_for_missing_vms
19
21
  ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
20
22
  instances.each do |instance|
21
23
  pool.process do
@@ -30,27 +32,9 @@ module Bosh::Director
30
32
  end
31
33
 
32
34
  def process_instance(instance)
33
- ips = []
34
35
  dns_records = []
35
- job_state = nil
36
- job_vitals = nil
37
- processes = []
38
36
 
39
- begin
40
- agent = AgentClient.with_vm_credentials_and_agent_id(instance.credentials, instance.agent_id, :timeout => TIMEOUT)
41
- agent_state = agent.get_state(@format)
42
- agent_state['networks'].each_value do |network|
43
- ips << network['ip']
44
- end
45
-
46
- job_state = agent_state['job_state']
47
- if agent_state['vitals']
48
- job_vitals = agent_state['vitals']
49
- end
50
- processes = agent_state['processes'] if agent_state['processes']
51
- rescue Bosh::Director::RpcTimeout
52
- job_state = 'unresponsive agent'
53
- end
37
+ job_state, job_vitals, processes, ips = vm_details(instance)
54
38
 
55
39
  if dns_manager.dns_enabled?
56
40
  dns_records = dns_manager.find_dns_record_names_by_instance(instance)
@@ -81,6 +65,35 @@ module Bosh::Director
81
65
 
82
66
  private
83
67
 
68
+ def vm_details(instance)
69
+ ips = []
70
+ processes = []
71
+ job_vitals = nil
72
+ job_state = nil
73
+
74
+ if instance.vm_cid
75
+ begin
76
+ agent = AgentClient.with_vm_credentials_and_agent_id(instance.credentials, instance.agent_id, :timeout => TIMEOUT)
77
+ agent_state = agent.get_state(@format)
78
+ agent_state['networks'].each_value do |network|
79
+ ips << network['ip']
80
+ end
81
+
82
+ job_state = agent_state['job_state']
83
+ if agent_state['vitals']
84
+ job_vitals = agent_state['vitals']
85
+ end
86
+ processes = agent_state['processes'] if agent_state['processes']
87
+ rescue Bosh::Director::RpcTimeout
88
+ job_state = 'unresponsive agent'
89
+ end
90
+ else
91
+ job_state = 'missing vm'
92
+ end
93
+
94
+ return job_state, job_vitals, processes, ips
95
+ end
96
+
84
97
  def get_index(agent_state)
85
98
  index = agent_state['index']
86
99
 
@@ -0,0 +1,54 @@
1
+ module Bosh
2
+ module Director
3
+ class KeyGenerator
4
+ def dependency_key_from_models(package, release_version)
5
+ @all_packages = release_version.packages.map do |p|
6
+ {
7
+ 'name' => p.name,
8
+ 'version' => p.version,
9
+ 'dependencies' => p.dependency_set
10
+ }
11
+ end
12
+
13
+ root_package_hash = {'name' => package.name, 'version' => package.version, 'dependencies' => package.dependency_set}
14
+ package_hashes = PackageDependenciesManager.new(release_version).transitive_dependencies(package)
15
+
16
+ root_package_hash['dependencies'].sort.map do |dependency_name|
17
+ arrayify(find_package_hash(dependency_name), package_hashes.dup)
18
+ end.to_json
19
+ end
20
+
21
+ def dependency_key_from_manifest(package_name, compiled_packages)
22
+ @all_packages = compiled_packages
23
+ package = compiled_packages.find { |package| package['name'] == package_name }
24
+ raise ReleaseExistingPackageHashMismatch, "Package '#{package_name}' not found in the release manifest." if package.nil?
25
+
26
+ package['dependencies'].sort.map do |dependency_name|
27
+ arrayify(find_package_hash(dependency_name), all_packages.dup)
28
+ end.to_json
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :all_packages
34
+
35
+ def arrayify(package, remaining_packages)
36
+ remaining_packages.delete(package)
37
+
38
+ [
39
+ package['name'],
40
+ package['version']
41
+ ].tap do |output|
42
+ if package['dependencies'] && package['dependencies'].length > 0
43
+ output << package['dependencies'].sort.map { |sub_dep| arrayify(find_package_hash(sub_dep), remaining_packages) }
44
+ end
45
+ output
46
+ end
47
+ end
48
+
49
+ def find_package_hash(name)
50
+ all_packages.find { |package| package['name'] == name }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -34,7 +34,7 @@ module Bosh::Director
34
34
  sleep_interval = [1.0, @expiration/2].max
35
35
  begin
36
36
  loop do
37
- @logger.debug("Renewing lock: #@name")
37
+ @logger.debug("Renewing lock: #@name, id: #@id")
38
38
  redis.watch(@name)
39
39
  existing_lock = redis.get(@name)
40
40
  lock_id = existing_lock.split(":")[1]
@@ -82,7 +82,7 @@ module Bosh::Director
82
82
  "else: #{existing_lock}")
83
83
  if lock_expired?(existing_lock)
84
84
  @logger.debug("Lock #@name is already expired, " +
85
- "trying to take it back")
85
+ "trying to take it back, id: #@id")
86
86
  replaced_lock = redis.getset(@name, "#{lock_expiration}:#@id")
87
87
  if replaced_lock == existing_lock
88
88
  @logger.debug("Lock #@name was revoked and relocked")
@@ -1,5 +1,6 @@
1
1
  module Bosh::Director
2
2
  class LogBundlesCleaner
3
+
3
4
  def initialize(blobstore, log_bundle_ttl, logger)
4
5
  @blobstore = blobstore
5
6
  @bundle_lifetime = log_bundle_ttl
@@ -9,9 +9,14 @@ module Bosh::Director
9
9
  class Changeset
10
10
  KEY_NAME = 'name'
11
11
 
12
- def initialize(before, after)
12
+ def initialize(before, after, redact = true, redacted_before = nil, redacted_after = nil)
13
+ @redact = redact
14
+ @redacted_before = redacted_before.nil? ? Redactor.redact_properties(Bosh::Common::DeepCopy.copy(before), redact) : redacted_before
15
+ @redacted_after = redacted_after.nil? ? Redactor.redact_properties(Bosh::Common::DeepCopy.copy(after), redact) : redacted_after
16
+
13
17
  @before = before
14
18
  @after = after
19
+
15
20
  if @before && @after
16
21
  @merged = @before.deep_merge(@after)
17
22
  elsif @before
@@ -26,16 +31,16 @@ module Bosh::Director
26
31
 
27
32
  @merged.each_pair do |key, value|
28
33
  if @before.nil? || @before[key].nil?
29
- lines.concat(yaml_lines({key => value}, indent, 'added'))
34
+ lines.concat(yaml_lines({key => @redacted_after[key]}, indent, 'added'))
30
35
 
31
36
  elsif @after.nil? || @after[key].nil?
32
- lines.concat(yaml_lines({key => value}, indent, 'removed'))
37
+ lines.concat(yaml_lines({key => @redacted_before[key]}, indent, 'removed'))
33
38
 
34
39
  elsif @before[key].is_a?(Array) && @after[key].is_a?(Array)
35
- lines.concat(compare_arrays(@before[key], @after[key], key, indent))
40
+ lines.concat(compare_arrays(@before[key], @after[key], @redacted_before[key], @redacted_after[key], key, indent))
36
41
 
37
42
  elsif value.is_a?(Hash)
38
- changeset = Changeset.new(@before[key], @after[key])
43
+ changeset = Changeset.new(@before[key], @after[key],@redact, @redacted_before[key], @redacted_after[key])
39
44
  diff_lines = changeset.diff(indent+1)
40
45
  unless diff_lines.empty?
41
46
  lines << Line.new(indent, "#{key}:", nil)
@@ -43,8 +48,8 @@ module Bosh::Director
43
48
  end
44
49
 
45
50
  elsif @before[key] != @after[key]
46
- lines << Line.new(indent, "#{key}: #{@before[key]}", 'removed')
47
- lines << Line.new(indent, "#{key}: #{@after[key]}", 'added')
51
+ lines.concat(yaml_lines({key => @redacted_before[key]}, indent, 'removed'))
52
+ lines.concat(yaml_lines({key => @redacted_after[key]}, indent, 'added'))
48
53
  end
49
54
  end
50
55
  lines
@@ -58,51 +63,63 @@ module Bosh::Director
58
63
  lines
59
64
  end
60
65
 
61
- def compare_arrays(old_value, new_value, parent_name, indent)
62
- added = new_value - old_value
63
- removed = old_value - new_value
66
+ def compare_arrays(old_value, new_value, redacted_old_value, redacted_new_value, parent_name, indent)
67
+ # combine arrays of redacted and unredacted values. unredacted arrays for diff logic, and redacted arrays for output
68
+ combined_old_value = old_value.zip redacted_old_value
69
+ combined_new_value = new_value.zip redacted_new_value
70
+
71
+ added = combined_new_value - combined_old_value
72
+ removed = combined_old_value - combined_new_value
64
73
 
65
74
  lines = DiffLines.new
66
75
 
67
- added.each do |elem|
76
+ added.each do |pair|
77
+
78
+ elem = pair.first
79
+ redacted_elem = pair.last
80
+
68
81
  if elem.is_a?(Hash)
69
- using_names = (added+removed).all? { |e| e['name'] }
70
- using_ranges = (added+removed).all? { |e| e['range'] }
82
+ using_names = (added+removed).all? { |e| e.first['name'] }
83
+
84
+ using_ranges = (added+removed).all? { |e| e.first['range'] }
71
85
  if using_names || using_ranges
86
+ #clean up duplicate values
72
87
  if using_names
73
- removed_same_name_element = removed.find { |e| e['name'] == elem['name'] }
88
+ removed_same_name_element = removed.find { |e| e.first['name'] == elem['name'] }
74
89
  elsif using_ranges
75
- removed_same_name_element = removed.find { |e| e['range'] == elem['range'] }
90
+ removed_same_name_element = removed.find { |e| e.first['range'] == elem['range'] }
76
91
  end
77
92
  removed.delete(removed_same_name_element)
78
93
 
79
94
  if removed_same_name_element
80
- changeset = Changeset.new(removed_same_name_element, elem)
95
+ changeset = Changeset.new(removed_same_name_element.first, elem, @redact, removed_same_name_element.last, redacted_elem)
81
96
  diff_lines = changeset.diff(indent+1)
82
97
 
83
98
  unless diff_lines.empty?
84
99
  # write name if elem has been changed
85
100
  if using_names
86
- lines.concat(yaml_lines([{'name' => elem['name']}], indent, nil))
101
+ lines.concat(yaml_lines([{'name' => redacted_elem['name']}], indent, nil))
87
102
  elsif using_ranges
88
- lines.concat(yaml_lines([{'range' => elem['range']}], indent, nil))
103
+ lines.concat(yaml_lines([{'range' => redacted_elem['range']}], indent, nil))
89
104
  end
90
105
  lines.concat(diff_lines)
91
106
  end
92
107
  else
93
- lines.concat(yaml_lines([elem], indent, 'added'))
108
+ lines.concat(yaml_lines([redacted_elem], indent, 'added'))
94
109
  end
95
110
 
96
111
  else
97
- lines.concat(yaml_lines([elem], indent, 'added'))
112
+ lines.concat(yaml_lines([redacted_elem], indent, 'added'))
98
113
  end
99
114
  else
100
- lines.concat(yaml_lines([elem], indent, 'added'))
115
+ lines.concat(yaml_lines([redacted_elem], indent, 'added'))
101
116
  end
102
117
  end
103
118
 
104
119
  unless removed.empty?
105
- lines.concat(yaml_lines(removed, indent, 'removed'))
120
+ redacted_removed = []
121
+ removed.each do |pair| redacted_removed.push(pair.last) end
122
+ lines.concat(yaml_lines(redacted_removed, indent, 'removed'))
106
123
  end
107
124
 
108
125
  unless lines.empty?
@@ -26,11 +26,7 @@ module Bosh::Director
26
26
  releases
27
27
  update
28
28
  jobs
29
- )
30
-
31
- REDACT_KEY_NAMES = %w(
32
- properties
33
- bosh
29
+ addons
34
30
  )
35
31
 
36
32
  def order
@@ -62,27 +58,5 @@ module Bosh::Director
62
58
 
63
59
  self.replace(ordered_lines)
64
60
  end
65
-
66
- def redact_properties
67
- i = 0
68
- while i < self.size
69
- line = self[i]
70
-
71
- if REDACT_KEY_NAMES.any? { |key_name| line.text =~ /\b#{key_name}:/ }
72
- properties_indent = line.full_indent
73
- i += 1
74
- line = self[i]
75
-
76
- while line && line.full_indent > properties_indent
77
- line.text.gsub!(/: .+/, ': <redacted>') # readact hash values
78
- line.text.gsub!(/- [^:]+$/, '- <redacted>') # redact array values
79
- i += 1
80
- line = self[i]
81
- end
82
- end
83
- i += 1
84
- end
85
- self
86
- end
87
61
  end
88
62
  end
@@ -1,16 +1,20 @@
1
+ require 'set'
2
+
1
3
  module Bosh::Director
2
4
  class Manifest
3
- def self.load_from_text(manifest_text, cloud_config)
5
+ def self.load_from_text(manifest_text, cloud_config, runtime_config)
4
6
  cloud_config_hash = cloud_config.nil? ? nil : cloud_config.manifest
7
+ runtime_config_hash = runtime_config.nil? ? nil : runtime_config.manifest
5
8
  manifest_hash = manifest_text.nil? ? {} : Psych.load(manifest_text)
6
- new(manifest_hash, cloud_config_hash)
9
+ new(manifest_hash, cloud_config_hash, runtime_config_hash)
7
10
  end
8
11
 
9
- attr_reader :manifest_hash, :cloud_config_hash
12
+ attr_reader :manifest_hash, :cloud_config_hash, :runtime_config_hash
10
13
 
11
- def initialize(manifest_hash, cloud_config_hash)
14
+ def initialize(manifest_hash, cloud_config_hash, runtime_config_hash)
12
15
  @manifest_hash = manifest_hash
13
16
  @cloud_config_hash = cloud_config_hash
17
+ @runtime_config_hash = runtime_config_hash
14
18
  end
15
19
 
16
20
  def resolve_aliases
@@ -28,12 +32,23 @@ module Bosh::Director
28
32
  end
29
33
  end
30
34
 
31
- def diff(other_manifest)
32
- Changeset.new(to_hash, other_manifest.to_hash).diff.order.redact_properties
35
+ def diff(other_manifest, redact)
36
+ Changeset.new(to_hash, other_manifest.to_hash, redact).diff.order
33
37
  end
34
38
 
35
39
  def to_hash
36
- @manifest_hash.merge(@cloud_config_hash || {})
40
+ hash = @manifest_hash.merge(@cloud_config_hash || {})
41
+ hash.merge(@runtime_config_hash || {}) do |key, old, new|
42
+ if key == 'releases'
43
+ if old && new
44
+ old.to_set.merge(new.to_set).to_a
45
+ else
46
+ old.nil? ? new : old
47
+ end
48
+ else
49
+ new
50
+ end
51
+ end
37
52
  end
38
53
 
39
54
  private
@@ -0,0 +1,44 @@
1
+ module Bosh::Director
2
+ class Redactor
3
+ REDACT_KEY_NAMES = %w(
4
+ properties
5
+ bosh
6
+ )
7
+
8
+ def self.redact_properties(obj, redact = true ,redact_key_is_ancestor = false)
9
+ return obj unless redact
10
+ if redact_key_is_ancestor
11
+ if obj.respond_to?(:key?)
12
+ obj.keys.each{ |key|
13
+ if obj[key].respond_to?(:each)
14
+ redact_properties(obj[key], redact, true)
15
+ else
16
+ obj[key] = '<redacted>'
17
+ end
18
+ }
19
+ elsif obj.respond_to?(:each_index)
20
+ obj.each_index { |i|
21
+ if obj[i].respond_to?(:each)
22
+ redact_properties(obj[i], redact, true)
23
+ else
24
+ obj[i] = '<redacted>'
25
+ end
26
+ }
27
+ end
28
+ else
29
+ if obj.respond_to?(:each)
30
+ obj.each{ |a|
31
+ if obj.respond_to?(:key?) && REDACT_KEY_NAMES.any? { |key| key == a.first } && a.last.respond_to?(:key?)
32
+ redact_properties(a.last, redact, true)
33
+ else
34
+ redact_properties(a.respond_to?(:last) ? a.last : a, redact)
35
+ end
36
+
37
+ }
38
+ end
39
+ end
40
+
41
+ obj
42
+ end
43
+ end
44
+ end
@@ -2,6 +2,7 @@
2
2
  #
3
3
 
4
4
  require 'bosh/director/models/cloud_config'
5
+ require 'bosh/director/models/runtime_config'
5
6
  require 'bosh/director/models/compiled_package'
6
7
  require 'bosh/director/models/deployment'
7
8
  require 'bosh/director/models/deployment_problem'