vmc 0.0.8 → 0.2.4
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/LICENSE +8 -3
- data/README.md +83 -0
- data/Rakefile +11 -65
- data/bin/vmc +3 -2
- data/lib/cli/commands/admin.rb +57 -0
- data/lib/cli/commands/apps.rb +828 -0
- data/lib/cli/commands/base.rb +56 -0
- data/lib/cli/commands/misc.rb +99 -0
- data/lib/cli/commands/services.rb +84 -0
- data/lib/cli/commands/user.rb +60 -0
- data/lib/cli/config.rb +109 -0
- data/lib/cli/core_ext.rb +119 -0
- data/lib/cli/errors.rb +19 -0
- data/lib/cli/frameworks.rb +97 -0
- data/lib/cli/runner.rb +437 -0
- data/lib/cli/services_helper.rb +74 -0
- data/lib/cli/usage.rb +94 -0
- data/lib/cli/version.rb +5 -0
- data/lib/cli/zip_util.rb +61 -0
- data/lib/cli.rb +30 -0
- data/lib/vmc/client.rb +415 -0
- data/lib/vmc/const.rb +19 -0
- data/lib/vmc.rb +2 -1589
- data/spec/assets/app_info.txt +9 -0
- data/spec/assets/app_listings.txt +9 -0
- data/spec/assets/bad_create_app.txt +9 -0
- data/spec/assets/delete_app.txt +9 -0
- data/spec/assets/global_service_listings.txt +9 -0
- data/spec/assets/good_create_app.txt +9 -0
- data/spec/assets/good_create_service.txt +9 -0
- data/spec/assets/info_authenticated.txt +27 -0
- data/spec/assets/info_return.txt +15 -0
- data/spec/assets/info_return_bad.txt +16 -0
- data/spec/assets/login_fail.txt +9 -0
- data/spec/assets/login_success.txt +9 -0
- data/spec/assets/sample_token.txt +1 -0
- data/spec/assets/service_already_exists.txt +9 -0
- data/spec/assets/service_listings.txt +9 -0
- data/spec/assets/service_not_found.txt +9 -0
- data/spec/assets/user_info.txt +9 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/unit/cli_opts_spec.rb +73 -0
- data/spec/unit/client_spec.rb +284 -0
- metadata +114 -71
- data/README +0 -58
- data/lib/parse.rb +0 -719
- data/lib/vmc_base.rb +0 -205
- data/vendor/gems/httpclient/VERSION +0 -1
- data/vendor/gems/httpclient/lib/http-access2/cookie.rb +0 -1
- data/vendor/gems/httpclient/lib/http-access2/http.rb +0 -1
- data/vendor/gems/httpclient/lib/http-access2.rb +0 -53
- data/vendor/gems/httpclient/lib/httpclient/auth.rb +0 -522
- data/vendor/gems/httpclient/lib/httpclient/cacert.p7s +0 -1579
- data/vendor/gems/httpclient/lib/httpclient/cacert_sha1.p7s +0 -1579
- data/vendor/gems/httpclient/lib/httpclient/connection.rb +0 -84
- data/vendor/gems/httpclient/lib/httpclient/cookie.rb +0 -562
- data/vendor/gems/httpclient/lib/httpclient/http.rb +0 -867
- data/vendor/gems/httpclient/lib/httpclient/session.rb +0 -864
- data/vendor/gems/httpclient/lib/httpclient/ssl_config.rb +0 -417
- data/vendor/gems/httpclient/lib/httpclient/timeout.rb +0 -136
- data/vendor/gems/httpclient/lib/httpclient/util.rb +0 -86
- data/vendor/gems/httpclient/lib/httpclient.rb +0 -1020
- data/vendor/gems/httpclient/lib/tags +0 -908
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Fri, 04 Mar 2011 02:56:21 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 243
|
8
|
+
|
9
|
+
{"resources":{"memory":64},"uris":["foo.vcap.me"],"staging":{"stack":"ruby foo.rb","model":"http://b20nine.com/unknown"},"state":"STARTED","instances":1,"name":"foo","meta":{"version":1,"created":1299207348},"services":[],"runningInstances":1}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 19:46:19 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 251
|
8
|
+
|
9
|
+
[{"resources":{"memory":128},"uris":["r.vcap.me"],"staging":{"stack":"ruby redis_sample.rb","model":"http://b20nine.com/unknown"},"state":"STARTED","instances":1,"name":"r","meta":{"version":1,"created":1298681379},"services":[],"runningInstances":1}]
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 400 Bad Request
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 23:37:51 GMT
|
4
|
+
Content-Type: text/html;charset=utf-8
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 157
|
8
|
+
|
9
|
+
{"code":10050,"description":"Invalid number of instances: \"'', App instances not presentApp instances is not a numberInstances must be between 1 and 100\""}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 20:20:15 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 381
|
8
|
+
|
9
|
+
{"key-value":{"redis":{"2":{"type":"key-value","tiers":{"free":{"order":1,"description":"Free offering (64MiB)"}},"version":"2","vendor":"redis","description":"Redis key-value store service"}}},"database":{"mysql":{"5.1":{"type":"database","tiers":{"free":{"order":1,"description":"Free offering (1GiB)"}},"version":"5.1","description":"MySQL database service","vendor":"mysql"}}}}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 19:25:34 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 380
|
8
|
+
|
9
|
+
{
|
10
|
+
"name": "vcap",
|
11
|
+
"build": "3465a13ab528443f1afcd3c9c2861a078549b8e5",
|
12
|
+
"support": "ac-support@vmware.com",
|
13
|
+
"version": 0.999,
|
14
|
+
"limits": {
|
15
|
+
"apps": 50,
|
16
|
+
"memory": 8192,
|
17
|
+
"app_uris": 4,
|
18
|
+
"services": 4
|
19
|
+
},
|
20
|
+
"user": "derek@gmail.com",
|
21
|
+
"description": "VMware's Cloud Application Platform",
|
22
|
+
"usage": {
|
23
|
+
"apps": 1,
|
24
|
+
"memory": 128,
|
25
|
+
"services": 0
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 19:04:04 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 189
|
8
|
+
|
9
|
+
{
|
10
|
+
"name": "vcap",
|
11
|
+
"build": "3465a13ab528443f1afcd3c9c2861a078549b8e5",
|
12
|
+
"support": "ac-support@vmware.com",
|
13
|
+
"version": 0.999,
|
14
|
+
"description": "VMware's Cloud Application Platform"
|
15
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
HTTP/1.1 301 Moved Permanently
|
2
|
+
Location: http://www.google.com/
|
3
|
+
Content-Type: text/html; charset=UTF-8
|
4
|
+
Date: Thu, 03 Mar 2011 19:06:04 GMT
|
5
|
+
Expires: Sat, 02 Apr 2011 19:06:04 GMT
|
6
|
+
Cache-Control: public, max-age=2592000
|
7
|
+
Server: gws
|
8
|
+
Content-Length: 219
|
9
|
+
X-XSS-Protection: 1; mode=block
|
10
|
+
|
11
|
+
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
|
12
|
+
<TITLE>301 Moved</TITLE></HEAD><BODY>
|
13
|
+
<H1>301 Moved</H1>
|
14
|
+
The document has moved
|
15
|
+
<A HREF="http://www.google.com/">here</A>.
|
16
|
+
</BODY></HTML>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 18:26:45 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 112
|
8
|
+
|
9
|
+
{"token":"04085b082214646572656b40676d61696c2e636f6d6c2b07e517794d22198e59d96b40ccbc3625964dfb8dcca21174835d7e"}
|
@@ -0,0 +1 @@
|
|
1
|
+
04085b082214646572656b40676d61696c2e636f6d6c2b07f014794d2219b3dd205faeaefc0a8c70bb3ba786628c8cb8d667
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 400 Bad Request
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Fri, 04 Mar 2011 02:19:28 GMT
|
4
|
+
Content-Type: text/html;charset=utf-8
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 93
|
8
|
+
|
9
|
+
{"code":20001,"description":"A service with the name: \"redis-86b7a8655555\" already exists"}
|
@@ -0,0 +1,9 @@
|
|
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}]
|
@@ -0,0 +1,9 @@
|
|
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"}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,73 @@
|
|
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 instance and instances correctly into numbers' 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 complain if instance arg is not a number' do
|
43
|
+
args = "--instance foo"
|
44
|
+
expect { VMC::Cli::Runner.new(args.split).parse_options! }.to raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should parse url, mem, path correctly' do
|
48
|
+
args = "--mem 64 --url http://foo.vcap.me --path ~derek"
|
49
|
+
cli = VMC::Cli::Runner.new(args.split).parse_options!
|
50
|
+
cli.options[:mem].should == '64'
|
51
|
+
cli.options[:url].should == 'http://foo.vcap.me'
|
52
|
+
cli.options[:path].should == '~derek'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should parse multiple forms of nostart correctly' do
|
56
|
+
cli = VMC::Cli::Runner.new().parse_options!
|
57
|
+
cli.options[:nostart].should_not be
|
58
|
+
args = "--nostart"
|
59
|
+
cli = VMC::Cli::Runner.new(args.split).parse_options!
|
60
|
+
cli.options[:nostart].should be_true
|
61
|
+
args = "--no-start"
|
62
|
+
cli = VMC::Cli::Runner.new(args.split).parse_options!
|
63
|
+
cli.options[:nostart].should be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should parse force and all correctly' do
|
67
|
+
args = "--force --all"
|
68
|
+
cli = VMC::Cli::Runner.new(args.split).parse_options!
|
69
|
+
cli.options[:force].should be_true
|
70
|
+
cli.options[:all].should be_true
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,284 @@
|
|
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
|
+
it 'should report its version' do
|
15
|
+
VMC::Client.version.should =~ /\d.\d.\d/
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should default to local target' do
|
19
|
+
client = VMC::Client.new
|
20
|
+
client.target.should == VMC::DEFAULT_TARGET
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should normalize target with no scheme' do
|
24
|
+
client = VMC::Client.new('api.cloudfoundry.com')
|
25
|
+
client.target.should == @target
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should properly initialize with auth_token' do
|
29
|
+
client = VMC::Client.new(@target, @auth_token)
|
30
|
+
client.target.should == @target
|
31
|
+
client.auth_token.should == @auth_token
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should allow login correctly and return an auth_token' do
|
35
|
+
login_path = "#{@local_target}/users/#{@user}/tokens"
|
36
|
+
stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
|
37
|
+
client = VMC::Client.new(@local_target)
|
38
|
+
auth_token = client.login(@user, @password)
|
39
|
+
client.target.should == @local_target
|
40
|
+
client.user.should == @user
|
41
|
+
client.auth_token.should be
|
42
|
+
auth_token.should be
|
43
|
+
auth_token.should == client.auth_token
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should raise exception if login fails' do
|
47
|
+
login_path = "#{@local_target}/users/#{@user}/tokens"
|
48
|
+
stub_request(:post, login_path).to_return(File.new(spec_asset('login_fail.txt')))
|
49
|
+
client = VMC::Client.new(@local_target)
|
50
|
+
expect { client.login(@user, @password) }.to raise_error(VMC::Client::TargetError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should allow admin users to proxy for others' do
|
54
|
+
proxy = 'vadim@gmail.com'
|
55
|
+
client = VMC::Client.new(@target)
|
56
|
+
client.proxy_for(proxy)
|
57
|
+
client.proxy.should == proxy
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should properly get info for valid target cloud' do
|
61
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
62
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
|
63
|
+
client = VMC::Client.new(@local_target)
|
64
|
+
info = client.info
|
65
|
+
a_request(:get, info_path).should have_been_made.once
|
66
|
+
info.should have_key :support
|
67
|
+
info.should have_key :description
|
68
|
+
info.should have_key :name
|
69
|
+
info.should have_key :version
|
70
|
+
info.should have_key :build
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should raise and exception for a bad target' do
|
74
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
75
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return_bad.txt')))
|
76
|
+
client = VMC::Client.new(@local_target)
|
77
|
+
expect {info = client.info}.to raise_error(VMC::Client::BadResponse)
|
78
|
+
a_request(:get, info_path).should have_been_made.once
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should have target_valid? return true for a good target' do
|
82
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
83
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
|
84
|
+
client = VMC::Client.new(@local_target)
|
85
|
+
client.target_valid?.should be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should have target_valid? return false for a bad target' do
|
89
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
90
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return_bad.txt')))
|
91
|
+
client = VMC::Client.new(@local_target)
|
92
|
+
client.target_valid?.should be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should respond ok if properly logged in' do
|
96
|
+
login_path = "#{@local_target}/users/#{@user}/tokens"
|
97
|
+
stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
|
98
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
99
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
100
|
+
client = VMC::Client.new(@local_target)
|
101
|
+
client.login(@user, @password)
|
102
|
+
client.logged_in?.should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should fail when trying to change password unless logged in' do
|
106
|
+
login_path = "#{@local_target}/users/#{@user}/tokens"
|
107
|
+
stub_request(:post, login_path).to_return(File.new(spec_asset('login_success.txt')))
|
108
|
+
user_info_path = "#{@local_target}/users/#{@user}"
|
109
|
+
stub_request(:get, user_info_path).to_return(File.new(spec_asset('user_info.txt')))
|
110
|
+
stub_request(:put, user_info_path)
|
111
|
+
client = VMC::Client.new(@local_target)
|
112
|
+
client.login(@user, @password)
|
113
|
+
client.change_password('bar')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should get a proper list of apps' do
|
117
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
118
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
119
|
+
apps_path = "#{@local_target}#{VMC::APPS_PATH}"
|
120
|
+
stub_request(:get, apps_path).to_return(File.new(spec_asset('app_listings.txt')))
|
121
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
122
|
+
apps = client.apps
|
123
|
+
apps.should have(1).items
|
124
|
+
app = apps.first
|
125
|
+
app.should have_key :state
|
126
|
+
app.should have_key :uris
|
127
|
+
app.should have_key :name
|
128
|
+
app.should have_key :services
|
129
|
+
app.should have_key :instances
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should get a proper list of services' do
|
133
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
134
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
135
|
+
services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
|
136
|
+
stub_request(:get, services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
|
137
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
138
|
+
services = client.services_info
|
139
|
+
services.should have(2).items
|
140
|
+
# FIXME, add in more details.
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should get a proper list of provisioned services' do
|
144
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
145
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
146
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
|
147
|
+
stub_request(:get, services_path).to_return(File.new(spec_asset('service_listings.txt')))
|
148
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
149
|
+
app_services = client.services
|
150
|
+
app_services.should have(1).items
|
151
|
+
redis = app_services.first
|
152
|
+
redis.should have_key :type
|
153
|
+
redis.should have_key :vendor
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should raise when trying to create an app with no manifest' do
|
157
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
158
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
159
|
+
app_path = "#{@local_target}#{VMC::APPS_PATH}"
|
160
|
+
stub_request(:post, app_path).to_return(File.new(spec_asset('bad_create_app.txt')))
|
161
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
162
|
+
expect { client.create_app('foo') }.to raise_error(VMC::Client::NotFound)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should create an app with a simple manifest' do
|
166
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
167
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
168
|
+
app_path = "#{@local_target}#{VMC::APPS_PATH}"
|
169
|
+
stub_request(:post, app_path).to_return(File.new(spec_asset('good_create_app.txt')))
|
170
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
171
|
+
manifest = {
|
172
|
+
:name => 'foo',
|
173
|
+
:uris => ['foo.vcap.me'],
|
174
|
+
:instances => 1,
|
175
|
+
:staging => { :model => 'nodejs/1.0' },
|
176
|
+
:resources => { :memory => 64 }
|
177
|
+
}
|
178
|
+
client.create_app('foo', manifest)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should allow us to delete an app we created' do
|
182
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
183
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
184
|
+
app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
|
185
|
+
stub_request(:delete, app_path).to_return(File.new(spec_asset('delete_app.txt')))
|
186
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
187
|
+
client.delete_app('foo')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should provision a service' do
|
191
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
192
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
193
|
+
global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
|
194
|
+
stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
|
195
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
|
196
|
+
stub_request(:post, services_path).to_return(File.new(spec_asset('good_create_service.txt')))
|
197
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
198
|
+
client.create_service('redis', 'foo')
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should complain if we try to provision a service that already exists with same name' do
|
202
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
203
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
204
|
+
global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
|
205
|
+
stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
|
206
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
|
207
|
+
stub_request(:post, services_path).to_return(File.new(spec_asset('service_already_exists.txt')))
|
208
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
209
|
+
expect { client.create_service('redis', 'foo') }.to raise_error(VMC::Client::NotFound)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should complain if we try to provision a service that does not exist' do
|
213
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
214
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
215
|
+
global_services_path = "#{@local_target}#{VMC::GLOBAL_SERVICES_PATH}"
|
216
|
+
stub_request(:get, global_services_path).to_return(File.new(spec_asset('global_service_listings.txt')))
|
217
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
|
218
|
+
stub_request(:post, services_path).to_return(File.new(spec_asset('service_not_found.txt')))
|
219
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
220
|
+
expect { client.create_service('redis', 'foo') }.to raise_error(VMC::Client::NotFound)
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should allow us to delete a provisioned service' do
|
224
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
225
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
226
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}"
|
227
|
+
stub_request(:get, services_path).to_return(File.new(spec_asset('service_listings.txt')))
|
228
|
+
services_path = "#{@local_target}#{VMC::SERVICES_PATH}/redis-7ed7da9"
|
229
|
+
stub_request(:delete, services_path)
|
230
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
231
|
+
client.delete_service('redis-7ed7da9')
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should bind a service to an app' do
|
235
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
236
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
237
|
+
app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
|
238
|
+
stub_request(:get, app_path).to_return(File.new(spec_asset('app_info.txt')))
|
239
|
+
stub_request(:put, app_path)
|
240
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
241
|
+
client.bind_service('my-redis', 'foo')
|
242
|
+
a_request(:get, app_path).should have_been_made.once
|
243
|
+
a_request(:put, app_path).should have_been_made.once
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should unbind an existing service from an app' do
|
247
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
248
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
|
249
|
+
app_path = "#{@local_target}#{VMC::APPS_PATH}/foo"
|
250
|
+
stub_request(:get, app_path).to_return(File.new(spec_asset('app_info.txt')))
|
251
|
+
stub_request(:put, app_path)
|
252
|
+
client = VMC::Client.new(@local_target, @auth_token)
|
253
|
+
client.unbind_service('my-redis', 'foo')
|
254
|
+
a_request(:get, app_path).should have_been_made.once
|
255
|
+
a_request(:put, app_path).should have_been_made.once
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should set a proxy if one is set' do
|
259
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
260
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
|
261
|
+
proxy = 'http://proxy.vmware.com:3128'
|
262
|
+
ENV['http_proxy'] = proxy
|
263
|
+
client = VMC::Client.new(@local_target)
|
264
|
+
info = client.info
|
265
|
+
RestClient.proxy.should == proxy
|
266
|
+
ENV['http_proxy'] = nil
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'should set a secure proxy over a normal proxy if one is set' do
|
270
|
+
info_path = "#{@local_target}#{VMC::INFO_PATH}"
|
271
|
+
stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
|
272
|
+
proxy = 'http://proxy.vmware.com:3128'
|
273
|
+
secure_proxy = 'https://proxy.vmware.com:3128'
|
274
|
+
ENV['http_proxy'] = proxy
|
275
|
+
ENV['https_proxy'] = secure_proxy
|
276
|
+
client = VMC::Client.new(@local_target)
|
277
|
+
info = client.info
|
278
|
+
RestClient.proxy.should == secure_proxy
|
279
|
+
ENV['http_proxy'] = ENV['https_proxy'] = nil
|
280
|
+
end
|
281
|
+
|
282
|
+
# WebMock.allow_net_connect!
|
283
|
+
|
284
|
+
end
|