bosh_cli 0.19.5 → 0.19.6

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.
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