vmc 0.3.13 → 0.3.14.beta.3

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
@@ -62,6 +62,8 @@ MIT license, please see the LICENSE file. All rights reserved._
62
62
  bind-service <servicename> <appname> Bind a service to an application
63
63
  unbind-service <servicename> <appname> Unbind service from the application
64
64
  clone-services <src-app> <dest-app> Clone service bindings from <src-app> application to <dest-app>
65
+ tunnel <servicename> [--port] Create a local tunnel to a service
66
+ tunnel <servicename> <clientcmd> Create a local tunnel to a service and start a local client
65
67
 
66
68
  Administration
67
69
  user Display user account information
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rack', '~> 1.2.0'
4
+ gem 'caldecott', '= 0.0.3'
5
+ gem 'bundler'
6
+ gem 'em-websocket'
7
+ gem 'async_sinatra'
8
+ gem 'thin'
9
+ gem 'json'
10
+ gem 'uuidtools'
@@ -0,0 +1,48 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.6)
5
+ async_sinatra (0.5.0)
6
+ rack (>= 1.2.1)
7
+ sinatra (>= 1.0)
8
+ caldecott (0.0.3)
9
+ addressable (= 2.2.6)
10
+ async_sinatra (= 0.5.0)
11
+ em-http-request (= 0.3.0)
12
+ em-websocket (= 0.3.1)
13
+ json (= 1.6.1)
14
+ uuidtools (= 2.1.2)
15
+ daemons (1.1.4)
16
+ em-http-request (0.3.0)
17
+ addressable (>= 2.0.0)
18
+ escape_utils
19
+ eventmachine (>= 0.12.9)
20
+ em-websocket (0.3.1)
21
+ addressable (>= 2.1.1)
22
+ eventmachine (>= 0.12.9)
23
+ escape_utils (0.2.4)
24
+ eventmachine (0.12.10)
25
+ json (1.6.1)
26
+ rack (1.2.4)
27
+ sinatra (1.2.7)
28
+ rack (~> 1.1)
29
+ tilt (>= 1.2.2, < 2.0)
30
+ thin (1.2.11)
31
+ daemons (>= 1.0.9)
32
+ eventmachine (>= 0.12.6)
33
+ rack (>= 1.0.0)
34
+ tilt (1.3.3)
35
+ uuidtools (2.1.2)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ async_sinatra
42
+ bundler
43
+ caldecott (= 0.0.3)
44
+ em-websocket
45
+ json
46
+ rack (~> 1.2.0)
47
+ thin
48
+ uuidtools
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (c) 2009-2011 VMware, Inc.
3
+ $:.unshift(File.dirname(__FILE__) + '/lib')
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+
8
+ require 'caldecott'
9
+ require 'sinatra'
10
+ require 'json'
11
+ require 'eventmachine'
12
+
13
+ port = ENV['VMC_APP_PORT']
14
+ port ||= 8081
15
+
16
+ # add vcap specific stuff to Caldecott
17
+ class VcapHttpTunnel < Caldecott::Server::HttpTunnel
18
+ get '/info' do
19
+ { "version" => '0.0.4' }.to_json
20
+ end
21
+
22
+ def self.get_tunnels
23
+ super
24
+ end
25
+
26
+ get '/services' do
27
+ services_env = ENV['VMC_SERVICES']
28
+ return "no services env" if services_env.nil? or services_env.empty?
29
+ services_env
30
+ end
31
+
32
+ get '/services/:service' do |service_name|
33
+ services_env = ENV['VMC_SERVICES']
34
+ not_found if services_env.nil?
35
+
36
+ services = JSON.parse(services_env)
37
+ service = services.find { |s| s["name"] == service_name }
38
+ not_found if service.nil?
39
+ service["options"].to_json
40
+ end
41
+ end
42
+
43
+ VcapHttpTunnel.run!(:port => port, :auth_token => ENV["CALDECOTT_AUTH"])
@@ -0,0 +1,11 @@
1
+ redis:
2
+ redis-cli: redis-cli -h ${host} -p ${port} -a ${password}
3
+
4
+ mysql:
5
+ mysql: mysql --protocol=TCP --host=${host} --port=${port} --user=${user} --password=${password} ${name}
6
+
7
+ mongodb:
8
+ mongo: mongo --host ${host} --port ${port} -u ${user} -p ${password} ${name}
9
+
10
+ postgresql:
11
+ psql: PGPASSWORD='${password}' psql -h ${host} -p ${port} -d ${name} -U ${user} -w
data/lib/cli.rb CHANGED
@@ -11,6 +11,7 @@ module VMC
11
11
  autoload :Runner, "#{ROOT}/cli/runner"
12
12
  autoload :ZipUtil, "#{ROOT}/cli/zip_util"
13
13
  autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
14
+ autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
14
15
 
15
16
  module Command
16
17
  autoload :Base, "#{ROOT}/cli/commands/base"
@@ -185,7 +185,7 @@ module VMC::Cli::Command
185
185
  uris << url
186
186
  app[:uris] = uris
187
187
  client.update_app(appname, app)
188
- display "Succesfully mapped url".green
188
+ display "Successfully mapped url".green
189
189
  end
190
190
 
191
191
  def unmap(appname, url)
@@ -196,7 +196,7 @@ module VMC::Cli::Command
196
196
  err "Invalid url" unless deleted
197
197
  app[:uris] = uris
198
198
  client.update_app(appname, app)
199
- display "Succesfully unmapped url".green
199
+ display "Successfully unmapped url".green
200
200
 
201
201
  end
202
202
 
@@ -268,6 +268,8 @@ module VMC::Cli::Command
268
268
  end
269
269
 
270
270
  def logs(appname)
271
+ # Check if we have an app before progressing further
272
+ client.app_info(appname)
271
273
  return grab_all_logs(appname) if @options[:all] && !@options[:instance]
272
274
  instance = @options[:instance] || '0'
273
275
  grab_logs(appname, instance)
@@ -686,7 +688,7 @@ module VMC::Cli::Command
686
688
 
687
689
  display "The following provisioned services are available"
688
690
  name = ask(
689
- "Please select one you which to prevision",
691
+ "Please select one you wish to use",
690
692
  { :indexed => true,
691
693
  :choices => user_services.collect { |s| s[:name] }
692
694
  }
@@ -38,7 +38,7 @@ module VMC::Cli::Command
38
38
  exit(false)
39
39
  else
40
40
  VMC::Cli::Config.store_target(target_url)
41
- say "Succesfully targeted to [#{target_url}]".green
41
+ say "Successfully targeted to [#{target_url}]".green
42
42
  end
43
43
  end
44
44
 
@@ -2,6 +2,7 @@ module VMC::Cli::Command
2
2
 
3
3
  class Services < Base
4
4
  include VMC::Cli::ServicesHelper
5
+ include VMC::Cli::TunnelHelper
5
6
 
6
7
  def services
7
8
  ss = client.services_info
@@ -81,5 +82,96 @@ module VMC::Cli::Command
81
82
  check_app_for_restart(dest_app)
82
83
  end
83
84
 
85
+ def tunnel(service=nil, client_name=nil)
86
+ unless defined? Caldecott
87
+ display "To use `vmc tunnel', you must first install Caldecott:"
88
+ display ""
89
+ display "\tgem install caldecott"
90
+ display ""
91
+ display "Note that you'll need a C compiler. If you're on OS X, Xcode"
92
+ display "will provide one. If you're on Windows, try DevKit."
93
+ display ""
94
+ display "This manual step will be removed in the future."
95
+ display ""
96
+ err "Caldecott is not installed."
97
+ end
98
+
99
+ ps = client.services
100
+ err "No services available to tunnel to" if ps.empty?
101
+
102
+ unless service
103
+ choices = ps.collect { |s| s[:name] }.sort
104
+ service = ask(
105
+ "Which service to tunnel to?",
106
+ :choices => choices,
107
+ :indexed => true
108
+ )
109
+ end
110
+
111
+ info = ps.select { |s| s[:name] == service }.first
112
+
113
+ err "Unknown service '#{service}'" unless info
114
+
115
+ # TODO: rather than default to a particular port, we should get
116
+ # the defaults based on the service name.. i.e. known services should
117
+ # have known local default ports for this side of the tunnel.
118
+ port = pick_tunnel_port(@options[:port] || 10000)
119
+
120
+ raise VMC::Client::AuthError unless client.logged_in?
121
+
122
+ if not tunnel_pushed?
123
+ display "Deploying tunnel application '#{tunnel_appname}'."
124
+ auth = ask("Create a password", :echo => "*")
125
+ push_caldecott(auth)
126
+ bind_service_banner(service, tunnel_appname, false)
127
+ start_caldecott
128
+ else
129
+ auth = ask("Password", :echo => "*")
130
+ end
131
+
132
+ if not tunnel_healthy?(auth)
133
+ display "Redeploying tunnel application '#{tunnel_appname}'."
134
+
135
+ # We don't expect caldecott not to be running, so take the
136
+ # most aggressive restart method.. delete/re-push
137
+ client.delete_app(tunnel_appname)
138
+ invalidate_tunnel_app_info
139
+
140
+ push_caldecott(auth)
141
+ bind_service_banner(service, tunnel_appname, false)
142
+ start_caldecott
143
+ end
144
+
145
+ if not tunnel_bound?(service)
146
+ bind_service_banner(service, tunnel_appname)
147
+ end
148
+
149
+ conn_info = tunnel_connection_info info[:vendor], service, auth
150
+ display_tunnel_connection_info(conn_info)
151
+ start_tunnel(service, port, conn_info, auth)
152
+
153
+ clients = get_clients_for(info[:vendor])
154
+ if clients.empty?
155
+ which = "none"
156
+ else
157
+ which = client_name || ask(
158
+ "Which client would you like to start?",
159
+ :choices => ["none"] + clients.keys,
160
+ :indexed => true
161
+ )
162
+ end
163
+
164
+ if which == "none"
165
+ wait_for_tunnel_end
166
+ else
167
+ wait_for_tunnel_start(port)
168
+ start_local_prog(which, local_prog_cmdline(clients[which], port, conn_info))
169
+ end
170
+ end
171
+
172
+ def get_clients_for(type)
173
+ conf = VMC::Cli::Config.clients
174
+ conf[type] || {}
175
+ end
84
176
  end
85
177
  end
@@ -15,6 +15,7 @@ module VMC::Cli::Command
15
15
  tries ||= 0
16
16
 
17
17
  unless no_prompt
18
+ display "Attempting login to [#{target_url}]" if target_url
18
19
  email ||= ask("Email")
19
20
  password ||= ask("Password", :echo => "*")
20
21
  end
data/lib/cli/config.rb CHANGED
@@ -14,6 +14,9 @@ module VMC::Cli
14
14
  TOKEN_FILE = '~/.vmc_token'
15
15
  INSTANCES_FILE = '~/.vmc_instances'
16
16
  ALIASES_FILE = '~/.vmc_aliases'
17
+ CLIENTS_FILE = '~/.vmc_clients'
18
+
19
+ STOCK_CLIENTS = File.expand_path("../../../config/clients.yml", __FILE__)
17
20
 
18
21
  class << self
19
22
  attr_accessor :colorize
@@ -102,6 +105,30 @@ module VMC::Cli
102
105
  File.open(aliases_file, 'wb') {|f| f.write(aliases.to_yaml)}
103
106
  end
104
107
 
108
+ def deep_merge(a, b)
109
+ merge = proc do |_, old, new|
110
+ if new.is_a?(Hash) and old.is_a?(Hash)
111
+ old.merge(new, &merge)
112
+ else
113
+ new
114
+ end
115
+ end
116
+
117
+ a.merge(b, &merge)
118
+ end
119
+
120
+ def clients
121
+ return @clients if @clients
122
+
123
+ stock = YAML.load_file(STOCK_CLIENTS)
124
+ if File.exists? CLIENTS_FILE
125
+ user = YAML.load_file(CLIENTS_FILE)
126
+ @clients = deep_merge(stock, user)
127
+ else
128
+ @clients = stock
129
+ end
130
+ end
131
+
105
132
  def lock_and_read(file)
106
133
  File.open(file, "r") {|f|
107
134
  f.flock(File::LOCK_EX)
data/lib/cli/runner.rb CHANGED
@@ -77,6 +77,8 @@ class VMC::Cli::Runner
77
77
  opts.on('-v', '--version') { set_cmd(:misc, :version) }
78
78
  opts.on('-h', '--help') { puts "#{command_usage}\n"; exit }
79
79
 
80
+ opts.on('--port PORT') { |port| @options[:port] = port }
81
+
80
82
  opts.on('--runtime RUNTIME') { |rt| @options[:runtime] = rt }
81
83
 
82
84
  # deprecated
@@ -367,6 +369,12 @@ class VMC::Cli::Runner
367
369
  usage('vmc unalias <alias>')
368
370
  set_cmd(:misc, :unalias, 1)
369
371
 
372
+ when 'tunnel'
373
+ usage('vmc tunnel [servicename] [clientcmd] [--port port]')
374
+ set_cmd(:services, :tunnel, 0) if @args.size == 0
375
+ set_cmd(:services, :tunnel, 1) if @args.size == 1
376
+ set_cmd(:services, :tunnel, 2) if @args.size == 2
377
+
370
378
  when 'help'
371
379
  display_help if @args.size == 0
372
380
  @help_only = true
@@ -0,0 +1,289 @@
1
+ # Copyright (c) 2009-2011 VMware, Inc.
2
+
3
+ require 'addressable/uri'
4
+
5
+ begin
6
+ require 'caldecott'
7
+ rescue LoadError
8
+ end
9
+
10
+ module VMC::Cli
11
+ module TunnelHelper
12
+ PORT_RANGE = 10
13
+
14
+ HELPER_APP = File.expand_path("../../../caldecott_helper", __FILE__)
15
+
16
+ # bump this AND the version info reported by HELPER_APP/server.rb
17
+ # this is to keep the helper in sync with any updates here
18
+ HELPER_VERSION = '0.0.4'
19
+
20
+ def tunnel_uniquename
21
+ random_service_name(tunnel_appname)
22
+ end
23
+
24
+ def tunnel_appname
25
+ "caldecott"
26
+ end
27
+
28
+ def tunnel_app_info
29
+ return @tun_app_info if @tunnel_app_info
30
+ begin
31
+ @tun_app_info = client.app_info(tunnel_appname)
32
+ rescue => e
33
+ @tun_app_info = nil
34
+ end
35
+ end
36
+
37
+ def tunnel_url
38
+ return @tunnel_url if @tunnel_url
39
+
40
+ tun_url = tunnel_app_info[:uris][0]
41
+
42
+ ["https", "http"].each do |scheme|
43
+ url = "#{scheme}://#{tun_url}"
44
+ begin
45
+ RestClient.get(url)
46
+
47
+ # https failed
48
+ rescue Errno::ECONNREFUSED
49
+
50
+ # we expect a 404 since this request isn't auth'd
51
+ rescue RestClient::ResourceNotFound
52
+ return @tunnel_url = url
53
+ end
54
+ end
55
+
56
+ err "Cannot determine URL for #{tun_url}"
57
+ end
58
+
59
+ def invalidate_tunnel_app_info
60
+ @tunnel_url = nil
61
+ @tunnel_app_info = nil
62
+ end
63
+
64
+ def tunnel_pushed?
65
+ not tunnel_app_info.nil?
66
+ end
67
+
68
+ def tunnel_healthy?(token)
69
+ return false unless tunnel_app_info[:state] == 'STARTED'
70
+
71
+ begin
72
+ response = RestClient.get(
73
+ "#{tunnel_url}/info",
74
+ "Auth-Token" => token
75
+ )
76
+
77
+ info = JSON.parse(response)
78
+ if info["version"] == HELPER_VERSION
79
+ true
80
+ else
81
+ stop_caldecott
82
+ false
83
+ end
84
+ rescue RestClient::Exception
85
+ stop_caldecott
86
+ false
87
+ end
88
+ end
89
+
90
+ def tunnel_bound?(service)
91
+ tunnel_app_info[:services].include?(service)
92
+ end
93
+
94
+ def tunnel_connection_info(type, service, token)
95
+ display "Getting tunnel connection info: ", false
96
+ response = nil
97
+ 10.times do
98
+ begin
99
+ response = RestClient.get("#{tunnel_url}/services/#{service}", "Auth-Token" => token)
100
+ break
101
+ rescue RestClient::Exception
102
+ sleep 1
103
+ end
104
+
105
+ display ".", false
106
+ end
107
+
108
+ unless response
109
+ err "Expected remote tunnel to know about #{service}, but it doesn't"
110
+ end
111
+
112
+ display "OK".green
113
+
114
+ info = JSON.parse(response)
115
+ case type
116
+ when "rabbitmq"
117
+ uri = Addressable::URI.parse info["url"]
118
+ info["hostname"] = uri.host
119
+ info["port"] = uri.port
120
+ info["vhost"] = uri.path[1..-1]
121
+ info["user"] = uri.user
122
+ info["password"] = uri.password
123
+ info.delete "url"
124
+
125
+ # we use "db" as the "name" for mongo
126
+ # existing "name" is junk
127
+ when "mongodb"
128
+ info["name"] = info["db"]
129
+ info.delete "db"
130
+
131
+ # our "name" is irrelevant for redis
132
+ when "redis"
133
+ info.delete "name"
134
+ end
135
+
136
+ ['hostname', 'port', 'password'].each do |k|
137
+ err "Could not determine #{k} for #{service}" if info[k].nil?
138
+ end
139
+
140
+ info
141
+ end
142
+
143
+ def display_tunnel_connection_info(info)
144
+ display ''
145
+ display "Service connection info: "
146
+
147
+ to_show = [nil, nil, nil] # reserved for user, pass, db name
148
+ info.keys.each do |k|
149
+ case k
150
+ when "host", "hostname", "port", "node_id"
151
+ # skip
152
+ when "user", "username"
153
+ # prefer "username" over "user"
154
+ to_show[0] = k unless to_show[0] == "username"
155
+ when "password"
156
+ to_show[1] = k
157
+ when "name"
158
+ to_show[2] = k
159
+ else
160
+ to_show << k
161
+ end
162
+ end
163
+ to_show.compact!
164
+
165
+ align_len = to_show.collect(&:size).max + 1
166
+
167
+ to_show.each do |k|
168
+ # TODO: modify the server services rest call to have explicit knowledge
169
+ # about the items to return. It should return all of them if
170
+ # the service is unknown so that we don't have to do this weird
171
+ # filtering.
172
+ display " #{k.ljust align_len}: ", false
173
+ display "#{info[k]}".yellow
174
+ end
175
+ display ''
176
+ end
177
+
178
+ def start_tunnel(service, local_port, conn_info, auth)
179
+ display "Starting tunnel to #{service.bold} on port #{local_port.to_s.bold}."
180
+
181
+ @local_tunnel_thread = Thread.new do
182
+ Caldecott::Client.start({
183
+ :local_port => local_port,
184
+ :tun_url => tunnel_url,
185
+ :dst_host => conn_info['hostname'],
186
+ :dst_port => conn_info['port'],
187
+ :log_file => STDOUT,
188
+ :log_level => "ERROR",
189
+ :auth_token => auth,
190
+ :quiet => true
191
+ })
192
+ end
193
+
194
+ at_exit { @local_tunnel_thread.kill }
195
+ end
196
+
197
+ def pick_tunnel_port(port)
198
+ original = port
199
+
200
+ PORT_RANGE.times do |n|
201
+ begin
202
+ TCPSocket.open('localhost', port)
203
+ port += 1
204
+ rescue => e
205
+ return port
206
+ end
207
+ end
208
+
209
+ err "Could not pick a port between #{original} and #{original + PORT_RANGE - 1}"
210
+ end
211
+
212
+ def wait_for_tunnel_start(port)
213
+ 10.times do |n|
214
+ begin
215
+ TCPSocket.open('localhost', port)
216
+ display '' if n > 0
217
+ return true
218
+ rescue => e
219
+ display "Waiting for local tunnel to become available", false if n == 0
220
+ display '.', false
221
+ sleep 1
222
+ end
223
+ end
224
+ err "Could not connect to local tunnel."
225
+ end
226
+
227
+ def wait_for_tunnel_end
228
+ display "Open another shell to run command-line clients or"
229
+ display "use a UI tool to connect using the displayed information."
230
+ display "Press Ctrl-C to exit..."
231
+ @local_tunnel_thread.join
232
+ end
233
+
234
+ def local_prog_cmdline(command, local_port, tunnel_info)
235
+ cmd = command.dup
236
+ cmd.gsub!(/\$\{\s*([^\}]+)\s*\}/) do
237
+ case $1
238
+ when "host"
239
+ # TODO: determine proper host
240
+ "localhost"
241
+ when "port"
242
+ local_port
243
+ when "user", "username"
244
+ tunnel_info["username"]
245
+ else
246
+ tunnel_info[$1] || err("Unknown symbol '#{$1}'")
247
+ end
248
+ end
249
+ cmd
250
+ end
251
+
252
+ def start_local_prog(which, cmdline)
253
+ display "Launching '#{cmdline}'"
254
+ display ''
255
+ unless system(cmdline)
256
+ err "Failed to start '#{which}' client; is it in your $PATH?"
257
+ end
258
+ end
259
+
260
+ def push_caldecott(token)
261
+ client.create_app(
262
+ tunnel_appname,
263
+ { :name => tunnel_appname,
264
+ :staging => {:framework => "sinatra"},
265
+ :uris => ["#{tunnel_uniquename}.#{VMC::Cli::Config.suggest_url}"],
266
+ :instances => 1,
267
+ :resources => {:memory => 64},
268
+ :env => ["CALDECOTT_AUTH=#{token}"]
269
+ }
270
+ )
271
+
272
+ Command::Apps.new({}).send(:upload_app_bits, tunnel_appname, HELPER_APP)
273
+
274
+ invalidate_tunnel_app_info
275
+ end
276
+
277
+ def stop_caldecott
278
+ Command::Apps.new({}).stop(tunnel_appname)
279
+
280
+ invalidate_tunnel_app_info
281
+ end
282
+
283
+ def start_caldecott
284
+ Command::Apps.new({}).start(tunnel_appname)
285
+
286
+ invalidate_tunnel_app_info
287
+ end
288
+ end
289
+ end
data/lib/cli/usage.rb CHANGED
@@ -78,6 +78,8 @@ Currently available vmc commands are:
78
78
  bind-service <servicename> <appname> Bind a service to an application
79
79
  unbind-service <servicename> <appname> Unbind service from the application
80
80
  clone-services <src-app> <dest-app> Clone service bindings from <src-app> application to <dest-app>
81
+ tunnel <servicename> [--port] Create a local tunnel to a service
82
+ tunnel <servicename> <clientcmd> Create a local tunnel to a service and start a local client
81
83
 
82
84
  Administration
83
85
  user Display user account information
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.13'
5
+ VERSION = '0.3.14.beta.3'
6
6
  end
7
7
  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.13
4
+ prerelease: 7
5
+ version: 0.3.14.beta.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - VMware
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-11-02 00:00:00 -07:00
13
+ date: 2011-11-14 00:00:00 -08:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -68,42 +68,53 @@ dependencies:
68
68
  requirements:
69
69
  - - ~>
70
70
  - !ruby/object:Gem::Version
71
- version: 0.2.0
71
+ version: 0.3.0
72
72
  type: :runtime
73
73
  version_requirements: *id005
74
74
  - !ruby/object:Gem::Dependency
75
- name: rake
75
+ name: addressable
76
76
  prerelease: false
77
77
  requirement: &id006 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.6
83
+ type: :runtime
84
+ version_requirements: *id006
85
+ - !ruby/object:Gem::Dependency
86
+ name: rake
87
+ prerelease: false
88
+ requirement: &id007 !ruby/object:Gem::Requirement
78
89
  none: false
79
90
  requirements:
80
91
  - - ">="
81
92
  - !ruby/object:Gem::Version
82
93
  version: "0"
83
94
  type: :development
84
- version_requirements: *id006
95
+ version_requirements: *id007
85
96
  - !ruby/object:Gem::Dependency
86
97
  name: rspec
87
98
  prerelease: false
88
- requirement: &id007 !ruby/object:Gem::Requirement
99
+ requirement: &id008 !ruby/object:Gem::Requirement
89
100
  none: false
90
101
  requirements:
91
102
  - - ~>
92
103
  - !ruby/object:Gem::Version
93
104
  version: 1.3.0
94
105
  type: :development
95
- version_requirements: *id007
106
+ version_requirements: *id008
96
107
  - !ruby/object:Gem::Dependency
97
108
  name: webmock
98
109
  prerelease: false
99
- requirement: &id008 !ruby/object:Gem::Requirement
110
+ requirement: &id009 !ruby/object:Gem::Requirement
100
111
  none: false
101
112
  requirements:
102
113
  - - "="
103
114
  - !ruby/object:Gem::Version
104
115
  version: 1.5.0
105
116
  type: :development
106
- version_requirements: *id008
117
+ version_requirements: *id009
107
118
  description: Client library and CLI that provides access to the VMware Cloud Application Platform.
108
119
  email: support@vmware.com
109
120
  executables:
@@ -117,6 +128,7 @@ files:
117
128
  - LICENSE
118
129
  - README.md
119
130
  - Rakefile
131
+ - config/clients.yml
120
132
  - lib/cli/commands/admin.rb
121
133
  - lib/cli/commands/apps.rb
122
134
  - lib/cli/commands/base.rb
@@ -129,6 +141,7 @@ files:
129
141
  - lib/cli/frameworks.rb
130
142
  - lib/cli/runner.rb
131
143
  - lib/cli/services_helper.rb
144
+ - lib/cli/tunnel_helper.rb
132
145
  - lib/cli/usage.rb
133
146
  - lib/cli/version.rb
134
147
  - lib/cli/zip_util.rb
@@ -136,6 +149,9 @@ files:
136
149
  - lib/vmc/client.rb
137
150
  - lib/vmc/const.rb
138
151
  - lib/vmc.rb
152
+ - caldecott_helper/Gemfile
153
+ - caldecott_helper/Gemfile.lock
154
+ - caldecott_helper/server.rb
139
155
  - bin/vmc
140
156
  has_rdoc: true
141
157
  homepage: http://vmware.com
@@ -155,9 +171,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
171
  required_rubygems_version: !ruby/object:Gem::Requirement
156
172
  none: false
157
173
  requirements:
158
- - - ">="
174
+ - - ">"
159
175
  - !ruby/object:Gem::Version
160
- version: "0"
176
+ version: 1.3.1
161
177
  requirements: []
162
178
 
163
179
  rubyforge_project: