vmc 0.0.4 → 0.0.5

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