af 0.3.22 → 0.5.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +14 -6
  2. data/LICENSE +1277 -24
  3. data/Rakefile +24 -87
  4. data/bin/af +7 -2
  5. data/lib/af/version.rb +3 -0
  6. data/lib/vmc.rb +7 -2
  7. data/lib/vmc/cli.rb +475 -0
  8. data/lib/vmc/cli/app/app.rb +45 -0
  9. data/lib/vmc/cli/app/apps.rb +105 -0
  10. data/lib/vmc/cli/app/base.rb +82 -0
  11. data/lib/vmc/cli/app/crashes.rb +46 -0
  12. data/lib/vmc/cli/app/delete.rb +95 -0
  13. data/lib/vmc/cli/app/deprecated.rb +11 -0
  14. data/lib/vmc/cli/app/env.rb +78 -0
  15. data/lib/vmc/cli/app/files.rb +137 -0
  16. data/lib/vmc/cli/app/health.rb +26 -0
  17. data/lib/vmc/cli/app/instances.rb +53 -0
  18. data/lib/vmc/cli/app/logs.rb +76 -0
  19. data/lib/vmc/cli/app/push.rb +107 -0
  20. data/lib/vmc/cli/app/push/create.rb +150 -0
  21. data/lib/vmc/cli/app/push/interactions.rb +100 -0
  22. data/lib/vmc/cli/app/push/sync.rb +64 -0
  23. data/lib/vmc/cli/app/rename.rb +39 -0
  24. data/lib/vmc/cli/app/restart.rb +20 -0
  25. data/lib/vmc/cli/app/scale.rb +71 -0
  26. data/lib/vmc/cli/app/start.rb +93 -0
  27. data/lib/vmc/cli/app/stats.rb +67 -0
  28. data/lib/vmc/cli/app/stop.rb +27 -0
  29. data/lib/vmc/cli/domain/base.rb +12 -0
  30. data/lib/vmc/cli/domain/domains.rb +40 -0
  31. data/lib/vmc/cli/domain/map.rb +55 -0
  32. data/lib/vmc/cli/domain/unmap.rb +56 -0
  33. data/lib/vmc/cli/help.rb +16 -0
  34. data/lib/vmc/cli/interactive.rb +105 -0
  35. data/lib/vmc/cli/organization/base.rb +14 -0
  36. data/lib/vmc/cli/organization/create.rb +32 -0
  37. data/lib/vmc/cli/organization/delete.rb +73 -0
  38. data/lib/vmc/cli/organization/org.rb +45 -0
  39. data/lib/vmc/cli/organization/orgs.rb +35 -0
  40. data/lib/vmc/cli/organization/rename.rb +36 -0
  41. data/lib/vmc/cli/route/base.rb +12 -0
  42. data/lib/vmc/cli/route/map.rb +80 -0
  43. data/lib/vmc/cli/route/routes.rb +26 -0
  44. data/lib/vmc/cli/route/unmap.rb +94 -0
  45. data/lib/vmc/cli/service/base.rb +8 -0
  46. data/lib/vmc/cli/service/bind.rb +44 -0
  47. data/lib/vmc/cli/service/create.rb +126 -0
  48. data/lib/vmc/cli/service/delete.rb +86 -0
  49. data/lib/vmc/cli/service/rename.rb +35 -0
  50. data/lib/vmc/cli/service/service.rb +42 -0
  51. data/lib/vmc/cli/service/services.rb +115 -0
  52. data/lib/vmc/cli/service/unbind.rb +38 -0
  53. data/lib/vmc/cli/space/base.rb +21 -0
  54. data/lib/vmc/cli/space/create.rb +56 -0
  55. data/lib/vmc/cli/space/delete.rb +95 -0
  56. data/lib/vmc/cli/space/rename.rb +39 -0
  57. data/lib/vmc/cli/space/space.rb +64 -0
  58. data/lib/vmc/cli/space/spaces.rb +55 -0
  59. data/lib/vmc/cli/space/take.rb +16 -0
  60. data/lib/vmc/cli/start/base.rb +80 -0
  61. data/lib/vmc/cli/start/colors.rb +13 -0
  62. data/lib/vmc/cli/start/info.rb +122 -0
  63. data/lib/vmc/cli/start/login.rb +92 -0
  64. data/lib/vmc/cli/start/logout.rb +13 -0
  65. data/lib/vmc/cli/start/target.rb +64 -0
  66. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  67. data/lib/vmc/cli/start/targets.rb +16 -0
  68. data/lib/vmc/cli/user/base.rb +29 -0
  69. data/lib/vmc/cli/user/create.rb +39 -0
  70. data/lib/vmc/cli/user/delete.rb +25 -0
  71. data/lib/vmc/cli/user/passwd.rb +50 -0
  72. data/lib/vmc/cli/user/register.rb +42 -0
  73. data/lib/vmc/cli/user/users.rb +32 -0
  74. data/lib/vmc/constants.rb +13 -0
  75. data/lib/vmc/detect.rb +134 -0
  76. data/lib/vmc/errors.rb +17 -0
  77. data/lib/vmc/plugin.rb +56 -0
  78. data/lib/vmc/spacing.rb +89 -0
  79. data/lib/vmc/spec_helper.rb +1 -0
  80. data/lib/vmc/test_support.rb +4 -0
  81. data/lib/vmc/test_support/command_helper.rb +32 -0
  82. data/lib/vmc/test_support/common_input_examples.rb +14 -0
  83. data/lib/vmc/test_support/fake_home_dir.rb +16 -0
  84. data/lib/vmc/test_support/interact_helper.rb +29 -0
  85. data/lib/vmc/version.rb +3 -0
  86. data/spec/assets/hello-sinatra/Gemfile +3 -0
  87. data/spec/assets/hello-sinatra/main.rb +6 -0
  88. data/spec/features/new_user_flow_spec.rb +71 -0
  89. data/spec/spec_helper.rb +63 -0
  90. data/spec/vmc/cli/app/base_spec.rb +17 -0
  91. data/spec/vmc/cli/app/delete_spec.rb +188 -0
  92. data/spec/vmc/cli/app/instances_spec.rb +65 -0
  93. data/spec/vmc/cli/app/push/create_spec.rb +571 -0
  94. data/spec/vmc/cli/app/push_spec.rb +369 -0
  95. data/spec/vmc/cli/app/rename_spec.rb +104 -0
  96. data/spec/vmc/cli/app/scale_spec.rb +81 -0
  97. data/spec/vmc/cli/app/stats_spec.rb +62 -0
  98. data/spec/vmc/cli/domain/map_spec.rb +140 -0
  99. data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
  100. data/spec/vmc/cli/organization/orgs_spec.rb +108 -0
  101. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  102. data/spec/vmc/cli/route/map_spec.rb +138 -0
  103. data/spec/vmc/cli/route/unmap_spec.rb +215 -0
  104. data/spec/vmc/cli/service/bind_spec.rb +25 -0
  105. data/spec/vmc/cli/service/delete_spec.rb +22 -0
  106. data/spec/vmc/cli/service/rename_spec.rb +105 -0
  107. data/spec/vmc/cli/service/service_spec.rb +23 -0
  108. data/spec/vmc/cli/service/unbind_spec.rb +25 -0
  109. data/spec/vmc/cli/space/rename_spec.rb +102 -0
  110. data/spec/vmc/cli/space/spaces_spec.rb +104 -0
  111. data/spec/vmc/cli/start/info_spec.rb +153 -0
  112. data/spec/vmc/cli/start/login_spec.rb +71 -0
  113. data/spec/vmc/cli/user/create_spec.rb +54 -0
  114. data/spec/vmc/cli/user/passwd_spec.rb +102 -0
  115. data/spec/vmc/cli/user/register_spec.rb +148 -0
  116. data/spec/vmc/cli_spec.rb +448 -0
  117. data/spec/vmc/detect_spec.rb +54 -0
  118. metadata +231 -124
  119. data/README.md +0 -155
  120. data/caldecott_helper/Gemfile +0 -10
  121. data/caldecott_helper/Gemfile.lock +0 -48
  122. data/caldecott_helper/server.rb +0 -43
  123. data/config/clients.yml +0 -17
  124. data/config/micro/offline.conf +0 -2
  125. data/config/micro/paths.yml +0 -22
  126. data/config/micro/refresh_ip.rb +0 -20
  127. data/lib/cli.rb +0 -48
  128. data/lib/cli/commands/admin.rb +0 -81
  129. data/lib/cli/commands/apps.rb +0 -1358
  130. data/lib/cli/commands/base.rb +0 -233
  131. data/lib/cli/commands/manifest.rb +0 -56
  132. data/lib/cli/commands/micro.rb +0 -115
  133. data/lib/cli/commands/misc.rb +0 -147
  134. data/lib/cli/commands/services.rb +0 -217
  135. data/lib/cli/commands/user.rb +0 -70
  136. data/lib/cli/config.rb +0 -176
  137. data/lib/cli/console_helper.rb +0 -163
  138. data/lib/cli/core_ext.rb +0 -122
  139. data/lib/cli/errors.rb +0 -19
  140. data/lib/cli/file_helper.rb +0 -123
  141. data/lib/cli/frameworks.rb +0 -265
  142. data/lib/cli/manifest_helper.rb +0 -316
  143. data/lib/cli/runner.rb +0 -633
  144. data/lib/cli/services_helper.rb +0 -104
  145. data/lib/cli/tunnel_helper.rb +0 -336
  146. data/lib/cli/usage.rb +0 -129
  147. data/lib/cli/version.rb +0 -7
  148. data/lib/cli/zip_util.rb +0 -102
  149. data/lib/vmc/client.rb +0 -574
  150. data/lib/vmc/const.rb +0 -27
  151. data/lib/vmc/micro.rb +0 -56
  152. data/lib/vmc/micro/switcher/base.rb +0 -97
  153. data/lib/vmc/micro/switcher/darwin.rb +0 -19
  154. data/lib/vmc/micro/switcher/dummy.rb +0 -15
  155. data/lib/vmc/micro/switcher/linux.rb +0 -16
  156. data/lib/vmc/micro/switcher/windows.rb +0 -31
  157. data/lib/vmc/micro/vmrun.rb +0 -158
@@ -1,7 +0,0 @@
1
- module VMC
2
- module Cli
3
- # This version number is used as the RubyGem release version.
4
- # The internal VMC version number is VMC::VERSION.
5
- VERSION = '0.3.22'
6
- end
7
- end
@@ -1,102 +0,0 @@
1
- require 'fileutils'
2
- require 'zip/zipfilesystem'
3
- require 'pathname'
4
-
5
- module VMC::Cli
6
-
7
- class ZipUtil
8
-
9
- PACK_EXCLUSION_GLOBS = ['..', '.', '*~', '#*#', '*.log']
10
-
11
- class << self
12
-
13
- def to_dev_null
14
- if WINDOWS
15
- 'nul'
16
- else
17
- '/dev/null'
18
- end
19
- end
20
-
21
- def entry_lines(file)
22
- contents = nil
23
- unless VMC::Cli::Config.nozip
24
- contents = `unzip -l #{file} 2> #{to_dev_null}`
25
- contents = nil if $? != 0
26
- end
27
- # Do Ruby version if told to or native version failed
28
- unless contents
29
- entries = []
30
- Zip::ZipFile.foreach(file) { |zentry| entries << zentry }
31
- contents = entries.join("\n")
32
- end
33
- contents
34
- end
35
-
36
- def unpack(file, dest)
37
- unless VMC::Cli::Config.nozip
38
- FileUtils.mkdir(dest)
39
- `unzip -q #{file} -d #{dest} 2> #{to_dev_null}`
40
- return unless $? != 0
41
- end
42
- # Do Ruby version if told to or native version failed
43
- Zip::ZipFile.foreach(file) do |zentry|
44
- epath = "#{dest}/#{zentry}"
45
- dirname = File.dirname(epath)
46
- FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
47
- zentry.extract(epath) unless File.exists?(epath)
48
- end
49
- end
50
-
51
- def get_files_to_pack(dir)
52
- Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).select do |f|
53
- process = true
54
- PACK_EXCLUSION_GLOBS.each { |e| process = false if File.fnmatch(e, File.basename(f)) }
55
- process && File.exists?(f)
56
- end
57
- end
58
-
59
- def pack(dir, zipfile)
60
- unless VMC::Cli::Config.nozip
61
- excludes = PACK_EXCLUSION_GLOBS.map { |e| "\\#{e}" }
62
- excludes = excludes.join(' ')
63
- Dir.chdir(dir) do
64
- `zip -y -q -r #{zipfile} . -x #{excludes} 2> #{to_dev_null}`
65
- return unless $? != 0
66
- end
67
- end
68
- # Do Ruby version if told to or native version failed
69
- Zip::ZipFile::open(zipfile, true) do |zf|
70
- get_files_to_pack(dir).each do |f|
71
- zf.add(f.sub("#{dir}/",''), f)
72
- end
73
- end
74
- end
75
-
76
- BLOCKSIZE_TO_READ = 1024 * 1000
77
-
78
- # not a valid tar file, since tar files include last modified date which breaks it for
79
- # use in hashing. this method just wraps up everything for use in hashing.
80
- def tar(path)
81
- tar_filename = Pathname.new(path).realpath.to_path + '.tar'
82
- File.open(tar_filename, 'wb') do |tarfile|
83
- get_files_to_pack(path).each do |file|
84
- if File.file?(file)
85
- File.open(file, 'rb') do |f|
86
- while buffer = f.read(BLOCKSIZE_TO_READ)
87
- tarfile.write buffer
88
- end
89
- end
90
- else
91
- tarfile.write file.gsub(path, '')
92
- end
93
- end
94
- end
95
-
96
- tar_filename
97
-
98
- end
99
-
100
- end
101
- end
102
- end
@@ -1,574 +0,0 @@
1
- # VMC client
2
- #
3
- # Example:
4
- #
5
- # require 'vmc'
6
- # client = VMC::Client.new('api.vcap.me')
7
- # client.login(:user, :pass)
8
- # client.create('myapplication', manifest)
9
- # client.create_service('aws', 'redis', 'my_redis_service', opts);
10
- #
11
-
12
- require 'rubygems'
13
- require 'json/pure'
14
- require 'open-uri'
15
-
16
- require File.expand_path('../const', __FILE__)
17
-
18
- class VMC::Client
19
-
20
- def self.version
21
- VMC::VERSION
22
- end
23
-
24
- attr_reader :target, :host, :user, :proxy, :auth_token
25
- attr_accessor :trace, :infra
26
-
27
- # Error codes
28
- VMC_HTTP_ERROR_CODES = [ 400, 500 ]
29
-
30
- HTTP_TIMEOUT = ENV['TIMEOUT'] ? ENV['TIMEOUT'].to_i : 10*60
31
-
32
- # Errors
33
- class BadTarget < RuntimeError; end
34
- class AuthError < RuntimeError; end
35
- class TargetError < RuntimeError; end
36
- class NotFound < RuntimeError; end
37
- class BadResponse < RuntimeError; end
38
- class HTTPException < RuntimeError; end
39
-
40
- # Initialize new client to the target_uri with optional auth_token
41
- def initialize(target_url=VMC::DEFAULT_TARGET, auth_token=nil)
42
- target_url = "https://#{target_url}" unless /^https?/ =~ target_url
43
- target_url = target_url.gsub(/\/+$/, '')
44
- @target = target_url
45
- @auth_token = auth_token
46
- end
47
-
48
- ######################################################
49
- # Target info
50
- ######################################################
51
-
52
- # Retrieves information on the target cloud, and optionally the logged in user
53
- def info
54
- # TODO: Should merge for new version IMO, general, services, user_account
55
- json_get(VMC::INFO_PATH)
56
- end
57
-
58
- def raw_info
59
- http_get(VMC::INFO_PATH)
60
- end
61
-
62
- # Global listing of services that are available on the target system
63
- def services_info
64
- check_login_status
65
- json_get(path(VMC::GLOBAL_SERVICES_PATH))
66
- end
67
-
68
- def runtimes_info
69
- json_get(path(VMC::GLOBAL_RUNTIMES_PATH))
70
- end
71
-
72
- ######################################################
73
- # Apps
74
- ######################################################
75
-
76
- def apps
77
- check_login_status
78
- json_get(VMC::APPS_PATH)
79
- end
80
-
81
- def create_app(name, manifest={})
82
- check_login_status
83
- app = manifest.dup
84
- app[:name] = name
85
- app[:instances] ||= 1
86
- json_post(VMC::APPS_PATH, app)
87
- end
88
-
89
- def update_app(name, manifest)
90
- check_login_status
91
- json_put(path(VMC::APPS_PATH, name), manifest)
92
- end
93
-
94
- def upload_app(name, zipfile, hash, label, resource_manifest=nil)
95
- #FIXME, manifest should be allowed to be null, here for compatability with old cc's
96
- resource_manifest ||= []
97
- check_login_status
98
- upload_data = {:_method => 'put'}
99
- if zipfile
100
- if zipfile.is_a? File
101
- file = zipfile
102
- else
103
- file = File.new(zipfile, 'rb')
104
- end
105
- upload_data[:application] = file
106
- end
107
- headers = {:hash => hash, :label => label}
108
- upload_data[:resources] = resource_manifest.to_json if resource_manifest
109
- http_post(path(VMC::APPS_PATH, name, "application"), upload_data, nil, headers)
110
- rescue RestClient::ServerBrokeConnection
111
- retry
112
- end
113
-
114
- def delete_app(name)
115
- check_login_status
116
- http_delete(path(VMC::APPS_PATH, name))
117
- end
118
-
119
- def app_info(name)
120
- check_login_status
121
- json_get(path(VMC::APPS_PATH, name))
122
- end
123
-
124
- def app_update_info(name)
125
- check_login_status
126
- json_get(path(VMC::APPS_PATH, name, "update"))
127
- end
128
-
129
- def app_stats(name)
130
- check_login_status
131
- stats_raw = json_get(path(VMC::APPS_PATH, name, "stats"))
132
- stats = []
133
- stats_raw.each_pair do |k, entry|
134
- # Skip entries with no stats
135
- next unless entry[:stats]
136
- entry[:instance] = k.to_s.to_i
137
- entry[:state] = entry[:state].to_sym if entry[:state]
138
- stats << entry
139
- end
140
- stats.sort { |a,b| a[:instance] - b[:instance] }
141
- end
142
-
143
- def app_instances(name)
144
- check_login_status
145
- json_get(path(VMC::APPS_PATH, name, "instances"))
146
- end
147
-
148
- def app_crashes(name)
149
- check_login_status
150
- json_get(path(VMC::APPS_PATH, name, "crashes"))
151
- end
152
-
153
- def app_history(name)
154
- check_login_status
155
- json_get(path(VMC::APPS_PATH, name, "history"))
156
- end
157
-
158
- def app_diff(name)
159
- check_login_status
160
- json_get(path(VMC::APPS_PATH, name, "diff"))
161
- end
162
-
163
- # List the directory or download the actual file indicated by
164
- # the path.
165
- def app_files(name, path, instance='0')
166
- check_login_status
167
- path = path.gsub('//', '/')
168
- url = path(VMC::APPS_PATH, name, "instances", instance, "files", path)
169
- _, body, headers = http_get(url)
170
- body
171
- end
172
-
173
- def app_download(name,path)
174
- check_login_status
175
- url = path(VMC::APPS_PATH, name, "application")
176
- status, body, headers = http_get(url,'application/octet-stream')
177
- file = File.new(path,"wb")
178
- file.write(body)
179
- file.close
180
- end
181
-
182
- def app_pull(name, dir)
183
- check_login_status
184
- url = path(VMC::APPS_PATH, name, "application")
185
- status, body, headers = http_get(url,'application/octet-stream')
186
- file = Tempfile.new(name)
187
- file.binmode
188
- file.write(body)
189
- file.close
190
- ::VMC::Cli::ZipUtil.unpack(file.path, dir)
191
- file.unlink
192
- end
193
-
194
- ######################################################
195
- # Services
196
- ######################################################
197
-
198
- # listing of services that are available in the system
199
- def services
200
- check_login_status
201
- json_get(VMC::SERVICES_PATH)
202
- end
203
-
204
- def create_service(infra,service, name)
205
- check_login_status
206
- services = services_info
207
- services ||= []
208
- service_hash = nil
209
-
210
- service = service.to_s
211
-
212
- # FIXME!
213
- services.each do |service_type, value|
214
- value.each do |vendor, version|
215
- version.each do |version_str, service_descr|
216
- if service == service_descr[:vendor]
217
- service_hash = {
218
- :type => service_descr[:type], :tier => 'free',
219
- :vendor => service, :version => version_str
220
- }
221
- service_hash[:infra] = { :provider => infra } if infra
222
- break
223
- end
224
- end
225
- end
226
- end
227
-
228
- raise TargetError, "Service [#{service}] is not a valid service choice" unless service_hash
229
- service_hash[:name] = name
230
- json_post(path(VMC::SERVICES_PATH), service_hash)
231
- end
232
-
233
- def delete_service(name)
234
- check_login_status
235
- svcs = services || []
236
- names = svcs.collect { |s| s[:name] }
237
- raise TargetError, "Service [#{name}] not a valid service" unless names.include? name
238
- http_delete(path(VMC::SERVICES_PATH, name))
239
- end
240
-
241
- def bind_service(service, appname)
242
- check_login_status
243
- svc = services.detect { |s| s[:name] == service }
244
- app = app_info(appname)
245
- if infra_supported? && ! infras_match?(app,svc)
246
- raise TargetError, "Service #{service} and App #{appname} are not on the same infra"
247
- end
248
- services = app[:services] || []
249
- app[:services] = services << service
250
- update_app(appname, app)
251
- end
252
-
253
- def unbind_service(service, appname)
254
- check_login_status
255
- app = app_info(appname)
256
- services = app[:services] || []
257
- services.delete(service)
258
- app[:services] = services
259
- update_app(appname, app)
260
- end
261
-
262
- def export_service(service)
263
- json_get(path(VMC::SERVICE_EXPORT_PATH, service))
264
- end
265
-
266
- def import_service(service,uri)
267
- json_post(path(VMC::SERVICE_IMPORT_PATH, service),{:uri => uri})
268
- end
269
-
270
- ######################################################
271
- # Resources
272
- ######################################################
273
-
274
- # Send in a resources manifest array to the system to have
275
- # it check what is needed to actually send. Returns array
276
- # indicating what is needed. This returned manifest should be
277
- # sent in with the upload if resources were removed.
278
- # E.g. [{:sha1 => xxx, :size => xxx, :fn => filename}]
279
- def check_resources(resources,infra=nil)
280
- check_login_status
281
- url = VMC::RESOURCES_PATH
282
- unless infra.nil?
283
- url += "?infra=#{infra}"
284
- end
285
- status, body, headers = json_post(url, resources)
286
- json_parse(body)
287
- end
288
-
289
- ######################################################
290
- # Validation Helpers
291
- ######################################################
292
-
293
- # Checks that the target is valid
294
- def target_valid?
295
- return false unless descr = info
296
- return false unless descr[:name]
297
- return false unless descr[:build]
298
- return false unless descr[:version]
299
- return false unless descr[:support]
300
- true
301
- rescue
302
- false
303
- end
304
-
305
- # Checks that the auth_token is valid
306
- def logged_in?
307
- descr = info
308
- if descr
309
- return false unless descr[:user]
310
- return false unless descr[:usage]
311
- @user = descr[:user]
312
- true
313
- end
314
- end
315
-
316
- ######################################################
317
- # User login/password
318
- ######################################################
319
-
320
- # login and return an auth_token
321
- # Auth token can be retained and used in creating
322
- # new clients, avoiding login.
323
- def login(user, password)
324
- status, body, headers = json_post(path(VMC::USERS_PATH, user, "tokens"), {:password => password})
325
- response_info = json_parse(body)
326
- if response_info
327
- @user = user
328
- @auth_token = response_info[:token]
329
- end
330
- end
331
-
332
- # sets the password for the current logged user
333
- def change_password(new_password)
334
- check_login_status
335
- user_info = json_get(path(VMC::USERS_PATH, @user))
336
- if user_info
337
- user_info[:password] = new_password
338
- json_put(path(VMC::USERS_PATH, @user), user_info)
339
- end
340
- end
341
-
342
- ######################################################
343
- # System administration
344
- ######################################################
345
-
346
- def proxy=(proxy)
347
- @proxy = proxy
348
- end
349
-
350
- def proxy_for(proxy)
351
- @proxy = proxy
352
- end
353
-
354
- def users
355
- check_login_status
356
- json_get(VMC::USERS_PATH)
357
- end
358
-
359
- def add_user(user_email, password)
360
- json_post(VMC::USERS_PATH, { :email => user_email, :password => password })
361
- end
362
-
363
- def delete_user(user_email)
364
- check_login_status
365
- http_delete(path(VMC::USERS_PATH, user_email))
366
- end
367
-
368
- ######################################################
369
-
370
- def self.path(*path)
371
- path.flatten.collect { |x|
372
- URI.encode x.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
373
- }.join("/")
374
- end
375
-
376
- ######################################################
377
- # Infrastructure
378
- ######################################################
379
-
380
- def infras
381
- json_get(path(VMC::GLOBAL_INFRAS_PATH))
382
- rescue
383
- []
384
- end
385
-
386
- def infra_supported?
387
- !infras.empty?
388
- end
389
-
390
- def base_for_infra(name)
391
- info = infras.detect { |i| i[:infra] == name }
392
- info ? info[:base] : default_base
393
- end
394
-
395
- def default_base
396
- # remove the protocol, and the first component of the url, which is normally api
397
- pattern = /https?:\/\/[^.]+\./
398
- if @target =~ pattern
399
- @target.sub(pattern,'')
400
- else
401
- "aws.af.cm"
402
- end
403
- end
404
-
405
- def infra_valid?(name)
406
- infras.detect { |i| i[:infra] == name }
407
- end
408
-
409
- def infra_descriptions
410
- infras.select{|i| !i.has_key?(:available) || i[:available] == true}.map { |i| i[:description] }
411
- end
412
-
413
- def infra_name_for_description(desc)
414
- info = infras.detect { |i| i[:description] == desc }
415
- info ? info[:infra] : ""
416
- end
417
-
418
- def suggest_url(infra=nil)
419
- @suggest_url ||= base_for_infra(infra || @infra)
420
- end
421
-
422
-
423
- private
424
-
425
- def path(*args, &blk)
426
- self.class.path(*args, &blk)
427
- end
428
-
429
- def json_get(url)
430
- status, body, headers = http_get(url, 'application/json')
431
- json_parse(body)
432
- rescue JSON::ParserError
433
- raise BadResponse, "Can't parse response into JSON", body
434
- end
435
-
436
- def json_post(url, payload)
437
- http_post(url, payload.to_json, 'application/json')
438
- end
439
-
440
- def json_put(url, payload)
441
- http_put(url, payload.to_json, 'application/json')
442
- end
443
-
444
- def json_parse(str)
445
- if str
446
- JSON.parse(str, :symbolize_names => true)
447
- end
448
- end
449
-
450
- require 'rest_client'
451
-
452
- # HTTP helpers
453
-
454
- def http_get(path, content_type=nil)
455
- request(:get, path, content_type)
456
- end
457
-
458
- def http_post(path, body, content_type=nil, headers = {})
459
- request(:post, path, content_type, body, headers)
460
- end
461
-
462
- def http_put(path, body, content_type=nil)
463
- request(:put, path, content_type, body)
464
- end
465
-
466
- def http_delete(path)
467
- request(:delete, path)
468
- end
469
-
470
- def request(method, path, content_type = nil, payload = nil, headers = {})
471
- headers = headers.dup
472
- headers['AUTHORIZATION'] = @auth_token if @auth_token
473
- headers['PROXY-USER'] = @proxy if @proxy
474
-
475
- if content_type
476
- headers['Content-Type'] = content_type
477
- headers['Accept'] = content_type
478
- end
479
-
480
- req = {
481
- :method => method, :url => "#{@target}/#{path}",
482
- :payload => payload, :headers => headers, :multipart => true,
483
- :timeout => HTTP_TIMEOUT, :open_timeout => HTTP_TIMEOUT
484
- }
485
- status, body, response_headers = perform_http_request(req)
486
-
487
- if request_failed?(status)
488
- # FIXME, old cc returned 400 on not found for file access
489
- err = (status == 404 || status == 400) ? NotFound : TargetError
490
- raise err, parse_error_message(status, body)
491
- else
492
- return status, body, response_headers
493
- end
494
- rescue URI::Error, SocketError, Errno::ECONNREFUSED => e
495
- raise BadTarget, "Cannot access target (%s)" % [ e.message ]
496
- end
497
-
498
- def request_failed?(status)
499
- VMC_HTTP_ERROR_CODES.detect{|error_code| status >= error_code}
500
- end
501
-
502
- def perform_http_request(req)
503
- proxy_uri = URI.parse(req[:url]).find_proxy()
504
- RestClient.proxy = proxy_uri.to_s if proxy_uri
505
-
506
- # Setup tracing if needed
507
- unless trace.nil?
508
- req[:headers]['X-VCAP-Trace'] = (trace == true ? '22' : trace)
509
- end
510
-
511
- result = nil
512
- RestClient::Request.execute(req) do |response, request|
513
- result = [ response.code, response.body, response.headers ]
514
- unless trace.nil?
515
- puts '>>>'
516
- puts "PROXY: #{RestClient.proxy}" if RestClient.proxy
517
- puts "REQUEST: #{req[:method]} #{req[:url]}"
518
- puts "RESPONSE_HEADERS:"
519
- response.headers.each do |key, value|
520
- puts " #{key} : #{value}"
521
- end
522
- puts "REQUEST_BODY: #{req[:payload]}" if req[:payload]
523
- puts "RESPONSE: [#{response.code}]"
524
- begin
525
- puts JSON.pretty_generate(JSON.parse(response.body))
526
- rescue
527
- puts "#{response.body}"
528
- end
529
- puts '<<<'
530
- end
531
- end
532
- result
533
- rescue Net::HTTPBadResponse => e
534
- raise BadTarget "Received bad HTTP response from target: #{e}"
535
- rescue SystemCallError, RestClient::Exception => e
536
- raise HTTPException, "HTTP exception: #{e.class}:#{e}"
537
- end
538
-
539
- def truncate(str, limit = 30)
540
- etc = '...'
541
- stripped = str.strip[0..limit]
542
- if stripped.length > limit
543
- stripped + etc
544
- else
545
- stripped
546
- end
547
- end
548
-
549
- def parse_error_message(status, body)
550
- parsed_body = json_parse(body.to_s)
551
- if parsed_body && parsed_body[:code] && parsed_body[:description]
552
- desc = parsed_body[:description].gsub("\"","'")
553
- "Error #{parsed_body[:code]}: #{desc}"
554
- else
555
- "Error (HTTP #{status}): #{body}"
556
- end
557
- rescue JSON::ParserError
558
- if body.nil? || body.empty?
559
- "Error (#{status}): No Response Received"
560
- else
561
- body_out = trace ? body : truncate(body)
562
- "Error (JSON #{status}): #{body_out}"
563
- end
564
- end
565
-
566
- def check_login_status
567
- raise AuthError unless @user || logged_in?
568
- end
569
-
570
- def infras_match?(o1,o2)
571
- o1 && o2 && ( o1[:infra] == o2[:infra])
572
- end
573
-
574
- end