vmc 0.3.10 → 0.3.12.beta.1

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/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: