linode 0.7.7 → 0.7.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -1
- data/Gemfile.lock +1 -0
- data/README.md +276 -0
- data/Rakefile +7 -2
- data/VERSION +1 -1
- data/lib/linode.rb +26 -21
- data/linode.gemspec +5 -5
- data/spec/linode_spec.rb +114 -105
- metadata +7 -7
- data/README +0 -148
data/CHANGELOG
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
0.7.8 / 2012-04-26
|
3
|
+
==================
|
4
|
+
|
5
|
+
* set yamler, when necessary, for github issue #12
|
6
|
+
* make Rakefile more robust for rdoc versions
|
7
|
+
|
8
|
+
0.7.7 / 2011-10-17
|
3
9
|
==================
|
4
10
|
|
5
11
|
* Adds support for linode.ip.addprivate API method (thanks to Adam Durana)
|
data/Gemfile.lock
CHANGED
data/README.md
ADDED
@@ -0,0 +1,276 @@
|
|
1
|
+
# Linode Ruby API
|
2
|
+
|
3
|
+
## INSTALLATION:
|
4
|
+
|
5
|
+
Make sure gemcutter.org is in your gem sources list, then:
|
6
|
+
|
7
|
+
% sudo gem install linode
|
8
|
+
|
9
|
+
To run tests you will need both rspec and mocha installed.
|
10
|
+
|
11
|
+
## RUNNING:
|
12
|
+
|
13
|
+
Consult the Linode API guide here: [http://www.linode.com/api/autodoc.cfm](http://www.linode.com/api/autodoc.cfm)
|
14
|
+
You will need to get an API key (check your account profile).
|
15
|
+
|
16
|
+
Here is an annoyingly exhaustive IRB session where I play around with the API:
|
17
|
+
|
18
|
+
irb> require 'rubygems'
|
19
|
+
irb> require 'linode'
|
20
|
+
irb> api_key = 'TOPSECRETAPIKEY'
|
21
|
+
irb> l = Linode.new(:api_key => api_key)
|
22
|
+
=> #<Linode:0x100e03c @api_key="TOPSECRETAPIKEY">
|
23
|
+
|
24
|
+
irb> result = l.test.echo(:foo => 'bar', :baz => 'xyzzy')
|
25
|
+
=> #<OpenStruct baz="xyzzy", foo="bar">
|
26
|
+
irb> result.foo
|
27
|
+
=> "bar"
|
28
|
+
|
29
|
+
irb> result.baz
|
30
|
+
=> "xyzzy"
|
31
|
+
|
32
|
+
irb> result = l.avail.datacenters
|
33
|
+
=> [#<OpenStruct datacenterid=2, location="Dallas, TX, USA">, #<OpenStruct datacenterid=3, location="Fremont, CA,
|
34
|
+
USA">, #<OpenStruct datacenterid=4, location="Atlanta, GA, USA">, #<OpenStruct datacenterid=6, location="Newark, NJ,
|
35
|
+
USA">]
|
36
|
+
irb> s = _
|
37
|
+
=> [#<OpenStruct datacenterid=2, location="Dallas, TX, USA">, #<OpenStruct datacenterid=3, location="Fremont, CA,
|
38
|
+
USA">, #<OpenStruct datacenterid=4, location="Atlanta, GA, USA">, #<OpenStruct datacenterid=6, location="Newark, NJ,
|
39
|
+
USA">]
|
40
|
+
irb> result.first
|
41
|
+
=> #<OpenStruct datacenterid=2, location="Dallas, TX, USA">
|
42
|
+
irb> result.first.location
|
43
|
+
=> "Dallas, TX, USA"
|
44
|
+
irb> l.avail.datacenters.collect {|i| i.location }
|
45
|
+
=> ["Dallas, TX, USA", "Fremont, CA, USA", "Atlanta, GA, USA", "Newark, NJ, USA"]
|
46
|
+
irb> l.avail.datacenters.collect {|i| i.datacenterid }
|
47
|
+
=> [2, 3, 4, 6]
|
48
|
+
|
49
|
+
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT')
|
50
|
+
=> #<OpenStruct api_key="TOPSECRETAPIKEY", username="me">
|
51
|
+
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').api_key
|
52
|
+
=> "TOPSECRETAPIKEY"
|
53
|
+
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').username
|
54
|
+
=> "me"
|
55
|
+
|
56
|
+
irb> l.avail.kernels
|
57
|
+
=> [#<OpenStruct isxen=1, label="2.6.16.38-x86_64-linode2", kernelid=85>, #<OpenStruct isxen=1,
|
58
|
+
label="2.6.18.8-domU-linode7", kernelid=81>, #<OpenStruct isxen=1, label="2.6.18.8-linode10", kernelid=89>,
|
59
|
+
#<OpenStruct isxen=1, label="2.6.18.8-linode16", kernelid=98>, #<OpenStruct isxen=1,
|
60
|
+
label="2.6.18.8-x86_64-linode1", kernelid=86>, #<OpenStruct isxen=1, label="2.6.24.4-linode8", kernelid=84>,
|
61
|
+
#<OpenStruct isxen=1, label="2.6.25-linode9", kernelid=88>, #<OpenStruct isxen=1, label="2.6.25.10-linode12",
|
62
|
+
kernelid=90>, #<OpenStruct isxen=1, label="2.6.26-linode13", kernelid=91>, #<OpenStruct isxen=1,
|
63
|
+
label="2.6.27.4-linode14", kernelid=93>, #<OpenStruct isxen=1, label="2.6.27.4-x86_64-linode3", kernelid=94>,
|
64
|
+
#<OpenStruct isxen=1, label="2.6.28-linode15", kernelid=96>, #<OpenStruct isxen=1,
|
65
|
+
label="2.6.28-x86_64-linode4", kernelid=97>, #<OpenStruct isxen=1, label="2.6.28.3-linode17", kernelid=99>,
|
66
|
+
#<OpenStruct isxen=1, label="2.6.28.3-x86_64-linode5", kernelid=100>, #<OpenStruct isxen=1,
|
67
|
+
label="2.6.29-linode18", kernelid=101>, #<OpenStruct isxen=1, label="2.6.29-x86_64-linode6", kernelid=102>,
|
68
|
+
#<OpenStruct isxen=1, label="Latest 2.6 Series (2.6.18.8-linode16)", kernelid=60>, #<OpenStruct isxen=1,
|
69
|
+
label="pv-grub-x86_32", kernelid=92>, #<OpenStruct isxen=1, label="pv-grub-x86_64", kernelid=95>, #<OpenStruct
|
70
|
+
isxen=1, label="Recovery - Finnix (kernel)", kernelid=61>]
|
71
|
+
irb> l.avail.kernels.size
|
72
|
+
=> 21
|
73
|
+
irb> l.avail.kernels.first
|
74
|
+
=> #<OpenStruct isxen=1, label="2.6.16.38-x86_64-linode2", kernelid=85>
|
75
|
+
irb> l.avail.kernels.first.label
|
76
|
+
=> "2.6.16.38-x86_64-linode2"
|
77
|
+
|
78
|
+
irb> l.avail.linodeplans
|
79
|
+
=> [#<OpenStruct ram=360, label="Linode 360", avail={"6"=>26, "2"=>57, "3"=>20, "4"=>39}, price=19.95, planid=1,
|
80
|
+
xfer=200, disk=16>, #<OpenStruct ram=540, label="Linode 540", avail={"6"=>11, "2"=>38, "3"=>14, "4"=>28},
|
81
|
+
price=29.95, planid=2, xfer=300, disk=24>, #<OpenStruct ram=720, label="Linode 720", avail={"6"=>13, "2"=>27,
|
82
|
+
"3"=>18, "4"=>30}, price=39.95, planid=3, xfer=400, disk=32>, #<OpenStruct ram=1080, label="Linode 1080",
|
83
|
+
avail={"6"=>18, "2"=>7, "3"=>9, "4"=>4}, price=59.95, planid=4, xfer=600, disk=48>, #<OpenStruct ram=1440,
|
84
|
+
label="Linode 1440", avail={"6"=>14, "2"=>5, "3"=>7, "4"=>3}, price=79.95, planid=5, xfer=800, disk=64>,
|
85
|
+
#<OpenStruct ram=2880, label="Linode 2880", avail={"6"=>3, "2"=>3, "3"=>3, "4"=>3}, price=159.95, planid=6,
|
86
|
+
xfer=1600, disk=128>, #<OpenStruct ram=5760, label="Linode 5760", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5},
|
87
|
+
price=319.95, planid=7, xfer=2000, disk=256>, #<OpenStruct ram=8640, label="Linode 8640", avail={"6"=>5, "2"=>6,
|
88
|
+
"3"=>5, "4"=>5}, price=479.95, planid=8, xfer=2000, disk=384>, #<OpenStruct ram=11520, label="Linode 11520",
|
89
|
+
avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=639.95, planid=9, xfer=2000, disk=512>, #<OpenStruct ram=14400,
|
90
|
+
label="Linode 14400", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=799.95, planid=10, xfer=2000, disk=640>]
|
91
|
+
irb> l.avail.linodeplans.size
|
92
|
+
=> 10
|
93
|
+
irb> l.avail.linodeplans.first
|
94
|
+
=> #<OpenStruct ram=360, label="Linode 360", avail={"6"=>26, "2"=>57, "3"=>20, "4"=>39}, price=19.95, planid=1,
|
95
|
+
xfer=200, disk=16>
|
96
|
+
irb> l.avail.linodeplans.first.avail
|
97
|
+
=> {"6"=>26, "2"=>57, "3"=>20, "4"=>39}
|
98
|
+
|
99
|
+
irb> l.avail.distributions
|
100
|
+
=> [#<OpenStruct label="Arch Linux 2007.08", minimagesize=436, create_dt="2007-10-24 00:00:00.0", is64bit=0,
|
101
|
+
distributionid=38>, #<OpenStruct label="Centos 5.0", minimagesize=594, create_dt="2007-04-27 00:00:00.0",
|
102
|
+
is64bit=0, distributionid=32>, #<OpenStruct label="Centos 5.2", minimagesize=950, create_dt="2008-11-30 00:00:00.0",
|
103
|
+
is64bit=0, distributionid=46>, #<OpenStruct label="Centos 5.2 64bit", minimagesize=980,
|
104
|
+
create_dt="2008-11-30 00:00:00.0", is64bit=1, distributionid=47>, #<OpenStruct label="Debian 4.0",
|
105
|
+
minimagesize=200, create_dt="2007-04-18 00:00:00.0", is64bit=0, distributionid=28>, #<OpenStruct
|
106
|
+
label="Debian 4.0 64bit", minimagesize=220, create_dt="2008-12-02 00:00:00.0", is64bit=1, distributionid=48>,
|
107
|
+
#<OpenStruct label="Debian 5.0", minimagesize=200, create_dt="2009-02-19 00:00:00.0", is64bit=0, distributionid=50>,
|
108
|
+
#<OpenStruct label="Debian 5.0 64bit", minimagesize=300, create_dt="2009-02-19 00:00:00.0", is64bit=1,
|
109
|
+
distributionid=51>, #<OpenStruct label="Fedora 8", minimagesize=740, create_dt="2007-11-09 00:00:00.0", is64bit=0,
|
110
|
+
distributionid=40>, #<OpenStruct label="Fedora 9", minimagesize=1175, create_dt="2008-06-09 15:15:21.0", is64bit=0,
|
111
|
+
distributionid=43>, #<OpenStruct label="Gentoo 2007.0", minimagesize=1800, create_dt="2007-08-29 00:00:00.0",
|
112
|
+
is64bit=0, distributionid=35>, #<OpenStruct label="Gentoo 2008.0", minimagesize=1500,
|
113
|
+
create_dt="2009-03-20 00:00:00.0", is64bit=0, distributionid=52>, #<OpenStruct label="Gentoo 2008.0 64bit",
|
114
|
+
minimagesize=2500, create_dt="2009-04-04 00:00:00.0", is64bit=1, distributionid=53>, #<OpenStruct
|
115
|
+
label="OpenSUSE 11.0", minimagesize=850, create_dt="2008-08-21 08:32:16.0", is64bit=0, distributionid=44>,
|
116
|
+
#<OpenStruct label="Slackware 12.0", minimagesize=315, create_dt="2007-07-16 00:00:00.0", is64bit=0,
|
117
|
+
distributionid=34>, #<OpenStruct label="Slackware 12.2", minimagesize=500, create_dt="2009-04-04 00:00:00.0",
|
118
|
+
is64bit=0, distributionid=54>, #<OpenStruct label="Ubuntu 8.04 LTS", minimagesize=400,
|
119
|
+
create_dt="2008-04-23 15:11:29.0", is64bit=0, distributionid=41>, #<OpenStruct label="Ubuntu 8.04 LTS 64bit",
|
120
|
+
minimagesize=350, create_dt="2008-06-03 12:51:11.0", is64bit=1, distributionid=42>,
|
121
|
+
#<OpenStruct label="Ubuntu 8.10", minimagesize=220, create_dt="2008-10-30 23:23:03.0", is64bit=0,
|
122
|
+
distributionid=45>, #<OpenStruct label="Ubuntu 8.10 64bit", minimagesize=230, create_dt="2008-12-02 00:00:00.0",
|
123
|
+
is64bit=1, distributionid=49>, #<OpenStruct label="Ubuntu 9.04", minimagesize=350,
|
124
|
+
create_dt="2009-04-23 00:00:00.0", is64bit=0, distributionid=55>, #<OpenStruct label="Ubuntu 9.04 64bit",
|
125
|
+
minimagesize=350, create_dt="2009-04-23 00:00:00.0", is64bit=1, distributionid=56>]
|
126
|
+
irb> l.avail.distributions.size
|
127
|
+
=> 22
|
128
|
+
irb> l.avail.distributions.first
|
129
|
+
=> #<OpenStruct label="Arch Linux 2007.08", minimagesize=436, create_dt="2007-10-24 00:00:00.0", is64bit=0,
|
130
|
+
distributionid=38>
|
131
|
+
irb> l.avail.distributions.first.label
|
132
|
+
=> "Arch Linux 2007.08"
|
133
|
+
|
134
|
+
irb> l.domain.resource.list
|
135
|
+
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{}]:
|
136
|
+
ERRORCODE6ERRORMESSAGEDOMAINID is required but was not passed in
|
137
|
+
from ./lib/linode.rb:31:in `send_request'
|
138
|
+
from ./lib/linode.rb:13:in `list'
|
139
|
+
from (irb):3
|
140
|
+
irb> l.domain.resource.list(:DomainId => '1')
|
141
|
+
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data
|
142
|
+
[{:DomainId=>"1"}]: ERRORCODE5ERRORMESSAGEObject not found
|
143
|
+
from ./lib/linode.rb:31:in `send_request'
|
144
|
+
from ./lib/linode.rb:13:in `list'
|
145
|
+
from (irb):5
|
146
|
+
irb> l.domain.resource.list(:DomainId => '1', :ResourceId => '2')
|
147
|
+
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data
|
148
|
+
[{:DomainId=>"1", :ResourceId=>"2"}]: ERRORCODE5ERRORMESSAGEObject not found
|
149
|
+
from ./lib/linode.rb:31:in `send_request'
|
150
|
+
from ./lib/linode.rb:13:in `list'
|
151
|
+
from (irb):7
|
152
|
+
|
153
|
+
irb> l.linode
|
154
|
+
=> #<Linode::Linode:0x10056e4 @api_url="https://api.linode.com/", @api_key="TOPSECRETAPIKEY">
|
155
|
+
irb> l.linode.list
|
156
|
+
=> [#<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1,
|
157
|
+
alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0,
|
158
|
+
backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0,
|
159
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152,
|
160
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=4, lpm_displaygroup="", totalxfer=200,
|
161
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
162
|
+
backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="bragi", totalram=360, backupwindow=0,
|
163
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15418, totalhd=16384,
|
164
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=2, lpm_displaygroup="", totalxfer=200,
|
165
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
166
|
+
backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="nerthus", totalram=360, backupwindow=0,
|
167
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15419, totalhd=16384,
|
168
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=3, lpm_displaygroup="", totalxfer=200,
|
169
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
170
|
+
backupsenabled=0, backupweeklyday=0, status=1, alert_cpu_enabled=1, label="hoenir", totalram=360, backupwindow=0,
|
171
|
+
alert_diskio_threshold=500, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=24405, totalhd=16384,
|
172
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>]
|
173
|
+
irb> l.linode.list.size
|
174
|
+
=> 4
|
175
|
+
irb> l.linode.list.first
|
176
|
+
=> #<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1,
|
177
|
+
watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1,
|
178
|
+
alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300,
|
179
|
+
alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1,
|
180
|
+
alert_bwout_enabled=1>
|
181
|
+
irb> l.linode.list.first.datacenterid
|
182
|
+
=> 6
|
183
|
+
irb> l.linode.list.first.label
|
184
|
+
=> "byggvir"
|
185
|
+
|
186
|
+
irb(main):003:0* l.linode.config.list
|
187
|
+
RuntimeError: Error completing request [linode.config.list] @ [https://api.linode.com/] with data [{}]:
|
188
|
+
ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
189
|
+
from ./lib/linode.rb:45:in `send_request'
|
190
|
+
from ./lib/linode.rb:13:in `list'
|
191
|
+
from (irb):3
|
192
|
+
irb> l.linode.list
|
193
|
+
=> [#<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1,
|
194
|
+
alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0,
|
195
|
+
backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0,
|
196
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152,
|
197
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=4, lpm_displaygroup="", totalxfer=200,
|
198
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
199
|
+
backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="bragi", totalram=360, backupwindow=0,
|
200
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15418, totalhd=16384,
|
201
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=2, lpm_displaygroup="", totalxfer=200,
|
202
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
203
|
+
backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="nerthus", totalram=360, backupwindow=0,
|
204
|
+
alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15419, totalhd=16384,
|
205
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=3, lpm_displaygroup="", totalxfer=200,
|
206
|
+
alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5,
|
207
|
+
backupsenabled=0, backupweeklyday=0, status=1, alert_cpu_enabled=1, label="hoenir", totalram=360, backupwindow=0,
|
208
|
+
alert_diskio_threshold=500, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=24405, totalhd=16384,
|
209
|
+
alert_bwin_enabled=1, alert_bwout_enabled=1>]
|
210
|
+
irb> l.linode.list.first
|
211
|
+
=> #<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1,
|
212
|
+
watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1,
|
213
|
+
alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300,
|
214
|
+
alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1,
|
215
|
+
alert_bwout_enabled=1>
|
216
|
+
irb> l.linode.list.first.linodeid
|
217
|
+
=> 12446
|
218
|
+
irb> l.linode.config.list(:LinodeId => 12446)
|
219
|
+
=> [#<OpenStruct helper_disableupdatedb=1, ramlimit=0, kernelid=60, helper_depmod=1, rootdevicecustom="",
|
220
|
+
disklist="79850,79851,79854,,,,,,", label="byggvir", runlevel="default", rootdevicero=true, configid=43615,
|
221
|
+
rootdevicenum=1, linodeid=12446, helper_libtls=false, helper_xen=1, comments="">]
|
222
|
+
irb> l.linode.config.list(:LinodeId => 12446).first.disklist
|
223
|
+
=> "79850,79851,79854,,,,,,"
|
224
|
+
|
225
|
+
irb> l.linode.job.list
|
226
|
+
RuntimeError: Error completing request [linode.job.list] @ [https://api.linode.com/] with data [{}]:
|
227
|
+
ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
228
|
+
from ./lib/linode.rb:45:in `send_request'
|
229
|
+
from ./lib/linode.rb:13:in `list'
|
230
|
+
from (irb):7
|
231
|
+
|
232
|
+
irb> l.linode.job.list(:LinodeId => 12446)
|
233
|
+
=> [#<OpenStruct action="linode.boot", jobid=1241724, duration=8, host_finish_dt="2009-07-14 17:07:29.0",
|
234
|
+
host_message="", linodeid=12446, host_success=1, host_start_dt="2009-07-14 17:07:21.0",
|
235
|
+
entered_dt="2009-07-14 17:06:25.0", label="System Boot - byggvir">, #<OpenStruct action="linode.shutdown",
|
236
|
+
jobid=1241723, duration=14, host_finish_dt="2009-07-14 17:07:20.0", host_message="", linodeid=12446, host_success=1,
|
237
|
+
host_start_dt="2009-07-14 17:07:06.0", entered_dt="2009-07-14 17:06:25.0", label="System Shutdown">,
|
238
|
+
#<OpenStruct action="linode.boot", jobid=1182441, duration=0, host_finish_dt="2009-06-10 04:27:49.0",
|
239
|
+
host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 04:27:49.0",
|
240
|
+
entered_dt="2009-06-10 04:26:05.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot",
|
241
|
+
jobid=1182436, duration=8, host_finish_dt="2009-06-10 04:27:49.0", host_message="", linodeid=12446, host_success=1,
|
242
|
+
host_start_dt="2009-06-10 04:27:41.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">,
|
243
|
+
#<OpenStruct action="linode.boot", jobid=1182273, duration=0, host_finish_dt="2009-06-10 03:02:31.0",
|
244
|
+
host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 03:02:31.0",
|
245
|
+
entered_dt="2009-06-10 02:59:49.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot",
|
246
|
+
jobid=1182268, duration=8, host_finish_dt="2009-06-10 03:02:31.0", host_message="", linodeid=12446, host_success=1,
|
247
|
+
host_start_dt="2009-06-10 03:02:23.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">,
|
248
|
+
#<OpenStruct action="linode.boot", jobid=1182150, duration=1, host_finish_dt="2009-06-10 01:28:40.0",
|
249
|
+
host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 01:28:39.0",
|
250
|
+
entered_dt="2009-06-10 01:26:55.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot",
|
251
|
+
jobid=1182145, duration=8, host_finish_dt="2009-06-10 01:28:39.0", host_message="", linodeid=12446, host_success=1,
|
252
|
+
host_start_dt="2009-06-10 01:28:31.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">]
|
253
|
+
irb> l.linode.job.list(:LinodeId => 12446).size
|
254
|
+
=> 8
|
255
|
+
|
256
|
+
irb> l.linode.ip.list
|
257
|
+
RuntimeError: Error completing request [linode.ip.list] @ [https://api.linode.com/] with data [{}]:
|
258
|
+
ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
259
|
+
from ./lib/linode.rb:45:in `send_request'
|
260
|
+
from ./lib/linode.rb:13:in `list'
|
261
|
+
from (irb):10
|
262
|
+
irb> l.linode.ip.list(:LinodeId => 12446)
|
263
|
+
=> [#<OpenStruct rdns_name="byggvir.websages.com", ipaddressid=12286, linodeid=12446, ispublic=1,
|
264
|
+
ipaddress="209.123.234.161">, #<OpenStruct rdns_name="li101-51.members.linode.com", ipaddressid=23981,
|
265
|
+
linodeid=12446, ispublic=1, ipaddress="97.107.140.51">]
|
266
|
+
irb> ^D@ Wed Aug 05 01:50:52 rick@Yer-Moms-Computer
|
267
|
+
|
268
|
+
## CREDITS:
|
269
|
+
|
270
|
+
* Thanks to Aditya Sanghi ([asanghi](http://github.com/asanghi)) for a patch to properly namespace stackscripts functionality.
|
271
|
+
* Thanks to Dan Hodos ([danhodos](http://github.com/danhodos)) for diagnosing and fixing an issue with sending GET requests instead of POST request.
|
272
|
+
* Thanks to Aaron Hamid for updates for RSpec 2 and work on user.getapikey + username/password initialization.
|
273
|
+
* Thanks to Musfuut ([musfuut](http://github.com/musfuut)) for diagnosing and recommending a fix for OpenStruct and 'type' data members in Linode returned results.
|
274
|
+
* Thanks to mihaibirsan ([mihaibirsan](http://github.com/mihaibirsan)) for diagnosing a problem with dependencies on the 'crack' library.
|
275
|
+
* Thanks to Adam Durana ([durana](http://github.com/durana)) for adding support for linode.ip.addprivate.
|
276
|
+
* Thanks to Gustavo Beathyate ([goddamnhippie](http://github/goddamnhippie)) for markdownifying the README.
|
data/Rakefile
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
require 'rake/testtask'
|
4
|
-
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rdoc/task'
|
7
|
+
rescue LoadError
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
end
|
5
10
|
require 'rspec/core/rake_task'
|
6
11
|
|
7
12
|
desc 'Default: run specs.'
|
@@ -27,7 +32,7 @@ begin
|
|
27
32
|
gemspec.add_dependency('httparty', '>= 0.4.4')
|
28
33
|
gemspec.add_dependency('crack', '>= 0.3.1')
|
29
34
|
end
|
30
|
-
Jeweler::GemcutterTasks.new
|
35
|
+
Jeweler::GemcutterTasks.new
|
31
36
|
rescue LoadError
|
32
37
|
end
|
33
38
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.8
|
data/lib/linode.rb
CHANGED
@@ -4,9 +4,14 @@ require 'ostruct_tweak'
|
|
4
4
|
require 'httparty'
|
5
5
|
require 'crack'
|
6
6
|
|
7
|
+
begin
|
8
|
+
YAML::ENGINE.yamler = 'syck'
|
9
|
+
rescue # see: https://github.com/rick/linode/issues/12
|
10
|
+
end
|
11
|
+
|
7
12
|
class Linode
|
8
13
|
attr_reader :username, :password
|
9
|
-
|
14
|
+
|
10
15
|
def self.has_method(*actions)
|
11
16
|
actions.each do |action|
|
12
17
|
define_method(action.to_sym) do |*data|
|
@@ -16,7 +21,7 @@ class Linode
|
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
19
|
-
|
24
|
+
|
20
25
|
def self.has_namespace(*namespaces)
|
21
26
|
namespaces.each do |namespace|
|
22
27
|
define_method(namespace.to_sym) do ||
|
@@ -28,35 +33,35 @@ class Linode
|
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
31
|
-
|
36
|
+
|
32
37
|
has_namespace :test, :avail, :user, :domain, :linode, :nodebalancer, :stackscript
|
33
|
-
|
38
|
+
|
34
39
|
@@documentation_category = {}
|
35
|
-
|
40
|
+
|
36
41
|
def self.documentation_category(category)
|
37
42
|
@@documentation_category[class_to_path(name)] = category
|
38
43
|
end
|
39
|
-
|
44
|
+
|
40
45
|
def documentation_categories
|
41
46
|
@@documentation_category
|
42
47
|
end
|
43
|
-
|
48
|
+
|
44
49
|
def self.action_path(class_name, action)
|
45
50
|
Linode.class_to_path(class_name) + ".#{action}"
|
46
51
|
end
|
47
|
-
|
52
|
+
|
48
53
|
def self.class_to_path(class_name)
|
49
54
|
class_name.downcase.sub(/^linode::/, '').gsub(/::/, '.')
|
50
55
|
end
|
51
|
-
|
56
|
+
|
52
57
|
def documentation_path(action)
|
53
58
|
hits = action.match(/^(.*)\.[^.]+$/)
|
54
59
|
"http://www.linode.com/api/" + @@documentation_category[hits[1]] + '/' + action
|
55
60
|
end
|
56
|
-
|
61
|
+
|
57
62
|
def initialize(args)
|
58
63
|
@api_url = args[:api_url] if args[:api_url]
|
59
|
-
|
64
|
+
|
60
65
|
if args.include?(:api_key)
|
61
66
|
@api_key = args[:api_key]
|
62
67
|
elsif args.include?(:username) and args.include?(:password)
|
@@ -66,7 +71,7 @@ class Linode
|
|
66
71
|
raise ArgumentError, "Either :api_key, or both :username and :password, are required."
|
67
72
|
end
|
68
73
|
end
|
69
|
-
|
74
|
+
|
70
75
|
def api_url
|
71
76
|
@api_url || 'https://api.linode.com/'
|
72
77
|
end
|
@@ -74,46 +79,46 @@ class Linode
|
|
74
79
|
def api_key
|
75
80
|
@api_key ||= fetch_api_key
|
76
81
|
end
|
77
|
-
|
82
|
+
|
78
83
|
def send_request(action, data)
|
79
84
|
data.delete_if {|k,v| [:api_key, :api_action, :api_responseFormat].include?(k) }
|
80
85
|
response = post({ :api_key => api_key, :api_action => action, :api_responseFormat => 'json' }.merge(data))
|
81
86
|
raise "Errors completing request [#{action}] @ [#{api_url}] with data [#{data.inspect}]:\n#{error_message(response, action)}" if error?(response)
|
82
87
|
reformat_response(response)
|
83
88
|
end
|
84
|
-
|
89
|
+
|
85
90
|
protected
|
86
|
-
|
91
|
+
|
87
92
|
def fetch_api_key
|
88
93
|
response = post(:api_action => 'user.getapikey', :api_responseFormat => 'json', :username => username, :password => password)
|
89
94
|
raise "Errors completing request [user.getapikey] @ [#{api_url}] for username [#{username}]:\n#{error_message(response, 'user.getapikey')}" if error?(response)
|
90
95
|
reformat_response(response).api_key
|
91
96
|
end
|
92
|
-
|
97
|
+
|
93
98
|
def post(data)
|
94
99
|
Crack::JSON.parse(HTTParty.post(api_url, :body => data))
|
95
100
|
end
|
96
|
-
|
101
|
+
|
97
102
|
def error?(response)
|
98
103
|
response and response["ERRORARRAY"] and ! response["ERRORARRAY"].empty?
|
99
104
|
end
|
100
|
-
|
105
|
+
|
101
106
|
def error_message(response, action)
|
102
107
|
response["ERRORARRAY"].collect { |err|
|
103
108
|
" - Error \##{err["ERRORCODE"]} - #{err["ERRORMESSAGE"]}. "+
|
104
109
|
"(Please consult #{documentation_path(action)})"
|
105
110
|
}.join("\n")
|
106
111
|
end
|
107
|
-
|
112
|
+
|
108
113
|
def reformat_response(response)
|
109
114
|
result = response['DATA']
|
110
115
|
return result.collect {|item| convert_item(item) } if result.class == Array
|
111
116
|
return result unless result.respond_to?(:keys)
|
112
117
|
convert_item(result)
|
113
118
|
end
|
114
|
-
|
119
|
+
|
115
120
|
def convert_item(item)
|
116
|
-
item.keys.each do |k|
|
121
|
+
item.keys.each do |k|
|
117
122
|
item[k.downcase] = item[k]
|
118
123
|
item.delete(k) if k != k.downcase
|
119
124
|
end
|
data/linode.gemspec
CHANGED
@@ -5,15 +5,15 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "linode"
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rick Bradley"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2012-04-26"
|
13
13
|
s.description = "This is a wrapper around Linode's automation facilities."
|
14
14
|
s.email = "rick@rickbradley.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
|
-
"README"
|
16
|
+
"README.md"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".rspec",
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
"Gemfile",
|
22
22
|
"Gemfile.lock",
|
23
23
|
"MIT-LICENSE",
|
24
|
-
"README",
|
24
|
+
"README.md",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
27
|
"autotest/discover.rb",
|
@@ -61,7 +61,7 @@ Gem::Specification.new do |s|
|
|
61
61
|
]
|
62
62
|
s.homepage = "http://github.com/rick/linode"
|
63
63
|
s.require_paths = ["lib"]
|
64
|
-
s.rubygems_version = "1.8.
|
64
|
+
s.rubygems_version = "1.8.11"
|
65
65
|
s.summary = "a Ruby wrapper for the Linode API"
|
66
66
|
|
67
67
|
if s.respond_to? :specification_version then
|
data/spec/linode_spec.rb
CHANGED
@@ -6,28 +6,28 @@ describe Linode do
|
|
6
6
|
it 'should be able to create a new Linode instance' do
|
7
7
|
Linode.should respond_to(:new)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
describe 'when creating a new Linode instance' do
|
11
11
|
it 'should accept an arguments hash' do
|
12
12
|
lambda { Linode.new(:api_key => 'foo') }.should_not raise_error(ArgumentError)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it 'should require an arguments hash' do
|
16
16
|
lambda { Linode.new }.should raise_error(ArgumentError)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'should not fail if an API key is given' do
|
20
|
-
lambda { Linode.new({ :api_key => 'foo' }) }.should_not raise_error(ArgumentError)
|
20
|
+
lambda { Linode.new({ :api_key => 'foo' }) }.should_not raise_error(ArgumentError)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it 'should not fail if a username/password combo is given' do
|
24
|
-
lambda { Linode.new({ :username => 'bar', :password => 'baz' }) }.should_not raise_error(ArgumentError)
|
24
|
+
lambda { Linode.new({ :username => 'bar', :password => 'baz' }) }.should_not raise_error(ArgumentError)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it 'should fail if no API key nor username/password combo is given' do
|
28
|
-
lambda { Linode.new({}) }.should raise_error(ArgumentError)
|
28
|
+
lambda { Linode.new({}) }.should raise_error(ArgumentError)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it 'should return a Linode instance' do
|
32
32
|
Linode.new(:api_key => 'foo').class.should == Linode
|
33
33
|
end
|
@@ -35,7 +35,7 @@ describe Linode do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
describe 'Linode' do
|
38
|
+
describe 'Linode' do
|
39
39
|
before :each do
|
40
40
|
@api_key = 'foo'
|
41
41
|
@api_url = 'https://fake.linode.com/'
|
@@ -43,14 +43,14 @@ describe 'Linode' do
|
|
43
43
|
@password = 'baz'
|
44
44
|
@linode = Linode.new(:api_key => @api_key, :api_url => @api_url)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
describe 'when initialized with username and password' do
|
48
48
|
before :each do
|
49
49
|
@linode = Linode.new(:username => @username, :password => @password, :api_url => @api_url)
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it 'should be able to return the username provided at creation time' do
|
53
|
-
@linode.username.should == 'bar'
|
53
|
+
@linode.username.should == 'bar'
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should be able to return the password provided at creation time' do
|
@@ -64,18 +64,18 @@ describe 'Linode' do
|
|
64
64
|
|
65
65
|
it 'should return the stock linode API URL if none was provided at creation time' do
|
66
66
|
@linode = Linode.new(:username => @username, :password => @api_url)
|
67
|
-
@linode.api_url.should == 'https://api.linode.com/'
|
67
|
+
@linode.api_url.should == 'https://api.linode.com/'
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'should use the user.getapikey remote call to look up the API key associated with the username/password combo specified at creation time' do
|
72
72
|
@json = '{"ERRORARRAY":[],"DATA":{"USERNAME":"ogc","API_KEY":"blahblahblah"},"ACTION":"user.getapikey"}'
|
73
|
-
HTTParty.expects(:post).with(@api_url,
|
74
|
-
:body => {
|
75
|
-
:api_action => 'user.getapikey',
|
76
|
-
:api_responseFormat => 'json',
|
77
|
-
:username => @username,
|
78
|
-
:password => @password
|
73
|
+
HTTParty.expects(:post).with(@api_url,
|
74
|
+
:body => {
|
75
|
+
:api_action => 'user.getapikey',
|
76
|
+
:api_responseFormat => 'json',
|
77
|
+
:username => @username,
|
78
|
+
:password => @password
|
79
79
|
}
|
80
80
|
).returns(@json)
|
81
81
|
@linode.api_key
|
@@ -85,12 +85,12 @@ describe 'Linode' do
|
|
85
85
|
@linode.stubs(:fetch_api_key).returns(@api_key)
|
86
86
|
@linode.api_key.should == @api_key
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
it 'should fail when looking up the API key if API key remote lookup fails' do
|
90
90
|
@linode.stubs(:fetch_api_key).raises
|
91
91
|
lambda { @linode.api_key }.should raise_error
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
it 'should cache API key remote lookups for later use' do
|
95
95
|
@linode.stubs(:fetch_api_key).returns(@api_key)
|
96
96
|
@linode.api_key
|
@@ -98,16 +98,16 @@ describe 'Linode' do
|
|
98
98
|
@linode.api_key.should == @api_key
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
describe 'when initialized with API key' do
|
103
103
|
it 'should return a nil username' do
|
104
104
|
@linode.username.should be_nil
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
it 'should return a nil password' do
|
108
108
|
@linode.password.should be_nil
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
it 'should be able to return the API key provided at creation time' do
|
112
112
|
@linode.api_key.should == 'foo'
|
113
113
|
end
|
@@ -120,34 +120,34 @@ describe 'Linode' do
|
|
120
120
|
|
121
121
|
it 'should return the stock linode API URL if none was provided at creation time' do
|
122
122
|
@linode = Linode.new(:api_key => @api_key)
|
123
|
-
@linode.api_url.should == 'https://api.linode.com/'
|
123
|
+
@linode.api_url.should == 'https://api.linode.com/'
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
it 'should be able to submit a request via the API' do
|
129
129
|
@linode.should respond_to(:send_request)
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
describe 'when submitting a request via the API' do
|
133
133
|
before :each do
|
134
134
|
@json = %Q!{
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
135
|
+
"ERRORARRAY":[],
|
136
|
+
"ACTION":"test.echo",
|
137
|
+
"DATA":{"FOO":"bar"}
|
138
|
+
}!
|
139
139
|
HTTParty.stubs(:post).returns(@json)
|
140
140
|
@linode.stubs(:api_url).returns('https://fake.linode.com/')
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
it 'should allow a request name and a data hash' do
|
144
144
|
lambda { @linode.send_request('test.echo', {}) }.should_not raise_error(ArgumentError)
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
it 'should require a request name and a data hash' do
|
148
|
-
lambda { @linode.send_request('test.echo') }.should raise_error(ArgumentError)
|
148
|
+
lambda { @linode.send_request('test.echo') }.should raise_error(ArgumentError)
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
it 'should make a request to the API url' do
|
152
152
|
@linode.stubs(:api_url).returns('https://fake.linode.com/')
|
153
153
|
HTTParty.expects(:post).with { |path, args|
|
@@ -155,134 +155,143 @@ describe 'Linode' do
|
|
155
155
|
}.returns(@json)
|
156
156
|
@linode.send_request('test.echo', { })
|
157
157
|
end
|
158
|
-
|
158
|
+
|
159
159
|
it 'should provide the API key when making its request' do
|
160
160
|
HTTParty.expects(:post).with { |path, args|
|
161
161
|
args[:body][:api_key] == @api_key
|
162
162
|
}.returns(@json)
|
163
|
-
@linode.send_request('test.echo', { })
|
163
|
+
@linode.send_request('test.echo', { })
|
164
164
|
end
|
165
|
-
|
165
|
+
|
166
166
|
it 'should set the designated request method as the HTTP API action' do
|
167
167
|
HTTParty.expects(:post).with { |path, args|
|
168
168
|
args[:body][:api_action] == 'test.echo'
|
169
169
|
}.returns(@json)
|
170
|
-
@linode.send_request('test.echo', { })
|
170
|
+
@linode.send_request('test.echo', { })
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
it 'should set the response format to JSON' do
|
174
174
|
HTTParty.expects(:post).with { |path, args|
|
175
175
|
args[:body][:api_responseFormat] == 'json'
|
176
176
|
}.returns(@json)
|
177
|
-
@linode.send_request('test.echo', { })
|
177
|
+
@linode.send_request('test.echo', { })
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
it 'should provide the data hash to the HTTP API request' do
|
181
181
|
HTTParty.expects(:post).with { |path, args|
|
182
182
|
args[:body]['foo'] == 'bar'
|
183
183
|
}.returns(@json)
|
184
|
-
@linode.send_request('test.echo', { 'foo' => 'bar' })
|
184
|
+
@linode.send_request('test.echo', { 'foo' => 'bar' })
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
it 'should not allow overriding the API key via the data hash' do
|
188
188
|
HTTParty.expects(:post).with { |path, args|
|
189
189
|
args[:body][:api_key] == @api_key
|
190
190
|
}.returns(@json)
|
191
|
-
@linode.send_request('test.echo', { :api_key => 'h4x0r' })
|
191
|
+
@linode.send_request('test.echo', { :api_key => 'h4x0r' })
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
it 'should not allow overriding the API action via the data hash' do
|
195
195
|
HTTParty.expects(:post).with { |path, args|
|
196
196
|
args[:body][:api_action] == 'test.echo'
|
197
197
|
}.returns(@json)
|
198
198
|
@linode.send_request('test.echo', { :api_action => 'h4x0r' })
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
it 'should not allow overriding the API response format via the data hash' do
|
202
202
|
HTTParty.expects(:post).with { |path, args|
|
203
203
|
args[:body][:api_responseFormat] == 'json'
|
204
204
|
}.returns(@json)
|
205
205
|
@linode.send_request('test.echo', { :api_responseFormat => 'h4x0r' })
|
206
206
|
end
|
207
|
-
|
207
|
+
|
208
208
|
it 'should fail when the request submission fails' do
|
209
209
|
HTTParty.stubs(:post).returns(%Q!{
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
"ERRORARRAY":["failure"],
|
211
|
+
"ACTION":"test.echo",
|
212
|
+
"DATA":{"foo":"bar"}
|
213
213
|
}!)
|
214
214
|
lambda { @linode.send_request('test.echo', { :api_action => 'failure' }) }.should raise_error
|
215
215
|
end
|
216
|
-
|
216
|
+
|
217
217
|
describe 'when the result is a list of hashes' do
|
218
218
|
it 'should return a list of objects with lower-cased methods for the data fields' do
|
219
219
|
HTTParty.stubs(:post).returns(%Q!{
|
220
|
-
|
221
|
-
|
222
|
-
|
220
|
+
"ERRORARRAY":[],
|
221
|
+
"ACTION":"test.echo",
|
222
|
+
"DATA":[{"FOO":"bar"},{"BAR":"baz"}]
|
223
223
|
}!)
|
224
224
|
@linode.send_request('test.echo', {}).first.foo.should == 'bar'
|
225
225
|
@linode.send_request('test.echo', {}).last.bar.should == 'baz'
|
226
226
|
end
|
227
|
-
|
227
|
+
|
228
228
|
it 'should return a list of objects which do not respond to upper-case URLs for the data fields' do
|
229
229
|
HTTParty.stubs(:post).returns(%Q!{
|
230
|
-
|
231
|
-
|
232
|
-
|
230
|
+
"ERRORARRAY":[],
|
231
|
+
"ACTION":"test.echo",
|
232
|
+
"DATA":[{"FOO":"bar"},{"BAR":"baz"}]
|
233
233
|
}!)
|
234
234
|
@linode.send_request('test.echo', {}).first.should_not respond_to(:FOO)
|
235
235
|
@linode.send_request('test.echo', {}).last.should_not respond_to(:BAR)
|
236
236
|
end
|
237
237
|
end
|
238
|
-
|
238
|
+
|
239
239
|
describe 'when the result is a hash' do
|
240
240
|
it 'should return an object with lower-cased methods for the data fields' do
|
241
241
|
@linode.send_request('test.echo', {}).foo.should == 'bar'
|
242
242
|
end
|
243
|
-
|
243
|
+
|
244
244
|
it 'should return an object which does not respond to upper-case URLs for the data fields' do
|
245
245
|
@linode.send_request('test.echo', {}).should_not respond_to(:FOO)
|
246
246
|
end
|
247
247
|
end
|
248
|
-
|
248
|
+
|
249
249
|
describe 'when the result is neither a list nor a hash' do
|
250
250
|
it 'should return the result unchanged' do
|
251
251
|
HTTParty.stubs(:post).returns(%Q!{
|
252
|
-
|
253
|
-
|
254
|
-
|
252
|
+
"ERRORARRAY":[],
|
253
|
+
"ACTION":"test.echo",
|
254
|
+
"DATA":"thingie"
|
255
255
|
}!)
|
256
256
|
@linode.send_request('test.echo', {}).should == "thingie"
|
257
257
|
end
|
258
258
|
end
|
259
|
+
|
260
|
+
it 'should be able to parse real JSON when processing a request' do
|
261
|
+
json = '{"ERRORARRAY":[],"DATA":[{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":90,"IS64BIT":0,"LABEL":"Arch Linux 2011.08","MINIMAGESIZE":500,"CREATE_DT":"2011-09-26 17:18:05.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":91,"IS64BIT":1,"LABEL":"Arch Linux 2011.08 64bit","MINIMAGESIZE":500,"CREATE_DT":"2011-09-26 17:18:05.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":88,"IS64BIT":0,"LABEL":"CentOS 6.2","MINIMAGESIZE":800,"CREATE_DT":"2011-07-19 11:38:20.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":89,"IS64BIT":1,"LABEL":"CentOS 6.2 64bit","MINIMAGESIZE":800,"CREATE_DT":"2011-07-19 11:38:20.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":77,"IS64BIT":0,"LABEL":"Debian 6","MINIMAGESIZE":550,"CREATE_DT":"2011-02-08 16:54:31.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":78,"IS64BIT":1,"LABEL":"Debian 6 64bit","MINIMAGESIZE":550,"CREATE_DT":"2011-02-08 16:54:31.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":94,"IS64BIT":0,"LABEL":"Fedora 16","MINIMAGESIZE":1000,"CREATE_DT":"2012-04-09 14:12:04.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":95,"IS64BIT":1,"LABEL":"Fedora 16 64bit","MINIMAGESIZE":1000,"CREATE_DT":"2012-04-09 14:12:32.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":72,"IS64BIT":0,"LABEL":"Gentoo","MINIMAGESIZE":1000,"CREATE_DT":"2010-09-13 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":53,"IS64BIT":1,"LABEL":"Gentoo 64bit","MINIMAGESIZE":1000,"CREATE_DT":"2009-04-04 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":96,"IS64BIT":0,"LABEL":"openSUSE 12.1","MINIMAGESIZE":1000,"CREATE_DT":"2012-04-13 11:43:30.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":97,"IS64BIT":1,"LABEL":"openSUSE 12.1 64bit","MINIMAGESIZE":1000,"CREATE_DT":"2012-04-13 11:43:30.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":86,"IS64BIT":0,"LABEL":"Slackware 13.37","MINIMAGESIZE":600,"CREATE_DT":"2011-06-05 15:11:59.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":87,"IS64BIT":1,"LABEL":"Slackware 13.37 64bit","MINIMAGESIZE":600,"CREATE_DT":"2011-06-05 15:11:59.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":64,"IS64BIT":0,"LABEL":"Ubuntu 10.04 LTS","MINIMAGESIZE":450,"CREATE_DT":"2010-04-29 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":65,"IS64BIT":1,"LABEL":"Ubuntu 10.04 LTS 64bit","MINIMAGESIZE":450,"CREATE_DT":"2010-04-29 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":92,"IS64BIT":0,"LABEL":"Ubuntu 11.10","MINIMAGESIZE":750,"CREATE_DT":"2011-10-14 14:29:42.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":93,"IS64BIT":1,"LABEL":"Ubuntu 11.10 64bit","MINIMAGESIZE":850,"CREATE_DT":"2011-10-14 14:29:42.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":59,"IS64BIT":0,"LABEL":"CentOS 5.6","MINIMAGESIZE":950,"CREATE_DT":"2009-08-17 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":60,"IS64BIT":1,"LABEL":"CentOS 5.6 64bit","MINIMAGESIZE":950,"CREATE_DT":"2009-08-17 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":50,"IS64BIT":0,"LABEL":"Debian 5.0","MINIMAGESIZE":350,"CREATE_DT":"2009-02-19 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":51,"IS64BIT":1,"LABEL":"Debian 5.0 64bit","MINIMAGESIZE":350,"CREATE_DT":"2009-02-19 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":84,"IS64BIT":0,"LABEL":"Fedora 15","MINIMAGESIZE":900,"CREATE_DT":"2011-05-25 18:57:36.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":85,"IS64BIT":1,"LABEL":"Fedora 15 64bit","MINIMAGESIZE":900,"CREATE_DT":"2011-05-25 18:58:07.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":79,"IS64BIT":0,"LABEL":"openSUSE 11.4","MINIMAGESIZE":650,"CREATE_DT":"2011-03-10 11:36:46.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":80,"IS64BIT":1,"LABEL":"openSUSE 11.4 64bit","MINIMAGESIZE":650,"CREATE_DT":"2011-03-10 11:36:46.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":68,"IS64BIT":0,"LABEL":"Slackware 13.1","MINIMAGESIZE":512,"CREATE_DT":"2010-05-10 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":69,"IS64BIT":1,"LABEL":"Slackware 13.1 64bit","MINIMAGESIZE":512,"CREATE_DT":"2010-05-10 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":73,"IS64BIT":0,"LABEL":"Ubuntu 10.10","MINIMAGESIZE":500,"CREATE_DT":"2010-10-11 15:19:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":74,"IS64BIT":1,"LABEL":"Ubuntu 10.10 64bit","MINIMAGESIZE":500,"CREATE_DT":"2010-10-11 15:19:00.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":82,"IS64BIT":0,"LABEL":"Ubuntu 11.04","MINIMAGESIZE":500,"CREATE_DT":"2011-04-28 16:28:48.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":83,"IS64BIT":1,"LABEL":"Ubuntu 11.04 64bit","MINIMAGESIZE":500,"CREATE_DT":"2011-04-28 16:28:48.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":41,"IS64BIT":0,"LABEL":"Ubuntu 8.04 LTS","MINIMAGESIZE":350,"CREATE_DT":"2008-04-23 15:11:29.0"},{"REQUIRESPVOPSKERNEL":1,"DISTRIBUTIONID":42,"IS64BIT":1,"LABEL":"Ubuntu 8.04 LTS 64bit","MINIMAGESIZE":350,"CREATE_DT":"2008-06-03 12:51:11.0"}],"ACTION":"avail.distributions"}'
|
262
|
+
HTTParty.stubs(:post).returns(json)
|
263
|
+
@linode.stubs(:api_url).returns('https://fake.linode.com/')
|
264
|
+
|
265
|
+
lambda { @linode.send_request('test.echo', {}) }.should_not raise_error
|
266
|
+
end
|
259
267
|
end
|
260
|
-
|
268
|
+
|
269
|
+
|
261
270
|
it 'should be able to provide access to the Linode Test API' do
|
262
271
|
@linode.should respond_to(:test)
|
263
272
|
end
|
264
|
-
|
273
|
+
|
265
274
|
describe 'when providing access to the Linode Test API' do
|
266
275
|
it 'should allow no arguments' do
|
267
276
|
lambda { @linode.test }.should_not raise_error(ArgumentError)
|
268
277
|
end
|
269
|
-
|
278
|
+
|
270
279
|
it 'should require no arguments' do
|
271
280
|
lambda { @linode.test(:foo) }.should raise_error(ArgumentError)
|
272
281
|
end
|
273
|
-
|
282
|
+
|
274
283
|
it 'should return a Linode::Test instance' do
|
275
284
|
@linode.test.class.should == Linode::Test
|
276
285
|
end
|
277
|
-
|
286
|
+
|
278
287
|
it 'should set the API key on the Linode::Test instance to be our API key' do
|
279
288
|
@linode.test.api_key.should == @api_key
|
280
289
|
end
|
281
|
-
|
290
|
+
|
282
291
|
it 'should set the API URL on the Linode::Test instance to be our API URL' do
|
283
292
|
@linode.test.api_url.should == @api_url
|
284
293
|
end
|
285
|
-
|
294
|
+
|
286
295
|
it 'should return the same Linode::Test instance when called again' do
|
287
296
|
linode = Linode.new(:api_key => @api_key)
|
288
297
|
result = linode.test
|
@@ -293,60 +302,60 @@ describe 'Linode' do
|
|
293
302
|
it 'should be able to provide access to the Linode Avail API' do
|
294
303
|
@linode.should respond_to(:avail)
|
295
304
|
end
|
296
|
-
|
305
|
+
|
297
306
|
describe 'when providing access to the Linode Avail API' do
|
298
307
|
it 'should allow no arguments' do
|
299
308
|
lambda { @linode.avail }.should_not raise_error(ArgumentError)
|
300
309
|
end
|
301
|
-
|
310
|
+
|
302
311
|
it 'should require no arguments' do
|
303
312
|
lambda { @linode.avail(:foo) }.should raise_error(ArgumentError)
|
304
313
|
end
|
305
|
-
|
314
|
+
|
306
315
|
it 'should return a Linode::Avail instance' do
|
307
316
|
@linode.avail.class.should == Linode::Avail
|
308
317
|
end
|
309
|
-
|
318
|
+
|
310
319
|
it 'should set the API key on the Linode::Avail instance to be our API key' do
|
311
320
|
@linode.avail.api_key.should == @api_key
|
312
321
|
end
|
313
|
-
|
322
|
+
|
314
323
|
it 'should set the API url on the Linode::Avail instance to be our API url' do
|
315
324
|
@linode.avail.api_url.should == @api_url
|
316
325
|
end
|
317
|
-
|
326
|
+
|
318
327
|
it 'should return the same Linode::Avail instance when called again' do
|
319
328
|
linode = Linode.new(:api_key => @api_key)
|
320
329
|
result = linode.avail
|
321
330
|
linode.avail.should == result
|
322
331
|
end
|
323
332
|
end
|
324
|
-
|
333
|
+
|
325
334
|
it 'should be able to provide access to the Linode User API' do
|
326
335
|
@linode.should respond_to(:user)
|
327
336
|
end
|
328
|
-
|
337
|
+
|
329
338
|
describe 'when providing access to the Linode User API' do
|
330
339
|
it 'should allow no arguments' do
|
331
340
|
lambda { @linode.user }.should_not raise_error(ArgumentError)
|
332
341
|
end
|
333
|
-
|
342
|
+
|
334
343
|
it 'should require no arguments' do
|
335
344
|
lambda { @linode.user(:foo) }.should raise_error(ArgumentError)
|
336
345
|
end
|
337
|
-
|
346
|
+
|
338
347
|
it 'should return a Linode::User instance' do
|
339
348
|
@linode.user.class.should == Linode::User
|
340
349
|
end
|
341
|
-
|
350
|
+
|
342
351
|
it 'should set the API key on the Linode::User instance to be our API key' do
|
343
352
|
@linode.user.api_key.should == @api_key
|
344
353
|
end
|
345
|
-
|
354
|
+
|
346
355
|
it 'should set the API url on the Linode::User instance to be our API url' do
|
347
356
|
@linode.user.api_url.should == @api_url
|
348
357
|
end
|
349
|
-
|
358
|
+
|
350
359
|
it 'should return the same Linode::User instance when called again' do
|
351
360
|
linode = Linode.new(:api_key => @api_key)
|
352
361
|
result = linode.user
|
@@ -357,60 +366,60 @@ describe 'Linode' do
|
|
357
366
|
it 'should be able to provide access to the Linode Domain API' do
|
358
367
|
@linode.should respond_to(:domain)
|
359
368
|
end
|
360
|
-
|
369
|
+
|
361
370
|
describe 'when providing access to the Linode Domain API' do
|
362
371
|
it 'should allow no arguments' do
|
363
372
|
lambda { @linode.domain }.should_not raise_error(ArgumentError)
|
364
373
|
end
|
365
|
-
|
374
|
+
|
366
375
|
it 'should require no arguments' do
|
367
376
|
lambda { @linode.domain(:foo) }.should raise_error(ArgumentError)
|
368
377
|
end
|
369
|
-
|
378
|
+
|
370
379
|
it 'should return a Linode::Domain instance' do
|
371
380
|
@linode.domain.class.should == Linode::Domain
|
372
381
|
end
|
373
|
-
|
382
|
+
|
374
383
|
it 'should set the API key on the Linode::Domain instance to be our API key' do
|
375
384
|
@linode.domain.api_key.should == @api_key
|
376
385
|
end
|
377
|
-
|
386
|
+
|
378
387
|
it 'should set the API url on the Linode::Domain instance to be our API url' do
|
379
388
|
@linode.domain.api_url.should == @api_url
|
380
389
|
end
|
381
|
-
|
390
|
+
|
382
391
|
it 'should return the same Linode::Domain instance when called again' do
|
383
392
|
linode = Linode.new(:api_key => @api_key)
|
384
393
|
result = linode.domain
|
385
394
|
linode.domain.should == result
|
386
395
|
end
|
387
396
|
end
|
388
|
-
|
397
|
+
|
389
398
|
it 'should be able to provide access to the Linode Linode API' do
|
390
399
|
@linode.should respond_to(:linode)
|
391
400
|
end
|
392
|
-
|
401
|
+
|
393
402
|
describe 'when providing access to the Linode Linode API' do
|
394
403
|
it 'should allow no arguments' do
|
395
404
|
lambda { @linode.linode }.should_not raise_error(ArgumentError)
|
396
405
|
end
|
397
|
-
|
406
|
+
|
398
407
|
it 'should require no arguments' do
|
399
408
|
lambda { @linode.linode(:foo) }.should raise_error(ArgumentError)
|
400
409
|
end
|
401
|
-
|
410
|
+
|
402
411
|
it 'should return a Linode::Linode instance' do
|
403
412
|
@linode.linode.class.should == Linode::Linode
|
404
413
|
end
|
405
|
-
|
414
|
+
|
406
415
|
it 'should set the API key on the Linode::Linode instance to be our API key' do
|
407
416
|
@linode.linode.api_key.should == @api_key
|
408
417
|
end
|
409
|
-
|
418
|
+
|
410
419
|
it 'should set the API url on the Linode::Linode instance to be our API url' do
|
411
420
|
@linode.linode.api_url.should == @api_url
|
412
421
|
end
|
413
|
-
|
422
|
+
|
414
423
|
it 'should return the same Linode::Linode instance when called again' do
|
415
424
|
linode = Linode.new(:api_key => @api_key)
|
416
425
|
result = linode.linode
|
@@ -421,28 +430,28 @@ describe 'Linode' do
|
|
421
430
|
it 'should be able to provide access to the Linode Nodebalancer API' do
|
422
431
|
@linode.should respond_to(:nodebalancer)
|
423
432
|
end
|
424
|
-
|
433
|
+
|
425
434
|
describe 'when providing access to the Linode Nodebalancer API' do
|
426
435
|
it 'should allow no arguments' do
|
427
436
|
lambda { @linode.nodebalancer }.should_not raise_error(ArgumentError)
|
428
437
|
end
|
429
|
-
|
438
|
+
|
430
439
|
it 'should require no arguments' do
|
431
440
|
lambda { @linode.nodebalancer(:foo) }.should raise_error(ArgumentError)
|
432
441
|
end
|
433
|
-
|
442
|
+
|
434
443
|
it 'should return a Linode::Nodebalancer instance' do
|
435
444
|
@linode.nodebalancer.class.should == Linode::Nodebalancer
|
436
445
|
end
|
437
|
-
|
446
|
+
|
438
447
|
it 'should set the API key on the Linode::Nodebalancer instance to be our API key' do
|
439
448
|
@linode.nodebalancer.api_key.should == @api_key
|
440
449
|
end
|
441
|
-
|
450
|
+
|
442
451
|
it 'should set the API url on the Linode::Nodebalancer instance to be our API url' do
|
443
452
|
@linode.nodebalancer.api_url.should == @api_url
|
444
453
|
end
|
445
|
-
|
454
|
+
|
446
455
|
it 'should return the same Linode::Nodebalancer instance when called again' do
|
447
456
|
linode = Linode.new(:api_key => @api_key)
|
448
457
|
result = linode.nodebalancer
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 8
|
10
|
+
version: 0.7.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Rick Bradley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-04-26 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -84,14 +84,14 @@ executables: []
|
|
84
84
|
extensions: []
|
85
85
|
|
86
86
|
extra_rdoc_files:
|
87
|
-
- README
|
87
|
+
- README.md
|
88
88
|
files:
|
89
89
|
- .rspec
|
90
90
|
- CHANGELOG
|
91
91
|
- Gemfile
|
92
92
|
- Gemfile.lock
|
93
93
|
- MIT-LICENSE
|
94
|
-
- README
|
94
|
+
- README.md
|
95
95
|
- Rakefile
|
96
96
|
- VERSION
|
97
97
|
- autotest/discover.rb
|
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
requirements: []
|
158
158
|
|
159
159
|
rubyforge_project:
|
160
|
-
rubygems_version: 1.8.
|
160
|
+
rubygems_version: 1.8.11
|
161
161
|
signing_key:
|
162
162
|
specification_version: 3
|
163
163
|
summary: a Ruby wrapper for the Linode API
|
data/README
DELETED
@@ -1,148 +0,0 @@
|
|
1
|
-
Linode Ruby API
|
2
|
-
|
3
|
-
INSTALLATION:
|
4
|
-
|
5
|
-
Make sure gemcutter.org is in your gem sources list, then:
|
6
|
-
|
7
|
-
% sudo gem install linode
|
8
|
-
|
9
|
-
To run tests you will need both rspec and mocha installed.
|
10
|
-
|
11
|
-
RUNNING:
|
12
|
-
|
13
|
-
Consult the Linode API guide here: http://www.linode.com/api/autodoc.cfm
|
14
|
-
You will need to get an API key (check your account profile).
|
15
|
-
|
16
|
-
Here is an annoyingly exhaustive IRB session where I play around with the API:
|
17
|
-
|
18
|
-
irb> require 'rubygems'
|
19
|
-
irb> require 'linode'
|
20
|
-
irb> api_key = 'TOPSECRETAPIKEY'
|
21
|
-
irb> l = Linode.new(:api_key => api_key)
|
22
|
-
=> #<Linode:0x100e03c @api_key="TOPSECRETAPIKEY">
|
23
|
-
|
24
|
-
irb> result = l.test.echo(:foo => 'bar', :baz => 'xyzzy')
|
25
|
-
=> #<OpenStruct baz="xyzzy", foo="bar">
|
26
|
-
irb> result.foo
|
27
|
-
=> "bar"
|
28
|
-
irb> result.baz
|
29
|
-
=> "xyzzy"
|
30
|
-
|
31
|
-
irb> result = l.avail.datacenters
|
32
|
-
=> [#<OpenStruct datacenterid=2, location="Dallas, TX, USA">, #<OpenStruct datacenterid=3, location="Fremont, CA, USA">, #<OpenStruct datacenterid=4, location="Atlanta, GA, USA">, #<OpenStruct datacenterid=6, location="Newark, NJ, USA">]
|
33
|
-
irb> s = _
|
34
|
-
=> [#<OpenStruct datacenterid=2, location="Dallas, TX, USA">, #<OpenStruct datacenterid=3, location="Fremont, CA, USA">, #<OpenStruct datacenterid=4, location="Atlanta, GA, USA">, #<OpenStruct datacenterid=6, location="Newark, NJ, USA">]
|
35
|
-
irb> result.first
|
36
|
-
=> #<OpenStruct datacenterid=2, location="Dallas, TX, USA">
|
37
|
-
irb> result.first.location
|
38
|
-
=> "Dallas, TX, USA"
|
39
|
-
irb> l.avail.datacenters.collect {|i| i.location }
|
40
|
-
=> ["Dallas, TX, USA", "Fremont, CA, USA", "Atlanta, GA, USA", "Newark, NJ, USA"]
|
41
|
-
irb> l.avail.datacenters.collect {|i| i.datacenterid }
|
42
|
-
=> [2, 3, 4, 6]
|
43
|
-
|
44
|
-
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT')
|
45
|
-
=> #<OpenStruct api_key="TOPSECRETAPIKEY", username="me">
|
46
|
-
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').api_key
|
47
|
-
=> "TOPSECRETAPIKEY"
|
48
|
-
irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').username
|
49
|
-
=> "me"
|
50
|
-
|
51
|
-
irb> l.avail.kernels
|
52
|
-
=> [#<OpenStruct isxen=1, label="2.6.16.38-x86_64-linode2", kernelid=85>, #<OpenStruct isxen=1, label="2.6.18.8-domU-linode7", kernelid=81>, #<OpenStruct isxen=1, label="2.6.18.8-linode10", kernelid=89>, #<OpenStruct isxen=1, label="2.6.18.8-linode16", kernelid=98>, #<OpenStruct isxen=1, label="2.6.18.8-x86_64-linode1", kernelid=86>, #<OpenStruct isxen=1, label="2.6.24.4-linode8", kernelid=84>, #<OpenStruct isxen=1, label="2.6.25-linode9", kernelid=88>, #<OpenStruct isxen=1, label="2.6.25.10-linode12", kernelid=90>, #<OpenStruct isxen=1, label="2.6.26-linode13", kernelid=91>, #<OpenStruct isxen=1, label="2.6.27.4-linode14", kernelid=93>, #<OpenStruct isxen=1, label="2.6.27.4-x86_64-linode3", kernelid=94>, #<OpenStruct isxen=1, label="2.6.28-linode15", kernelid=96>, #<OpenStruct isxen=1, label="2.6.28-x86_64-linode4", kernelid=97>, #<OpenStruct isxen=1, label="2.6.28.3-linode17", kernelid=99>, #<OpenStruct isxen=1, label="2.6.28.3-x86_64-linode5", kernelid=100>, #<OpenStruct isxen=1, label="2.6.29-linode18", kernelid=101>, #<OpenStruct isxen=1, label="2.6.29-x86_64-linode6", kernelid=102>, #<OpenStruct isxen=1, label="Latest 2.6 Series (2.6.18.8-linode16)", kernelid=60>, #<OpenStruct isxen=1, label="pv-grub-x86_32", kernelid=92>, #<OpenStruct isxen=1, label="pv-grub-x86_64", kernelid=95>, #<OpenStruct isxen=1, label="Recovery - Finnix (kernel)", kernelid=61>]
|
53
|
-
irb> l.avail.kernels.size
|
54
|
-
=> 21
|
55
|
-
irb> l.avail.kernels.first
|
56
|
-
=> #<OpenStruct isxen=1, label="2.6.16.38-x86_64-linode2", kernelid=85>
|
57
|
-
irb> l.avail.kernels.first.label
|
58
|
-
=> "2.6.16.38-x86_64-linode2"
|
59
|
-
|
60
|
-
irb> l.avail.linodeplans
|
61
|
-
=> [#<OpenStruct ram=360, label="Linode 360", avail={"6"=>26, "2"=>57, "3"=>20, "4"=>39}, price=19.95, planid=1, xfer=200, disk=16>, #<OpenStruct ram=540, label="Linode 540", avail={"6"=>11, "2"=>38, "3"=>14, "4"=>28}, price=29.95, planid=2, xfer=300, disk=24>, #<OpenStruct ram=720, label="Linode 720", avail={"6"=>13, "2"=>27, "3"=>18, "4"=>30}, price=39.95, planid=3, xfer=400, disk=32>, #<OpenStruct ram=1080, label="Linode 1080", avail={"6"=>18, "2"=>7, "3"=>9, "4"=>4}, price=59.95, planid=4, xfer=600, disk=48>, #<OpenStruct ram=1440, label="Linode 1440", avail={"6"=>14, "2"=>5, "3"=>7, "4"=>3}, price=79.95, planid=5, xfer=800, disk=64>, #<OpenStruct ram=2880, label="Linode 2880", avail={"6"=>3, "2"=>3, "3"=>3, "4"=>3}, price=159.95, planid=6, xfer=1600, disk=128>, #<OpenStruct ram=5760, label="Linode 5760", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=319.95, planid=7, xfer=2000, disk=256>, #<OpenStruct ram=8640, label="Linode 8640", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=479.95, planid=8, xfer=2000, disk=384>, #<OpenStruct ram=11520, label="Linode 11520", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=639.95, planid=9, xfer=2000, disk=512>, #<OpenStruct ram=14400, label="Linode 14400", avail={"6"=>5, "2"=>6, "3"=>5, "4"=>5}, price=799.95, planid=10, xfer=2000, disk=640>]
|
62
|
-
irb> l.avail.linodeplans.size
|
63
|
-
=> 10
|
64
|
-
irb> l.avail.linodeplans.first
|
65
|
-
=> #<OpenStruct ram=360, label="Linode 360", avail={"6"=>26, "2"=>57, "3"=>20, "4"=>39}, price=19.95, planid=1, xfer=200, disk=16>
|
66
|
-
irb> l.avail.linodeplans.first.avail
|
67
|
-
=> {"6"=>26, "2"=>57, "3"=>20, "4"=>39}
|
68
|
-
|
69
|
-
irb> l.avail.distributions
|
70
|
-
=> [#<OpenStruct label="Arch Linux 2007.08", minimagesize=436, create_dt="2007-10-24 00:00:00.0", is64bit=0, distributionid=38>, #<OpenStruct label="Centos 5.0", minimagesize=594, create_dt="2007-04-27 00:00:00.0", is64bit=0, distributionid=32>, #<OpenStruct label="Centos 5.2", minimagesize=950, create_dt="2008-11-30 00:00:00.0", is64bit=0, distributionid=46>, #<OpenStruct label="Centos 5.2 64bit", minimagesize=980, create_dt="2008-11-30 00:00:00.0", is64bit=1, distributionid=47>, #<OpenStruct label="Debian 4.0", minimagesize=200, create_dt="2007-04-18 00:00:00.0", is64bit=0, distributionid=28>, #<OpenStruct label="Debian 4.0 64bit", minimagesize=220, create_dt="2008-12-02 00:00:00.0", is64bit=1, distributionid=48>, #<OpenStruct label="Debian 5.0", minimagesize=200, create_dt="2009-02-19 00:00:00.0", is64bit=0, distributionid=50>, #<OpenStruct label="Debian 5.0 64bit", minimagesize=300, create_dt="2009-02-19 00:00:00.0", is64bit=1, distributionid=51>, #<OpenStruct label="Fedora 8", minimagesize=740, create_dt="2007-11-09 00:00:00.0", is64bit=0, distributionid=40>, #<OpenStruct label="Fedora 9", minimagesize=1175, create_dt="2008-06-09 15:15:21.0", is64bit=0, distributionid=43>, #<OpenStruct label="Gentoo 2007.0", minimagesize=1800, create_dt="2007-08-29 00:00:00.0", is64bit=0, distributionid=35>, #<OpenStruct label="Gentoo 2008.0", minimagesize=1500, create_dt="2009-03-20 00:00:00.0", is64bit=0, distributionid=52>, #<OpenStruct label="Gentoo 2008.0 64bit", minimagesize=2500, create_dt="2009-04-04 00:00:00.0", is64bit=1, distributionid=53>, #<OpenStruct label="OpenSUSE 11.0", minimagesize=850, create_dt="2008-08-21 08:32:16.0", is64bit=0, distributionid=44>, #<OpenStruct label="Slackware 12.0", minimagesize=315, create_dt="2007-07-16 00:00:00.0", is64bit=0, distributionid=34>, #<OpenStruct label="Slackware 12.2", minimagesize=500, create_dt="2009-04-04 00:00:00.0", is64bit=0, distributionid=54>, #<OpenStruct label="Ubuntu 8.04 LTS", minimagesize=400, create_dt="2008-04-23 15:11:29.0", is64bit=0, distributionid=41>, #<OpenStruct label="Ubuntu 8.04 LTS 64bit", minimagesize=350, create_dt="2008-06-03 12:51:11.0", is64bit=1, distributionid=42>, #<OpenStruct label="Ubuntu 8.10", minimagesize=220, create_dt="2008-10-30 23:23:03.0", is64bit=0, distributionid=45>, #<OpenStruct label="Ubuntu 8.10 64bit", minimagesize=230, create_dt="2008-12-02 00:00:00.0", is64bit=1, distributionid=49>, #<OpenStruct label="Ubuntu 9.04", minimagesize=350, create_dt="2009-04-23 00:00:00.0", is64bit=0, distributionid=55>, #<OpenStruct label="Ubuntu 9.04 64bit", minimagesize=350, create_dt="2009-04-23 00:00:00.0", is64bit=1, distributionid=56>]
|
71
|
-
irb> l.avail.distributions.size
|
72
|
-
=> 22
|
73
|
-
irb> l.avail.distributions.first
|
74
|
-
=> #<OpenStruct label="Arch Linux 2007.08", minimagesize=436, create_dt="2007-10-24 00:00:00.0", is64bit=0, distributionid=38>
|
75
|
-
irb> l.avail.distributions.first.label
|
76
|
-
=> "Arch Linux 2007.08"
|
77
|
-
|
78
|
-
irb> l.domain.resource.list
|
79
|
-
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGEDOMAINID is required but was not passed in
|
80
|
-
from ./lib/linode.rb:31:in `send_request'
|
81
|
-
from ./lib/linode.rb:13:in `list'
|
82
|
-
from (irb):3
|
83
|
-
irb> l.domain.resource.list(:DomainId => '1')
|
84
|
-
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{:DomainId=>"1"}]: ERRORCODE5ERRORMESSAGEObject not found
|
85
|
-
from ./lib/linode.rb:31:in `send_request'
|
86
|
-
from ./lib/linode.rb:13:in `list'
|
87
|
-
from (irb):5
|
88
|
-
irb> l.domain.resource.list(:DomainId => '1', :ResourceId => '2')
|
89
|
-
RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{:DomainId=>"1", :ResourceId=>"2"}]: ERRORCODE5ERRORMESSAGEObject not found
|
90
|
-
from ./lib/linode.rb:31:in `send_request'
|
91
|
-
from ./lib/linode.rb:13:in `list'
|
92
|
-
from (irb):7
|
93
|
-
|
94
|
-
irb> l.linode
|
95
|
-
=> #<Linode::Linode:0x10056e4 @api_url="https://api.linode.com/", @api_key="TOPSECRETAPIKEY">
|
96
|
-
irb> l.linode.list
|
97
|
-
=> [#<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=4, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="bragi", totalram=360, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15418, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=2, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="nerthus", totalram=360, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15419, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=3, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday=0, status=1, alert_cpu_enabled=1, label="hoenir", totalram=360, backupwindow=0, alert_diskio_threshold=500, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=24405, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>]
|
98
|
-
irb> l.linode.list.size
|
99
|
-
=> 4
|
100
|
-
irb> l.linode.list.first
|
101
|
-
=> #<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1, alert_bwout_enabled=1>
|
102
|
-
irb> l.linode.list.first.datacenterid
|
103
|
-
=> 6
|
104
|
-
irb> l.linode.list.first.label
|
105
|
-
=> "byggvir"
|
106
|
-
|
107
|
-
irb(main):003:0* l.linode.config.list
|
108
|
-
RuntimeError: Error completing request [linode.config.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
109
|
-
from ./lib/linode.rb:45:in `send_request'
|
110
|
-
from ./lib/linode.rb:13:in `list'
|
111
|
-
from (irb):3
|
112
|
-
irb> l.linode.list
|
113
|
-
=> [#<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=4, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="bragi", totalram=360, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15418, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=2, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="nerthus", totalram=360, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=15419, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>, #<OpenStruct datacenterid=3, lpm_displaygroup="", totalxfer=200, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday=0, status=1, alert_cpu_enabled=1, label="hoenir", totalram=360, backupwindow=0, alert_diskio_threshold=500, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=24405, totalhd=16384, alert_bwin_enabled=1, alert_bwout_enabled=1>]
|
114
|
-
irb> l.linode.list.first
|
115
|
-
=> #<OpenStruct datacenterid=6, lpm_displaygroup="", totalxfer=600, alert_bwquota_enabled=1, alert_diskio_enabled=1, watchdog=1, alert_cpu_threshold=90, alert_bwout_threshold=5, backupsenabled=0, backupweeklyday="", status=1, alert_cpu_enabled=1, label="byggvir", totalram=1080, backupwindow=0, alert_diskio_threshold=300, alert_bwin_threshold=5, alert_bwquota_threshold=80, linodeid=12446, totalhd=49152, alert_bwin_enabled=1, alert_bwout_enabled=1>
|
116
|
-
irb> l.linode.list.first.linodeid
|
117
|
-
=> 12446
|
118
|
-
irb> l.linode.config.list(:LinodeId => 12446)
|
119
|
-
=> [#<OpenStruct helper_disableupdatedb=1, ramlimit=0, kernelid=60, helper_depmod=1, rootdevicecustom="", disklist="79850,79851,79854,,,,,,", label="byggvir", runlevel="default", rootdevicero=true, configid=43615, rootdevicenum=1, linodeid=12446, helper_libtls=false, helper_xen=1, comments="">]
|
120
|
-
irb> l.linode.config.list(:LinodeId => 12446).first.disklist
|
121
|
-
=> "79850,79851,79854,,,,,,"
|
122
|
-
|
123
|
-
irb> l.linode.job.list
|
124
|
-
RuntimeError: Error completing request [linode.job.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
125
|
-
from ./lib/linode.rb:45:in `send_request'
|
126
|
-
from ./lib/linode.rb:13:in `list'
|
127
|
-
from (irb):7
|
128
|
-
irb> l.linode.job.list(:LinodeId => 12446)
|
129
|
-
=> [#<OpenStruct action="linode.boot", jobid=1241724, duration=8, host_finish_dt="2009-07-14 17:07:29.0", host_message="", linodeid=12446, host_success=1, host_start_dt="2009-07-14 17:07:21.0", entered_dt="2009-07-14 17:06:25.0", label="System Boot - byggvir">, #<OpenStruct action="linode.shutdown", jobid=1241723, duration=14, host_finish_dt="2009-07-14 17:07:20.0", host_message="", linodeid=12446, host_success=1, host_start_dt="2009-07-14 17:07:06.0", entered_dt="2009-07-14 17:06:25.0", label="System Shutdown">, #<OpenStruct action="linode.boot", jobid=1182441, duration=0, host_finish_dt="2009-06-10 04:27:49.0", host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 04:27:49.0", entered_dt="2009-06-10 04:26:05.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot", jobid=1182436, duration=8, host_finish_dt="2009-06-10 04:27:49.0", host_message="", linodeid=12446, host_success=1, host_start_dt="2009-06-10 04:27:41.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">, #<OpenStruct action="linode.boot", jobid=1182273, duration=0, host_finish_dt="2009-06-10 03:02:31.0", host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 03:02:31.0", entered_dt="2009-06-10 02:59:49.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot", jobid=1182268, duration=8, host_finish_dt="2009-06-10 03:02:31.0", host_message="", linodeid=12446, host_success=1, host_start_dt="2009-06-10 03:02:23.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">, #<OpenStruct action="linode.boot", jobid=1182150, duration=1, host_finish_dt="2009-06-10 01:28:40.0", host_message="Linode already running", linodeid=12446, host_success=0, host_start_dt="2009-06-10 01:28:39.0", entered_dt="2009-06-10 01:26:55.0", label="Lassie initiated boot">, #<OpenStruct action="linode.boot", jobid=1182145, duration=8, host_finish_dt="2009-06-10 01:28:39.0", host_message="", linodeid=12446, host_success=1, host_start_dt="2009-06-10 01:28:31.0", entered_dt="1974-01-04 00:00:00.0", label="Host initiated restart">]
|
130
|
-
irb> l.linode.job.list(:LinodeId => 12446).size
|
131
|
-
=> 8
|
132
|
-
|
133
|
-
irb> l.linode.ip.list
|
134
|
-
RuntimeError: Error completing request [linode.ip.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
|
135
|
-
from ./lib/linode.rb:45:in `send_request'
|
136
|
-
from ./lib/linode.rb:13:in `list'
|
137
|
-
from (irb):10
|
138
|
-
irb> l.linode.ip.list(:LinodeId => 12446)
|
139
|
-
=> [#<OpenStruct rdns_name="byggvir.websages.com", ipaddressid=12286, linodeid=12446, ispublic=1, ipaddress="209.123.234.161">, #<OpenStruct rdns_name="li101-51.members.linode.com", ipaddressid=23981, linodeid=12446, ispublic=1, ipaddress="97.107.140.51">]
|
140
|
-
irb> ^D@ Wed Aug 05 01:50:52 rick@Yer-Moms-Computer
|
141
|
-
|
142
|
-
CREDITS:
|
143
|
-
- Thanks to Aditya Sanghi (github: asanghi) for a patch to properly namespace stackscripts functionality.
|
144
|
-
- Thanks to Dan Hodos (github: danhodos) for diagnosing and fixing an issue with sending GET requests instead of POST request.
|
145
|
-
- Thanks to Aaron Hamid for updates for RSpec 2 and work on user.getapikey + username/password initialization.
|
146
|
-
- Thanks to Musfuut (github: musfuut) for diagnosing and recommending a fix for OpenStruct and 'type' data members in Linode returned results.
|
147
|
-
- Thanks to mihaibirsan (github: mihaibirsan) for diagnosing a problem with dependencies on the 'crack' library.
|
148
|
-
- Thanks to Adam Durana (github: durana) for adding support for linode.ip.addprivate.
|