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 +2 -0
- data/lib/cli/commands/base.rb +3 -2
- data/lib/cli/commands/deployment.rb +9 -0
- data/lib/cli/commands/release.rb +15 -0
- data/lib/cli/core_ext.rb +2 -1
- data/lib/cli/release.rb +60 -15
- data/lib/cli/runner.rb +29 -7
- data/lib/cli/version.rb +1 -1
- data/spec/assets/config/atmos/config/final.yml +6 -0
- data/spec/assets/config/atmos/config/private.yml +4 -0
- data/spec/assets/config/deprecation/config/final.yml +5 -0
- data/spec/assets/config/deprecation/config/private.yml +2 -0
- data/spec/assets/config/s3/config/final.yml +5 -0
- data/spec/assets/config/s3/config/private.yml +5 -0
- data/spec/unit/base_command_spec.rb +3 -3
- data/spec/unit/release_spec.rb +35 -0
- metadata +19 -7
data/lib/cli.rb
CHANGED
data/lib/cli/commands/base.rb
CHANGED
@@ -87,8 +87,9 @@ module Bosh::Cli
|
|
87
87
|
|
88
88
|
# @return [String] Target director URL
|
89
89
|
def target
|
90
|
-
|
91
|
-
config.resolve_alias(:target,
|
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")
|
data/lib/cli/commands/release.rb
CHANGED
@@ -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)
|
data/lib/cli/core_ext.rb
CHANGED
data/lib/cli/release.rb
CHANGED
@@ -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
|
56
|
-
#
|
55
|
+
# Check if the deprecated blobstore secret is provided in the private
|
56
|
+
# config file
|
57
57
|
# @return [Boolean]
|
58
|
-
def
|
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
|
77
|
-
|
78
|
-
|
100
|
+
deprecate_blobstore_secret if has_legacy_secret?
|
101
|
+
|
102
|
+
options = merge_private_data(provider, options)
|
79
103
|
|
80
|
-
|
81
|
-
|
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)
|
data/lib/cli/runner.rb
CHANGED
@@ -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
|
-
|
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)
|
data/lib/cli/version.rb
CHANGED
@@ -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
|
data/spec/unit/release_spec.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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.
|
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:
|
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:
|
337
|
+
hash: -389599683879577066
|
332
338
|
requirements: []
|
333
339
|
rubyforge_project:
|
334
|
-
rubygems_version: 1.8.
|
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
|