bosh_cli 1.3001.0 → 1.3003.0

Sign up to get free protection for your applications and to get access to all the features.
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