vmc 0.3.13.beta.2 → 0.3.13.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/Rakefile +84 -2
  2. data/lib/cli.rb +2 -3
  3. data/lib/cli/commands/admin.rb +9 -6
  4. data/lib/cli/commands/apps.rb +144 -111
  5. data/lib/cli/commands/base.rb +8 -15
  6. data/lib/cli/commands/misc.rb +3 -2
  7. data/lib/cli/commands/services.rb +15 -16
  8. data/lib/cli/commands/user.rb +11 -2
  9. data/lib/cli/config.rb +5 -1
  10. data/lib/cli/core_ext.rb +331 -0
  11. data/lib/cli/frameworks.rb +10 -4
  12. data/lib/cli/runner.rb +4 -0
  13. data/lib/cli/services_helper.rb +8 -2
  14. data/lib/cli/usage.rb +4 -3
  15. data/lib/cli/version.rb +1 -1
  16. data/lib/vmc/client.rb +4 -0
  17. data/lib/vmc/const.rb +1 -0
  18. metadata +13 -46
  19. data/spec/assets/app_info.txt +0 -9
  20. data/spec/assets/app_listings.txt +0 -9
  21. data/spec/assets/bad_create_app.txt +0 -9
  22. data/spec/assets/delete_app.txt +0 -9
  23. data/spec/assets/global_service_listings.txt +0 -9
  24. data/spec/assets/good_create_app.txt +0 -9
  25. data/spec/assets/good_create_service.txt +0 -9
  26. data/spec/assets/info_authenticated.txt +0 -27
  27. data/spec/assets/info_return.txt +0 -15
  28. data/spec/assets/info_return_bad.txt +0 -16
  29. data/spec/assets/list_users.txt +0 -13
  30. data/spec/assets/login_fail.txt +0 -9
  31. data/spec/assets/login_success.txt +0 -9
  32. data/spec/assets/sample_token.txt +0 -1
  33. data/spec/assets/service_already_exists.txt +0 -9
  34. data/spec/assets/service_gateway_fail.txt +0 -9
  35. data/spec/assets/service_listings.txt +0 -9
  36. data/spec/assets/service_not_found.txt +0 -9
  37. data/spec/assets/user_info.txt +0 -9
  38. data/spec/spec_helper.rb +0 -11
  39. data/spec/unit/cli_opts_spec.rb +0 -68
  40. data/spec/unit/client_spec.rb +0 -345
@@ -1,9 +0,0 @@
1
- HTTP/1.1 502 Bad Gateway
2
- Server : nginx/0.8.54
3
- Date : Tue, 16 Aug 2011 20:54:51 GMT
4
- Content_type : application/json; charset=utf-8
5
- Connection : keep-alive
6
- Keep-Alive: timeout=20
7
- Content-Length: 68
8
-
9
- {"code":503,"description":"Unexpected response from service gateway"}
@@ -1,9 +0,0 @@
1
- HTTP/1.1 200 OK
2
- Server: nginx/0.7.65
3
- Date: Thu, 03 Mar 2011 21:46:29 GMT
4
- Content-Type: application/json
5
- Connection: keep-alive
6
- Keep-Alive: timeout=20
7
- Content-Length: 313
8
-
9
- [{"type":"key-value","vendor":"redis","version":"2","options":{"name":"redis-83ddf593-0690-4856-baba-24cc7ad9b1b0","port":6148,"node_id":"redis_node_1","hostname":"127.0.0.1","password":"2167d1f8-c251-46a8-8eed-7d390ab74757"},"tier":"free","name":"redis-7ed7da9","meta":{"version":1,"created":1299188448},"id":3}]
@@ -1,9 +0,0 @@
1
- HTTP/1.1 404 Not Found
2
- Server: nginx/0.7.65
3
- Date: Fri, 04 Mar 2011 02:26:39 GMT
4
- Content-Type: text/html;charset=utf-8
5
- Connection: keep-alive
6
- Keep-Alive: timeout=20
7
- Content-Length: 75
8
-
9
- {"code":21100,"description":"Service provision call failed due to timeout"}
@@ -1,9 +0,0 @@
1
- HTTP/1.1 200 OK
2
- Server: nginx/0.7.65
3
- Date: Thu, 03 Mar 2011 19:38:32 GMT
4
- Content-Type: application/json
5
- Connection: keep-alive
6
- Keep-Alive: timeout=20
7
- Content-Length: 69
8
-
9
- {"meta":{"version":1,"created":1298681367},"email":"derek@gmail.com"}
@@ -1,11 +0,0 @@
1
-
2
- $:.unshift('./lib')
3
- require 'vmc'
4
- require 'cli'
5
-
6
- require 'spec'
7
- require 'webmock/rspec'
8
-
9
- def spec_asset(filename)
10
- File.expand_path(File.join(File.dirname(__FILE__), "assets", filename))
11
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'VMC::Cli::Runner' do
4
-
5
- it 'should parse email and password correctly' do
6
- args = "--email derek@gmail.com --password foo"
7
- cli = VMC::Cli::Runner.new(args.split).parse_options!
8
- cli.options.should have(3).items
9
- cli.options.should have_key :email
10
- cli.options[:email].should == 'derek@gmail.com'
11
- cli.options[:password].should == 'foo'
12
- end
13
-
14
- it 'should parse multiple variations of password' do
15
- args = "--password foo"
16
- cli = VMC::Cli::Runner.new(args.split).parse_options!
17
- cli.options[:password].should == 'foo'
18
-
19
- args = "--pass foo"
20
- cli = VMC::Cli::Runner.new(args.split).parse_options!
21
- cli.options[:password].should == 'foo'
22
-
23
- args = "--passwd foo"
24
- cli = VMC::Cli::Runner.new(args.split).parse_options!
25
- cli.options[:password].should == 'foo'
26
- end
27
-
28
- it 'should parse name and bind args correctly' do
29
- args = "--name foo --bind bar"
30
- cli = VMC::Cli::Runner.new(args.split).parse_options!
31
- cli.options[:name].should == 'foo'
32
- cli.options[:bind].should == 'bar'
33
- end
34
-
35
- it 'should parse instances and instance into a number and string' do
36
- args = "--instances 1 --instance 2"
37
- cli = VMC::Cli::Runner.new(args.split).parse_options!
38
- cli.options[:instances].should == 1
39
- cli.options[:instance].should == "2"
40
- end
41
-
42
- it 'should parse url, mem, path correctly' do
43
- args = "--mem 64 --url http://foo.vcap.me --path ~derek"
44
- cli = VMC::Cli::Runner.new(args.split).parse_options!
45
- cli.options[:mem].should == '64'
46
- cli.options[:url].should == 'http://foo.vcap.me'
47
- cli.options[:path].should == '~derek'
48
- end
49
-
50
- it 'should parse multiple forms of nostart correctly' do
51
- cli = VMC::Cli::Runner.new().parse_options!
52
- cli.options[:nostart].should_not be
53
- args = "--nostart"
54
- cli = VMC::Cli::Runner.new(args.split).parse_options!
55
- cli.options[:nostart].should be_true
56
- args = "--no-start"
57
- cli = VMC::Cli::Runner.new(args.split).parse_options!
58
- cli.options[:nostart].should be_true
59
- end
60
-
61
- it 'should parse force and all correctly' do
62
- args = "--force --all"
63
- cli = VMC::Cli::Runner.new(args.split).parse_options!
64
- cli.options[:force].should be_true
65
- cli.options[:all].should be_true
66
- end
67
-
68
- end
@@ -1,345 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'VMC::Client' do
4
- include WebMock::API
5
-
6
- before(:all) do
7
- @target = VMC::DEFAULT_TARGET
8
- @local_target = VMC::DEFAULT_LOCAL_TARGET
9
- @user = 'derek@gmail.com'
10
- @password = 'foo'
11
- @auth_token = spec_asset('sample_token.txt')
12
- end
13
-
14
- before(:each) do
15
- # make sure these get cleared so we don't have tests pass that shouldn't
16
- RestClient.proxy = nil
17
- ENV['http_proxy'] = nil
18
- ENV['https_proxy'] = nil
19
- end
20
-
21
- it 'should report its version' do
22
- VMC::Client.version.should =~ /\d.\d.\d/
23
- end
24
-
25
- it 'should default to local target' do
26
- client = VMC::Client.new
27
- client.target.should == VMC::DEFAULT_TARGET
28
- end
29
-
30
- it 'should default to use secure protocol' do
31
- client = VMC::Client.new
32
- client.target.match(/^https/)
33
- end
34
-
35
- it 'should normalize target with no scheme' do
36
- client = VMC::Client.new('api.cloudfoundry.com')
37
- client.target.should == 'http://api.cloudfoundry.com'
38
- end
39
-
40
- it 'should properly initialize with auth_token' do
41
- client = VMC::Client.new(@target, @auth_token)
42
- client.target.should == @target
43
- client.auth_token.should == @auth_token
44
- end
45
-
46
- it 'should allow login correctly and return an auth_token' do
47
- login_path = "#{@local_target}/users/#{@user}/tokens"
48
- stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
49
- client = VMC::Client.new(@local_target)
50
- auth_token = client.login(@user, @password)
51
- client.target.should == @local_target
52
- client.user.should == @user
53
- client.auth_token.should be
54
- auth_token.should be
55
- auth_token.should == client.auth_token
56
- end
57
-
58
- it 'should raise exception if login fails' do
59
- login_path = "#{@local_target}/users/#{@user}/tokens"
60
- stub_request(:post, login_path).to_return(File.new(spec_asset('login_fail.txt')))
61
- client = VMC::Client.new(@local_target)
62
- expect { client.login(@user, @password) }.to raise_error(VMC::Client::TargetError)
63
- end
64
-
65
- it 'should allow admin users to proxy for others' do
66
- proxy = 'vadim@gmail.com'
67
- client = VMC::Client.new(@target)
68
- client.proxy_for(proxy)
69
- client.proxy.should == proxy
70
- end
71
-
72
- it 'should properly get info for valid target cloud' do
73
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
74
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
75
- client = VMC::Client.new(@local_target)
76
- info = client.info
77
- a_request(:get, info_path).should have_been_made.once
78
- info.should have_key :support
79
- info.should have_key :description
80
- info.should have_key :name
81
- info.should have_key :version
82
- info.should have_key :build
83
- end
84
-
85
- it 'should raise and exception for a bad target' do
86
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
87
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return_bad.txt')))
88
- client = VMC::Client.new(@local_target)
89
- expect {info = client.info}.to raise_error(VMC::Client::BadResponse)
90
- a_request(:get, info_path).should have_been_made.once
91
- end
92
-
93
- it 'should have target_valid? return true for a good target' do
94
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
95
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
96
- client = VMC::Client.new(@local_target)
97
- client.target_valid?.should be_true
98
- end
99
-
100
- it 'should have target_valid? return false for a bad target' do
101
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
102
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return_bad.txt')))
103
- client = VMC::Client.new(@local_target)
104
- client.target_valid?.should be_false
105
- end
106
-
107
- it 'should respond ok if properly logged in' do
108
- login_path = "#{@local_target}/users/#{@user}/tokens"
109
- stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
110
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
111
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
112
- client = VMC::Client.new(@local_target)
113
- client.login(@user, @password)
114
- client.logged_in?.should be_true
115
- end
116
-
117
- it 'should fail when trying to change password unless logged in' do
118
- login_path = "#{@local_target}/users/#{@user}/tokens"
119
- stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
120
- user_info_path = "#{@local_target}/users/#{@user}"
121
- stub_request(:get, user_info_path).to_return(File.new(spec_asset('user_info.txt')))
122
- stub_request(:put, user_info_path)
123
- client = VMC::Client.new(@local_target)
124
- client.login(@user, @password)
125
- client.change_password('bar')
126
- end
127
-
128
- it 'should get a proper list of apps' do
129
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
130
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
131
- apps_path = "#{@local_target}#{VMC::APPS_PATH}"
132
- stub_request(:get, apps_path).to_return(File.new(spec_asset('app_listings.txt')))
133
- client = VMC::Client.new(@local_target, @auth_token)
134
- apps = client.apps
135
- apps.should have(1).items
136
- app = apps.first
137
- app.should have_key :state
138
- app.should have_key :uris
139
- app.should have_key :name
140
- app.should have_key :services
141
- app.should have_key :instances
142
- end
143
-
144
- it 'should get a proper list of users' do
145
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
146
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
147
- users_path = "#{@local_target}#{VMC::USERS_PATH}"
148
- stub_request(:get, users_path).to_return(File.new(spec_asset('list_users.txt')))
149
- client = VMC::Client.new(@local_target, @auth_token)
150
- users = client.users
151
- users.should have(4).items
152
- user = users.first
153
- user.should have_key :email
154
- user.should have_key :admin
155
- user.should have_key :apps
156
- end
157
-
158
- it 'should get a proper list of services' do
159
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
160
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
161
- services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
162
- stub_request(:get, services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
163
- client = VMC::Client.new(@local_target, @auth_token)
164
- services = client.services_info
165
- services.should have(2).items
166
- # FIXME, add in more details.
167
- end
168
-
169
- it 'should get a proper list of provisioned services' do
170
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
171
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
172
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
173
- stub_request(:get, services_path).to_return(File.new(spec_asset('service_listings.txt')))
174
- client = VMC::Client.new(@local_target, @auth_token)
175
- app_services = client.services
176
- app_services.should have(1).items
177
- redis = app_services.first
178
- redis.should have_key :type
179
- redis.should have_key :vendor
180
- end
181
-
182
- it 'should raise when trying to create an app with no manifest' do
183
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
184
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
185
- app_path = "#{@local_target}#{VMC::APPS_PATH}"
186
- stub_request(:post, app_path).to_return(File.new(spec_asset('bad_create_app.txt')))
187
- client = VMC::Client.new(@local_target, @auth_token)
188
- expect { client.create_app('foo') }.to raise_error(VMC::Client::NotFound)
189
- end
190
-
191
- it 'should create an app with a simple manifest' do
192
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
193
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
194
- app_path = "#{@local_target}#{VMC::APPS_PATH}"
195
- stub_request(:post, app_path).to_return(File.new(spec_asset('good_create_app.txt')))
196
- client = VMC::Client.new(@local_target, @auth_token)
197
- manifest = {
198
- :name => 'foo',
199
- :uris => ['foo.vcap.me'],
200
- :instances => 1,
201
- :staging => { :model => 'nodejs/1.0' },
202
- :resources => { :memory => 64 }
203
- }
204
- client.create_app('foo', manifest)
205
- end
206
-
207
- it 'should allow us to delete an app we created' do
208
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
209
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
210
- app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
211
- stub_request(:delete, app_path).to_return(File.new(spec_asset('delete_app.txt')))
212
- client = VMC::Client.new(@local_target, @auth_token)
213
- client.delete_app('foo')
214
- end
215
-
216
- it 'should provision a service' do
217
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
218
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
219
- global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
220
- stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
221
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
222
- stub_request(:post, services_path).to_return(File.new(spec_asset('good_create_service.txt')))
223
- client = VMC::Client.new(@local_target, @auth_token)
224
- client.create_service('redis', 'foo')
225
- end
226
-
227
- it 'should complain if we try to provision a service that already exists with same name' do
228
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
229
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
230
- global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
231
- stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
232
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
233
- stub_request(:post, services_path).to_return(File.new(spec_asset('service_already_exists.txt')))
234
- client = VMC::Client.new(@local_target, @auth_token)
235
- expect { client.create_service('redis', 'foo') }.to raise_error(VMC::Client::NotFound)
236
- end
237
-
238
- it 'should complain if we try to provision a service that does not exist' do
239
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
240
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
241
- global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
242
- stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
243
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
244
- stub_request(:post, services_path).to_return(File.new(spec_asset('service_not_found.txt')))
245
- client = VMC::Client.new(@local_target, @auth_token)
246
- expect { client.create_service('redis', 'foo') }.to raise_error(VMC::Client::NotFound)
247
- end
248
-
249
- it 'should allow us to delete a provisioned service' do
250
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
251
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
252
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
253
- stub_request(:get, services_path).to_return(File.new(spec_asset('service_listings.txt')))
254
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}/redis-7ed7da9"
255
- stub_request(:delete, services_path)
256
- client = VMC::Client.new(@local_target, @auth_token)
257
- client.delete_service('redis-7ed7da9')
258
- end
259
-
260
- it 'should bind a service to an app' do
261
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
262
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
263
- app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
264
- stub_request(:get, app_path).to_return(File.new(spec_asset('app_info.txt')))
265
- stub_request(:put, app_path)
266
- client = VMC::Client.new(@local_target, @auth_token)
267
- client.bind_service('my-redis', 'foo')
268
- a_request(:get, app_path).should have_been_made.once
269
- a_request(:put, app_path).should have_been_made.once
270
- end
271
-
272
- it 'should unbind an existing service from an app' do
273
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
274
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
275
- app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
276
- stub_request(:get, app_path).to_return(File.new(spec_asset('app_info.txt')))
277
- stub_request(:put, app_path)
278
- client = VMC::Client.new(@local_target, @auth_token)
279
- client.unbind_service('my-redis', 'foo')
280
- a_request(:get, app_path).should have_been_made.once
281
- a_request(:put, app_path).should have_been_made.once
282
- end
283
-
284
- it 'should set a proxy if one is set' do
285
- target = "http://nonlocal.domain.com"
286
- info_path = "#{target}#{VMC::INFO_PATH}"
287
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
288
- proxy = 'http://proxy.vmware.com:3128'
289
- ENV['http_proxy'] = proxy
290
- client = VMC::Client.new(target)
291
- info = client.info
292
- RestClient.proxy.should == proxy
293
- end
294
-
295
- it 'should not set a proxy when accessing localhost' do
296
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
297
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
298
- proxy = 'http://proxy.vmware.com:3128'
299
- ENV['http_proxy'] = proxy
300
- client = VMC::Client.new(@local_target)
301
- info = client.info
302
- RestClient.proxy.should == nil
303
- end
304
-
305
- it 'should use a secure proxy over a normal proxy if one is set' do
306
- info_path = "#{@target}#{VMC::INFO_PATH}"
307
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
308
- proxy = 'http://proxy.vmware.com:3128'
309
- secure_proxy = 'http://secure-proxy.vmware.com:3128'
310
- ENV['http_proxy'] = proxy
311
- ENV['https_proxy'] = secure_proxy
312
- client = VMC::Client.new(@target)
313
- info = client.info
314
- RestClient.proxy.should == secure_proxy
315
- end
316
-
317
- it 'should not use a secure proxy for non-secure site' do
318
- target = "http://nonlocal.domain.com"
319
- info_path = "#{target}#{VMC::INFO_PATH}"
320
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
321
- proxy = 'http://proxy.vmware.com:3128'
322
- secure_proxy = 'http://secure-proxy.vmware.com:3128'
323
- ENV['http_proxy'] = proxy
324
- ENV['https_proxy'] = secure_proxy
325
- client = VMC::Client.new(target)
326
- info = client.info
327
- RestClient.proxy.should == proxy
328
- end
329
-
330
- it 'should fail when there is a service gateway failure' do
331
- info_path = "#{@local_target}#{VMC::INFO_PATH}"
332
- stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
333
- global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
334
- stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
335
- services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
336
- # A service gateway failure will typically happen when provisioning a new service instance -
337
- # e.g. provisioning too many instances of mysql service.
338
- stub_request(:post, services_path).to_return(File.new(spec_asset('service_gateway_fail.txt')))
339
- client = VMC::Client.new(@local_target, @auth_token)
340
- expect { client.create_service('mysql', 'foo') }.to raise_error(VMC::Client::TargetError)
341
- end
342
-
343
- # WebMock.allow_net_connect!
344
-
345
- end