bosh_cli 0.19.5 → 0.19.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cli.rb CHANGED
@@ -37,6 +37,8 @@ unless defined?(Bosh::Cli::VERSION)
37
37
  require "cli/version"
38
38
  end
39
39
 
40
+ require "common/common"
41
+
40
42
  require "cli/config"
41
43
  require "cli/core_ext"
42
44
  require "cli/errors"
@@ -87,8 +87,9 @@ module Bosh::Cli
87
87
 
88
88
  # @return [String] Target director URL
89
89
  def target
90
- url = options[:target] || config.target
91
- config.resolve_alias(:target, url) || url
90
+ raw_url = options[:target] || config.target
91
+ url = config.resolve_alias(:target, raw_url) || raw_url
92
+ url ? normalize_url(url) : nil
92
93
  end
93
94
  alias_method :target_url, :target
94
95
 
@@ -67,6 +67,15 @@ module Bosh::Cli::Command
67
67
  config.save
68
68
  end
69
69
 
70
+ def edit
71
+ unless deployment
72
+ quit("Deployment not set".red)
73
+ end
74
+
75
+ editor = ENV['EDITOR'] || "vi"
76
+ system("#{editor} #{deployment}")
77
+ end
78
+
70
79
  def perform(*options)
71
80
  auth_required
72
81
  recreate = options.include?("--recreate")
@@ -112,6 +112,8 @@ module Bosh::Cli::Command
112
112
  remote_release = get_remote_release(manifest["name"]) rescue nil
113
113
  package_matches = match_remote_packages(File.read(manifest_path))
114
114
 
115
+ find_release_dir(manifest_path)
116
+
115
117
  blobstore = release.blobstore
116
118
  tmpdir = Dir.mktmpdir
117
119
 
@@ -429,6 +431,19 @@ module Bosh::Cli::Command
429
431
 
430
432
  private
431
433
 
434
+ # if we aren't already in a release directory, try going up two levels
435
+ # to see if that is a release directory, and then use that as the base
436
+ def find_release_dir(manifest_path)
437
+ unless in_release_dir?
438
+ dir = File.expand_path("../..", manifest_path)
439
+ Dir.chdir(dir)
440
+ if in_release_dir?
441
+ @release = Bosh::Cli::Release.new(dir)
442
+ end
443
+ end
444
+
445
+ end
446
+
432
447
  def show_summary(builder)
433
448
  packages_table = table do |t|
434
449
  t.headings = %w(Name Version Notes Fingerprint)
@@ -108,7 +108,8 @@ module BoshStringExtensions
108
108
  end
109
109
 
110
110
  def colorize(color_code)
111
- if Bosh::Cli::Config.output.tty? &&
111
+ if Bosh::Cli::Config.output &&
112
+ Bosh::Cli::Config.output.tty? &&
112
113
  Bosh::Cli::Config.colorize &&
113
114
  COLOR_CODES[color_code]
114
115
 
@@ -52,13 +52,37 @@ module Bosh::Cli
52
52
  end
53
53
  end
54
54
 
55
- # Check if the blobstore secret is provided in the private config file
56
- #
55
+ # Check if the deprecated blobstore secret is provided in the private
56
+ # config file
57
57
  # @return [Boolean]
58
- def has_blobstore_secret?
58
+ def has_legacy_secret?
59
59
  @private_config.has_key?("blobstore_secret")
60
60
  end
61
61
 
62
+ def has_blobstore_secret?
63
+ bs = @private_config["blobstore"]
64
+ has_legacy_secret? ||
65
+ has_blobstore_secrets?(bs, "atmos", "secret") ||
66
+ has_blobstore_secrets?(bs, "simple", "user", "password") ||
67
+ has_blobstore_secrets?(bs, "s3", "access_key_id", "secret_access_key")
68
+ end
69
+
70
+ # final.yml
71
+ # ---
72
+ # blobstore:
73
+ # provider: ...
74
+ # options:
75
+ # ...: ...
76
+
77
+ # private.yml
78
+ # ---
79
+ # blobstore:
80
+ # s3:
81
+ # secret_access_key: ...
82
+ # access_key_id: ...
83
+ # atmos:
84
+ # secret: ...
85
+
62
86
  # Picks blobstore client to use with current release.
63
87
  #
64
88
  # @return [Bosh::Blobstore::Client] blobstore client
@@ -73,12 +97,12 @@ module Bosh::Cli
73
97
  provider = blobstore_config["provider"]
74
98
  options = blobstore_config["options"] || {}
75
99
 
76
- if has_blobstore_secret?
77
- options["secret"] = @private_config["blobstore_secret"]
78
- end
100
+ deprecate_blobstore_secret if has_legacy_secret?
101
+
102
+ options = merge_private_data(provider, options)
79
103
 
80
- @blobstore = Bosh::Blobstore::Client.create(provider,
81
- symbolize_keys(options))
104
+ opts = Bosh::Common.symbolize_keys(options)
105
+ @blobstore = Bosh::Blobstore::Client.create(provider, opts)
82
106
 
83
107
  rescue Bosh::Blobstore::BlobstoreError => e
84
108
  err("Cannot initialize blobstore: #{e}")
@@ -97,6 +121,34 @@ module Bosh::Cli
97
121
 
98
122
  private
99
123
 
124
+ def has_blobstore_secrets?(blobstore, name, *keys)
125
+ return false unless blobstore
126
+ return false unless blobstore[name]
127
+ keys.each {|key| return false unless blobstore[name][key]}
128
+ true
129
+ end
130
+
131
+
132
+ # Extracts private blobstore data from final.yml (i.e. secrets)
133
+ # and merges it into the blobstore options.
134
+ def merge_private_data(provider, options)
135
+ bs = @private_config["blobstore"]
136
+ options.merge(bs ? bs[provider] : {})
137
+ end
138
+
139
+ # stores blobstore_secret as blobstore.atmos.secret
140
+ def deprecate_blobstore_secret
141
+ say("WARNING:".red + " use of blobstore_secret is deprecated")
142
+
143
+ @private_config["blobstore"] ||= {}
144
+ bs = @private_config["blobstore"]
145
+
146
+ bs["atmos"] ||= {}
147
+ atmos = bs["atmos"]
148
+
149
+ atmos["secret"] = @private_config["blobstore_secret"]
150
+ end
151
+
100
152
  # Upgrade path for legacy clients that kept release metadata
101
153
  # in config/dev.yml and config/final.yml
102
154
  #
@@ -156,13 +208,6 @@ module Bosh::Cli
156
208
  end
157
209
  end
158
210
 
159
- def symbolize_keys(hash)
160
- hash.inject({}) do |h, (key, value)|
161
- h[key.to_sym] = value
162
- h
163
- end
164
- end
165
-
166
211
  def load_config(file)
167
212
  if File.exists?(file)
168
213
  load_yaml_file(file)
@@ -34,16 +34,16 @@ module Bosh::Cli
34
34
 
35
35
  def prepare
36
36
  define_commands
37
- define_plugin_commands
38
- build_parse_tree
39
- add_shortcuts
40
37
  parse_options!
41
-
38
+ Config.output ||= STDOUT unless @options[:quiet]
42
39
  Config.interactive = !@options[:non_interactive]
43
40
  Config.colorize = @options.delete(:colorize)
44
- Config.output ||= STDOUT unless @options[:quiet]
45
41
  Config.cache = Bosh::Cli::Cache.new(@options[:cache_dir] ||
46
42
  Bosh::Cli::DEFAULT_CACHE_DIR)
43
+
44
+ define_plugin_commands
45
+ build_parse_tree
46
+ add_shortcuts
47
47
  end
48
48
 
49
49
  def run
@@ -144,7 +144,7 @@ module Bosh::Cli
144
144
 
145
145
  # for use with:
146
146
  # complete -C 'bosh complete' bosh
147
- # @param [String] command line (minus "bosh")
147
+ # @param [String] line command line (minus "bosh")
148
148
  # @return [Array]
149
149
  def complete(line)
150
150
  words = line.split(/\s+/)
@@ -234,6 +234,12 @@ module Bosh::Cli
234
234
  route :deployment, :perform
235
235
  end
236
236
 
237
+ command :edit_deployment do
238
+ usage "edit deployment"
239
+ desc "Edit current deployment manifest"
240
+ route :deployment, :edit
241
+ end
242
+
237
243
  command :ssh do
238
244
  usage "ssh <job> [index] [<options>] [command]"
239
245
  desc "Given a job, execute the given command or " +
@@ -592,7 +598,23 @@ module Bosh::Cli
592
598
  end
593
599
 
594
600
  def define_plugin_commands
595
- Gem.find_files("bosh/cli/commands/*.rb", true).each do |file|
601
+ plugins_glob = "bosh/cli/commands/*.rb"
602
+
603
+ unless Gem.respond_to?(:find_files)
604
+ say("Cannot load plugins, ".yellow +
605
+ "please run `gem update --system' to ".yellow +
606
+ "update your RubyGems".yellow)
607
+ return
608
+ end
609
+
610
+ plugins = begin
611
+ Gem.find_files(plugins_glob, true)
612
+ rescue ArgumentError
613
+ # Handling rubygems compatibility issue
614
+ Gem.find_files(plugins_glob)
615
+ end
616
+
617
+ plugins.each do |file|
596
618
  class_name = File.basename(file, ".rb").capitalize
597
619
 
598
620
  next if Bosh::Cli::Command.const_defined?(class_name)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bosh
4
4
  module Cli
5
- VERSION = "0.19.5"
5
+ VERSION = "0.19.6"
6
6
  end
7
7
  end
@@ -0,0 +1,6 @@
1
+ ---
2
+ blobstore:
3
+ provider: atmos
4
+ options:
5
+ uid: bosh
6
+ secret: foo
@@ -0,0 +1,4 @@
1
+ ---
2
+ blobstore:
3
+ atmos:
4
+ secret: bar
@@ -0,0 +1,5 @@
1
+ ---
2
+ blobstore:
3
+ provider: atmos
4
+ options:
5
+ uid: bosh
@@ -0,0 +1,2 @@
1
+ ---
2
+ blobstore_secret: bar
@@ -0,0 +1,5 @@
1
+ ---
2
+ blobstore:
3
+ provider: s3
4
+ options:
5
+ bucket_name: test
@@ -0,0 +1,5 @@
1
+ ---
2
+ blobstore:
3
+ s3:
4
+ secret_access_key: foo
5
+ access_key_id: bar
@@ -26,7 +26,7 @@ describe Bosh::Cli::Command::Base do
26
26
  cmd = make_command(:verbose => true, :dry_run => true)
27
27
  cmd.verbose?.should be_true
28
28
  cmd.dry_run?.should be_true
29
- cmd.target.should == "localhost:8080"
29
+ cmd.target.should == "http://localhost:8080"
30
30
  cmd.deployment.should == "test"
31
31
  cmd.username.should == nil
32
32
  cmd.password.should == nil
@@ -54,7 +54,7 @@ describe Bosh::Cli::Command::Base do
54
54
 
55
55
  add_config("target" => "localhost:8080", "deployment" => "test")
56
56
  cmd2 = make_command(:target => "foo", :deployment => "bar")
57
- cmd2.target.should == "foo"
57
+ cmd2.target.should == "http://foo:25555"
58
58
  cmd2.deployment.should == "bar"
59
59
  end
60
60
 
@@ -62,7 +62,7 @@ describe Bosh::Cli::Command::Base do
62
62
  add_config("target" => "localhost:8080", "deployment" => "test")
63
63
 
64
64
  cmd = make_command
65
- cmd.director.director_uri.should == "localhost:8080"
65
+ cmd.director.director_uri.should == "http://localhost:8080"
66
66
  end
67
67
 
68
68
  it "can evaluate other commands" do
@@ -63,4 +63,39 @@ describe Bosh::Cli::Release do
63
63
  r.final_name.should be_nil
64
64
  r.min_cli_version.should be_nil
65
65
  end
66
+
67
+ describe "merging final.yml with private.yml" do
68
+ it "should print a warning when it contains blobstore_secret" do
69
+ r = Bosh::Cli::Release.new(spec_asset("config/deprecation"))
70
+ opts = {
71
+ :uid => "bosh",
72
+ :secret => "bar"
73
+ }
74
+ Bosh::Blobstore::Client.should_receive(:create).with("atmos", opts)
75
+ r.should_receive(:say)
76
+
77
+ r.blobstore
78
+ end
79
+
80
+ it "should merge s3 secrets into options" do
81
+ r = Bosh::Cli::Release.new(spec_asset("config/s3"))
82
+ opts = {
83
+ :bucket_name => "test",
84
+ :secret_access_key => "foo",
85
+ :access_key_id => "bar"
86
+ }
87
+ Bosh::Blobstore::Client.should_receive(:create).with("s3", opts)
88
+ r.blobstore
89
+ end
90
+
91
+ it "should merge atmos secrets into options" do
92
+ r = Bosh::Cli::Release.new(spec_asset("config/atmos"))
93
+ opts = {
94
+ :uid => "bosh",
95
+ :secret => "bar"
96
+ }
97
+ Bosh::Blobstore::Client.should_receive(:create).with("atmos", opts)
98
+ r.blobstore
99
+ end
100
+ end
66
101
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.5
4
+ version: 0.19.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-01 00:00:00.000000000 Z
12
+ date: 2012-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json_pure
@@ -104,7 +104,7 @@ dependencies:
104
104
  requirements:
105
105
  - - ~>
106
106
  - !ruby/object:Gem::Version
107
- version: 0.3.13
107
+ version: 0.4.0
108
108
  type: :runtime
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
@@ -112,7 +112,7 @@ dependencies:
112
112
  requirements:
113
113
  - - ~>
114
114
  - !ruby/object:Gem::Version
115
- version: 0.3.13
115
+ version: 0.4.0
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: net-ssh
118
118
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +250,12 @@ files:
250
250
  - spec/assets/biff/no_subnet_config.yml
251
251
  - spec/assets/biff/ok_network_config.yml
252
252
  - spec/assets/biff/properties_template.erb
253
+ - spec/assets/config/atmos/config/final.yml
254
+ - spec/assets/config/atmos/config/private.yml
255
+ - spec/assets/config/deprecation/config/final.yml
256
+ - spec/assets/config/deprecation/config/private.yml
257
+ - spec/assets/config/s3/config/final.yml
258
+ - spec/assets/config/s3/config/private.yml
253
259
  - spec/assets/deployment.MF
254
260
  - spec/assets/plugins/bosh/cli/commands/echo.rb
255
261
  - spec/assets/plugins/bosh/cli/commands/ruby.rb
@@ -319,7 +325,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
319
325
  version: '0'
320
326
  segments:
321
327
  - 0
322
- hash: 1133822301070881682
328
+ hash: -389599683879577066
323
329
  required_rubygems_version: !ruby/object:Gem::Requirement
324
330
  none: false
325
331
  requirements:
@@ -328,10 +334,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
328
334
  version: '0'
329
335
  segments:
330
336
  - 0
331
- hash: 1133822301070881682
337
+ hash: -389599683879577066
332
338
  requirements: []
333
339
  rubyforge_project:
334
- rubygems_version: 1.8.23
340
+ rubygems_version: 1.8.24
335
341
  signing_key:
336
342
  specification_version: 3
337
343
  summary: BOSH CLI
@@ -348,6 +354,12 @@ test_files:
348
354
  - spec/assets/biff/no_subnet_config.yml
349
355
  - spec/assets/biff/ok_network_config.yml
350
356
  - spec/assets/biff/properties_template.erb
357
+ - spec/assets/config/atmos/config/final.yml
358
+ - spec/assets/config/atmos/config/private.yml
359
+ - spec/assets/config/deprecation/config/final.yml
360
+ - spec/assets/config/deprecation/config/private.yml
361
+ - spec/assets/config/s3/config/final.yml
362
+ - spec/assets/config/s3/config/private.yml
351
363
  - spec/assets/deployment.MF
352
364
  - spec/assets/plugins/bosh/cli/commands/echo.rb
353
365
  - spec/assets/plugins/bosh/cli/commands/ruby.rb