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/LICENSE +18 -2
- data/README +0 -3
- data/Rakefile +35 -3
- data/bin/vmc +5 -0
- data/bin/vmc.bat +1 -0
- data/lib/parse.rb +719 -0
- data/lib/vmc.rb +1588 -0
- data/lib/vmc_base.rb +205 -0
- data/vendor/gems/httpclient/VERSION +1 -0
- data/vendor/gems/httpclient/lib/http-access2/cookie.rb +1 -0
- data/vendor/gems/httpclient/lib/http-access2/http.rb +1 -0
- data/vendor/gems/httpclient/lib/http-access2.rb +53 -0
- data/vendor/gems/httpclient/lib/httpclient/auth.rb +522 -0
- data/vendor/gems/httpclient/lib/httpclient/cacert.p7s +1579 -0
- data/vendor/gems/httpclient/lib/httpclient/cacert_sha1.p7s +1579 -0
- data/vendor/gems/httpclient/lib/httpclient/connection.rb +84 -0
- data/vendor/gems/httpclient/lib/httpclient/cookie.rb +562 -0
- data/vendor/gems/httpclient/lib/httpclient/http.rb +867 -0
- data/vendor/gems/httpclient/lib/httpclient/session.rb +864 -0
- data/vendor/gems/httpclient/lib/httpclient/ssl_config.rb +417 -0
- data/vendor/gems/httpclient/lib/httpclient/timeout.rb +136 -0
- data/vendor/gems/httpclient/lib/httpclient/util.rb +86 -0
- data/vendor/gems/httpclient/lib/httpclient.rb +1020 -0
- data/vendor/gems/httpclient/lib/tags +908 -0
- metadata +142 -10
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
|