1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
class LeapTest
#
# generates a couchdb url for when couchdb is running
# remotely and is available via stunnel.
#
# example properties:
#
# stunnel:
# clients:
# couch_client:
# couch1_5984:
# accept_port: 4000
# connect: couch1.bitmask.i
# connect_port: 15984
#
def couchdb_urls_via_stunnel(path="", options=nil)
path = path.gsub('"', '%22')
if options && options[:username] && options[:password]
userpart = "%{username}:%{password}@" % options
else
userpart = ""
end
assert_property('stunnel.clients.couch_client').values.collect do |stunnel_conf|
assert port = stunnel_conf['accept_port'], 'Field `accept_port` must be present in `stunnel` property.'
URLString.new("http://#{userpart}localhost:#{port}#{path}").tap {|url|
remote_ip_address = TCPSocket.gethostbyname(stunnel_conf['connect']).last
url.memo = "(via stunnel to %s:%s, aka %s)" % [stunnel_conf['connect'], stunnel_conf['connect_port'], remote_ip_address]
}
end
end
#
# generates a couchdb url for accessing couchdb via haproxy
#
# example properties:
#
# haproxy:
# couch:
# listen_port: 4096
# servers:
# panda:
# backup: false
# host: localhost
# port: 4000
# weight: 100
# writable: true
#
def couchdb_url_via_haproxy(path="", options=nil)
path = path.gsub('"', '%22')
if options && options[:username] && options[:password]
userpart = "%{username}:%{password}@" % options
else
userpart = ""
end
port = assert_property('haproxy.couch.listen_port')
return URLString.new("http://#{userpart}localhost:#{port}#{path}").tap { |url|
url.memo = '(via haproxy)'
}
end
#
# generates a couchdb url for when couchdb is running locally.
#
# example properties:
#
# couch:
# port: 5984
#
def couchdb_url_via_localhost(path="", options=nil)
path = path.gsub('"', '%22')
port = (options && options[:port]) || assert_property('couch.port')
if options && options[:username]
password = property("couch.users.%{username}.password" % options)
userpart = "%s:%s@" % [options[:username], password]
else
userpart = ""
end
return URLString.new("http://#{userpart}localhost:#{port}#{path}").tap { |url|
url.memo = '(via direct localhost connection)'
}
end
#
# returns a single url for accessing couchdb
#
def couchdb_url(path="", options=nil)
if property('couch.port')
couchdb_url_via_localhost(path, options)
elsif property('stunnel.clients.couch_client')
couchdb_urls_via_stunnel(path, options).first
end
end
#
# returns an array of urls for accessing couchdb
#
def couchdb_urls(path="", options=nil)
if property('couch.port')
[couchdb_url_via_localhost(path, options)]
elsif property('stunnel.clients.couch_client')
couchdb_urls_via_stunnel(path, options)
end
end
def assert_destroy_user_db(user_id, options=nil)
db_name = "user-#{user_id}"
url = couchdb_url("/#{db_name}", options)
http_options = {:ok_codes => [200, 404]} # ignore missing dbs
assert_delete(url, nil, http_options)
end
def assert_create_user_db(user_id, options=nil)
db_name = "user-#{user_id}"
url = couchdb_url("/#{db_name}", options)
http_options = {:ok_codes => [200, 404]} # ignore missing dbs
assert_put(url, nil, :format => :json) do |body|
assert response = JSON.parse(body), "PUT response should be JSON"
assert response["ok"], "PUT response should be OK"
end
end
#
# returns true if the per-user db created by soledad-server exists.
#
def user_db_exists?(user_id, options=nil)
db_name = "user-#{user_id}"
url = couchdb_url("/#{db_name}", options)
get(url) do |body, response, error|
if response.nil?
fail "could not query couchdb #{url}: #{error}\n#{body}"
elsif response.code.to_i == 200
return true
elsif response.code.to_i == 404
return false
else
fail ["could not query couchdb #{url}: expected response code 200 or 404, but got #{response.code}.", error, body].compact.join("\n")
end
end
end
end
|