vmc 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vmc_base.rb ADDED
@@ -0,0 +1,205 @@
1
+ # Copyright 2010, VMware, Inc. Licensed under the
2
+ # MIT license, please see the LICENSE file. All rights reserved
3
+
4
+ require 'digest/sha1'
5
+ require 'fileutils'
6
+ require 'tempfile'
7
+ require 'tmpdir'
8
+
9
+ # self contained
10
+ $:.unshift File.expand_path('../../vendor/gems/httpclient/lib', __FILE__)
11
+
12
+ require 'json/pure'
13
+ require 'httpclient'
14
+ require 'zip/zipfilesystem'
15
+
16
+ # This class captures the common interactions with AppCloud that can be shared by different
17
+ # clients. Clients that use this class are the vmc CLI and the integration test automation.
18
+ # TBD - ABS: This is currently a minimal extraction of methods to tease out
19
+ # the interactive aspects of the vmc CLI from the AppCloud API calls.
20
+
21
+ module VMC
22
+
23
+ class BaseClient
24
+
25
+ def register_internal(base_uri, email, password, auth_hdr = {})
26
+ response = HTTPClient.post("#{base_uri}/users", {:email => email, :password => password}.to_json, auth_hdr)
27
+ raise(JSON.parse(response.content)['description'] || 'registration failed') if response.status != 200 && response.status != 204
28
+ end
29
+
30
+ def login_internal(base_uri, email, password)
31
+ response = HTTPClient.post "#{base_uri}/users/#{email}/tokens", {:password => password}.to_json
32
+ raise "login failed" if response.status != 200
33
+ token = JSON.parse(response.content)['token']
34
+ display "successfully logged in"
35
+ token
36
+ end
37
+
38
+ def change_passwd_internal(base_uri, user_info, auth_hdr)
39
+ email = user_info['email']
40
+ response = HTTPClient.put("#{base_uri}/users/#{email}", user_info.to_json, auth_hdr)
41
+ raise(JSON.parse(response.content)['description'] || 'password change failed') if response.status != 200 && response.status != 204
42
+ end
43
+
44
+ def get_user_internal(base_uri, email, auth_hdr)
45
+ response = HTTPClient.get "#{base_uri}/users/#{email}", nil, auth_hdr
46
+ end
47
+
48
+ def delete_user_internal(base_uri, email, auth_hdr)
49
+ response = HTTPClient.delete "#{base_uri}/users/#{email}", auth_hdr
50
+ end
51
+
52
+ def get_apps_internal(droplets_uri, auth_hdr)
53
+ response = HTTPClient.get droplets_uri, nil, auth_hdr
54
+ raise "(#{response.status}) can not contact server" if (response.status > 500 || response.status == 404)
55
+ raise "Access Denied, please login or register" if response.status == 403
56
+ droplets_full = JSON.parse(response.content)
57
+ rescue => e
58
+ error "Problem executing list command, #{e}"
59
+ end
60
+
61
+ def create_app_internal(droplets_uri, app_manifest, auth_hdr)
62
+ response = HTTPClient.post droplets_uri, app_manifest.to_json, auth_hdr
63
+ end
64
+
65
+ def get_app_internal(droplets_uri, appname, auth_hdr)
66
+ response = HTTPClient.get "#{droplets_uri}/#{appname}", nil, auth_hdr
67
+ end
68
+
69
+ def delete_app_internal(droplets_uri, appname, services_to_delete, auth_hdr)
70
+ HTTPClient.delete "#{droplets_uri}/#{appname}", auth_hdr
71
+ services_to_delete.each { |service_name|
72
+ HTTPClient.delete "#{services_uri}/#{service_name}", auth_hdr
73
+ }
74
+ end
75
+
76
+ def upload_app_bits(resources_uri, droplets_uri, appname, auth_hdr, opt_war_file, provisioned_db = false)
77
+ explode_dir = "#{Dir.tmpdir}/.vmc_#{appname}_files"
78
+ FileUtils.rm_rf(explode_dir) # Make sure we didn't have anything left over..
79
+
80
+ # Stage the app appropriately and do the appropriate fingerprinting, etc.
81
+ if opt_war_file
82
+ Zip::ZipFile.foreach(opt_war_file) { |zentry|
83
+ epath = "#{explode_dir}/#{zentry}"
84
+ FileUtils.mkdir_p(File.dirname(epath)) unless (File.exists?(File.dirname(epath)))
85
+ zentry.extract("#{explode_dir}/#{zentry}")
86
+ }
87
+ else
88
+ FileUtils.cp_r('.', explode_dir)
89
+ end
90
+
91
+ # Send the resource list to the cloud controller, the response will tell us what it already has..
92
+ fingerprints = []
93
+ resource_files = Dir.glob("#{explode_dir}/**/*", File::FNM_DOTMATCH)
94
+ resource_files.each { |filename|
95
+ fingerprints << { :size => File.size(filename),
96
+ :sha1 => Digest::SHA1.file(filename).hexdigest,
97
+ :fn => filename # TODO(dlc) probably should not send over the wire
98
+ } unless (File.directory?(filename) || !File.exists?(filename))
99
+ }
100
+
101
+ # Send resource fingerprints to the cloud controller
102
+ response = HTTPClient.post resources_uri, fingerprints.to_json, auth_hdr
103
+ appcloud_resources = nil
104
+ if response.status == 200
105
+ appcloud_resources = JSON.parse(response.content)
106
+ # we will use the exploded version of the files here to whip through and delete what we
107
+ # will have appcloud fill in for us.
108
+ appcloud_resources.each { |resource| FileUtils.rm_f resource['fn'] }
109
+ end
110
+
111
+ # Perform Packing of the upload bits here.
112
+ upload_file = "#{Dir.tmpdir}/#{appname}.zip"
113
+ FileUtils.rm_f(upload_file)
114
+ exclude = ['..', '*~', '#*#', '*.log']
115
+ exclude << '*.sqlite3' if provisioned_db
116
+ Zip::ZipFile::open(upload_file, true) { |zf|
117
+ Dir.glob("#{explode_dir}/**/*", File::FNM_DOTMATCH).each { |f|
118
+ process = true
119
+ exclude.each { |e| process = false if File.fnmatch(e, File.basename(f)) }
120
+ zf.add(f.sub("#{explode_dir}/",''), f) if (process && File.exists?(f))
121
+ }
122
+ }
123
+
124
+ upload_size = File.size(upload_file);
125
+
126
+ upload_data = {:application => File.new(upload_file, 'rb'), :_method => 'put'}
127
+ if appcloud_resources
128
+ # Need to adjust filenames sans the explode_dir prefix
129
+ appcloud_resources.each { |ar| ar['fn'].sub!("#{explode_dir}/", '') }
130
+ upload_data[:resources] = appcloud_resources.to_json
131
+ end
132
+
133
+ response = HTTPClient.post "#{droplets_uri}/#{appname}/application", upload_data, auth_hdr
134
+ raise "Problem uploading application bits" if response.status != 200
135
+ upload_size
136
+
137
+ ensure
138
+ # Cleanup if we created an exploded directory.
139
+ FileUtils.rm_f(upload_file)
140
+ FileUtils.rm_rf(explode_dir)
141
+ end
142
+
143
+ def update_app_state_internal droplets_uri, appname, appinfo, auth_hdr
144
+ hdrs = auth_hdr.merge({'content-type' => 'application/json'})
145
+ response = HTTPClient.put "#{droplets_uri}/#{appname}", appinfo.to_json, hdrs
146
+ end
147
+
148
+ def get_app_instances_internal(droplets_uri, appname, auth_hdr)
149
+ response = HTTPClient.get "#{droplets_uri}/#{appname}/instances", nil, auth_hdr
150
+ instances_info = JSON.parse(response.content)
151
+ end
152
+
153
+ def get_app_files_internal(droplets_uri, appname, instance, path, auth_hdr)
154
+ cc_url = "#{droplets_uri}/#{appname}/instances/#{instance}/files/#{path}"
155
+ cc_url.gsub!('files//', 'files/')
156
+ response = HTTPClient.get cc_url, nil, auth_hdr
157
+ end
158
+
159
+ def get_app_crashes_internal(droplets_uri, appname, auth_hdr)
160
+ response = HTTPClient.get "#{droplets_uri}/#{appname}/crashes", nil, auth_hdr
161
+ end
162
+
163
+ def get_app_stats_internal(droplets_uri, appname, auth_hdr)
164
+ response = HTTPClient.get "#{droplets_uri}/#{appname}/stats", nil, auth_hdr
165
+ end
166
+
167
+ def update_app_internal(droplets_uri, appname, auth_hdr)
168
+ response = HTTPClient.put "#{droplets_uri}/#{appname}/update", '', auth_hdr
169
+ end
170
+
171
+ def get_update_app_status(droplets_uri, appname, auth_hdr)
172
+ response = HTTPClient.get "#{droplets_uri}/#{appname}/update", nil, auth_hdr
173
+ raise "Problem updating application" if response.status != 200
174
+ response
175
+ end
176
+
177
+ def add_service_internal(services_uri, service_manifest, auth_hdr)
178
+ response = HTTPClient.post services_uri, service_manifest.to_json, auth_hdr
179
+ end
180
+
181
+ def remove_service_internal(services_uri, service_id, auth_hdr)
182
+ HTTPClient.delete "#{services_uri}/#{service_id}", auth_hdr
183
+ end
184
+
185
+ def delete_services_internal(services_uri, services, auth_hdr)
186
+ services.each do |service_name|
187
+ HTTPClient.delete "#{services_uri}/#{service_name}", auth_hdr
188
+ end
189
+ end
190
+
191
+ def fast_uuid
192
+ values = [
193
+ rand(0x0010000),rand(0x0010000),rand(0x0010000),
194
+ rand(0x0010000),rand(0x0010000),rand(0x1000000),
195
+ rand(0x1000000),
196
+ ]
197
+ "%04x%04x%04x%04x%04x%06x%06x" % values
198
+ end
199
+
200
+ def error(msg)
201
+ STDERR.puts(msg)
202
+ end
203
+ end
204
+
205
+ end
@@ -0,0 +1 @@
1
+ 2.1.5.2
@@ -0,0 +1 @@
1
+ require 'httpclient/cookie'
@@ -0,0 +1 @@
1
+ require 'httpclient/http'
@@ -0,0 +1,53 @@
1
+ # HTTPAccess2 - HTTP accessing library.
2
+ # Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
3
+
4
+ # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
5
+ # redistribute it and/or modify it under the same terms of Ruby's license;
6
+ # either the dual license version in 2003, or any later version.
7
+
8
+ # http-access2.rb is based on http-access.rb in http-access/0.0.4. Some part
9
+ # of code in http-access.rb was recycled in http-access2.rb. Those part is
10
+ # copyrighted by Maehashi-san.
11
+
12
+
13
+ require 'httpclient'
14
+
15
+
16
+ module HTTPAccess2
17
+ VERSION = ::HTTPClient::VERSION
18
+ RUBY_VERSION_STRING = ::HTTPClient::RUBY_VERSION_STRING
19
+ SSLEnabled = ::HTTPClient::SSLEnabled
20
+ SSPIEnabled = ::HTTPClient::SSPIEnabled
21
+ DEBUG_SSL = true
22
+
23
+ Util = ::HTTPClient::Util
24
+
25
+ class Client < ::HTTPClient
26
+ class RetryableResponse < StandardError
27
+ end
28
+ end
29
+
30
+ SSLConfig = ::HTTPClient::SSLConfig
31
+ BasicAuth = ::HTTPClient::BasicAuth
32
+ DigestAuth = ::HTTPClient::DigestAuth
33
+ NegotiateAuth = ::HTTPClient::NegotiateAuth
34
+ AuthFilterBase = ::HTTPClient::AuthFilterBase
35
+ WWWAuth = ::HTTPClient::WWWAuth
36
+ ProxyAuth = ::HTTPClient::ProxyAuth
37
+ Site = ::HTTPClient::Site
38
+ Connection = ::HTTPClient::Connection
39
+ SessionManager = ::HTTPClient::SessionManager
40
+ SSLSocketWrap = ::HTTPClient::SSLSocketWrap
41
+ DebugSocket = ::HTTPClient::DebugSocket
42
+
43
+ class Session < ::HTTPClient::Session
44
+ class Error < StandardError
45
+ end
46
+ class InvalidState < Error
47
+ end
48
+ class BadResponse < Error
49
+ end
50
+ class KeepAliveDisconnected < Error
51
+ end
52
+ end
53
+ end