bosh_cli 1.3001.0 → 1.3003.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f21a6d034215d86da7746b2ce276bf08be43b72
4
- data.tar.gz: 058c7ec3e9f97e5178a3087e6a851a8c8bef4ed8
3
+ metadata.gz: ce5adb0bf07eb205144b59a5503f2831cd6c4706
4
+ data.tar.gz: 9d39b975d52d3183e8c636a7c5d72cd4f185c76a
5
5
  SHA512:
6
- metadata.gz: a870aed8adc35d7fd4e8893f7736a7245130bfc9a7dca6ba5fd65dd6b2bb72af939ccd4a348bc9d0617f90e3c02dac29145c150d5afb9d2a408d712a570e4327
7
- data.tar.gz: 8c545256e4df5ddb77fc838fa8cf90432c77e86dbc5d6585d9d0d1d46e74a3c3fa11fba95ae5ef5bd1916a82e302121337f35d2bbad57c3670b147281f085df6
6
+ metadata.gz: 3cb26f22b9460558b5382088276075387f8b1d09a5595b06caf258a011b1c1bd87d3ded85ccb937d4865e1e0b2db6369e3541bfd483903edf432f225e0dabb70
7
+ data.tar.gz: 272037c9bfe1d1ca829d7a1af260604f070b773000417d7bbe3a862a8283dc603dc9083ee78dcc463b880c389dd1fa8605a0536d941bf168aea40010eb01d823
data/lib/cli.rb CHANGED
@@ -56,6 +56,7 @@ require 'cli/glob_match'
56
56
  require 'cli/yaml_helper'
57
57
  require 'cli/dependency_helper'
58
58
  require 'cli/deployment_manifest'
59
+ require 'cli/manifest'
59
60
  require 'cli/manifest_warnings'
60
61
  require 'cli/deployment_helper'
61
62
  require 'cli/validation'
@@ -122,6 +122,14 @@ module Bosh::Cli
122
122
  File.join(Dir.home, '.bosh', 'cache')
123
123
  end
124
124
 
125
+ def show_current_state(deployment_name=nil)
126
+ user_desc = auth_info.client_auth? ? 'client' : 'user'
127
+ msg = "Acting as #{user_desc} '#{credentials.username.to_s.make_green}'"
128
+ msg += " on deployment '#{deployment_name.make_green}'" if deployment_name
129
+ msg += " on '#{target_name.make_green}'" if target_name
130
+ say(msg)
131
+ end
132
+
125
133
  protected
126
134
 
127
135
  def auth_info
@@ -187,14 +195,6 @@ module Bosh::Cli
187
195
  say("Current deployment is #{deployment.make_green}")
188
196
  end
189
197
 
190
- def show_current_state(deployment_name=nil)
191
- user_desc = auth_info.client_auth? ? 'client' : 'user'
192
- msg = "Acting as #{user_desc} '#{credentials.username.to_s.make_green}'"
193
- msg += " on deployment '#{deployment_name.make_green}'" if deployment_name
194
- msg += " on '#{target_name.make_green}'" if target_name
195
- say(msg)
196
- end
197
-
198
198
  def no_track_unsupported
199
199
  if @options.delete(:no_track)
200
200
  say('Ignoring `' + '--no-track'.make_yellow + "' option")
@@ -232,8 +232,8 @@ module Bosh::Cli
232
232
  end
233
233
  end
234
234
 
235
- def valid_index_for(job, index, options = {})
236
- index = '0' if job_unique_in_deployment?(job)
235
+ def valid_index_for(manifest_hash, job, index, options = {})
236
+ index = '0' if job_unique_in_deployment?(manifest_hash, job)
237
237
  err('You should specify the job index. There is more than one instance of this job type.') if index.nil?
238
238
  index = index.to_i if options[:integer_index]
239
239
  index
@@ -39,7 +39,7 @@ module Bosh
39
39
  end
40
40
 
41
41
  def refresh(access_info)
42
- with_save { @token_issuer.refresh(access_info) }
42
+ @token_issuer.refresh(access_info)
43
43
  rescue CF::UAA::TargetError
44
44
  nil
45
45
  end
@@ -13,12 +13,12 @@ module Bosh::Cli::Command
13
13
  "don't attempt to resolve problems"
14
14
  def perform(deployment_name = nil)
15
15
  auth_required
16
- show_current_state(deployment_name)
17
-
18
16
  no_track_unsupported
19
17
  @auto_mode = options[:auto]
20
18
  @report_mode = options[:report]
21
19
 
20
+ deployment_name ||= prepare_deployment_manifest(show_state: true).name
21
+
22
22
  if non_interactive? && !(@report_mode || @auto_mode)
23
23
  err ("Cloudcheck cannot be run in non-interactive mode\n" +
24
24
  "Please use `--auto' flag if you want automated resolutions " +
@@ -29,8 +29,8 @@ module Bosh::Cli::Command
29
29
  err("Can't use --auto and --report mode together")
30
30
  end
31
31
 
32
+
32
33
  say("Performing cloud check...")
33
- deployment_name ||= prepare_deployment_manifest["name"]
34
34
 
35
35
  status, task_id = director.perform_cloud_scan(deployment_name)
36
36
 
@@ -23,7 +23,7 @@ module Bosh::Cli::Command
23
23
  end
24
24
 
25
25
  unless manifest["target"].blank?
26
- err(manifest_target_upgrade_notice)
26
+ err(Bosh::Cli::Manifest::MANIFEST_TARGET_UPGRADE_NOTICE)
27
27
  end
28
28
 
29
29
  if manifest["director_uuid"].blank?
@@ -86,27 +86,24 @@ module Bosh::Cli::Command
86
86
  recreate = !!options[:recreate]
87
87
  redact_diff = !!options[:redact_diff]
88
88
 
89
- manifest = prepare_deployment_manifest(resolve_properties: true)
90
- manifest_yaml = Psych.dump(manifest)
89
+ manifest = prepare_deployment_manifest(resolve_properties: true, show_state: true)
91
90
 
92
91
  inspect_deployment_changes(
93
- Psych.load(manifest_yaml),
92
+ manifest.hash,
94
93
  interactive: interactive?,
95
94
  redact_diff: redact_diff
96
95
  )
97
96
  say('Please review all changes carefully'.make_yellow) if interactive?
98
97
 
99
98
  header('Deploying')
100
- deployment_name = manifest['name']
101
- show_current_state(deployment_name)
102
99
 
103
100
  unless confirmed?('Are you sure you want to deploy?')
104
101
  cancel_deployment
105
102
  end
106
103
 
107
- status, task_id = director.deploy(manifest_yaml, :recreate => recreate)
104
+ status, task_id = director.deploy(manifest.yaml, :recreate => recreate)
108
105
 
109
- task_report(status, task_id, "Deployed `#{deployment_name.make_green}' to `#{target_name.make_green}'")
106
+ task_report(status, task_id, "Deployed `#{manifest.name.make_green}' to `#{target_name.make_green}'")
110
107
  end
111
108
 
112
109
  # bosh delete deployment
@@ -142,14 +139,14 @@ module Bosh::Cli::Command
142
139
  "deployment manifest as the source of properties"
143
140
  def validate_jobs
144
141
  check_if_release_dir
145
- manifest = prepare_deployment_manifest(:resolve_properties => true)
142
+ manifest = prepare_deployment_manifest(:resolve_properties => true, show_state: true)
146
143
 
147
- if manifest["release"]
148
- release_name = manifest["release"]["name"]
149
- elsif manifest["releases"].count > 1
144
+ if manifest.hash["release"]
145
+ release_name = manifest.hash["release"]["name"]
146
+ elsif manifest.hash["releases"].count > 1
150
147
  err("Cannot validate a deployment manifest with more than 1 release")
151
148
  else
152
- release_name = manifest["releases"].first["name"]
149
+ release_name = manifest.hash["releases"].first["name"]
153
150
  end
154
151
  if release_name == release.dev_name || release_name == release.final_name
155
152
  nl
@@ -169,7 +166,7 @@ module Bosh::Cli::Command
169
166
  )
170
167
 
171
168
  say(" - validating properties")
172
- validator = Bosh::Cli::JobPropertyValidator.new(jobs, manifest)
169
+ validator = Bosh::Cli::JobPropertyValidator.new(jobs, manifest.hash)
173
170
  validator.validate
174
171
 
175
172
  unless validator.jobs_without_properties.empty?
@@ -38,8 +38,7 @@ module Bosh::Cli::Command
38
38
 
39
39
  private
40
40
  def perform_run_errand(errand_name)
41
- deployment_name = prepare_deployment_manifest['name']
42
- show_current_state(deployment_name)
41
+ deployment_name = prepare_deployment_manifest(show_state: true).name
43
42
 
44
43
  errands_client = Bosh::Cli::Client::ErrandsClient.new(director)
45
44
  status, task_id, errand_result = errands_client.run_errand(deployment_name, errand_name, options[:keep_alive] || FALSE)
@@ -48,9 +48,11 @@ module Bosh::Cli
48
48
  private
49
49
 
50
50
  def change_job_state(state, job, index = nil)
51
- check_arguments(state, job)
52
- index = valid_index_for(job, index)
53
- vm_state = VmState.new(self, force?)
51
+ auth_required
52
+ manifest = parse_manifest(state, job)
53
+
54
+ index = valid_index_for(manifest.hash, job, index)
55
+ vm_state = VmState.new(self, manifest, force?)
54
56
  job_state = JobState.new(self, vm_state)
55
57
  status, task_id, completion_desc = job_state.change(state, job, index)
56
58
  task_report(status, task_id, completion_desc)
@@ -68,10 +70,9 @@ module Bosh::Cli
68
70
  options[:force]
69
71
  end
70
72
 
71
- def check_arguments(operation, job)
72
- auth_required
73
- job_must_exist_in_deployment(job)
74
- show_current_state(prepare_deployment_manifest['name'])
73
+ def parse_manifest(operation, job)
74
+ manifest = prepare_deployment_manifest(show_state: true)
75
+ job_must_exist_in_deployment(manifest.hash, job)
75
76
 
76
77
  if hard? && soft?
77
78
  err('Cannot handle both --hard and --soft options, please choose one')
@@ -80,6 +81,8 @@ module Bosh::Cli
80
81
  if !hard_and_soft_options_allowed?(operation) && (hard? || soft?)
81
82
  err("--hard and --soft options only make sense for `stop' operation")
82
83
  end
84
+
85
+ manifest
83
86
  end
84
87
 
85
88
  def hard_and_soft_options_allowed?(operation)
@@ -7,9 +7,7 @@ module Bosh::Cli::Command
7
7
  option "--force", "Ignore errors"
8
8
  def rename(old_name, new_name)
9
9
  auth_required
10
- manifest_yaml = prepare_deployment_manifest(:yaml => true)
11
- manifest = Psych.load(manifest_yaml)
12
- show_current_state(manifest['name'])
10
+ manifest = prepare_deployment_manifest(show_state: true)
13
11
 
14
12
  force = options[:force]
15
13
  say("You are about to rename `#{old_name.make_green}' to `#{new_name.make_green}'")
@@ -20,18 +18,17 @@ module Bosh::Cli::Command
20
18
  exit(0)
21
19
  end
22
20
 
23
- sanity_check_job_rename(manifest_yaml, old_name, new_name)
21
+ sanity_check_job_rename(manifest, old_name, new_name)
24
22
 
25
23
  status, task_id = director.rename_job(
26
- manifest["name"], manifest_yaml, old_name, new_name, force)
24
+ manifest.name, manifest.yaml, old_name, new_name, force)
27
25
 
28
26
  task_report(status, task_id, "Rename successful")
29
27
  end
30
28
 
31
- def sanity_check_job_rename(manifest_yaml, old_name, new_name)
29
+ def sanity_check_job_rename(manifest, old_name, new_name)
32
30
  # Makes sure the new deployment manifest contains the renamed job
33
- manifest = Psych.load(manifest_yaml)
34
- new_jobs = manifest["jobs"].map { |job| job["name"] }
31
+ new_jobs = manifest.hash["jobs"].map { |job| job["name"] }
35
32
  unless new_jobs.include?(new_name)
36
33
  err("Please update your deployment manifest to include the " +
37
34
  "new job name `#{new_name}'")
@@ -43,7 +40,7 @@ module Bosh::Cli::Command
43
40
  end
44
41
 
45
42
  # Make sure that the old deployment manifest contains the old job
46
- current_deployment = director.get_deployment(manifest["name"])
43
+ current_deployment = director.get_deployment(manifest.name)
47
44
  if current_deployment["manifest"].nil?
48
45
  err("Director could not find manifest for deployment " +
49
46
  "`#{manifest["name"]}'")
@@ -96,8 +93,7 @@ module Bosh::Cli::Command
96
93
  end
97
94
 
98
95
  # Now the manifests should be the same
99
- manifest = Psych.load(manifest_yaml)
100
- if deployment_changed?(current_manifest.dup, manifest.dup)
96
+ if deployment_changed?(current_manifest.dup, manifest.hash.dup)
101
97
  err("You cannot have any other changes to your manifest during " +
102
98
  "rename. Please revert the above changes and retry.")
103
99
  end
@@ -12,17 +12,20 @@ module Bosh::Cli::Command
12
12
  option '--all', 'deprecated'
13
13
 
14
14
  def fetch_logs(job, index = nil)
15
- index = valid_index_for(job, index)
15
+ auth_required
16
+
17
+ manifest = prepare_deployment_manifest(show_state: true)
18
+ index = valid_index_for(manifest.hash, job, index)
16
19
  check_arguments(index)
17
20
 
18
21
  logs_downloader = Bosh::Cli::LogsDownloader.new(director, self)
19
22
 
20
- resource_id = fetch_log_resource_id(index, job)
23
+ resource_id = fetch_log_resource_id(manifest.name, index, job)
21
24
  logs_path = logs_downloader.build_destination_path(job, index, options[:dir] || Dir.pwd)
22
25
  logs_downloader.download(resource_id, logs_path)
23
26
  end
24
27
 
25
- def fetch_log_resource_id(index, job)
28
+ def fetch_log_resource_id(deployment_name, index, job)
26
29
  resource_id = director.fetch_logs(deployment_name, job, index, log_type, filters)
27
30
  err('Error retrieving logs') if resource_id.nil?
28
31
 
@@ -40,8 +43,6 @@ module Bosh::Cli::Command
40
43
  end
41
44
 
42
45
  def check_arguments(index)
43
- auth_required
44
- show_current_state(deployment_name)
45
46
  no_track_unsupported
46
47
 
47
48
  err('Job index is expected to be a positive integer') if index !~ /^\d+$/
@@ -73,10 +74,6 @@ module Bosh::Cli::Command
73
74
  end
74
75
  filter
75
76
  end
76
-
77
- def deployment_name
78
- @deployment_name ||= prepare_deployment_manifest['name']
79
- end
80
77
  end
81
78
  end
82
79
 
@@ -121,9 +121,7 @@ module Bosh::Cli::Command
121
121
 
122
122
  def prepare
123
123
  auth_required
124
- manifest = prepare_deployment_manifest
125
- @deployment_name = manifest["name"]
126
- show_current_state(@deployment_name)
124
+ @deployment_name = prepare_deployment_manifest(show_state: true).name
127
125
  end
128
126
 
129
127
  def show_header
@@ -11,18 +11,16 @@ module Bosh::Cli::Command
11
11
 
12
12
  def export(release, stemcell)
13
13
  auth_required
14
- deployment_required
15
- show_current_state
14
+ manifest = prepare_deployment_manifest(show_state: true)
16
15
 
17
- deployment_name = prepare_deployment_manifest["name"]
18
16
  release = Bosh::Cli::NameVersionPair.parse(release)
19
17
  stemcell = Bosh::Cli::NameVersionPair.parse(stemcell)
20
18
  stemcell_os = stemcell.name
21
19
 
22
20
  client = Bosh::Cli::Client::ExportReleaseClient.new(director)
23
- status, task_id = client.export(deployment_name, release.name, release.version, stemcell_os, stemcell.version)
21
+ status, task_id = client.export(manifest.name, release.name, release.version, stemcell_os, stemcell.version)
24
22
  task_report(status, task_id)
25
23
  end
26
24
  end
27
25
  end
28
- end
26
+ end
@@ -7,8 +7,7 @@ module Bosh::Cli::Command
7
7
  def list(job = nil, index = nil)
8
8
  auth_required
9
9
 
10
- deployment_name = prepare_deployment_manifest['name']
11
- show_current_state(deployment_name)
10
+ deployment_name = prepare_deployment_manifest(show_state: true).name
12
11
 
13
12
  snapshots = director.list_snapshots(deployment_name, job, index)
14
13
 
@@ -39,8 +38,7 @@ module Bosh::Cli::Command
39
38
  def take(job = nil, index = nil)
40
39
  auth_required
41
40
 
42
- deployment_name = prepare_deployment_manifest['name']
43
- show_current_state(deployment_name)
41
+ deployment_name = prepare_deployment_manifest(show_state: true).name
44
42
 
45
43
  unless job && index
46
44
  unless confirmed?("Are you sure you want to take a snapshot of all deployment `#{deployment_name}'?")
@@ -59,8 +57,7 @@ module Bosh::Cli::Command
59
57
  def delete(snapshot_cid)
60
58
  auth_required
61
59
 
62
- deployment_name = prepare_deployment_manifest['name']
63
- show_current_state(deployment_name)
60
+ deployment_name = prepare_deployment_manifest(show_state: true).name
64
61
 
65
62
  unless confirmed?("Are you sure you want to delete snapshot `#{snapshot_cid}'?")
66
63
  say('Canceled deleting snapshot'.make_green)
@@ -77,8 +74,7 @@ module Bosh::Cli::Command
77
74
  def delete_all
78
75
  auth_required
79
76
 
80
- deployment_name = prepare_deployment_manifest['name']
81
- show_current_state(deployment_name)
77
+ deployment_name = prepare_deployment_manifest(show_state: true).name
82
78
 
83
79
  unless confirmed?("Are you sure you want to delete all snapshots of deployment `#{deployment_name}'?")
84
80
  say('Canceled deleting snapshots'.make_green)
@@ -25,14 +25,16 @@ module Bosh::Cli
25
25
  job, index = prompt_for_job_and_index
26
26
  end
27
27
 
28
- job_must_exist_in_deployment(job)
29
- index = valid_index_for(job, index, integer_index: true)
28
+ manifest = prepare_deployment_manifest(show_state: true)
29
+ job_must_exist_in_deployment(manifest.hash, job)
30
+
31
+ index = valid_index_for(manifest.hash, job, index, integer_index: true)
30
32
 
31
33
  if command.empty?
32
- setup_interactive_shell(job, index)
34
+ setup_interactive_shell(manifest.name, job, index)
33
35
  else
34
36
  say("Executing `#{command.join(' ')}' on #{job}/#{index}")
35
- perform_operation(:exec, job, index, command)
37
+ perform_operation(:exec, manifest.name, job, index, command)
36
38
  end
37
39
  end
38
40
 
@@ -55,13 +57,14 @@ module Bosh::Cli
55
57
  err('Please specify either --upload or --download')
56
58
  end
57
59
 
58
- job_must_exist_in_deployment(job)
60
+ manifest = prepare_deployment_manifest(show_state: true)
61
+ job_must_exist_in_deployment(manifest.hash, job)
59
62
 
60
63
  if args.size != 2
61
64
  err('Please enter valid source and destination paths')
62
65
  end
63
66
  say("Executing file operations on job #{job}")
64
- perform_operation(upload ? :upload : :download, job, index, args)
67
+ perform_operation(upload ? :upload : :download, manifest.name, job, index, args)
65
68
  end
66
69
 
67
70
  usage 'cleanup ssh'
@@ -73,12 +76,11 @@ module Bosh::Cli
73
76
  err("SSH cleanup doesn't accept any extra args")
74
77
  end
75
78
 
76
- job_must_exist_in_deployment(job)
77
-
78
- manifest_name = prepare_deployment_manifest['name']
79
+ manifest = prepare_deployment_manifest(show_state: true)
80
+ job_must_exist_in_deployment(manifest.hash, job)
79
81
 
80
82
  say("Cleaning up ssh artifacts from #{job}/#{index}")
81
- director.cleanup_ssh(manifest_name, job, "^#{SSH_USER_PREFIX}", [index])
83
+ director.cleanup_ssh(manifest.name, job, "^#{SSH_USER_PREFIX}", [index])
82
84
  end
83
85
 
84
86
  private
@@ -106,9 +108,8 @@ module Bosh::Cli
106
108
  # @param [String] job
107
109
  # @param [Integer] index
108
110
  # @param [optional,String] password
109
- def setup_ssh(job, index, password = nil)
111
+ def setup_ssh(deployment_name, job, index, password)
110
112
  user = random_ssh_username
111
- deployment_name = prepare_deployment_manifest['name']
112
113
 
113
114
  say("Target deployment is `#{deployment_name}'")
114
115
  nl
@@ -166,8 +167,7 @@ module Bosh::Cli
166
167
 
167
168
  # @param [String] job Job name
168
169
  # @param [Integer] index Job index
169
- def setup_interactive_shell(job, index)
170
- deployment_required
170
+ def setup_interactive_shell(deployment_name, job, index)
171
171
  password = options[:default_password]
172
172
 
173
173
  if password.nil?
@@ -178,7 +178,7 @@ module Bosh::Cli
178
178
  err('Please provide ssh password') if password.blank?
179
179
  end
180
180
 
181
- setup_ssh(job, index, password) do |sessions, user, gateway|
181
+ setup_ssh(deployment_name, job, index, password) do |sessions, user, gateway|
182
182
  session = sessions.first
183
183
 
184
184
  unless session['status'] == 'success' && session['ip']
@@ -199,8 +199,8 @@ module Bosh::Cli
199
199
  end
200
200
  end
201
201
 
202
- def perform_operation(operation, job, index, args)
203
- setup_ssh(job, index, nil) do |sessions, user, gateway|
202
+ def perform_operation(operation, deployment_name, job, index, args)
203
+ setup_ssh(deployment_name, job, index, nil) do |sessions, user, gateway|
204
204
  sessions.each do |session|
205
205
  unless session['status'] == 'success' && session['ip']
206
206
  err("Failed to set up SSH on #{job}/#{index}: #{session.inspect}")
@@ -9,6 +9,7 @@ module Bosh::Cli
9
9
  def resurrection_state(job=nil, index=nil, new_state)
10
10
  if job.nil? && index.nil?
11
11
  resurrection = Resurrection.new(new_state)
12
+ show_current_state
12
13
 
13
14
  director.change_vm_resurrection_for_all(resurrection.paused?)
14
15
  else
@@ -16,11 +17,11 @@ module Bosh::Cli
16
17
  job, index, _ = job_args.to_a
17
18
  resurrection = Resurrection.new(new_state)
18
19
 
19
- job_must_exist_in_deployment(job)
20
- index = valid_index_for(job, index, integer_index: true)
20
+ manifest = prepare_deployment_manifest(show_state: true)
21
+ job_must_exist_in_deployment(manifest.hash, job)
22
+ index = valid_index_for(manifest.hash, job, index, integer_index: true)
21
23
 
22
- manifest = prepare_deployment_manifest
23
- director.change_vm_resurrection(manifest['name'], job, index, resurrection.paused?)
24
+ director.change_vm_resurrection(manifest.name, job, index, resurrection.paused?)
24
25
  end
25
26
  end
26
27
  end
@@ -2,68 +2,17 @@ module Bosh::Cli
2
2
  module DeploymentHelper
3
3
  def prepare_deployment_manifest(options = {})
4
4
  deployment_required
5
- manifest_filename = deployment
6
-
7
- unless File.exists?(manifest_filename)
8
- err("Cannot find deployment manifest in `#{manifest_filename}'")
9
- end
10
-
11
- header('Processing deployment manifest')
12
-
13
- manifest = load_yaml_file(manifest_filename)
14
- manifest_yaml = File.read(manifest_filename)
15
-
16
- if manifest['name'].blank?
17
- err('Deployment name not found in the deployment manifest')
18
- end
19
-
20
- if manifest['target']
21
- err(manifest_target_upgrade_notice)
22
- end
23
-
24
- if options[:resolve_properties]
25
- compiler = DeploymentManifestCompiler.new(manifest_yaml)
26
- properties = {}
27
-
28
- begin
29
- say('Getting deployment properties from director...')
30
- properties = director.list_properties(manifest['name'])
31
- rescue Bosh::Cli::DirectorError
32
- say('Unable to get properties list from director, ' +
33
- 'trying without it...')
34
- end
35
-
36
- say('Compiling deployment manifest...')
37
- compiler.properties = properties.inject({}) do |hash, property|
38
- hash[property['name']] = property['value']
39
- hash
40
- end
41
-
42
- manifest = Psych.load(compiler.result)
5
+ manifest = Manifest.new(deployment, director)
6
+ manifest.load
7
+ if options.fetch(:show_state, false)
8
+ show_current_state(manifest.name)
43
9
  end
10
+ manifest.validate(options)
44
11
 
45
- if manifest['name'].blank? || manifest['director_uuid'].blank?
46
- err("Invalid manifest `#{File.basename(deployment)}': " +
47
- 'name and director UUID are required')
48
- end
49
-
50
- if director.uuid != manifest['director_uuid']
51
- err("Target director UUID doesn't match UUID from deployment manifest")
52
- end
53
-
54
- if manifest['release'].blank? && manifest['releases'].blank?
55
- err("Deployment manifest doesn't have release information: '" +
56
- "please add 'release' or 'releases' section")
57
- end
58
-
59
- resolve_release_aliases(manifest)
60
- resolve_stemcell_aliases(manifest)
61
-
62
- report_manifest_warnings(manifest)
63
-
64
- options[:yaml] ? Psych.dump(manifest) : manifest
12
+ manifest
65
13
  end
66
14
 
15
+
67
16
  # Check if the 2 deployments are different.
68
17
  # Print out a summary if "show" is true.
69
18
  def deployment_changed?(current_manifest, manifest, show = true)
@@ -201,55 +150,17 @@ module Bosh::Cli
201
150
  end
202
151
  end
203
152
 
204
- def latest_release_versions
205
- @_latest_release_versions ||= begin
206
- director.list_releases.inject({}) do |hash, release|
207
- name = release['name']
208
- versions = release['versions'] || release['release_versions'].map { |release_version| release_version['version'] }
209
- parsed_versions = versions.map do |version|
210
- {
211
- original: version,
212
- parsed: Bosh::Common::Version::ReleaseVersion.parse(version)
213
- }
214
- end
215
- latest_version = parsed_versions.sort_by {|v| v[:parsed] }.last[:original]
216
- hash[name] = latest_version.to_s
217
- hash
218
- end
219
- end
220
- end
221
-
222
- # @param [Hash] manifest Deployment manifest (will be modified)
223
- # @return [void]
224
- def resolve_release_aliases(manifest)
225
- releases = manifest['releases'] || [manifest['release']]
226
-
227
- releases.each do |release|
228
- if release['version'] == 'latest'
229
- latest_release_version = latest_release_versions[release['name']]
230
- unless latest_release_version
231
- err("Release '#{release['name']}' not found on director. Unable to resolve 'latest' alias in manifest.")
232
- end
233
- release['version'] = latest_release_version
234
- end
235
-
236
- if release['version'].to_i.to_s == release['version']
237
- release['version'] = release['version'].to_i
238
- end
239
- end
240
- end
241
-
242
- def job_unique_in_deployment?(job_name)
243
- job = find_job(job_name)
153
+ def job_unique_in_deployment?(manifest_hash, job_name)
154
+ job = find_job(manifest_hash, job_name)
244
155
  job ? job.fetch('instances') == 1 : false
245
156
  end
246
157
 
247
- def job_exists_in_deployment?(job_name)
248
- !!find_job(job_name)
158
+ def job_exists_in_deployment?(manifest_hash, job_name)
159
+ !!find_job(manifest_hash, job_name)
249
160
  end
250
161
 
251
- def job_must_exist_in_deployment(job)
252
- err("Job `#{job}' doesn't exist") unless job_exists_in_deployment?(job)
162
+ def job_must_exist_in_deployment(manifest_hash, job)
163
+ err("Job `#{job}' doesn't exist") unless job_exists_in_deployment?(manifest_hash, job)
253
164
  end
254
165
 
255
166
  def prompt_for_job_and_index
@@ -280,7 +191,7 @@ module Bosh::Cli
280
191
  end
281
192
 
282
193
  def jobs_and_indexes
283
- jobs = prepare_deployment_manifest.fetch('jobs')
194
+ jobs = prepare_deployment_manifest.hash.fetch('jobs')
284
195
 
285
196
  jobs.inject([]) do |jobs_and_indexes, job|
286
197
  job_name = job.fetch('name')
@@ -297,13 +208,13 @@ module Bosh::Cli
297
208
 
298
209
  private
299
210
 
300
- def find_job(job_name)
301
- jobs = prepare_deployment_manifest.fetch('jobs')
211
+ def find_job(manifest_hash, job_name)
212
+ jobs = manifest_hash.fetch('jobs')
302
213
  jobs.find { |job| job.fetch('name') == job_name }
303
214
  end
304
215
 
305
216
  def list_errands
306
- deployment_name = prepare_deployment_manifest.fetch('name')
217
+ deployment_name = prepare_deployment_manifest.name
307
218
  director.list_errands(deployment_name)
308
219
  end
309
220
 
@@ -315,15 +226,6 @@ module Bosh::Cli
315
226
  end
316
227
  end
317
228
 
318
- def manifest_target_upgrade_notice
319
- <<-EOS.gsub(/^\s*/, '').gsub(/\n$/, '')
320
- Please upgrade your deployment manifest to use director UUID instead
321
- of target. Just replace 'target' key with 'director_uuid' key in your
322
- manifest. You can get your director UUID by targeting your director
323
- with 'bosh target' and running 'bosh status' command afterwards.
324
- EOS
325
- end
326
-
327
229
  def print_summary(diff, key, redact, title = nil)
328
230
  title ||= key.to_s.gsub(/[-_]/, ' ').capitalize
329
231
 
@@ -363,54 +265,5 @@ module Bosh::Cli
363
265
  end
364
266
  end
365
267
  end
366
-
367
- # @param [Hash] manifest Deployment manifest (will be modified)
368
- # @return [void]
369
- def resolve_stemcell_aliases(manifest)
370
- return if manifest['resource_pools'].nil?
371
-
372
- manifest['resource_pools'].each do |rp|
373
- stemcell = rp['stemcell']
374
- unless stemcell.is_a?(Hash)
375
- err('Invalid stemcell spec in the deployment manifest')
376
- end
377
- if stemcell['version'] == 'latest'
378
- latest_version = latest_stemcells[stemcell['name']]
379
- if latest_version.nil?
380
- err("Latest version for stemcell `#{stemcell['name']}' is unknown")
381
- end
382
- # Avoiding {Float,Fixnum} -> String noise in diff
383
- if latest_version.to_s == latest_version.to_f.to_s
384
- latest_version = latest_version.to_f
385
- elsif latest_version.to_s == latest_version.to_i.to_s
386
- latest_version = latest_version.to_i
387
- end
388
- stemcell['version'] = latest_version
389
- end
390
- end
391
- end
392
-
393
- # @return [Array]
394
- def latest_stemcells
395
- @_latest_stemcells ||= begin
396
- stemcells = director.list_stemcells.inject({}) do |hash, stemcell|
397
- unless stemcell.is_a?(Hash) && stemcell['name'] && stemcell['version']
398
- err('Invalid director stemcell list format')
399
- end
400
- hash[stemcell['name']] ||= []
401
- hash[stemcell['name']] << stemcell['version']
402
- hash
403
- end
404
-
405
- stemcells.inject({}) do |hash, (name, versions)|
406
- hash[name] = Bosh::Common::Version::StemcellVersionList.parse(versions).latest.to_s
407
- hash
408
- end
409
- end
410
- end
411
-
412
- def report_manifest_warnings(manifest)
413
- ManifestWarnings.new(manifest).report
414
- end
415
268
  end
416
269
  end
@@ -0,0 +1,172 @@
1
+ module Bosh::Cli
2
+ class Manifest
3
+ attr_reader :hash
4
+
5
+ def initialize(deployment_file, director)
6
+ @deployment_file = deployment_file
7
+ @director = director
8
+ end
9
+
10
+ def name
11
+ @hash['name']
12
+ end
13
+
14
+ def load
15
+ unless File.exists?(@deployment_file)
16
+ err("Cannot find deployment manifest in `#{@deployment_file}'")
17
+ end
18
+
19
+ @hash = load_yaml_file(@deployment_file)
20
+ end
21
+
22
+ def validate(options={})
23
+ if @hash['name'].blank?
24
+ err('Deployment name not found in the deployment manifest')
25
+ end
26
+
27
+ if @hash['target']
28
+ err(MANIFEST_TARGET_UPGRADE_NOTICE)
29
+ end
30
+
31
+ if options[:resolve_properties]
32
+ compiler = DeploymentManifestCompiler.new(File.read(@deployment_file))
33
+ properties = {}
34
+
35
+ begin
36
+ say('Getting deployment properties from director...')
37
+ properties = @director.list_properties(name)
38
+ rescue Bosh::Cli::DirectorError
39
+ say('Unable to get properties list from director, ' +
40
+ 'trying without it...')
41
+ end
42
+
43
+ compiler.properties = properties.inject({}) do |hash, property|
44
+ hash[property['name']] = property['value']
45
+ hash
46
+ end
47
+
48
+ @hash = Psych.load(compiler.result)
49
+ end
50
+
51
+ if name.blank? || @hash['director_uuid'].blank?
52
+ err("Invalid manifest `#{File.basename(@deployment_file)}': " +
53
+ 'name and director UUID are required')
54
+ end
55
+
56
+ if @director.uuid != @hash['director_uuid']
57
+ err("Target director UUID doesn't match UUID from deployment manifest")
58
+ end
59
+
60
+ if @hash['release'].blank? && @hash['releases'].blank?
61
+ err("Deployment manifest doesn't have release information: '" +
62
+ "please add 'release' or 'releases' section")
63
+ end
64
+
65
+ resolve_release_aliases
66
+ resolve_stemcell_aliases
67
+
68
+ report_manifest_warnings
69
+
70
+ @hash
71
+ end
72
+
73
+ def yaml
74
+ @yaml ||= Psych.dump(@hash)
75
+ end
76
+
77
+ # @param [Hash] manifest Deployment manifest (will be modified)
78
+ # @return [void]
79
+ def resolve_stemcell_aliases
80
+ return if @hash['resource_pools'].nil?
81
+
82
+ @hash['resource_pools'].each do |rp|
83
+ stemcell = rp['stemcell']
84
+ unless stemcell.is_a?(Hash)
85
+ err('Invalid stemcell spec in the deployment manifest')
86
+ end
87
+ if stemcell['version'] == 'latest'
88
+ latest_version = latest_stemcells[stemcell['name']]
89
+ if latest_version.nil?
90
+ err("Latest version for stemcell `#{stemcell['name']}' is unknown")
91
+ end
92
+ # Avoiding {Float,Fixnum} -> String noise in diff
93
+ if latest_version.to_s == latest_version.to_f.to_s
94
+ latest_version = latest_version.to_f
95
+ elsif latest_version.to_s == latest_version.to_i.to_s
96
+ latest_version = latest_version.to_i
97
+ end
98
+ stemcell['version'] = latest_version
99
+ end
100
+ end
101
+ end
102
+
103
+ # @return [Array]
104
+ def latest_stemcells
105
+ @_latest_stemcells ||= begin
106
+ stemcells = @director.list_stemcells.inject({}) do |hash, stemcell|
107
+ unless stemcell.is_a?(Hash) && stemcell['name'] && stemcell['version']
108
+ err('Invalid director stemcell list format')
109
+ end
110
+ hash[stemcell['name']] ||= []
111
+ hash[stemcell['name']] << stemcell['version']
112
+ hash
113
+ end
114
+
115
+ stemcells.inject({}) do |hash, (name, versions)|
116
+ hash[name] = Bosh::Common::Version::StemcellVersionList.parse(versions).latest.to_s
117
+ hash
118
+ end
119
+ end
120
+ end
121
+
122
+ # @param [Hash] manifest Deployment manifest (will be modified)
123
+ # @return [void]
124
+ def resolve_release_aliases
125
+ releases = @hash['releases'] || [@hash['release']]
126
+
127
+ releases.each do |release|
128
+ if release['version'] == 'latest'
129
+ latest_release_version = latest_release_versions[release['name']]
130
+ unless latest_release_version
131
+ err("Release '#{release['name']}' not found on director. Unable to resolve 'latest' alias in manifest.")
132
+ end
133
+ release['version'] = latest_release_version
134
+ end
135
+
136
+ if release['version'].to_i.to_s == release['version']
137
+ release['version'] = release['version'].to_i
138
+ end
139
+ end
140
+ end
141
+
142
+ def latest_release_versions
143
+ @_latest_release_versions ||= begin
144
+ @director.list_releases.inject({}) do |hash, release|
145
+ name = release['name']
146
+ versions = release['versions'] || release['release_versions'].map { |release_version| release_version['version'] }
147
+ parsed_versions = versions.map do |version|
148
+ {
149
+ original: version,
150
+ parsed: Bosh::Common::Version::ReleaseVersion.parse(version)
151
+ }
152
+ end
153
+ latest_version = parsed_versions.sort_by { |v| v[:parsed] }.last[:original]
154
+ hash[name] = latest_version.to_s
155
+ hash
156
+ end
157
+ end
158
+ end
159
+
160
+ MANIFEST_TARGET_UPGRADE_NOTICE =
161
+ <<-EOS.gsub(/^\s*/, '').gsub(/\n$/, '')
162
+ Please upgrade your deployment manifest to use director UUID instead
163
+ of target. Just replace 'target' key with 'director_uuid' key in your
164
+ manifest. You can get your director UUID by targeting your director
165
+ with 'bosh target' and running 'bosh status' command afterwards.
166
+ EOS
167
+
168
+ def report_manifest_warnings
169
+ ManifestWarnings.new(@hash).report
170
+ end
171
+ end
172
+ end
data/lib/cli/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Cli
3
- VERSION = '1.3001.0'
3
+ VERSION = '1.3003.0'
4
4
  end
5
5
  end
data/lib/cli/vm_state.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  module Bosh::Cli
2
2
  class VmState
3
- def initialize(command, force)
3
+ def initialize(command, manifest, force)
4
4
  @command = command
5
+ @manifest = manifest
5
6
  @force = force
6
7
  end
7
8
 
8
9
  def change(job, index, new_state, operation_desc)
9
10
  command.say("You are about to #{operation_desc.make_green}")
10
- manifest = command.prepare_deployment_manifest
11
- manifest_yaml = Psych.dump(manifest)
12
11
 
13
12
  if command.interactive?
14
- check_if_manifest_changed(manifest)
13
+ check_if_manifest_changed(@manifest.hash)
15
14
 
16
15
  unless command.confirmed?("#{operation_desc.capitalize}?")
17
16
  command.cancel_deployment
@@ -20,7 +19,7 @@ module Bosh::Cli
20
19
 
21
20
  command.nl
22
21
  command.say("Performing `#{operation_desc}'...")
23
- command.director.change_job_state(manifest['name'], manifest_yaml, job, index, new_state)
22
+ command.director.change_job_state(@manifest.name, @manifest.yaml, job, index, new_state)
24
23
  end
25
24
 
26
25
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3001.0
4
+ version: 1.3003.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-25 00:00:00.000000000 Z
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3001.0
19
+ version: 1.3003.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3001.0
26
+ version: 1.3003.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bosh-template
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.3001.0
33
+ version: 1.3003.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.3001.0
40
+ version: 1.3003.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cf-uaa-lib
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.3001.0
131
+ version: 1.3003.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.3001.0
138
+ version: 1.3003.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: net-ssh
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -306,7 +306,7 @@ dependencies:
306
306
  version: '0'
307
307
  description: |-
308
308
  BOSH CLI
309
- 7cc77f
309
+ 44f0b8
310
310
  email: support@cloudfoundry.com
311
311
  executables:
312
312
  - bosh
@@ -395,6 +395,7 @@ files:
395
395
  - lib/cli/job_state.rb
396
396
  - lib/cli/line_wrap.rb
397
397
  - lib/cli/logs_downloader.rb
398
+ - lib/cli/manifest.rb
398
399
  - lib/cli/manifest_warnings.rb
399
400
  - lib/cli/name_version_pair.rb
400
401
  - lib/cli/non_interactive_progress_renderer.rb