bosh_cli 1.2891.0 → 1.2902.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: 8b313380c45d38aa82a3f8091a13dc1cdd69dfbe
4
- data.tar.gz: 7f000f6fd769d7db14f82aee761352773f428f71
3
+ metadata.gz: 19c9cd4f833a3224f4d43207e1c66cfe52920a65
4
+ data.tar.gz: 59021c4b5c48314318d6b9607c80ed04ed62db01
5
5
  SHA512:
6
- metadata.gz: feb792be9ea7cb30d37f601a76a43913d6f79b4c306ec974ec718d1e18db95e95552eb12fc536dc522873d5d6552657b36c0d03913c86f04aa6dfe4bb1504bc1
7
- data.tar.gz: 51e41427c1c775537034fee707b641bc2d06ab8e0473d1dcaca2b58cfeadd6fca277e071376c5d392eb7e9e6baf9379077ad6c0063f9669679fb30baff1b4bd0
6
+ metadata.gz: 76e5c79e0300f5359af52aea8fa6b407c6245154888c9cb4eaf74fe056545240e940f3c07e48a4a0ed0a7abc58077732bbf5b3311b33cd94403969a79a2028fb
7
+ data.tar.gz: 3946323d25b1b5d95c7b5b10c9c8427a10c1f19d8f62c740c64cc011e02b403479f7e3995307998f6c302359eec1043339ef774ad3785a9fbe88783be4c006c4
data/lib/cli.rb CHANGED
@@ -61,6 +61,7 @@ require 'cli/deployment_helper'
61
61
  require 'cli/validation'
62
62
  require 'cli/stemcell'
63
63
  require 'cli/client/director'
64
+ require 'cli/client/credentials'
64
65
  require 'cli/director_task'
65
66
 
66
67
  require 'cli/line_wrap'
@@ -89,6 +90,7 @@ require 'cli/deployment_manifest_compiler'
89
90
  require 'cli/task_tracking'
90
91
 
91
92
  require 'cli/release'
93
+ require 'cli/release_archiver'
92
94
  require 'cli/release_builder'
93
95
  require 'cli/release_compiler'
94
96
  require 'cli/release_tarball'
@@ -42,7 +42,7 @@ module Bosh::Cli
42
42
 
43
43
  def director
44
44
  @director ||= Bosh::Cli::Client::Director.new(
45
- target, username, password, @options.select { |k, _| k == :no_track })
45
+ target, credentials, @options.select { |k, _| k == :no_track })
46
46
  end
47
47
 
48
48
  def release
@@ -64,7 +64,7 @@ module Bosh::Cli
64
64
  end
65
65
 
66
66
  def logged_in?
67
- !!(username && password)
67
+ !!(credentials)
68
68
  end
69
69
 
70
70
  def non_interactive?
@@ -101,14 +101,15 @@ module Bosh::Cli
101
101
  options[:deployment] || config.deployment
102
102
  end
103
103
 
104
- # @return [String] Director username
105
- def username
106
- options[:username] || ENV['BOSH_USER'] || config.username(target)
107
- end
104
+ def credentials
105
+ auth_token = config.token(target)
106
+ return Bosh::Cli::Client::UaaCredentials.new(auth_token) if auth_token
108
107
 
109
- # @return [String] Director password
110
- def password
111
- options[:password] || ENV['BOSH_PASSWORD'] || config.password(target)
108
+ if username && password
109
+ return Bosh::Cli::Client::BasicCredentials.new(username, password)
110
+ end
111
+
112
+ nil
112
113
  end
113
114
 
114
115
  def target_name
@@ -121,6 +122,16 @@ module Bosh::Cli
121
122
 
122
123
  protected
123
124
 
125
+ # @return [String] Director username
126
+ def username
127
+ options[:username] || ENV['BOSH_USER'] || config.username(target)
128
+ end
129
+
130
+ # @return [String] Director password
131
+ def password
132
+ options[:password] || ENV['BOSH_PASSWORD'] || config.password(target)
133
+ end
134
+
124
135
  # Prints director task completion report. Note that event log usually
125
136
  # contains pretty detailed error report and other UI niceties, so most
126
137
  # of the time this could just do nothing
@@ -1,10 +1,9 @@
1
- require 'highline'
2
1
  require 'cli/core_ext'
3
2
  require 'cli/errors'
4
3
 
5
4
  module Bosh
6
5
  module Cli
7
- class LoginService
6
+ class BasicLoginStrategy
8
7
  def initialize(terminal, director, config, interactive)
9
8
  @terminal = terminal
10
9
  @director = director
@@ -19,19 +18,22 @@ module Bosh
19
18
  end
20
19
 
21
20
  if username.blank? || password.blank?
22
- raise Bosh::Cli::CliError.new("Please provide username and password")
21
+ err("Please provide username and password")
23
22
  end
24
23
 
25
24
  if @director.login(username, password)
26
25
  @terminal.say_green("Logged in as `#{username}'")
27
- @config.set_credentials(target, username, password)
26
+ @config.set_credentials(target, {
27
+ "username" => username,
28
+ "password" => password
29
+ })
28
30
  @config.save
29
31
  else
30
32
  if @interactive
31
33
  @terminal.say_red("Cannot log in as `#{username}', please try again")
32
34
  login(target, username, '')
33
35
  else
34
- raise Bosh::Cli::CliError.new("Cannot log in as `#{username}'")
36
+ err("Cannot log in as `#{username}'")
35
37
  end
36
38
  end
37
39
  end
@@ -0,0 +1,26 @@
1
+ module Bosh
2
+ module Cli
3
+ module Client
4
+ class UaaCredentials
5
+ def initialize(token)
6
+ @token = token
7
+ end
8
+
9
+ def authorization_header
10
+ @token
11
+ end
12
+ end
13
+
14
+ class BasicCredentials
15
+ def initialize(username, password)
16
+ @username = username
17
+ @password = password
18
+ end
19
+
20
+ def authorization_header
21
+ 'Basic ' + Base64.encode64("#{@username}:#{@password}").strip
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -19,16 +19,10 @@ module Bosh
19
19
 
20
20
  attr_reader :director_uri
21
21
 
22
- # @return [String]
23
- attr_accessor :user
24
-
25
- # @return [String]
26
- attr_accessor :password
27
-
28
22
  # Options can include:
29
23
  # * :no_track => true - do not use +TaskTracker+ for long-running
30
24
  # +request_and_track+ calls
31
- def initialize(director_uri, user = nil, password = nil, options = {})
25
+ def initialize(director_uri, credentials = nil, options = {})
32
26
  if director_uri.nil? || director_uri =~ /^\s*$/
33
27
  raise DirectorMissing, 'no director URI given'
34
28
  end
@@ -37,8 +31,7 @@ module Bosh
37
31
  @director_ip = Resolv.getaddresses(@director_uri.host).last
38
32
  @scheme = @director_uri.scheme
39
33
  @port = @director_uri.port
40
- @user = user
41
- @password = password
34
+ @credentials = credentials
42
35
  @track_tasks = !options.delete(:no_track)
43
36
  @num_retries = options.fetch(:num_retries, 5)
44
37
  @retry_wait_interval = options.fetch(:retry_wait_interval, 5)
@@ -65,12 +58,13 @@ module Bosh
65
58
  end
66
59
 
67
60
  def login(username, password)
68
- self.user = username
69
- self.password = password
61
+ @credentials = BasicCredentials.new(username, password)
70
62
  authenticated?
71
63
  end
72
64
 
73
65
  def authenticated?
66
+ # getting status verifies credentials
67
+ # if credentials are wrong it will raise DirectorError
74
68
  status = get_status
75
69
  # Backward compatibility: older directors return 200
76
70
  # only for logged in users
@@ -684,11 +678,8 @@ module Bosh
684
678
  http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
685
679
  http_client.ssl_config.verify_callback = Proc.new {}
686
680
 
687
- # HTTPClient#set_auth doesn't seem to work properly,
688
- # injecting header manually instead.
689
- if @user && @password
690
- headers['Authorization'] = 'Basic ' +
691
- Base64.encode64("#{@user}:#{@password}").strip
681
+ if @credentials
682
+ headers['Authorization'] = @credentials.authorization_header
692
683
  end
693
684
 
694
685
  http_client.request(method, uri, {
@@ -712,7 +703,7 @@ module Bosh
712
703
 
713
704
  # HTTPClient doesn't have a root exception but instead subclasses RuntimeError
714
705
  rescue RuntimeError => e
715
- puts "Perform request #{method}, #{uri}, #{headers.inspect}, #{payload.inspect}"
706
+ say("Perform request #{method}, #{uri}, #{headers.inspect}, #{payload.inspect}")
716
707
  err("REST API call exception: #{e}")
717
708
  end
718
709
 
@@ -0,0 +1,48 @@
1
+ require 'uaa'
2
+ require 'uri'
3
+
4
+ module Bosh
5
+ module Cli
6
+ module Client
7
+ class Uaa
8
+ def initialize(options, ssl_ca_file)
9
+ url = options.fetch('url')
10
+ unless URI.parse(url).instance_of?(URI::HTTPS)
11
+ err('Failed to connect to UAA, HTTPS protocol is required')
12
+ end
13
+ @ssl_ca_file = ssl_ca_file
14
+ @token_issuer = CF::UAA::TokenIssuer.new(url, 'bosh_cli', nil, { ssl_ca_file: ssl_ca_file })
15
+ end
16
+
17
+ def prompts
18
+ @token_issuer.prompts.map do |field, (type, display_text)|
19
+ Prompt.new(field, type, display_text)
20
+ end
21
+ rescue CF::UAA::SSLException => e
22
+ raise e unless @ssl_ca_file.nil?
23
+ err('Invalid SSL Cert. Use --ca-cert to specify SSL certificate')
24
+ end
25
+
26
+ def login(credentials)
27
+ token = @token_issuer.implicit_grant_with_creds(credentials)
28
+ if token
29
+ decoded = CF::UAA::TokenCoder.decode(
30
+ token.info['access_token'],
31
+ { verify: false }, # token signature not verified because CLI doesn't have the secret key
32
+ nil, nil)
33
+ full_token = "#{token.info['token_type']} #{token.info['access_token']}"
34
+ { username: decoded['user_name'], token: full_token }
35
+ end
36
+ rescue CF::UAA::BadResponse
37
+ nil
38
+ end
39
+
40
+ class Prompt < Struct.new(:field, :type, :display_text)
41
+ def password?
42
+ type == 'password'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -32,7 +32,7 @@ module Bosh::Cli::Command
32
32
  end
33
33
 
34
34
  if target
35
- old_director = Bosh::Cli::Client::Director.new(target, username, password)
35
+ old_director = Bosh::Cli::Client::Director.new(target, credentials)
36
36
  old_director_uuid = old_director.get_status["uuid"] rescue nil
37
37
  else
38
38
  old_director_uuid = nil
@@ -51,7 +51,7 @@ module Bosh::Cli::Command
51
51
  end
52
52
 
53
53
  new_director = Bosh::Cli::Client::Director.new(
54
- new_target_url, username, password)
54
+ new_target_url, credentials)
55
55
 
56
56
  status = new_director.get_status
57
57
 
@@ -1,35 +1,51 @@
1
+ require 'cli/basic_login_strategy'
2
+ require 'cli/uaa_login_strategy'
3
+ require 'cli/client/uaa'
1
4
  require 'cli/terminal'
2
- require 'cli/login_service'
3
5
 
4
6
  module Bosh::Cli::Command
5
7
  class Login < Base
6
8
  # bosh login
7
- usage "login"
8
- desc "Log in to currently targeted director. " +
9
- "The username and password can also be " +
10
- "set in the BOSH_USER and BOSH_PASSWORD " +
11
- "environment variables."
9
+ usage 'login'
10
+ desc 'Log in to currently targeted director. ' +
11
+ 'The username and password can also be ' +
12
+ 'set in the BOSH_USER and BOSH_PASSWORD ' +
13
+ 'environment variables.'
14
+ option '--ca-cert FILE', String, 'Path to client certificate provided to UAA server'
12
15
  def login(username = nil, password = nil)
13
16
  target_required
14
17
 
15
- terminal = Bosh::Cli::Terminal.new(HighLine.new)
16
- Bosh::Cli::LoginService.new(terminal, director, config, interactive?).login(target, username.to_s, password.to_s)
18
+ login_strategy(director_info).login(target, username.to_s, password.to_s)
17
19
  end
18
20
 
19
21
  # bosh logout
20
- usage "logout"
21
- desc "Forget saved credentials for targeted director"
22
+ usage 'logout'
23
+ desc 'Forget saved credentials for targeted director'
22
24
  def logout
23
25
  target_required
24
- config.set_credentials(target, nil, nil)
26
+ config.set_credentials(target, nil)
25
27
  config.save
26
28
  say("You are no longer logged in to `#{target}'".make_yellow)
27
29
  end
28
30
 
29
31
  private
30
32
 
31
- def get_director_status
32
- Bosh::Cli::Client::Director.new(target).get_status
33
+ def director_info
34
+ director.get_status
35
+ rescue Bosh::Cli::AuthError
36
+ {}
37
+ end
38
+
39
+ def login_strategy(director_info)
40
+ terminal = Bosh::Cli::Terminal.new(HighLine.new, BoshExtensions)
41
+ auth_info = director_info.fetch('user_authentication', {})
42
+
43
+ if auth_info['type'] == 'uaa'
44
+ uaa = Bosh::Cli::Client::Uaa.new(auth_info['options'], options[:ca_cert])
45
+ Bosh::Cli::UaaLoginStrategy.new(terminal, uaa, config, interactive?)
46
+ else
47
+ Bosh::Cli::BasicLoginStrategy.new(terminal, director, config, interactive?)
48
+ end
33
49
  end
34
50
  end
35
51
  end
@@ -33,7 +33,7 @@ module Bosh::Cli::Command
33
33
  print_value("Name", status["name"])
34
34
  print_value("URL", target_url)
35
35
  print_value("Version", status["version"])
36
- print_value("User", username, "not logged in")
36
+ print_value("User", status["user"], "not logged in")
37
37
  print_value("UUID", status["uuid"])
38
38
  print_value("CPI", status["cpi"], "n/a")
39
39
  print_feature_list(status["features"]) if status["features"]
@@ -66,6 +66,7 @@ module Bosh::Cli::Command
66
66
  usage "target"
67
67
  desc "Choose director to talk to (optionally creating an alias). " +
68
68
  "If no arguments given, show currently targeted director"
69
+ option '--ca-cert FILE', String, 'Path to client certificate provided to UAA server'
69
70
  def set_target(director_url = nil, name = nil)
70
71
  if director_url.nil?
71
72
  show_target
@@ -234,7 +235,7 @@ module Bosh::Cli::Command
234
235
  end
235
236
 
236
237
  def get_director_status
237
- Bosh::Cli::Client::Director.new(target).get_status
238
+ Bosh::Cli::Client::Director.new(target, credentials).get_status
238
239
  end
239
240
  end
240
241
  end
@@ -251,10 +251,10 @@ module Bosh::Cli::Command
251
251
  end
252
252
  end
253
253
 
254
- if builder.license_artifact
254
+ if builder.license
255
255
  license_table = table do |t|
256
256
  t.headings = %w(Name Version Notes)
257
- t << artifact_summary(builder.license_artifact)
257
+ t << artifact_summary(builder.license)
258
258
  end
259
259
 
260
260
  say('License')
@@ -70,12 +70,9 @@ module Bosh::Cli
70
70
  end
71
71
  end
72
72
 
73
- def set_credentials(target, username, password)
73
+ def set_credentials(target, credentials)
74
74
  @config_file["auth"] ||= {}
75
- @config_file["auth"][target] = {
76
- "username" => username,
77
- "password" => password
78
- }
75
+ @config_file["auth"][target] = credentials
79
76
  end
80
77
 
81
78
  def set_alias(category, alias_name, value)
@@ -118,6 +115,12 @@ module Bosh::Cli
118
115
  credentials_for(target)["password"]
119
116
  end
120
117
 
118
+ # @param [String] target Target director url
119
+ # @return [String] Token associated with target
120
+ def token(target)
121
+ credentials_for(target)["token"]
122
+ end
123
+
121
124
  # Deployment used to be a string that was only stored for your
122
125
  # current target. As soon as you switched targets, the deployment
123
126
  # was erased. If the user has the old config we convert it to the
@@ -0,0 +1,63 @@
1
+ module Bosh::Cli
2
+ class ReleaseArchiver
3
+ attr_reader :filepath
4
+
5
+ def initialize(filepath, manifest, packages, jobs, license = nil)
6
+ @filepath = filepath
7
+ @manifest = manifest
8
+ @packages = packages
9
+ @jobs = jobs
10
+ @license = license
11
+
12
+ @build_dir = Dir.mktmpdir
13
+ end
14
+
15
+ def build
16
+ FileUtils.copy(manifest, File.join(build_dir, 'release.MF'), :preserve => true)
17
+
18
+ packages_dir = FileUtils.mkdir_p(File.join(build_dir, 'packages'))
19
+ header("Copying packages")
20
+ packages.each do |package|
21
+ say(package.name.make_green)
22
+ FileUtils.copy(package.tarball_path, File.join(packages_dir, "#{package.name}.tgz"), :preserve => true)
23
+ end
24
+ nl
25
+
26
+ jobs_dir = FileUtils.mkdir_p(File.join(build_dir, 'jobs'))
27
+ header("Copying jobs")
28
+ jobs.each do |job|
29
+ say(job.name.make_green)
30
+ FileUtils.copy(job.tarball_path, File.join(jobs_dir, "#{job.name}.tgz"), :preserve => true)
31
+ end
32
+ nl
33
+
34
+ if license
35
+ header("Copying license")
36
+ say("license".make_green)
37
+ nl
38
+ `tar -xzf #{license.tarball_path} -C #{build_dir} 2>&1`
39
+ unless $?.exitstatus == 0
40
+ raise InvalidRelease, "Cannot extract license tarball"
41
+ end
42
+ end
43
+
44
+ in_build_dir do
45
+ `tar -czf #{filepath} . 2>&1`
46
+ unless $?.exitstatus == 0
47
+ raise InvalidRelease, "Cannot create release tarball"
48
+ end
49
+ say("Generated #{filepath.make_green}")
50
+ say("Release size: #{pretty_size(filepath).make_green}")
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :manifest, :packages, :jobs, :license, :build_dir
57
+
58
+ def in_build_dir(&block)
59
+ Dir.chdir(build_dir) { yield }
60
+ end
61
+
62
+ end
63
+ end
@@ -4,7 +4,7 @@ module Bosh::Cli
4
4
 
5
5
  attr_reader(
6
6
  :release,
7
- :license_artifact,
7
+ :license,
8
8
  :packages,
9
9
  :jobs,
10
10
  :name,
@@ -25,7 +25,7 @@ module Bosh::Cli
25
25
  @uncommitted_changes = options.fetch(:uncommitted_changes, true)
26
26
  @packages = package_artifacts # todo
27
27
  @jobs = job_artifacts # todo
28
- @license_artifact = license_artifact
28
+ @license = license_artifact
29
29
  @name = name
30
30
  raise 'Release name is blank' if name.blank?
31
31
 
@@ -87,10 +87,9 @@ module Bosh::Cli
87
87
  options = { :generate_tarball => true }.merge(options)
88
88
 
89
89
  header("Generating manifest...")
90
- generate_manifest
90
+ manifest_path = generate_manifest
91
91
  if options[:generate_tarball]
92
- header("Generating tarball...")
93
- generate_tarball
92
+ generate_tarball(manifest_path)
94
93
  end
95
94
  @build_complete = true
96
95
  end
@@ -117,11 +116,11 @@ module Bosh::Cli
117
116
  }
118
117
  end
119
118
 
120
- unless @license_artifact.nil?
119
+ unless @license.nil?
121
120
  manifest['license'] = {
122
- 'version' => @license_artifact.version,
123
- 'fingerprint' => @license_artifact.fingerprint,
124
- 'sha1' => @license_artifact.sha1,
121
+ 'version' => @license.version,
122
+ 'fingerprint' => @license.fingerprint,
123
+ 'sha1' => @license.sha1,
125
124
  }
126
125
  end
127
126
 
@@ -150,25 +149,15 @@ module Bosh::Cli
150
149
  end
151
150
 
152
151
  @manifest_generated = true
152
+ manifest_path
153
153
  end
154
154
 
155
- def generate_tarball
156
- generate_manifest unless @manifest_generated
155
+ def generate_tarball(manifest_path = nil)
156
+ manifest_path ||= generate_manifest
157
157
  return if @release_storage.has_file?(release_filename)
158
158
 
159
- copy_jobs
160
- copy_packages
161
- copy_license
162
-
163
- FileUtils.mkdir_p(File.dirname(tarball_path))
164
-
165
- in_build_dir do
166
- `tar -czf #{tarball_path} . 2>&1`
167
- unless $?.exitstatus == 0
168
- raise InvalidRelease, "Cannot create release tarball"
169
- end
170
- say("Generated #{tarball_path}")
171
- end
159
+ archiver = ReleaseArchiver.new(tarball_path, manifest_path, packages, jobs, license)
160
+ archiver.build
172
161
  end
173
162
 
174
163
  def releases_dir
@@ -202,44 +191,6 @@ module Bosh::Cli
202
191
  nl
203
192
  end
204
193
 
205
- # Copies jobs into release todo DRY vs copy_packages
206
- def copy_jobs
207
- header("Copying jobs...")
208
- jobs.each do |job_artifact|
209
- copy_artifact(job_artifact, 'jobs')
210
- end
211
- nl
212
- end
213
-
214
- def copy_license
215
- return if @license_artifact.nil?
216
-
217
- header("Copying license...")
218
- copied = copy_artifact(@license_artifact)
219
- extract_license(copied)
220
- nl
221
- end
222
-
223
- def copy_artifact(artifact, dest = nil)
224
- name = artifact.name
225
- source_path = artifact.tarball_path
226
- output_path = File.join([build_dir, dest, "#{name}.tgz"].compact)
227
-
228
- say("%-40s %s" % [name.make_green, pretty_size(tarball_path)])
229
- FileUtils.cp(source_path, output_path, :preserve => true)
230
-
231
- output_path
232
- end
233
-
234
- def extract_license(tarball_path)
235
- return if @license_artifact.nil?
236
-
237
- in_build_dir do
238
- `tar -xzf #{tarball_path} 2>&1`
239
- `rm #{tarball_path} 2>&1`
240
- end
241
- end
242
-
243
194
  def assign_version
244
195
  latest_final_version = Versions::ReleaseVersionsIndex.new(@final_index).latest_version
245
196
  latest_final_version ||= Bosh::Common::Version::ReleaseVersion.parse('0')
@@ -20,7 +20,7 @@ module Bosh::Cli
20
20
 
21
21
  @blobstore = blobstore
22
22
  @release_source = release_source || Dir.pwd
23
- @manifest_file = File.expand_path(manifest_file, @release_source)
23
+ @manifest_path = File.expand_path(manifest_file, @release_source)
24
24
  @tarball_path = nil
25
25
 
26
26
  @artifacts_dir = artifacts_dir
@@ -42,58 +42,26 @@ module Bosh::Cli
42
42
  @license = @manifest["license"] ? OpenStruct.new(@manifest["license"]) : nil
43
43
  end
44
44
 
45
+ def artifact_from(resource, type)
46
+ return nil unless resource
47
+ BuildArtifact.new(resource.name, resource.fingerprint, send(:"find_#{type}", resource), resource.sha1, [], nil, nil)
48
+ end
49
+
45
50
  def compile
46
51
  if exists?
47
52
  quit("You already have this version in `#{tarball_path.make_green}'")
48
53
  end
49
54
 
50
- FileUtils.cp(@manifest_file, File.join(@build_dir, "release.MF"), :preserve => true)
51
-
52
- header("Copying packages")
53
- @packages.each do |package|
54
- say("#{package.name} (#{package.version})".ljust(30), " ")
55
- if remote_package_exists?(package)
56
- say("SKIP".make_yellow)
57
- next
58
- end
59
- nl
60
- package_file_path = find_package(package)
61
- FileUtils.cp(package_file_path,
62
- File.join(@packages_dir, "#{package.name}.tgz"),
63
- :preserve => true)
64
- end
65
-
66
- header("Copying jobs")
67
- @jobs.each do |job|
68
- say("#{job.name} (#{job.version})".ljust(30), " ")
69
- if remote_job_exists?(job)
70
- say("SKIP".make_yellow)
71
- next
72
- end
73
- nl
74
- job_file_path = find_job(job)
75
- FileUtils.cp(job_file_path,
76
- File.join(@jobs_dir, "#{job.name}.tgz"),
77
- :preserve => true)
78
- end
79
-
80
- header("Copying license")
81
- if @license
82
- say("license (#{@license.version})".ljust(30), " ")
83
- nl
84
- license_file_path = find_license(@license)
85
- FileUtils.cp(license_file_path, File.join(@build_dir, 'license.tgz'), preserve: true)
86
- end
55
+ packages = @packages
56
+ .reject { |package| remote_package_exists?(package) }
57
+ .map { |package| artifact_from(package, :package) }
58
+ jobs = @jobs
59
+ .reject { |job| remote_job_exists?(job) }
60
+ .map { |job| artifact_from(job, :job) }
61
+ license = artifact_from(@license, :license)
87
62
 
88
- header("Building tarball")
89
- Dir.chdir(@build_dir) do
90
- tar_out = `tar -czf #{tarball_path} . 2>&1`
91
- unless $?.exitstatus == 0
92
- raise InvalidRelease, "Cannot create release tarball: #{tar_out}"
93
- end
94
- say("Generated #{tarball_path.make_green}")
95
- say("Release size: #{pretty_size(tarball_path).make_green}")
96
- end
63
+ archiver = ReleaseArchiver.new(tarball_path, @manifest_path, packages, jobs, license)
64
+ archiver.build
97
65
  end
98
66
 
99
67
  def exists?
@@ -101,7 +69,7 @@ module Bosh::Cli
101
69
  end
102
70
 
103
71
  def tarball_path
104
- @tarball_path || File.join(File.dirname(@manifest_file),
72
+ @tarball_path || File.join(File.dirname(@manifest_path),
105
73
  "#{@name}-#{@version}.tgz")
106
74
  end
107
75
 
@@ -3,8 +3,9 @@ module Bosh
3
3
  class Terminal
4
4
  extend Forwardable
5
5
 
6
- def initialize(highline)
6
+ def initialize(highline, sayer)
7
7
  @highline = highline
8
+ @sayer = sayer
8
9
  end
9
10
 
10
11
  def ask(prompt)
@@ -16,15 +17,15 @@ module Bosh
16
17
  end
17
18
 
18
19
  def say_green(message)
19
- highline.say(message.make_green)
20
+ sayer.say(message.make_green)
20
21
  end
21
22
 
22
23
  def say_red(message)
23
- highline.say(message.make_red)
24
+ sayer.say(message.make_red)
24
25
  end
25
26
 
26
27
  private
27
- attr_reader :highline
28
+ attr_reader :highline, :sayer
28
29
  end
29
30
  end
30
31
  end
@@ -0,0 +1,38 @@
1
+ require 'cli/core_ext'
2
+ require 'cli/errors'
3
+
4
+ module Bosh
5
+ module Cli
6
+ class UaaLoginStrategy
7
+ def initialize(terminal, uaa, config, interactive)
8
+ @terminal = terminal
9
+ @uaa = uaa
10
+ @config = config
11
+ @interactive = interactive
12
+ end
13
+
14
+ def login(target, username = nil, password = nil)
15
+ if @interactive
16
+ credentials = {}
17
+ @uaa.prompts.map do |prompt|
18
+ if prompt.password?
19
+ credentials[prompt.field] = @terminal.ask_password("#{prompt.display_text}: ")
20
+ else
21
+ credentials[prompt.field] = @terminal.ask("#{prompt.display_text}: ")
22
+ end
23
+ end
24
+
25
+ if results = @uaa.login(credentials)
26
+ @terminal.say_green("Logged in as `#{results[:username]}'")
27
+ @config.set_credentials(target, { 'token' => results[:token] })
28
+ @config.save
29
+ else
30
+ err('Failed to log in')
31
+ end
32
+ else
33
+ err('Non-interactive UAA login is not supported.')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Cli
3
- VERSION = '1.2891.0'
3
+ VERSION = '1.2902.0'
4
4
  end
5
5
  end
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.2891.0
4
+ version: 1.2902.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-03-23 00:00:00.000000000 Z
11
+ date: 2015-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2891.0
19
+ version: 1.2902.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.2891.0
26
+ version: 1.2902.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.2891.0
33
+ version: 1.2902.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.2891.0
40
+ version: 1.2902.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: cf-uaa-lib
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.2.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: json_pure
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +128,14 @@ dependencies:
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: 1.2891.0
131
+ version: 1.2902.0
118
132
  type: :runtime
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: 1.2891.0
138
+ version: 1.2902.0
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: net-ssh
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -292,7 +306,7 @@ dependencies:
292
306
  version: '0'
293
307
  description: |-
294
308
  BOSH CLI
295
- 1d294c
309
+ ac0a41
296
310
  email: support@cloudfoundry.com
297
311
  executables:
298
312
  - bosh
@@ -306,12 +320,15 @@ files:
306
320
  - lib/cli/archive_repository_provider.rb
307
321
  - lib/cli/backup_destination_path.rb
308
322
  - lib/cli/base_command.rb
323
+ - lib/cli/basic_login_strategy.rb
309
324
  - lib/cli/blob_manager.rb
310
325
  - lib/cli/build_artifact.rb
311
326
  - lib/cli/changeset_helper.rb
312
327
  - lib/cli/client/compiled_packages_client.rb
328
+ - lib/cli/client/credentials.rb
313
329
  - lib/cli/client/director.rb
314
330
  - lib/cli/client/errands_client.rb
331
+ - lib/cli/client/uaa.rb
315
332
  - lib/cli/command_discovery.rb
316
333
  - lib/cli/command_handler.rb
317
334
  - lib/cli/commands/backup.rb
@@ -365,7 +382,6 @@ files:
365
382
  - lib/cli/job_property_validator.rb
366
383
  - lib/cli/job_state.rb
367
384
  - lib/cli/line_wrap.rb
368
- - lib/cli/login_service.rb
369
385
  - lib/cli/logs_downloader.rb
370
386
  - lib/cli/manifest_warnings.rb
371
387
  - lib/cli/name_version_pair.rb
@@ -374,6 +390,7 @@ files:
374
390
  - lib/cli/public_stemcell_presenter.rb
375
391
  - lib/cli/public_stemcells.rb
376
392
  - lib/cli/release.rb
393
+ - lib/cli/release_archiver.rb
377
394
  - lib/cli/release_builder.rb
378
395
  - lib/cli/release_compiler.rb
379
396
  - lib/cli/release_tarball.rb
@@ -394,6 +411,7 @@ files:
394
411
  - lib/cli/task_tracking/task_tracker.rb
395
412
  - lib/cli/task_tracking/total_duration.rb
396
413
  - lib/cli/terminal.rb
414
+ - lib/cli/uaa_login_strategy.rb
397
415
  - lib/cli/validation.rb
398
416
  - lib/cli/version.rb
399
417
  - lib/cli/versions/local_artifact_storage.rb