nimbu 0.4 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/nimbu/client.rb DELETED
@@ -1,289 +0,0 @@
1
- require 'rexml/document'
2
- require 'rest_client'
3
- require 'uri'
4
- require 'time'
5
- require 'nimbu/auth'
6
- require 'nimbu/helpers'
7
- require 'nimbu/version'
8
-
9
- # A Ruby class to call the Nimbu REST API. You might use this if you want to
10
- # manage your Nimbu apps from within a Ruby program, such as Capistrano.
11
- #
12
- # Example:
13
- #
14
- # require 'nimbu'
15
- # nimbu = Nimbu::Client.new('me@example.com', 'mypass')
16
- # nimbu.create('myapp')
17
- #
18
- class Nimbu::Client
19
-
20
- include Nimbu::Helpers
21
- extend Nimbu::Helpers
22
-
23
- def self.version
24
- Nimbu::VERSION
25
- end
26
-
27
- def self.gem_version_string
28
- "nimbu-gem/#{version}"
29
- end
30
-
31
- attr_accessor :host, :user, :password
32
-
33
- def self.auth(user, password, host=Nimbu::Auth.host)
34
- client = new(user, password, host)
35
- json_decode client.post('/login', { :user => {:email => user, :password => password }}, :accept => 'json').to_s
36
- end
37
-
38
- def initialize(user, password, host=Nimbu::Auth.host)
39
- @user = user
40
- @password = password
41
- @host = host
42
- end
43
-
44
- # Show a list of sites
45
- def list
46
- doc = xml(get('/sites').to_s)
47
- doc.elements.to_a("//sites/site").map do |a|
48
- name = a.elements.to_a("name").first
49
- owner = a.elements.to_a("domain").first
50
- [name.text, owner.text]
51
- end
52
- end
53
-
54
- # Show info such as mode, custom domain, and collaborators on an app.
55
- def info(name_or_domain)
56
- raise ArgumentError.new("name_or_domain is required for info") unless name_or_domain
57
- name_or_domain = name_or_domain.gsub(/^(http:\/\/)?(www\.)?/, '')
58
- doc = xml(get("/apps/#{name_or_domain}").to_s)
59
- attrs = hash_from_xml_doc(doc)[:app]
60
- attrs.merge!(:collaborators => list_collaborators(attrs[:name]))
61
- attrs.merge!(:addons => installed_addons(attrs[:name]))
62
- end
63
-
64
- def on_warning(&blk)
65
- @warning_callback = blk
66
- end
67
-
68
- def get_template(params)
69
- post("/engine/template",params)
70
- end
71
-
72
- def get_request(params)
73
- post("/engine/render",params)
74
- end
75
-
76
- def post_request(params)
77
- post("/engine/process",params)
78
- end
79
-
80
- def list_themes
81
- get("/themes")
82
- end
83
-
84
- def show_theme_contents(theme)
85
- get("/themes/#{theme}/list")
86
- end
87
-
88
- def fetch_theme_layout(theme,id)
89
- get("/themes/#{theme}/layouts/#{id}")
90
- end
91
-
92
- def fetch_theme_template(theme,id)
93
- get("/themes/#{theme}/templates/#{id}")
94
- end
95
-
96
- def fetch_theme_assets(theme,id)
97
- get("/themes/#{theme}/assets/#{id}")
98
- end
99
-
100
- def upload_layout(theme,name,content)
101
- post("/themes/#{theme}/layouts", {:name => name, :content => content})
102
- end
103
-
104
- def upload_template(theme,name,content)
105
- post("/themes/#{theme}/templates", {:name => name, :content => content})
106
- end
107
-
108
- def upload_snippet(theme,name,content)
109
- post("/themes/#{theme}/snippets", {:name => name, :content => content})
110
- end
111
-
112
- def upload_asset(theme,name,file)
113
- post("/themes/#{theme}/assets", {:name => name, :file => file})
114
- end
115
-
116
- ##################
117
-
118
- def resource(uri, options={})
119
- if http_proxy
120
- RestClient.proxy = http_proxy
121
- end
122
- resource = RestClient::Resource.new(realize_full_uri(uri), options)
123
- resource
124
- end
125
-
126
- def get(uri, extra_headers={}) # :nodoc:
127
- process(:get, uri, extra_headers)
128
- end
129
-
130
- def post(uri, payload="", extra_headers={}) # :nodoc:
131
- process(:post, uri, extra_headers, payload)
132
- end
133
-
134
- def put(uri, payload, extra_headers={}) # :nodoc:
135
- process(:put, uri, extra_headers, payload)
136
- end
137
-
138
- def delete(uri, extra_headers={}) # :nodoc:
139
- process(:delete, uri, extra_headers)
140
- end
141
-
142
- def process(method, uri, extra_headers={}, payload=nil)
143
- headers = nimbu_headers.merge(extra_headers)
144
- args = [method, payload, headers].compact
145
-
146
- resource_options = default_resource_options_for_uri(uri)
147
-
148
- begin
149
- response = resource(uri, resource_options).send(*args)
150
- rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketError
151
- host = URI.parse(realize_full_uri(uri)).host
152
- error "Unable to connect to #{host}"
153
- rescue RestClient::SSLCertificateNotVerified => ex
154
- host = URI.parse(realize_full_uri(uri)).host
155
- error "WARNING: Unable to verify SSL certificate for #{host}\nTo disable SSL verification, run with HEROKU_SSL_VERIFY=disable"
156
- end
157
-
158
- extract_warning(response)
159
- response
160
- end
161
-
162
- def extract_warning(response)
163
- return unless response
164
- if response.headers[:x_nimbu_warning] && @warning_callback
165
- warning = response.headers[:x_nimbu_warning]
166
- @displayed_warnings ||= {}
167
- unless @displayed_warnings[warning]
168
- @warning_callback.call(warning)
169
- @displayed_warnings[warning] = true
170
- end
171
- end
172
- end
173
-
174
- def nimbu_headers # :nodoc:
175
- {
176
- 'X-Nimbu-API-Version' => '1',
177
- 'X-Nimbu-Token' => password,
178
- 'User-Agent' => self.class.gem_version_string,
179
- 'X-Ruby-Version' => RUBY_VERSION,
180
- 'X-Ruby-Platform' => RUBY_PLATFORM
181
- }
182
- end
183
-
184
- def xml(raw) # :nodoc:
185
- REXML::Document.new(raw)
186
- end
187
-
188
- def escape(value) # :nodoc:
189
- escaped = URI.escape(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
190
- escaped.gsub('.', '%2E') # not covered by the previous URI.escape
191
- end
192
-
193
- module JSON
194
- def self.parse(json)
195
- json_decode(json)
196
- end
197
- end
198
-
199
- private
200
-
201
- def configure_addon(action, app_name, addon, config = {})
202
- response = update_addon action,
203
- addon_path(app_name, addon),
204
- config
205
-
206
- json_decode(response.to_s) unless response.to_s.empty?
207
- end
208
-
209
- def addon_path(app_name, addon)
210
- "/apps/#{app_name}/addons/#{escape(addon)}"
211
- end
212
-
213
- def update_addon(action, path, config)
214
- params = { :config => config }
215
- app = params[:config].delete(:confirm)
216
- headers = { :accept => 'application/json' }
217
- params.merge!(:confirm => app) if app
218
-
219
- case action
220
- when :install
221
- post path, params, headers
222
- when :upgrade
223
- put path, params, headers
224
- when :uninstall
225
- confirm = app ? "confirm=#{app}" : ''
226
- delete "#{path}?#{confirm}", headers
227
- end
228
- end
229
-
230
- def realize_full_uri(given)
231
- full_host = (host =~ /^http/) ? host : "http://#{host}"
232
- host = URI.parse(full_host)
233
- uri = URI.parse(given)
234
- uri.host ||= host.host
235
- uri.scheme ||= host.scheme || "http"
236
- uri.path = "/api/v2" + ((uri.path[0..0] == "/") ? uri.path : "/#{uri.path}")
237
- uri.port = host.port if full_host =~ /\:\d+/
238
- uri.to_s
239
- end
240
-
241
- def default_resource_options_for_uri(uri)
242
- if ENV["HEROKU_SSL_VERIFY"] == "disable"
243
- {}
244
- elsif realize_full_uri(uri) =~ %r|^https://api.getnimbu.com|
245
- { :verify_ssl => OpenSSL::SSL::VERIFY_PEER, :ssl_ca_file => local_ca_file }
246
- else
247
- {}
248
- end
249
- end
250
-
251
- def local_ca_file
252
- File.expand_path("../../../data/cacert.pem", __FILE__)
253
- end
254
-
255
- def hash_from_xml_doc(elements)
256
- elements.inject({}) do |hash, e|
257
- next(hash) unless e.respond_to?(:children)
258
- hash.update(e.name.gsub("-","_").to_sym => case e.children.length
259
- when 0 then nil
260
- when 1 then e.text
261
- else hash_from_xml_doc(e.children)
262
- end)
263
- end
264
- end
265
-
266
- def http_proxy
267
- proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
268
- if proxy && !proxy.empty?
269
- unless /^[^:]+:\/\// =~ proxy
270
- proxy = "http://" + proxy
271
- end
272
- proxy
273
- else
274
- nil
275
- end
276
- end
277
-
278
- def https_proxy
279
- proxy = ENV['HTTPS_PROXY'] || ENV['https_proxy']
280
- if proxy && !proxy.empty?
281
- unless /^[^:]+:\/\// =~ proxy
282
- proxy = "https://" + proxy
283
- end
284
- proxy
285
- else
286
- nil
287
- end
288
- end
289
- end
@@ -1,76 +0,0 @@
1
- require "timeout"
2
- require "socket"
3
- require "uri"
4
- require "nimbu/client"
5
- require "nimbu/helpers"
6
-
7
- class Nimbu::Client::Rendezvous
8
- attr_reader :rendezvous_url, :connect_timeout, :activity_timeout, :input, :output, :on_connect
9
-
10
- def initialize(opts)
11
- @rendezvous_url = opts[:rendezvous_url]
12
- @connect_timeout = opts[:connect_timeout]
13
- @activity_timeout = opts[:activity_timeout]
14
- @input = opts[:input]
15
- @output = opts[:output]
16
- end
17
-
18
- def on_connect(&blk)
19
- @on_connect = blk if block_given?
20
- @on_connect
21
- end
22
-
23
- def start
24
- uri = URI.parse(rendezvous_url)
25
- host, port, secret = uri.host, uri.port, uri.path[1..-1]
26
-
27
- ssl_socket = Timeout.timeout(connect_timeout) do
28
- ssl_context = OpenSSL::SSL::SSLContext.new
29
- if ((host =~ /nimbu\.com$/) && !(ENV["HEROKU_SSL_VERIFY"] == "disable"))
30
- ssl_context.ca_file = File.expand_path("../../../../data/cacert.pem", __FILE__)
31
- ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
32
- end
33
- tcp_socket = TCPSocket.open(host, port)
34
- ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
35
- ssl_socket.connect
36
- ssl_socket.puts(secret)
37
- ssl_socket.readline
38
- ssl_socket
39
- end
40
-
41
- on_connect.call if on_connect
42
-
43
- readables = [input, ssl_socket].compact
44
-
45
- begin
46
- loop do
47
- if o = IO.select(readables, nil, nil, activity_timeout)
48
- if (input && (o.first.first == input))
49
- begin
50
- data = input.readpartial(10000)
51
- rescue EOFError
52
- readables.delete(input)
53
- next
54
- end
55
- ssl_socket.write(data)
56
- ssl_socket.flush
57
- elsif (o.first.first == ssl_socket)
58
- begin
59
- data = ssl_socket.readpartial(10000)
60
- rescue EOFError
61
- break
62
- end
63
- output.write(data)
64
- end
65
- else
66
- raise(Timeout::Error.new)
67
- end
68
- end
69
- rescue Interrupt
70
- ssl_socket.write("\003")
71
- ssl_socket.flush
72
- retry
73
- rescue Errno::EIO
74
- end
75
- end
76
- end
@@ -1 +0,0 @@
1
- Hello world!