azuki 0.0.1
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.
- checksums.yaml +7 -0
- data/README.md +71 -0
- data/bin/azuki +17 -0
- data/data/cacert.pem +3988 -0
- data/lib/azuki.rb +17 -0
- data/lib/azuki/auth.rb +339 -0
- data/lib/azuki/cli.rb +38 -0
- data/lib/azuki/client.rb +764 -0
- data/lib/azuki/client/azuki_postgresql.rb +141 -0
- data/lib/azuki/client/cisaurus.rb +26 -0
- data/lib/azuki/client/pgbackups.rb +113 -0
- data/lib/azuki/client/rendezvous.rb +108 -0
- data/lib/azuki/client/ssl_endpoint.rb +25 -0
- data/lib/azuki/command.rb +294 -0
- data/lib/azuki/command/account.rb +23 -0
- data/lib/azuki/command/accounts.rb +34 -0
- data/lib/azuki/command/addons.rb +305 -0
- data/lib/azuki/command/apps.rb +393 -0
- data/lib/azuki/command/auth.rb +86 -0
- data/lib/azuki/command/base.rb +230 -0
- data/lib/azuki/command/certs.rb +209 -0
- data/lib/azuki/command/config.rb +137 -0
- data/lib/azuki/command/db.rb +218 -0
- data/lib/azuki/command/domains.rb +85 -0
- data/lib/azuki/command/drains.rb +46 -0
- data/lib/azuki/command/fork.rb +164 -0
- data/lib/azuki/command/git.rb +64 -0
- data/lib/azuki/command/help.rb +179 -0
- data/lib/azuki/command/keys.rb +115 -0
- data/lib/azuki/command/labs.rb +147 -0
- data/lib/azuki/command/logs.rb +45 -0
- data/lib/azuki/command/maintenance.rb +61 -0
- data/lib/azuki/command/pg.rb +269 -0
- data/lib/azuki/command/pgbackups.rb +329 -0
- data/lib/azuki/command/plugins.rb +110 -0
- data/lib/azuki/command/ps.rb +232 -0
- data/lib/azuki/command/regions.rb +22 -0
- data/lib/azuki/command/releases.rb +124 -0
- data/lib/azuki/command/run.rb +180 -0
- data/lib/azuki/command/sharing.rb +89 -0
- data/lib/azuki/command/ssl.rb +43 -0
- data/lib/azuki/command/stack.rb +62 -0
- data/lib/azuki/command/status.rb +51 -0
- data/lib/azuki/command/update.rb +47 -0
- data/lib/azuki/command/version.rb +23 -0
- data/lib/azuki/deprecated.rb +5 -0
- data/lib/azuki/deprecated/help.rb +38 -0
- data/lib/azuki/distribution.rb +9 -0
- data/lib/azuki/excon.rb +9 -0
- data/lib/azuki/helpers.rb +517 -0
- data/lib/azuki/helpers/azuki_postgresql.rb +165 -0
- data/lib/azuki/helpers/log_displayer.rb +70 -0
- data/lib/azuki/plugin.rb +163 -0
- data/lib/azuki/updater.rb +171 -0
- data/lib/azuki/version.rb +3 -0
- data/lib/vendor/azuki/okjson.rb +598 -0
- data/spec/azuki/auth_spec.rb +256 -0
- data/spec/azuki/client/azuki_postgresql_spec.rb +71 -0
- data/spec/azuki/client/pgbackups_spec.rb +43 -0
- data/spec/azuki/client/rendezvous_spec.rb +62 -0
- data/spec/azuki/client/ssl_endpoint_spec.rb +48 -0
- data/spec/azuki/client_spec.rb +564 -0
- data/spec/azuki/command/addons_spec.rb +601 -0
- data/spec/azuki/command/apps_spec.rb +351 -0
- data/spec/azuki/command/auth_spec.rb +38 -0
- data/spec/azuki/command/base_spec.rb +109 -0
- data/spec/azuki/command/certs_spec.rb +178 -0
- data/spec/azuki/command/config_spec.rb +144 -0
- data/spec/azuki/command/db_spec.rb +110 -0
- data/spec/azuki/command/domains_spec.rb +87 -0
- data/spec/azuki/command/drains_spec.rb +34 -0
- data/spec/azuki/command/fork_spec.rb +56 -0
- data/spec/azuki/command/git_spec.rb +144 -0
- data/spec/azuki/command/help_spec.rb +93 -0
- data/spec/azuki/command/keys_spec.rb +120 -0
- data/spec/azuki/command/labs_spec.rb +100 -0
- data/spec/azuki/command/logs_spec.rb +60 -0
- data/spec/azuki/command/maintenance_spec.rb +51 -0
- data/spec/azuki/command/pg_spec.rb +236 -0
- data/spec/azuki/command/pgbackups_spec.rb +307 -0
- data/spec/azuki/command/plugins_spec.rb +104 -0
- data/spec/azuki/command/ps_spec.rb +195 -0
- data/spec/azuki/command/releases_spec.rb +130 -0
- data/spec/azuki/command/run_spec.rb +83 -0
- data/spec/azuki/command/sharing_spec.rb +59 -0
- data/spec/azuki/command/stack_spec.rb +46 -0
- data/spec/azuki/command/status_spec.rb +48 -0
- data/spec/azuki/command/version_spec.rb +16 -0
- data/spec/azuki/command_spec.rb +211 -0
- data/spec/azuki/helpers/azuki_postgresql_spec.rb +155 -0
- data/spec/azuki/helpers_spec.rb +48 -0
- data/spec/azuki/plugin_spec.rb +172 -0
- data/spec/azuki/updater_spec.rb +44 -0
- data/spec/helper/legacy_help.rb +16 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +224 -0
- data/spec/support/display_message_matcher.rb +49 -0
- data/spec/support/openssl_mock_helper.rb +8 -0
- metadata +211 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "azuki/client"
|
|
3
|
+
require "azuki/helpers"
|
|
4
|
+
require 'azuki/command'
|
|
5
|
+
|
|
6
|
+
describe Azuki::Client do
|
|
7
|
+
include Azuki::Helpers
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
@client = Azuki::Client.new(nil, nil)
|
|
11
|
+
@resource = mock('azuki rest resource')
|
|
12
|
+
@client.stub!(:extract_warning)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "Client.auth -> get user details" do
|
|
16
|
+
user_info = { "api_key" => "abc" }
|
|
17
|
+
stub_request(:post, "https://foo:bar@api.azukiapp.com/login").to_return(:body => json_encode(user_info))
|
|
18
|
+
capture_stderr do # capture deprecation message
|
|
19
|
+
Azuki::Client.auth("foo", "bar").should == user_info
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "list -> get a list of this user's apps" do
|
|
24
|
+
stub_api_request(:get, "/apps").to_return(:body => <<-EOXML)
|
|
25
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
26
|
+
<apps type="array">
|
|
27
|
+
<app><name>example</name><owner>test@azukiapp.com</owner></app>
|
|
28
|
+
<app><name>example2</name><owner>test@azukiapp.com</owner></app>
|
|
29
|
+
</apps>
|
|
30
|
+
EOXML
|
|
31
|
+
capture_stderr do # capture deprecation message
|
|
32
|
+
@client.list.should == [
|
|
33
|
+
["example", "test@azukiapp.com"],
|
|
34
|
+
["example2", "test@azukiapp.com"]
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "info -> get app attributes" do
|
|
40
|
+
stub_api_request(:get, "/apps/example").to_return(:body => <<-EOXML)
|
|
41
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
42
|
+
<app>
|
|
43
|
+
<blessed type='boolean'>true</blessed>
|
|
44
|
+
<created-at type='datetime'>2008-07-08T17:21:50-07:00</created-at>
|
|
45
|
+
<id type='integer'>49134</id>
|
|
46
|
+
<name>example</name>
|
|
47
|
+
<production type='boolean'>true</production>
|
|
48
|
+
<share-public type='boolean'>true</share-public>
|
|
49
|
+
<domain_name/>
|
|
50
|
+
</app>
|
|
51
|
+
EOXML
|
|
52
|
+
@client.stub!(:list_collaborators).and_return([:jon, :mike])
|
|
53
|
+
@client.stub!(:installed_addons).and_return([:addon1])
|
|
54
|
+
capture_stderr do # capture deprecation message
|
|
55
|
+
@client.info('example').should == { :blessed => 'true', :created_at => '2008-07-08T17:21:50-07:00', :id => '49134', :name => 'example', :production => 'true', :share_public => 'true', :domain_name => nil, :collaborators => [:jon, :mike], :addons => [:addon1] }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "create_request -> create a new blank app" do
|
|
60
|
+
stub_api_request(:post, "/apps").with(:body => "").to_return(:body => <<-EOXML)
|
|
61
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
62
|
+
<app><name>untitled-123</name></app>
|
|
63
|
+
EOXML
|
|
64
|
+
capture_stderr do # capture deprecation message
|
|
65
|
+
@client.create_request.should == "untitled-123"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "create_request(name) -> create a new blank app with a specified name" do
|
|
70
|
+
stub_api_request(:post, "/apps").with(:body => "app[name]=newapp").to_return(:body => <<-EOXML)
|
|
71
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
72
|
+
<app><name>newapp</name></app>
|
|
73
|
+
EOXML
|
|
74
|
+
capture_stderr do # capture deprecation message
|
|
75
|
+
@client.create_request("newapp").should == "newapp"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "create_complete?(name) -> checks if a create request is complete" do
|
|
80
|
+
@response = mock('response')
|
|
81
|
+
@response.should_receive(:code).and_return(202)
|
|
82
|
+
@client.should_receive(:resource).and_return(@resource)
|
|
83
|
+
@resource.should_receive(:put).with({}, @client.azuki_headers).and_return(@response)
|
|
84
|
+
capture_stderr do # capture deprecation message
|
|
85
|
+
@client.create_complete?('example').should be_false
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "update(name, attributes) -> updates existing apps" do
|
|
90
|
+
stub_api_request(:put, "/apps/example").with(:body => "app[mode]=production")
|
|
91
|
+
capture_stderr do # capture deprecation message
|
|
92
|
+
@client.update("example", :mode => 'production')
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "destroy(name) -> destroy the named app" do
|
|
97
|
+
stub_api_request(:delete, "/apps/destroyme")
|
|
98
|
+
capture_stderr do # capture deprecation message
|
|
99
|
+
@client.destroy("destroyme")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "rake(app_name, cmd) -> run a rake command on the app" do
|
|
104
|
+
stub_api_request(:post, "/apps/example/services").with(:body => "rake db:migrate").to_return(:body => "foo")
|
|
105
|
+
stub_api_request(:get, "/foo").to_return(:body => "output")
|
|
106
|
+
capture_stderr do # capture deprecation message
|
|
107
|
+
@client.rake('example', 'db:migrate')
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "console(app_name, cmd) -> run a console command on the app" do
|
|
112
|
+
stub_api_request(:post, "/apps/example/console").with(:body => "command=2%2B2")
|
|
113
|
+
@client.console('example', '2+2')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "console(app_name) { |c| } -> opens a console session, yields one accessor and closes it after the block" do
|
|
117
|
+
stub_api_request(:post, "/apps/example/consoles").to_return(:body => "consolename")
|
|
118
|
+
stub_api_request(:post, "/apps/example/consoles/consolename/command").with(:body => "command=1%2B1").to_return(:body => "2")
|
|
119
|
+
stub_api_request(:delete, "/apps/example/consoles/consolename")
|
|
120
|
+
|
|
121
|
+
@client.console('example') do |c|
|
|
122
|
+
c.run("1+1").should == '=> 2'
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "shows an error message when a console request fails" do
|
|
127
|
+
stub_request(:post, %r{.*/apps/example/console}).to_return({
|
|
128
|
+
:body => "ERRMSG", :status => 502
|
|
129
|
+
})
|
|
130
|
+
lambda { @client.console('example') }.should raise_error(Azuki::Client::AppCrashed, /Your application may have crashed/)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "restart(app_name) -> restarts the app servers" do
|
|
134
|
+
stub_api_request(:delete, "/apps/example/server")
|
|
135
|
+
capture_stderr do # capture deprecation message
|
|
136
|
+
@client.restart('example')
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
describe "read_logs" do
|
|
141
|
+
describe "old style" do
|
|
142
|
+
before(:each) do
|
|
143
|
+
stub_api_request(:get, "/apps/example/logs?logplex=true").to_return(:body => "Use old logs")
|
|
144
|
+
stub_api_request(:get, "/apps/example/logs").to_return(:body => "oldlogs")
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "can read old style logs" do
|
|
148
|
+
@client.should_receive(:puts).with("oldlogs")
|
|
149
|
+
@client.read_logs("example")
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe "new style" do
|
|
154
|
+
before(:each) do
|
|
155
|
+
stub_api_request(:get, "/apps/example/logs?logplex=true").to_return(:body => "https://logplex.azukiapp.com/identifier")
|
|
156
|
+
stub_request(:get, "https://logplex.azukiapp.com/identifier").to_return(:body => "newlogs")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "can read new style logs" do
|
|
160
|
+
@client.read_logs("example") do |logs|
|
|
161
|
+
logs.should == "newlogs"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "logs(app_name) -> returns recent output of the app logs" do
|
|
168
|
+
stub_api_request(:get, "/apps/example/logs").to_return(:body => "log")
|
|
169
|
+
capture_stderr do # capture deprecation message
|
|
170
|
+
@client.logs('example').should == 'log'
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "can get the number of dynos" do
|
|
175
|
+
stub_api_request(:get, "/apps/example").to_return(:body => <<-EOXML)
|
|
176
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
177
|
+
<app>
|
|
178
|
+
<dynos type='integer'>5</dynos>
|
|
179
|
+
</app>
|
|
180
|
+
EOXML
|
|
181
|
+
capture_stderr do # capture deprecation message
|
|
182
|
+
@client.dynos('example').should == 5
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it "can get the number of workers" do
|
|
187
|
+
stub_api_request(:get, "/apps/example").to_return(:body => <<-EOXML)
|
|
188
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
189
|
+
<app>
|
|
190
|
+
<workers type='integer'>5</workers>
|
|
191
|
+
</app>
|
|
192
|
+
EOXML
|
|
193
|
+
capture_stderr do # capture deprecation message
|
|
194
|
+
@client.workers('example').should == 5
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "set_dynos(app_name, qty) -> scales the app" do
|
|
199
|
+
stub_api_request(:put, "/apps/example/dynos").with(:body => "dynos=3")
|
|
200
|
+
capture_stderr do # capture deprecation message
|
|
201
|
+
@client.set_dynos('example', 3)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "rake catches 502s and shows the app crashlog" do
|
|
206
|
+
e = RestClient::RequestFailed.new
|
|
207
|
+
e.stub!(:http_code).and_return(502)
|
|
208
|
+
e.stub!(:http_body).and_return('the crashlog')
|
|
209
|
+
@client.should_receive(:post).and_raise(e)
|
|
210
|
+
capture_stderr do # capture deprecation message
|
|
211
|
+
lambda { @client.rake('example', '') }.should raise_error(Azuki::Client::AppCrashed)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "rake passes other status codes (i.e., 500) as standard restclient exceptions" do
|
|
216
|
+
e = RestClient::RequestFailed.new
|
|
217
|
+
e.stub!(:http_code).and_return(500)
|
|
218
|
+
e.stub!(:http_body).and_return('not a crashlog')
|
|
219
|
+
@client.should_receive(:post).and_raise(e)
|
|
220
|
+
capture_stderr do # capture deprecation message
|
|
221
|
+
lambda { @client.rake('example', '') }.should raise_error(RestClient::RequestFailed)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "ps_scale" do
|
|
226
|
+
it "scales a process and returns the new count" do
|
|
227
|
+
stub_api_request(:post, "/apps/example/ps/scale").with(:body => { :type => "web", :qty => "5" }).to_return(:body => "5")
|
|
228
|
+
capture_stderr do # capture deprecation message
|
|
229
|
+
@client.ps_scale("example", :type => "web", :qty => "5").should == 5
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe "collaborators" do
|
|
235
|
+
it "list(app_name) -> list app collaborators" do
|
|
236
|
+
stub_api_request(:get, "/apps/example/collaborators").to_return(:body => <<-EOXML)
|
|
237
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
238
|
+
<collaborators type="array">
|
|
239
|
+
<collaborator><email>joe@example.com</email></collaborator>
|
|
240
|
+
<collaborator><email>jon@example.com</email></collaborator>
|
|
241
|
+
</collaborators>
|
|
242
|
+
EOXML
|
|
243
|
+
capture_stderr do # capture deprecation message
|
|
244
|
+
@client.list_collaborators('example').should == [
|
|
245
|
+
{ :email => 'joe@example.com' },
|
|
246
|
+
{ :email => 'jon@example.com' }
|
|
247
|
+
]
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it "add_collaborator(app_name, email) -> adds collaborator to app" do
|
|
252
|
+
stub_api_request(:post, "/apps/example/collaborators").with(:body => "collaborator%5Bemail%5D=joe%40example.com")
|
|
253
|
+
capture_stderr do # capture deprecation message
|
|
254
|
+
@client.add_collaborator('example', 'joe@example.com')
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "remove_collaborator(app_name, email) -> removes collaborator from app" do
|
|
259
|
+
stub_api_request(:delete, "/apps/example/collaborators/joe%40example%2Ecom")
|
|
260
|
+
capture_stderr do # capture deprecation message
|
|
261
|
+
@client.remove_collaborator('example', 'joe@example.com')
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe "domain names" do
|
|
267
|
+
it "list(app_name) -> list app domain names" do
|
|
268
|
+
stub_api_request(:get, "/apps/example/domains").to_return(:body => <<-EOXML)
|
|
269
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
270
|
+
<domain-names type="array">
|
|
271
|
+
<domain-name><domain>example1.com</domain></domain-name>
|
|
272
|
+
<domain-name><domain>example2.com</domain></domain-name>
|
|
273
|
+
</domain-names>
|
|
274
|
+
EOXML
|
|
275
|
+
capture_stderr do # capture deprecation message
|
|
276
|
+
@client.list_domains('example').should == [{:domain => 'example1.com'}, {:domain => 'example2.com'}]
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "add_domain(app_name, domain) -> adds domain name to app" do
|
|
281
|
+
stub_api_request(:post, "/apps/example/domains").with(:body => "example.com")
|
|
282
|
+
capture_stderr do # capture deprecation message
|
|
283
|
+
@client.add_domain('example', 'example.com')
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "remove_domain(app_name, domain) -> removes domain name from app" do
|
|
288
|
+
stub_api_request(:delete, "/apps/example/domains/example.com")
|
|
289
|
+
capture_stderr do # capture deprecation message
|
|
290
|
+
@client.remove_domain('example', 'example.com')
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "remove_domain(app_name, domain) -> makes sure a domain is set" do
|
|
295
|
+
lambda do
|
|
296
|
+
capture_stderr do # capture deprecation message
|
|
297
|
+
@client.remove_domain('example', '')
|
|
298
|
+
end
|
|
299
|
+
end.should raise_error(ArgumentError)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "remove_domains(app_name) -> removes all domain names from app" do
|
|
303
|
+
stub_api_request(:delete, "/apps/example/domains")
|
|
304
|
+
capture_stderr do # capture deprecation message
|
|
305
|
+
@client.remove_domains('example')
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it "add_ssl(app_name, pem, key) -> adds a ssl cert to the domain" do
|
|
310
|
+
stub_api_request(:post, "/apps/example/ssl").with do |request|
|
|
311
|
+
body = CGI::parse(request.body)
|
|
312
|
+
body["key"].first.should == "thekey"
|
|
313
|
+
body["pem"].first.should == "thepem"
|
|
314
|
+
end.to_return(:body => "{}")
|
|
315
|
+
@client.add_ssl('example', 'thepem', 'thekey')
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "remove_ssl(app_name, domain) -> removes the ssl cert for the domain" do
|
|
319
|
+
stub_api_request(:delete, "/apps/example/domains/example.com/ssl")
|
|
320
|
+
@client.remove_ssl('example', 'example.com')
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
describe "SSH keys" do
|
|
325
|
+
it "fetches a list of the user's current keys" do
|
|
326
|
+
stub_api_request(:get, "/user/keys").to_return(:body => <<-EOXML)
|
|
327
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
328
|
+
<keys type="array">
|
|
329
|
+
<key>
|
|
330
|
+
<contents>ssh-dss thekey== joe@workstation</contents>
|
|
331
|
+
</key>
|
|
332
|
+
</keys>
|
|
333
|
+
EOXML
|
|
334
|
+
capture_stderr do # capture deprecation message
|
|
335
|
+
@client.keys.should == [ "ssh-dss thekey== joe@workstation" ]
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
it "add_key(key) -> add an SSH key (e.g., the contents of id_rsa.pub) to the user" do
|
|
340
|
+
stub_api_request(:post, "/user/keys").with(:body => "a key")
|
|
341
|
+
capture_stderr do # capture deprecation message
|
|
342
|
+
@client.add_key('a key')
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "remove_key(key) -> remove an SSH key by name (user@box)" do
|
|
347
|
+
stub_api_request(:delete, "/user/keys/joe%40workstation")
|
|
348
|
+
capture_stderr do # capture deprecation message
|
|
349
|
+
@client.remove_key('joe@workstation')
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it "remove_all_keys -> removes all SSH keys for the user" do
|
|
354
|
+
stub_api_request(:delete, "/user/keys")
|
|
355
|
+
capture_stderr do # capture deprecation message
|
|
356
|
+
@client.remove_all_keys
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "database_session(app_name) -> creates a taps database session" do
|
|
361
|
+
module ::Taps
|
|
362
|
+
def self.version
|
|
363
|
+
"0.3.0"
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
stub_api_request(:post, "/apps/example/database/session2").to_return(:body => "{\"session_id\":\"x234\"}")
|
|
368
|
+
@client.database_session('example')
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it "database_reset(app_name) -> reset an app's database" do
|
|
372
|
+
stub_api_request(:post, "/apps/example/database/reset")
|
|
373
|
+
@client.database_reset('example')
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "maintenance(app_name, :on) -> sets maintenance mode for an app" do
|
|
377
|
+
stub_api_request(:post, "/apps/example/server/maintenance").with(:body => "maintenance_mode=1")
|
|
378
|
+
capture_stderr do # capture deprecation message
|
|
379
|
+
@client.maintenance('example', :on)
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it "maintenance(app_name, :off) -> turns off maintenance mode for an app" do
|
|
384
|
+
stub_api_request(:post, "/apps/example/server/maintenance").with(:body => "maintenance_mode=0")
|
|
385
|
+
capture_stderr do # capture deprecation message
|
|
386
|
+
@client.maintenance('example', :off)
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
describe "config vars" do
|
|
392
|
+
it "config_vars(app_name) -> json hash of config vars for the app" do
|
|
393
|
+
stub_api_request(:get, "/apps/example/config_vars").to_return(:body => '{"A":"one", "B":"two"}')
|
|
394
|
+
capture_stderr do # capture deprecation message
|
|
395
|
+
@client.config_vars('example').should == { 'A' => 'one', 'B' => 'two'}
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
it "add_config_vars(app_name, vars)" do
|
|
400
|
+
stub_api_request(:put, "/apps/example/config_vars").with(:body => '{"x":"y"}')
|
|
401
|
+
capture_stderr do # capture deprecation message
|
|
402
|
+
@client.add_config_vars('example', {'x'=> 'y'})
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
it "remove_config_var(app_name, key)" do
|
|
407
|
+
stub_api_request(:delete, "/apps/example/config_vars/mykey")
|
|
408
|
+
capture_stderr do # capture deprecation message
|
|
409
|
+
@client.remove_config_var('example', 'mykey')
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it "clear_config_vars(app_name) -> resets all config vars for this app" do
|
|
414
|
+
stub_api_request(:delete, "/apps/example/config_vars")
|
|
415
|
+
capture_stderr do # capture deprecation message
|
|
416
|
+
@client.clear_config_vars('example')
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it "can handle config vars with special characters" do
|
|
421
|
+
stub_api_request(:delete, "/apps/example/config_vars/foo%5Bbar%5D")
|
|
422
|
+
capture_stderr do # capture deprecation message
|
|
423
|
+
lambda { @client.remove_config_var('example', 'foo[bar]') }.should_not raise_error
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
describe "addons" do
|
|
429
|
+
it "addons -> array with addons available for installation" do
|
|
430
|
+
stub_api_request(:get, "/addons").to_return(:body => '[{"name":"addon1"}, {"name":"addon2"}]')
|
|
431
|
+
@client.addons.should == [{'name' => 'addon1'}, {'name' => 'addon2'}]
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
it "installed_addons(app_name) -> array of installed addons" do
|
|
435
|
+
stub_api_request(:get, "/apps/example/addons").to_return(:body => '[{"name":"addon1"}]')
|
|
436
|
+
@client.installed_addons('example').should == [{'name' => 'addon1'}]
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
it "install_addon(app_name, addon_name)" do
|
|
440
|
+
stub_api_request(:post, "/apps/example/addons/addon1")
|
|
441
|
+
@client.install_addon('example', 'addon1').should be_nil
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it "upgrade_addon(app_name, addon_name)" do
|
|
445
|
+
stub_api_request(:put, "/apps/example/addons/addon1")
|
|
446
|
+
@client.upgrade_addon('example', 'addon1').should be_nil
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it "downgrade_addon(app_name, addon_name)" do
|
|
450
|
+
stub_api_request(:put, "/apps/example/addons/addon1")
|
|
451
|
+
@client.downgrade_addon('example', 'addon1').should be_nil
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
it "uninstall_addon(app_name, addon_name)" do
|
|
455
|
+
stub_api_request(:delete, "/apps/example/addons/addon1?").
|
|
456
|
+
to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"}))
|
|
457
|
+
|
|
458
|
+
@client.uninstall_addon('example', 'addon1').should be_true
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it "uninstall_addon(app_name, addon_name) with confirmation" do
|
|
462
|
+
stub_api_request(:delete, "/apps/example/addons/addon1?confirm=example").
|
|
463
|
+
to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"}))
|
|
464
|
+
|
|
465
|
+
@client.uninstall_addon('example', 'addon1', :confirm => "example").should be_true
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it "install_addon(app_name, addon_name) with response" do
|
|
469
|
+
stub_request(:post, "https://api.azukiapp.com/apps/example/addons/addon1").
|
|
470
|
+
to_return(:body => json_encode({'price' => 'free', 'message' => "Don't Panic"}))
|
|
471
|
+
|
|
472
|
+
@client.install_addon('example', 'addon1').
|
|
473
|
+
should == { 'price' => 'free', 'message' => "Don't Panic" }
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it "upgrade_addon(app_name, addon_name) with response" do
|
|
477
|
+
stub_request(:put, "https://api.azukiapp.com/apps/example/addons/addon1").
|
|
478
|
+
to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
|
|
479
|
+
|
|
480
|
+
@client.upgrade_addon('example', 'addon1').
|
|
481
|
+
should == { 'price' => 'free', 'message' => "Don't Panic" }
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it "downgrade_addon(app_name, addon_name) with response" do
|
|
485
|
+
stub_request(:put, "https://api.azukiapp.com/apps/example/addons/addon1").
|
|
486
|
+
to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
|
|
487
|
+
|
|
488
|
+
@client.downgrade_addon('example', 'addon1').
|
|
489
|
+
should == { 'price' => 'free', 'message' => "Don't Panic" }
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
it "uninstall_addon(app_name, addon_name) with response" do
|
|
493
|
+
stub_api_request(:delete, "/apps/example/addons/addon1?").
|
|
494
|
+
to_return(:body => json_encode('price'=> 'free', 'message'=> "Don't Panic"))
|
|
495
|
+
|
|
496
|
+
@client.uninstall_addon('example', 'addon1').
|
|
497
|
+
should == { 'price' => 'free', 'message' => "Don't Panic" }
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
describe "internal" do
|
|
502
|
+
before do
|
|
503
|
+
@client = Azuki::Client.new(nil, nil)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it "creates a RestClient resource for making calls" do
|
|
507
|
+
@client.stub!(:host).and_return('azukiapp.com')
|
|
508
|
+
@client.stub!(:user).and_return('joe@example.com')
|
|
509
|
+
@client.stub!(:password).and_return('secret')
|
|
510
|
+
|
|
511
|
+
res = @client.resource('/xyz')
|
|
512
|
+
|
|
513
|
+
res.url.should == 'https://api.azukiapp.com/xyz'
|
|
514
|
+
res.user.should == 'joe@example.com'
|
|
515
|
+
res.password.should == 'secret'
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
it "appends the api. prefix to the host" do
|
|
519
|
+
@client.host = "azukiapp.com"
|
|
520
|
+
@client.resource('/xyz').url.should == 'https://api.azukiapp.com/xyz'
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it "doesn't add the api. prefix to full hosts" do
|
|
524
|
+
@client.host = 'http://resource'
|
|
525
|
+
res = @client.resource('/xyz')
|
|
526
|
+
res.url.should == 'http://resource/xyz'
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it "runs a callback when the API sets a warning header" do
|
|
530
|
+
response = mock('rest client response', :headers => { :x_azuki_warning => 'Warning' })
|
|
531
|
+
@client.should_receive(:resource).and_return(@resource)
|
|
532
|
+
@resource.should_receive(:get).and_return(response)
|
|
533
|
+
@client.on_warning { |msg| @callback = msg }
|
|
534
|
+
@client.get('test')
|
|
535
|
+
@callback.should == 'Warning'
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
it "doesn't run the callback twice for the same warning" do
|
|
539
|
+
response = mock('rest client response', :headers => { :x_azuki_warning => 'Warning' })
|
|
540
|
+
@client.stub!(:resource).and_return(@resource)
|
|
541
|
+
@resource.stub!(:get).and_return(response)
|
|
542
|
+
@client.on_warning { |msg| @callback_called ||= 0; @callback_called += 1 }
|
|
543
|
+
@client.get('test1')
|
|
544
|
+
@client.get('test2')
|
|
545
|
+
@callback_called.should == 1
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
describe "stacks" do
|
|
550
|
+
it "list_stacks(app_name) -> json hash of available stacks" do
|
|
551
|
+
stub_api_request(:get, "/apps/example/stack?include_deprecated=false").to_return(:body => '{"stack":"one"}')
|
|
552
|
+
capture_stderr do # capture deprecation message
|
|
553
|
+
@client.list_stacks("example").should == { 'stack' => 'one' }
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
it "list_stacks(app_name, include_deprecated=true) passes the deprecated option" do
|
|
558
|
+
stub_api_request(:get, "/apps/example/stack?include_deprecated=true").to_return(:body => '{"stack":"one"}')
|
|
559
|
+
capture_stderr do # capture deprecation message
|
|
560
|
+
@client.list_stacks("example", :include_deprecated => true).should == { 'stack' => 'one' }
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
end
|