vmc 0.3.15 → 0.3.16.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.
@@ -34,6 +34,15 @@ module VMC::Cli
34
34
  end
35
35
  end
36
36
 
37
+ def tunnel_auth
38
+ tunnel_app_info[:env].each do |e|
39
+ name, val = e.split("=", 2)
40
+ return val if name == "CALDECOTT_AUTH"
41
+ end
42
+
43
+ nil
44
+ end
45
+
37
46
  def tunnel_url
38
47
  return @tunnel_url if @tunnel_url
39
48
 
@@ -96,7 +105,7 @@ module VMC::Cli
96
105
  response = nil
97
106
  10.times do
98
107
  begin
99
- response = RestClient.get("#{tunnel_url}/services/#{service}", "Auth-Token" => token)
108
+ response = RestClient.get(tunnel_url + "/" + VMC::Client.path("services", service), "Auth-Token" => token)
100
109
  break
101
110
  rescue RestClient::Exception
102
111
  sleep 1
@@ -201,12 +210,21 @@ module VMC::Cli
201
210
  begin
202
211
  TCPSocket.open('localhost', port)
203
212
  port += 1
204
- rescue => e
213
+ rescue
205
214
  return port
206
215
  end
207
216
  end
208
217
 
209
- err "Could not pick a port between #{original} and #{original + PORT_RANGE - 1}"
218
+ grab_ephemeral_port
219
+ end
220
+
221
+ def grab_ephemeral_port
222
+ socket = TCPServer.new('0.0.0.0', 0)
223
+ socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
224
+ Socket.do_not_reverse_lookup = true
225
+ port = socket.addr[1]
226
+ socket.close
227
+ return port
210
228
  end
211
229
 
212
230
  def wait_for_tunnel_start(port)
@@ -247,16 +265,23 @@ module VMC::Cli
247
265
  end
248
266
  end
249
267
 
250
- def start_local_prog(client, info, port)
268
+ def start_local_prog(clients, command, info, port)
269
+ client = clients[File.basename(command)]
270
+
271
+ cmdline = "#{command} "
272
+
251
273
  case client
252
274
  when Hash
253
- cmdline = resolve_symbols(client["command"], info, port)
275
+ cmdline << resolve_symbols(client["command"], info, port)
254
276
  client["environment"].each do |e|
255
- e =~ /([^=]+)=(["']?)([^"']*)\2/
256
- ENV[$1] = resolve_symbols($3, info, port)
277
+ if e =~ /([^=]+)=(["']?)([^"']*)\2/
278
+ ENV[$1] = resolve_symbols($3, info, port)
279
+ else
280
+ err "Invalid environment variable: #{e}"
281
+ end
257
282
  end
258
283
  when String
259
- cmdline = resolve_symbols(client, info, port)
284
+ cmdline << resolve_symbols(client, info, port)
260
285
  else
261
286
  err "Unknown client info: #{client.inspect}."
262
287
  end
@@ -279,19 +304,19 @@ module VMC::Cli
279
304
  }
280
305
  )
281
306
 
282
- Command::Apps.new({}).send(:upload_app_bits, tunnel_appname, HELPER_APP)
307
+ Command::Apps.new(@options).send(:upload_app_bits, tunnel_appname, HELPER_APP)
283
308
 
284
309
  invalidate_tunnel_app_info
285
310
  end
286
311
 
287
312
  def stop_caldecott
288
- Command::Apps.new({}).stop(tunnel_appname)
313
+ Command::Apps.new(@options).stop(tunnel_appname)
289
314
 
290
315
  invalidate_tunnel_app_info
291
316
  end
292
317
 
293
318
  def start_caldecott
294
- Command::Apps.new({}).start(tunnel_appname)
319
+ Command::Apps.new(@options).start(tunnel_appname)
295
320
 
296
321
  invalidate_tunnel_app_info
297
322
  end
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.15'
5
+ VERSION = '0.3.16.beta.1'
6
6
  end
7
7
  end
data/lib/cli.rb CHANGED
@@ -12,6 +12,7 @@ module VMC
12
12
  autoload :ZipUtil, "#{ROOT}/cli/zip_util"
13
13
  autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
14
14
  autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
15
+ autoload :ManifestHelper, "#{ROOT}/cli/manifest_helper"
15
16
 
16
17
  module Command
17
18
  autoload :Base, "#{ROOT}/cli/commands/base"
@@ -20,6 +21,7 @@ module VMC
20
21
  autoload :Misc, "#{ROOT}/cli/commands/misc"
21
22
  autoload :Services, "#{ROOT}/cli/commands/services"
22
23
  autoload :User, "#{ROOT}/cli/commands/user"
24
+ autoload :Manifest, "#{ROOT}/cli/commands/manifest"
23
25
  end
24
26
 
25
27
  end
data/lib/vmc/client.rb CHANGED
@@ -60,11 +60,11 @@ class VMC::Client
60
60
  # Global listing of services that are available on the target system
61
61
  def services_info
62
62
  check_login_status
63
- json_get(VMC::GLOBAL_SERVICES_PATH)
63
+ json_get(path(VMC::GLOBAL_SERVICES_PATH))
64
64
  end
65
65
 
66
66
  def runtimes_info
67
- json_get(VMC::GLOBAL_RUNTIMES_PATH)
67
+ json_get(path(VMC::GLOBAL_RUNTIMES_PATH))
68
68
  end
69
69
 
70
70
  ######################################################
@@ -86,7 +86,7 @@ class VMC::Client
86
86
 
87
87
  def update_app(name, manifest)
88
88
  check_login_status
89
- json_put("#{VMC::APPS_PATH}/#{name}", manifest)
89
+ json_put(path(VMC::APPS_PATH, name), manifest)
90
90
  end
91
91
 
92
92
  def upload_app(name, zipfile, resource_manifest=nil)
@@ -103,29 +103,29 @@ class VMC::Client
103
103
  upload_data[:application] = file
104
104
  end
105
105
  upload_data[:resources] = resource_manifest.to_json if resource_manifest
106
- http_post("#{VMC::APPS_PATH}/#{name}/application", upload_data)
106
+ http_post(path(VMC::APPS_PATH, name, "application"), upload_data)
107
107
  rescue RestClient::ServerBrokeConnection
108
108
  retry
109
109
  end
110
110
 
111
111
  def delete_app(name)
112
112
  check_login_status
113
- http_delete("#{VMC::APPS_PATH}/#{name}")
113
+ http_delete(path(VMC::APPS_PATH, name))
114
114
  end
115
115
 
116
116
  def app_info(name)
117
117
  check_login_status
118
- json_get("#{VMC::APPS_PATH}/#{name}")
118
+ json_get(path(VMC::APPS_PATH, name))
119
119
  end
120
120
 
121
121
  def app_update_info(name)
122
122
  check_login_status
123
- json_get("#{VMC::APPS_PATH}/#{name}/update")
123
+ json_get(path(VMC::APPS_PATH, name, "update"))
124
124
  end
125
125
 
126
126
  def app_stats(name)
127
127
  check_login_status
128
- stats_raw = json_get("#{VMC::APPS_PATH}/#{name}/stats")
128
+ stats_raw = json_get(path(VMC::APPS_PATH, name, "stats"))
129
129
  stats = []
130
130
  stats_raw.each_pair do |k, entry|
131
131
  # Skip entries with no stats
@@ -139,20 +139,20 @@ class VMC::Client
139
139
 
140
140
  def app_instances(name)
141
141
  check_login_status
142
- json_get("#{VMC::APPS_PATH}/#{name}/instances")
142
+ json_get(path(VMC::APPS_PATH, name, "instances"))
143
143
  end
144
144
 
145
145
  def app_crashes(name)
146
146
  check_login_status
147
- json_get("#{VMC::APPS_PATH}/#{name}/crashes")
147
+ json_get(path(VMC::APPS_PATH, name, "crashes"))
148
148
  end
149
149
 
150
150
  # List the directory or download the actual file indicated by
151
151
  # the path.
152
152
  def app_files(name, path, instance=0)
153
153
  check_login_status
154
- url = "#{VMC::APPS_PATH}/#{name}/instances/#{instance}/files/#{path}"
155
- url.gsub!('//', '/')
154
+ path = path.gsub('//', '/')
155
+ url = path(VMC::APPS_PATH, name, "instances", instance, "files", path)
156
156
  _, body, headers = http_get(url)
157
157
  body
158
158
  end
@@ -192,7 +192,7 @@ class VMC::Client
192
192
 
193
193
  raise TargetError, "Service [#{service}] is not a valid service choice" unless service_hash
194
194
  service_hash[:name] = name
195
- json_post(VMC::SERVICES_PATH, service_hash)
195
+ json_post(path(VMC::SERVICES_PATH), service_hash)
196
196
  end
197
197
 
198
198
  def delete_service(name)
@@ -200,7 +200,7 @@ class VMC::Client
200
200
  svcs = services || []
201
201
  names = svcs.collect { |s| s[:name] }
202
202
  raise TargetError, "Service [#{name}] not a valid service" unless names.include? name
203
- http_delete("#{VMC::SERVICES_PATH}/#{name}")
203
+ http_delete(path(VMC::SERVICES_PATH, name))
204
204
  end
205
205
 
206
206
  def bind_service(service, appname)
@@ -270,7 +270,7 @@ class VMC::Client
270
270
  # Auth token can be retained and used in creating
271
271
  # new clients, avoiding login.
272
272
  def login(user, password)
273
- status, body, headers = json_post("#{VMC::USERS_PATH}/#{user}/tokens", {:password => password})
273
+ status, body, headers = json_post(path(VMC::USERS_PATH, user, "tokens"), {:password => password})
274
274
  response_info = json_parse(body)
275
275
  if response_info
276
276
  @user = user
@@ -281,10 +281,10 @@ class VMC::Client
281
281
  # sets the password for the current logged user
282
282
  def change_password(new_password)
283
283
  check_login_status
284
- user_info = json_get("#{VMC::USERS_PATH}/#{@user}")
284
+ user_info = json_get(path(VMC::USERS_PATH, @user))
285
285
  if user_info
286
286
  user_info[:password] = new_password
287
- json_put("#{VMC::USERS_PATH}/#{@user}", user_info)
287
+ json_put(path(VMC::USERS_PATH, @user), user_info)
288
288
  end
289
289
  end
290
290
 
@@ -311,13 +311,23 @@ class VMC::Client
311
311
 
312
312
  def delete_user(user_email)
313
313
  check_login_status
314
- http_delete("#{VMC::USERS_PATH}/#{user_email}")
314
+ http_delete(path(VMC::USERS_PATH, user_email))
315
315
  end
316
316
 
317
317
  ######################################################
318
318
 
319
+ def self.path(*path)
320
+ path.flatten.collect { |x|
321
+ URI.encode x, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
322
+ }.join("/")
323
+ end
324
+
319
325
  private
320
326
 
327
+ def path(*args, &blk)
328
+ self.class.path(*args, &blk)
329
+ end
330
+
321
331
  def json_get(url)
322
332
  status, body, headers = http_get(url, 'application/json')
323
333
  json_parse(body)
@@ -370,7 +380,7 @@ class VMC::Client
370
380
  end
371
381
 
372
382
  req = {
373
- :method => method, :url => "#{@target}#{path}",
383
+ :method => method, :url => "#{@target}/#{path}",
374
384
  :payload => payload, :headers => headers, :multipart => true
375
385
  }
376
386
  status, body, response_headers = perform_http_request(req)
data/lib/vmc/const.rb CHANGED
@@ -9,14 +9,14 @@ module VMC
9
9
  DEFAULT_LOCAL_TARGET = 'http://api.vcap.me'
10
10
 
11
11
  # General Paths
12
- INFO_PATH = '/info'
13
- GLOBAL_SERVICES_PATH = '/info/services'
14
- GLOBAL_RUNTIMES_PATH = '/info/runtimes'
15
- RESOURCES_PATH = '/resources'
12
+ INFO_PATH = 'info'
13
+ GLOBAL_SERVICES_PATH = ['info', 'services']
14
+ GLOBAL_RUNTIMES_PATH = ['info', 'runtimes']
15
+ RESOURCES_PATH = 'resources'
16
16
 
17
17
  # User specific paths
18
- APPS_PATH = '/apps'
19
- SERVICES_PATH = '/services'
20
- USERS_PATH = '/users'
18
+ APPS_PATH = 'apps'
19
+ SERVICES_PATH = 'services'
20
+ USERS_PATH = 'users'
21
21
 
22
22
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmc
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.15
4
+ prerelease: 7
5
+ version: 0.3.16.beta.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - VMware
@@ -19,20 +19,23 @@ dependencies:
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
- - - ~>
22
+ - - ">="
23
23
  - !ruby/object:Gem::Version
24
24
  version: 1.5.1
25
+ - - <
26
+ - !ruby/object:Gem::Version
27
+ version: 1.7.0
25
28
  type: :runtime
26
29
  version_requirements: *id001
27
30
  - !ruby/object:Gem::Dependency
28
- name: rubyzip2
31
+ name: rubyzip
29
32
  prerelease: false
30
33
  requirement: &id002 !ruby/object:Gem::Requirement
31
34
  none: false
32
35
  requirements:
33
36
  - - ~>
34
37
  - !ruby/object:Gem::Version
35
- version: 2.0.1
38
+ version: 0.9.4
36
39
  type: :runtime
37
40
  version_requirements: *id002
38
41
  - !ruby/object:Gem::Dependency
@@ -83,38 +86,49 @@ dependencies:
83
86
  type: :runtime
84
87
  version_requirements: *id006
85
88
  - !ruby/object:Gem::Dependency
86
- name: rake
89
+ name: uuidtools
87
90
  prerelease: false
88
91
  requirement: &id007 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 2.1.0
97
+ type: :runtime
98
+ version_requirements: *id007
99
+ - !ruby/object:Gem::Dependency
100
+ name: rake
101
+ prerelease: false
102
+ requirement: &id008 !ruby/object:Gem::Requirement
89
103
  none: false
90
104
  requirements:
91
105
  - - ">="
92
106
  - !ruby/object:Gem::Version
93
107
  version: "0"
94
108
  type: :development
95
- version_requirements: *id007
109
+ version_requirements: *id008
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: rspec
98
112
  prerelease: false
99
- requirement: &id008 !ruby/object:Gem::Requirement
113
+ requirement: &id009 !ruby/object:Gem::Requirement
100
114
  none: false
101
115
  requirements:
102
116
  - - ~>
103
117
  - !ruby/object:Gem::Version
104
118
  version: 1.3.0
105
119
  type: :development
106
- version_requirements: *id008
120
+ version_requirements: *id009
107
121
  - !ruby/object:Gem::Dependency
108
122
  name: webmock
109
123
  prerelease: false
110
- requirement: &id009 !ruby/object:Gem::Requirement
124
+ requirement: &id010 !ruby/object:Gem::Requirement
111
125
  none: false
112
126
  requirements:
113
127
  - - "="
114
128
  - !ruby/object:Gem::Version
115
129
  version: 1.5.0
116
130
  type: :development
117
- version_requirements: *id009
131
+ version_requirements: *id010
118
132
  description: Client library and CLI that provides access to the VMware Cloud Application Platform.
119
133
  email: support@vmware.com
120
134
  executables:
@@ -132,6 +146,7 @@ files:
132
146
  - lib/cli/commands/admin.rb
133
147
  - lib/cli/commands/apps.rb
134
148
  - lib/cli/commands/base.rb
149
+ - lib/cli/commands/manifest.rb
135
150
  - lib/cli/commands/misc.rb
136
151
  - lib/cli/commands/services.rb
137
152
  - lib/cli/commands/user.rb
@@ -139,6 +154,7 @@ files:
139
154
  - lib/cli/core_ext.rb
140
155
  - lib/cli/errors.rb
141
156
  - lib/cli/frameworks.rb
157
+ - lib/cli/manifest_helper.rb
142
158
  - lib/cli/runner.rb
143
159
  - lib/cli/services_helper.rb
144
160
  - lib/cli/tunnel_helper.rb
@@ -171,9 +187,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
187
  required_rubygems_version: !ruby/object:Gem::Requirement
172
188
  none: false
173
189
  requirements:
174
- - - ">="
190
+ - - ">"
175
191
  - !ruby/object:Gem::Version
176
- version: "0"
192
+ version: 1.3.1
177
193
  requirements: []
178
194
 
179
195
  rubyforge_project: