vmc 0.3.10 → 0.3.12.beta.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -86,7 +86,7 @@ MIT license, please see the LICENSE file. All rights reserved._
86
86
 
87
87
  ## Simple Story (for Ruby apps)
88
88
 
89
- vmc target api.vcloudlabs.com
89
+ vmc target api.cloudfoundry.com
90
90
  vmc login
91
91
  bundle package
92
92
  vmc push
@@ -2,6 +2,25 @@ module VMC::Cli::Command
2
2
 
3
3
  class Admin < Base
4
4
 
5
+ def list_users
6
+ users = client.users
7
+ users.sort! {|a, b| a[:email] <=> b[:email] }
8
+ return display JSON.pretty_generate(users || []) if @options[:json]
9
+
10
+ display "\n"
11
+ return display "No Users" if users.nil? || users.empty?
12
+
13
+ users_table = table do |t|
14
+ t.headings = 'Email', 'Admin', 'Apps'
15
+ users.each do |user|
16
+ t << [user[:email], user[:admin], user[:apps].map {|x| x[:name]}.join(', ')]
17
+ end
18
+ end
19
+ display users_table
20
+ end
21
+
22
+ alias :users :list_users
23
+
5
24
  def add_user(email=nil)
6
25
  email = @options[:email] unless email
7
26
  password = @options[:password]
@@ -48,6 +67,7 @@ module VMC::Cli::Command
48
67
  end
49
68
 
50
69
  display 'Deleting User: ', false
70
+ client.proxy = nil
51
71
  client.delete_user(user_email)
52
72
  display 'OK'.green
53
73
  end
@@ -11,6 +11,7 @@ module VMC::Cli::Command
11
11
 
12
12
  def list
13
13
  apps = client.apps
14
+ apps.sort! {|a, b| a[:name] <=> b[:name] }
14
15
  return display JSON.pretty_generate(apps || []) if @options[:json]
15
16
 
16
17
  display "\n"
@@ -483,7 +484,7 @@ module VMC::Cli::Command
483
484
  etable = table do |t|
484
485
  t.headings = 'Variable', 'Value'
485
486
  env.each do |e|
486
- k,v = e.split('=')
487
+ k,v = e.split('=', 2)
487
488
  t << [k, v]
488
489
  end
489
490
  end
@@ -494,7 +495,7 @@ module VMC::Cli::Command
494
495
  def environment_add(appname, k, v=nil)
495
496
  app = client.app_info(appname)
496
497
  env = app[:env] || []
497
- k,v = k.split('=') unless v
498
+ k,v = k.split('=', 2) unless v
498
499
  env << "#{k}=#{v}"
499
500
  display "Adding Environment Variable [#{k}=#{v}]: ", false
500
501
  app[:env] = env
@@ -558,6 +559,8 @@ module VMC::Cli::Command
558
559
  else
559
560
  FileUtils.mkdir(explode_dir)
560
561
  files = Dir.glob('{*,.[^\.]*}')
562
+ # Do not process .git files
563
+ files.delete('.git') if files
561
564
  FileUtils.cp_r(files, explode_dir)
562
565
  end
563
566
 
@@ -639,7 +642,7 @@ module VMC::Cli::Command
639
642
  return unless prompt_ok
640
643
  selected = false
641
644
  choose do |menu|
642
- menu.header = "The following provisioned services are available:"
645
+ menu.header = "The following provisioned services are available"
643
646
  menu.prompt = 'Please select one you wish to provision: '
644
647
  menu.select_by = :index_or_name
645
648
  user_services.each do |s|
@@ -657,7 +660,7 @@ module VMC::Cli::Command
657
660
  def choose_new_service(appname, services)
658
661
  return unless prompt_ok
659
662
  choose do |menu|
660
- menu.header = "The following system services are available:"
663
+ menu.header = "The following system services are available"
661
664
  menu.prompt = 'Please select one you wish to provision: '
662
665
  menu.select_by = :index_or_name
663
666
  service_choices = []
@@ -6,6 +6,8 @@ module VMC::Cli::Command
6
6
  def services
7
7
  ss = client.services_info
8
8
  ps = client.services
9
+ ps.sort! {|a, b| a[:name] <=> b[:name] }
10
+
9
11
  if @options[:json]
10
12
  services = { :system => ss, :provisioned => ps }
11
13
  return display JSON.pretty_generate(services)
@@ -9,10 +9,12 @@ module VMC::Cli
9
9
  'Rails' => ['rails3', { :mem => '256M', :description => 'Rails Application'}],
10
10
  'Spring' => ['spring', { :mem => '512M', :description => 'Java SpringSource Spring Application'}],
11
11
  'Grails' => ['grails', { :mem => '512M', :description => 'Java SpringSource Grails Application'}],
12
+ 'Lift' => ['lift', { :mem => '512M', :description => 'Scala Lift Application'}],
12
13
  'Roo' => ['spring', { :mem => '512M', :description => 'Java SpringSource Roo Application'}],
13
14
  'JavaWeb' => ['spring', { :mem => '512M', :description => 'Java Web Application'}],
14
15
  'Sinatra' => ['sinatra', { :mem => '128M', :description => 'Sinatra Application'}],
15
16
  'Node' => ['node', { :mem => '64M', :description => 'Node.js Application'}],
17
+ 'Erlang/OTP Rebar' => ['otp_rebar', { :mem => '64M', :description => 'Erlang/OTP Rebar Application'}]
16
18
  }
17
19
 
18
20
  class << self
@@ -37,9 +39,11 @@ module VMC::Cli
37
39
  war_file = Dir.glob('*.war').first
38
40
  contents = ZipUtil.entry_lines(war_file)
39
41
 
40
- # Spring Variations
42
+ # Spring/Lift Variations
41
43
  if contents =~ /WEB-INF\/lib\/grails-web.*\.jar/
42
44
  return Framework.lookup('Grails')
45
+ elsif contents =~ /WEB-INF\/lib\/lift-webkit.*\.jar/
46
+ return Framework.lookup('Lift')
43
47
  elsif contents =~ /WEB-INF\/classes\/org\/springframework/
44
48
  return Framework.lookup('Spring')
45
49
  elsif contents =~ /WEB-INF\/lib\/spring-core.*\.jar/
@@ -55,7 +59,7 @@ module VMC::Cli
55
59
  next if matched_file
56
60
  File.open(fname, 'r') do |f|
57
61
  str = f.read # This might want to be limited
58
- matched_file = fname if (str && str.match(/^\s*require\s*['"]sinatra['"]/))
62
+ matched_file = fname if (str && str.match(/^\s*require[\s\(]*['"]sinatra['"]/))
59
63
  end
60
64
  end
61
65
  if matched_file
@@ -66,10 +70,13 @@ module VMC::Cli
66
70
 
67
71
  # Node.js
68
72
  elsif !Dir.glob('*.js').empty?
69
- # Fixme, make other files work too..
70
- if File.exist?('app.js') || File.exist?('index.js') || File.exist?('main.js')
73
+ if File.exist?('server.js') || File.exist?('app.js') || File.exist?('index.js') || File.exist?('main.js')
71
74
  return Framework.lookup('Node')
72
75
  end
76
+
77
+ # Erlang/OTP using Rebar
78
+ elsif !Dir.glob('releases/*/*.rel').empty? && !Dir.glob('releases/*/*.boot').empty?
79
+ return Framework.lookup('Erlang/OTP Rebar')
73
80
  end
74
81
  end
75
82
  nil
data/lib/cli/runner.rb CHANGED
@@ -107,7 +107,6 @@ class VMC::Cli::Runner
107
107
  def convert_options!
108
108
  # make sure certain options are valid and in correct form.
109
109
  @options[:instances] = Integer(@options[:instances]) if @options[:instances]
110
- @options[:instance] = Integer(@options[:instance]) if @options[:instance]
111
110
  end
112
111
 
113
112
  def set_cmd(namespace, action, args_range=0)
@@ -204,6 +203,10 @@ class VMC::Cli::Runner
204
203
  usage('vmc delete-user <user>')
205
204
  set_cmd(:admin, :delete_user, 1)
206
205
 
206
+ when 'users'
207
+ usage('vmc users')
208
+ set_cmd(:admin, :users)
209
+
207
210
  when 'apps'
208
211
  usage('vmc apps')
209
212
  set_cmd(:apps, :apps)
@@ -286,7 +289,7 @@ class VMC::Cli::Runner
286
289
  set_cmd(:apps, :crashlogs, 1)
287
290
 
288
291
  when 'push'
289
- usage('vmc push [appname] [--path PATH] [--url URL] [--instances N] [--mem] [--no-start]')
292
+ usage('vmc push [appname] [--path PATH] [--url URL] [--instances N] [--mem] [--runtime RUNTIME] [--no-start]')
290
293
  if @args.size == 1
291
294
  set_cmd(:apps, :push, 1)
292
295
  else
@@ -8,16 +8,20 @@ module VMC::Cli
8
8
 
9
9
  return display "No system services available" if services.empty?
10
10
 
11
- services_table = table do |t|
12
- t.headings = 'Service', 'Version', 'Description'
13
- services.each do |service_type, value|
14
- value.each do |vendor, version|
15
- version.each do |version_str, service|
16
- t << [ vendor, version_str, service[:description] ]
17
- end
11
+ displayed_services = []
12
+ services.each do |service_type, value|
13
+ value.each do |vendor, version|
14
+ version.each do |version_str, service|
15
+ displayed_services << [ vendor, version_str, service[:description] ]
18
16
  end
19
17
  end
20
18
  end
19
+ displayed_services.sort! { |a, b| a.first.to_s <=> b.first.to_s}
20
+
21
+ services_table = table do |t|
22
+ t.headings = 'Service', 'Version', 'Description'
23
+ displayed_services.each { |s| t << s }
24
+ end
21
25
  display services_table
22
26
  end
23
27
 
data/lib/cli/usage.rb CHANGED
@@ -38,6 +38,7 @@ Currently available vmc commands are:
38
38
  push [appname] --url Set the url for the application
39
39
  push [appname] --instances <N> Set the expected number <N> of instances
40
40
  push [appname] --mem M Set the memory reservation for the application
41
+ push [appname] --runtime RUNTIME Set the runtime to use for the application
41
42
  push [appname] --no-start Do not auto-start the application
42
43
 
43
44
  Application Operations
data/lib/cli/version.rb CHANGED
@@ -2,6 +2,6 @@ module VMC
2
2
  module Cli
3
3
  # This version number is used as the RubyGem release version.
4
4
  # The internal VMC version number is VMC::VERSION.
5
- VERSION = '0.3.10'
5
+ VERSION = '0.3.12.beta.1'
6
6
  end
7
7
  end
data/lib/vmc/client.rb CHANGED
@@ -11,6 +11,7 @@
11
11
 
12
12
  require 'rubygems'
13
13
  require 'json/pure'
14
+ require 'open-uri'
14
15
 
15
16
  require File.expand_path('../const', __FILE__)
16
17
 
@@ -293,11 +294,17 @@ class VMC::Client
293
294
  @proxy = proxy
294
295
  end
295
296
 
297
+ def users
298
+ check_login_status
299
+ json_get(VMC::USERS_PATH)
300
+ end
301
+
296
302
  def add_user(user_email, password)
297
303
  json_post(VMC::USERS_PATH, { :email => user_email, :password => password })
298
304
  end
299
305
 
300
306
  def delete_user(user_email)
307
+ check_login_status
301
308
  http_delete("#{VMC::USERS_PATH}/#{user_email}")
302
309
  end
303
310
 
@@ -374,7 +381,7 @@ class VMC::Client
374
381
  end
375
382
 
376
383
  def perform_http_request(req)
377
- RestClient.proxy = ENV['https_proxy'] || ENV['http_proxy']
384
+ RestClient.proxy = URI.parse(req[:url]).find_proxy()
378
385
 
379
386
  # Setup tracing if needed
380
387
  unless trace.nil?
data/lib/vmc/const.rb CHANGED
@@ -5,7 +5,7 @@ module VMC
5
5
  VERSION = '0.3.2'
6
6
 
7
7
  # Targets
8
- DEFAULT_TARGET = 'http://api.cloudfoundry.com'
8
+ DEFAULT_TARGET = 'https://api.cloudfoundry.com'
9
9
  DEFAULT_LOCAL_TARGET = 'http://api.vcap.me'
10
10
 
11
11
  # General Paths
@@ -0,0 +1,13 @@
1
+ HTTP/1.1 200 OK
2
+ Server: nginx/0.7.65
3
+ Date: Sun, 22 May 2011 18:58:41 GMT
4
+ Content-Type: application/json; charset=utf-8
5
+ Transfer-Encoding: chunked
6
+ Connection: keep-alive
7
+ Keep-Alive: timeout=20
8
+ ETag: "eb21ee2635a8b6b378f896e26b61f006"
9
+ Cache-Control: max-age=0, private, must-revalidate
10
+ X-UA-Compatible: IE=Edge
11
+ Content-Length: 365
12
+
13
+ [{"email":"test@example.com","admin":true,"apps":[{"name":"chat","state":"STARTED"},{"name":"smith","state":"STARTED"},{"name":"env","state":"STARTED"},{"name":"redirect","state":"STARTED"}]},{"email":"user2@example.com","admin":false,"apps":[]},{"email":"autotest@adamgreenfield.com","admin":false,"apps":[]},{"email":"user3@example.com","admin":false,"apps":[]}]
@@ -20,9 +20,14 @@ describe 'VMC::Client' do
20
20
  client.target.should == VMC::DEFAULT_TARGET
21
21
  end
22
22
 
23
+ it 'should default to use secure protocol' do
24
+ client = VMC::Client.new
25
+ client.target.match(/^https/)
26
+ end
27
+
23
28
  it 'should normalize target with no scheme' do
24
29
  client = VMC::Client.new('api.cloudfoundry.com')
25
- client.target.should == @target
30
+ client.target.should == 'http://api.cloudfoundry.com'
26
31
  end
27
32
 
28
33
  it 'should properly initialize with auth_token' do
@@ -129,6 +134,20 @@ describe 'VMC::Client' do
129
134
  app.should have_key :instances
130
135
  end
131
136
 
137
+ it 'should get a proper list of users' do
138
+ info_path = "#{@local_target}#{VMC::INFO_PATH}"
139
+ stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
140
+ users_path = "#{@local_target}#{VMC::USERS_PATH}"
141
+ stub_request(:get, users_path).to_return(File.new(spec_asset('list_users.txt')))
142
+ client = VMC::Client.new(@local_target, @auth_token)
143
+ users = client.users
144
+ users.should have(4).items
145
+ user = users.first
146
+ user.should have_key :email
147
+ user.should have_key :admin
148
+ user.should have_key :apps
149
+ end
150
+
132
151
  it 'should get a proper list of services' do
133
152
  info_path = "#{@local_target}#{VMC::INFO_PATH}"
134
153
  stub_request(:get, info_path).to_return(File.new(spec_asset('info_authenticated.txt')))
@@ -266,16 +285,29 @@ describe 'VMC::Client' do
266
285
  ENV['http_proxy'] = nil
267
286
  end
268
287
 
269
- it 'should set a secure proxy over a normal proxy if one is set' do
288
+ it 'should use a secure proxy over a normal proxy if one is set' do
289
+ info_path = "#{@target}#{VMC::INFO_PATH}"
290
+ stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
291
+ proxy = 'http://proxy.vmware.com:3128'
292
+ secure_proxy = 'http://secure-proxy.vmware.com:3128'
293
+ ENV['http_proxy'] = proxy
294
+ ENV['https_proxy'] = secure_proxy
295
+ client = VMC::Client.new(@target)
296
+ info = client.info
297
+ RestClient.proxy.should == secure_proxy
298
+ ENV['http_proxy'] = ENV['https_proxy'] = nil
299
+ end
300
+
301
+ it 'should not use a secure proxy for non-secure site' do
270
302
  info_path = "#{@local_target}#{VMC::INFO_PATH}"
271
303
  stub_request(:get, info_path).to_return(File.new(spec_asset('info_return.txt')))
272
304
  proxy = 'http://proxy.vmware.com:3128'
273
- secure_proxy = 'https://proxy.vmware.com:3128'
305
+ secure_proxy = 'http://secure-proxy.vmware.com:3128'
274
306
  ENV['http_proxy'] = proxy
275
307
  ENV['https_proxy'] = secure_proxy
276
308
  client = VMC::Client.new(@local_target)
277
309
  info = client.info
278
- RestClient.proxy.should == secure_proxy
310
+ RestClient.proxy.should == proxy
279
311
  ENV['http_proxy'] = ENV['https_proxy'] = nil
280
312
  end
281
313
 
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmc
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease:
6
- segments:
7
- - 0
8
- - 3
9
- - 10
10
- version: 0.3.10
4
+ prerelease: 7
5
+ version: 0.3.12.beta.1
11
6
  platform: ruby
12
7
  authors:
13
8
  - VMware
@@ -15,7 +10,7 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-04-11 00:00:00 -07:00
13
+ date: 2011-06-02 00:00:00 -07:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
@@ -26,11 +21,6 @@ dependencies:
26
21
  requirements:
27
22
  - - ~>
28
23
  - !ruby/object:Gem::Version
29
- hash: 1
30
- segments:
31
- - 1
32
- - 5
33
- - 1
34
24
  version: 1.5.1
35
25
  type: :runtime
36
26
  version_requirements: *id001
@@ -42,11 +32,6 @@ dependencies:
42
32
  requirements:
43
33
  - - ~>
44
34
  - !ruby/object:Gem::Version
45
- hash: 13
46
- segments:
47
- - 2
48
- - 0
49
- - 1
50
35
  version: 2.0.1
51
36
  type: :runtime
52
37
  version_requirements: *id002
@@ -58,11 +43,6 @@ dependencies:
58
43
  requirements:
59
44
  - - ~>
60
45
  - !ruby/object:Gem::Version
61
- hash: 13
62
- segments:
63
- - 1
64
- - 6
65
- - 1
66
46
  version: 1.6.1
67
47
  type: :runtime
68
48
  version_requirements: *id003
@@ -74,19 +54,9 @@ dependencies:
74
54
  requirements:
75
55
  - - ">="
76
56
  - !ruby/object:Gem::Version
77
- hash: 13
78
- segments:
79
- - 1
80
- - 6
81
- - 1
82
57
  version: 1.6.1
83
58
  - - <
84
59
  - !ruby/object:Gem::Version
85
- hash: 11
86
- segments:
87
- - 1
88
- - 7
89
- - 0
90
60
  version: 1.7.0
91
61
  type: :runtime
92
62
  version_requirements: *id004
@@ -98,11 +68,6 @@ dependencies:
98
68
  requirements:
99
69
  - - ~>
100
70
  - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 1
104
- - 4
105
- - 2
106
71
  version: 1.4.2
107
72
  type: :runtime
108
73
  version_requirements: *id005
@@ -114,9 +79,6 @@ dependencies:
114
79
  requirements:
115
80
  - - ">="
116
81
  - !ruby/object:Gem::Version
117
- hash: 3
118
- segments:
119
- - 0
120
82
  version: "0"
121
83
  type: :development
122
84
  version_requirements: *id006
@@ -128,11 +90,6 @@ dependencies:
128
90
  requirements:
129
91
  - - ~>
130
92
  - !ruby/object:Gem::Version
131
- hash: 27
132
- segments:
133
- - 1
134
- - 3
135
- - 0
136
93
  version: 1.3.0
137
94
  type: :development
138
95
  version_requirements: *id007
@@ -144,11 +101,6 @@ dependencies:
144
101
  requirements:
145
102
  - - ~>
146
103
  - !ruby/object:Gem::Version
147
- hash: 3
148
- segments:
149
- - 1
150
- - 5
151
- - 0
152
104
  version: 1.5.0
153
105
  type: :development
154
106
  version_requirements: *id008
@@ -165,45 +117,46 @@ files:
165
117
  - LICENSE
166
118
  - README.md
167
119
  - Rakefile
168
- - lib/cli/config.rb
169
- - lib/cli/services_helper.rb
170
120
  - lib/cli/commands/admin.rb
171
- - lib/cli/commands/services.rb
172
- - lib/cli/commands/misc.rb
173
121
  - lib/cli/commands/apps.rb
174
- - lib/cli/commands/user.rb
175
122
  - lib/cli/commands/base.rb
176
- - lib/cli/usage.rb
177
- - lib/cli/frameworks.rb
123
+ - lib/cli/commands/misc.rb
124
+ - lib/cli/commands/services.rb
125
+ - lib/cli/commands/user.rb
126
+ - lib/cli/config.rb
127
+ - lib/cli/core_ext.rb
178
128
  - lib/cli/errors.rb
129
+ - lib/cli/frameworks.rb
130
+ - lib/cli/runner.rb
131
+ - lib/cli/services_helper.rb
132
+ - lib/cli/usage.rb
179
133
  - lib/cli/version.rb
180
134
  - lib/cli/zip_util.rb
181
- - lib/cli/core_ext.rb
182
- - lib/cli/runner.rb
135
+ - lib/cli.rb
183
136
  - lib/vmc/client.rb
184
137
  - lib/vmc/const.rb
185
- - lib/cli.rb
186
138
  - lib/vmc.rb
187
- - spec/unit/client_spec.rb
188
- - spec/unit/cli_opts_spec.rb
189
- - spec/spec_helper.rb
190
- - spec/assets/info_return_bad.txt
191
- - spec/assets/info_return.txt
192
- - spec/assets/service_listings.txt
139
+ - spec/assets/app_info.txt
140
+ - spec/assets/app_listings.txt
141
+ - spec/assets/bad_create_app.txt
193
142
  - spec/assets/delete_app.txt
194
- - spec/assets/user_info.txt
143
+ - spec/assets/global_service_listings.txt
195
144
  - spec/assets/good_create_app.txt
196
- - spec/assets/service_already_exists.txt
145
+ - spec/assets/good_create_service.txt
146
+ - spec/assets/info_authenticated.txt
147
+ - spec/assets/info_return.txt
148
+ - spec/assets/info_return_bad.txt
149
+ - spec/assets/list_users.txt
197
150
  - spec/assets/login_fail.txt
198
- - spec/assets/app_info.txt
199
151
  - spec/assets/login_success.txt
200
- - spec/assets/app_listings.txt
201
- - spec/assets/global_service_listings.txt
202
- - spec/assets/bad_create_app.txt
203
152
  - spec/assets/sample_token.txt
153
+ - spec/assets/service_already_exists.txt
154
+ - spec/assets/service_listings.txt
204
155
  - spec/assets/service_not_found.txt
205
- - spec/assets/info_authenticated.txt
206
- - spec/assets/good_create_service.txt
156
+ - spec/assets/user_info.txt
157
+ - spec/spec_helper.rb
158
+ - spec/unit/cli_opts_spec.rb
159
+ - spec/unit/client_spec.rb
207
160
  - bin/vmc
208
161
  has_rdoc: true
209
162
  homepage: http://vmware.com
@@ -219,19 +172,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
172
  requirements:
220
173
  - - ">="
221
174
  - !ruby/object:Gem::Version
222
- hash: 3
223
- segments:
224
- - 0
225
175
  version: "0"
226
176
  required_rubygems_version: !ruby/object:Gem::Requirement
227
177
  none: false
228
178
  requirements:
229
- - - ">="
179
+ - - ">"
230
180
  - !ruby/object:Gem::Version
231
- hash: 3
232
- segments:
233
- - 0
234
- version: "0"
181
+ version: 1.3.1
235
182
  requirements: []
236
183
 
237
184
  rubyforge_project: