linode 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ coverage/
2
+ pkg/
data/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+
2
+ * 2009/08/04 - Initial commit.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009, Rick Bradley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,138 @@
1
+ Linode Ruby API
2
+
3
+ INSTALLATION:
4
+
5
+ % sudo gem install rick-linode
6
+
7
+ To run tests you will need both rspec and mocha installed.
8
+
9
+ RUNNING:
10
+
11
+ Consult the Linode API guide here: http://www.linode.com/api/autodoc.cfm
12
+ You will need to get an API key (check your account profile).
13
+
14
+ Here is an annoyingly exhaustive IRB session where I play around with the API:
15
+
16
+ irb> require 'rubygems'
17
+ irb> require 'linode'
18
+ irb> api_key = 'TOPSECRETAPIKEY'
19
+ irb> l = Linode.new(:api_key => api_key)
20
+ => #<Linode:0x100e03c @api_key="TOPSECRETAPIKEY">
21
+
22
+ irb> result = l.test.echo(:foo => 'bar', :baz => 'xyzzy')
23
+ => #<OpenStruct baz="xyzzy", foo="bar">
24
+ irb> result.foo
25
+ => "bar"
26
+ irb> result.baz
27
+ => "xyzzy"
28
+
29
+ irb> result = l.avail.datacenters
30
+ => [#<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">]
31
+ irb> s = _
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> result.first
34
+ => #<OpenStruct datacenterid=2, location="Dallas, TX, USA">
35
+ irb> result.first.location
36
+ => "Dallas, TX, USA"
37
+ irb> l.avail.datacenters.collect {|i| i.location }
38
+ => ["Dallas, TX, USA", "Fremont, CA, USA", "Atlanta, GA, USA", "Newark, NJ, USA"]
39
+ irb> l.avail.datacenters.collect {|i| i.datacenterid }
40
+ => [2, 3, 4, 6]
41
+
42
+ irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT')
43
+ => #<OpenStruct api_key="TOPSECRETAPIKEY", username="me">
44
+ irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').api_key
45
+ => "TOPSECRETAPIKEY"
46
+ irb> l.user.getapikey(:username => 'me', :password => 'SECKRIT').username
47
+ => "me"
48
+
49
+ irb> l.avail.kernels
50
+ => [#<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>]
51
+ irb> l.avail.kernels.size
52
+ => 21
53
+ irb> l.avail.kernels.first
54
+ => #<OpenStruct isxen=1, label="2.6.16.38-x86_64-linode2", kernelid=85>
55
+ irb> l.avail.kernels.first.label
56
+ => "2.6.16.38-x86_64-linode2"
57
+
58
+ irb> l.avail.linodeplans
59
+ => [#<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>]
60
+ irb> l.avail.linodeplans.size
61
+ => 10
62
+ irb> l.avail.linodeplans.first
63
+ => #<OpenStruct ram=360, label="Linode 360", avail={"6"=>26, "2"=>57, "3"=>20, "4"=>39}, price=19.95, planid=1, xfer=200, disk=16>
64
+ irb> l.avail.linodeplans.first.avail
65
+ => {"6"=>26, "2"=>57, "3"=>20, "4"=>39}
66
+
67
+ irb> l.avail.distributions
68
+ => [#<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>]
69
+ irb> l.avail.distributions.size
70
+ => 22
71
+ irb> l.avail.distributions.first
72
+ => #<OpenStruct label="Arch Linux 2007.08", minimagesize=436, create_dt="2007-10-24 00:00:00.0", is64bit=0, distributionid=38>
73
+ irb> l.avail.distributions.first.label
74
+ => "Arch Linux 2007.08"
75
+
76
+ irb> l.domain.resource.list
77
+ RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGEDOMAINID is required but was not passed in
78
+ from ./lib/linode.rb:31:in `send_request'
79
+ from ./lib/linode.rb:13:in `list'
80
+ from (irb):3
81
+ irb> l.domain.resource.list(:DomainId => '1')
82
+ RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{:DomainId=>"1"}]: ERRORCODE5ERRORMESSAGEObject not found
83
+ from ./lib/linode.rb:31:in `send_request'
84
+ from ./lib/linode.rb:13:in `list'
85
+ from (irb):5
86
+ irb> l.domain.resource.list(:DomainId => '1', :ResourceId => '2')
87
+ RuntimeError: Error completing request [domain.resource.list] @ [https://api.linode.com/] with data [{:DomainId=>"1", :ResourceId=>"2"}]: ERRORCODE5ERRORMESSAGEObject not found
88
+ from ./lib/linode.rb:31:in `send_request'
89
+ from ./lib/linode.rb:13:in `list'
90
+ from (irb):7
91
+
92
+ irb> l.linode
93
+ => #<Linode::Linode:0x10056e4 @api_url="https://api.linode.com/", @api_key="TOPSECRETAPIKEY">
94
+ irb> l.linode.list
95
+ => [#<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>]
96
+ irb> l.linode.list.size
97
+ => 4
98
+ irb> l.linode.list.first
99
+ => #<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>
100
+ irb> l.linode.list.first.datacenterid
101
+ => 6
102
+ irb> l.linode.list.first.label
103
+ => "byggvir"
104
+
105
+ irb(main):003:0* l.linode.config.list
106
+ RuntimeError: Error completing request [linode.config.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
107
+ from ./lib/linode.rb:45:in `send_request'
108
+ from ./lib/linode.rb:13:in `list'
109
+ from (irb):3
110
+ irb> l.linode.list
111
+ => [#<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>]
112
+ irb> l.linode.list.first
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>
114
+ irb> l.linode.list.first.linodeid
115
+ => 12446
116
+ irb> l.linode.config.list(:LinodeId => 12446)
117
+ => [#<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="">]
118
+ irb> l.linode.config.list(:LinodeId => 12446).first.disklist
119
+ => "79850,79851,79854,,,,,,"
120
+
121
+ irb> l.linode.job.list
122
+ RuntimeError: Error completing request [linode.job.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
123
+ from ./lib/linode.rb:45:in `send_request'
124
+ from ./lib/linode.rb:13:in `list'
125
+ from (irb):7
126
+ irb> l.linode.job.list(:LinodeId => 12446)
127
+ => [#<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">]
128
+ irb> l.linode.job.list(:LinodeId => 12446).size
129
+ => 8
130
+
131
+ irb> l.linode.ip.list
132
+ RuntimeError: Error completing request [linode.ip.list] @ [https://api.linode.com/] with data [{}]: ERRORCODE6ERRORMESSAGELINODEID is required but was not passed in
133
+ from ./lib/linode.rb:45:in `send_request'
134
+ from ./lib/linode.rb:13:in `list'
135
+ from (irb):10
136
+ irb> l.linode.ip.list(:LinodeId => 12446)
137
+ => [#<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">]
138
+ irb> ^D@ Wed Aug 05 01:50:52 rick@Yer-Moms-Computer
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'spec/rake/spectask'
5
+
6
+ desc 'Default: run specs.'
7
+ task :default => :spec
8
+
9
+ desc 'Test the linode library.'
10
+ Spec::Rake::SpecTask.new('spec') do |t|
11
+ t.spec_files = FileList['spec/**/*_spec.rb']
12
+ end
13
+
14
+ begin
15
+ require 'jeweler'
16
+ Jeweler::Tasks.new do |gemspec|
17
+ gemspec.name = "linode"
18
+ gemspec.summary = "a Ruby wrapper for the Linode API"
19
+ gemspec.description = "This is a wrapper around Linode's automation facilities."
20
+ gemspec.email = "rick@rickbradley.com"
21
+ gemspec.homepage = "http://github.com/rick/linode"
22
+ gemspec.authors = ["Rick Bradley"]
23
+ gemspec.add_dependency('httparty', '>= 0.4.4')
24
+ end
25
+ Jeweler::GemcutterTasks.new
26
+ rescue LoadError
27
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
28
+ end
29
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.4
data/lib/linode.rb ADDED
@@ -0,0 +1,79 @@
1
+ require 'rubygems'
2
+ require 'ostruct'
3
+ require 'httparty'
4
+
5
+ class Linode
6
+ attr_reader :api_key
7
+
8
+ def self.has_method(*actions)
9
+ actions.each do |action|
10
+ define_method(action.to_sym) do |*data|
11
+ data = data.shift if data
12
+ data ||= {}
13
+ send_request(self.class.name.downcase.sub(/^linode::/, '').gsub(/::/, '.') + ".#{action}", data)
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.has_namespace(*namespaces)
19
+ namespaces.each do |namespace|
20
+ define_method(namespace.to_sym) do ||
21
+ lookup = instance_variable_get("@#{namespace}")
22
+ return lookup if lookup
23
+ subclass = self.class.const_get(namespace.to_s.capitalize).new(:api_key => api_key, :api_url => api_url)
24
+ instance_variable_set("@#{namespace}", subclass)
25
+ subclass
26
+ end
27
+ end
28
+ end
29
+
30
+ has_namespace :test, :avail, :user, :domain, :linode
31
+
32
+ def initialize(args)
33
+ raise ArgumentError, ":api_key is required" unless args[:api_key]
34
+ @api_key = args[:api_key]
35
+ @api_url = args[:api_url] if args[:api_url]
36
+ end
37
+
38
+ def api_url
39
+ @api_url || 'https://api.linode.com/'
40
+ end
41
+
42
+ def send_request(action, data)
43
+ data.delete_if {|k,v| [:api_key, :api_action, :api_responseFormat].include?(k) }
44
+ result = Crack::JSON.parse(HTTParty.get(api_url, :query => { :api_key => api_key, :api_action => action, :api_responseFormat => 'json' }.merge(data)))
45
+ raise "Errors completing request [#{action}] @ [#{api_url}] with data [#{data.inspect}]:\n#{error_message(result, action)}" if error?(result)
46
+ reformat_response(result)
47
+ end
48
+
49
+ protected
50
+
51
+ def error?(response)
52
+ response and response["ERRORARRAY"] and ! response["ERRORARRAY"].empty?
53
+ end
54
+
55
+ def error_message(response, action)
56
+ response["ERRORARRAY"].collect { |err|
57
+ " - Error \##{err["ERRORCODE"]} - #{err["ERRORMESSAGE"]}. (Please consult http://www.linode.com/api/autodoc.cfm?method=#{action})"
58
+ }.join("\n")
59
+ end
60
+
61
+ def reformat_response(response)
62
+ result = response['DATA']
63
+ return result.collect {|item| convert_item(item) } if result.class == Array
64
+ return result unless result.respond_to?(:keys)
65
+ convert_item(result)
66
+ end
67
+
68
+ def convert_item(item)
69
+ item.keys.each do |k|
70
+ item[k.downcase] = item[k]
71
+ item.delete(k) if k != k.downcase
72
+ end
73
+ ::OpenStruct.new(item)
74
+ end
75
+ end
76
+
77
+ # include all Linode API namespace classes
78
+ Dir[File.expand_path(File.dirname(__FILE__) + '/linode/*.rb')].each {|f| require f }
79
+ Dir[File.expand_path(File.dirname(__FILE__) + '/linode/**/*.rb')].each {|f| require f }
@@ -0,0 +1,3 @@
1
+ class Linode::Avail < Linode
2
+ has_method :datacenters, :kernels, :linodeplans, :distributions
3
+ end
@@ -0,0 +1,4 @@
1
+ class Linode::Domain < Linode
2
+ has_namespace :resource
3
+ has_method :update, :create, :list, :delete
4
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Domain::Resource < Linode
2
+ has_method :create, :delete, :update, :list
3
+ end
@@ -0,0 +1,4 @@
1
+ class Linode::Linode < Linode
2
+ has_namespace :config, :disk, :ip, :job
3
+ has_method :update, :create, :list, :shutdown, :boot, :delete, :reboot
4
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Linode::Config < Linode
2
+ has_method :create, :delete, :update, :list
3
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Linode::Disk < Linode
2
+ has_method :update, :create, :list, :createfromdistribution, :duplicate, :delete, :resize
3
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Linode::Ip < Linode
2
+ has_method :list
3
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Linode::Job < Linode
2
+ has_method :list
3
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::Test < Linode
2
+ has_method :echo
3
+ end
@@ -0,0 +1,3 @@
1
+ class Linode::User < Linode
2
+ has_method :getapikey
3
+ end
data/linode.gemspec ADDED
@@ -0,0 +1,84 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{linode}
8
+ s.version = "0.5.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rick Bradley"]
12
+ s.date = %q{2009-12-20}
13
+ s.description = %q{This is a wrapper around Linode's automation facilities.}
14
+ s.email = %q{rick@rickbradley.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "CHANGELOG",
21
+ "MIT-LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/linode.rb",
26
+ "lib/linode/avail.rb",
27
+ "lib/linode/domain.rb",
28
+ "lib/linode/domain/resource.rb",
29
+ "lib/linode/linode.rb",
30
+ "lib/linode/linode/config.rb",
31
+ "lib/linode/linode/disk.rb",
32
+ "lib/linode/linode/ip.rb",
33
+ "lib/linode/linode/job.rb",
34
+ "lib/linode/test.rb",
35
+ "lib/linode/user.rb",
36
+ "linode.gemspec",
37
+ "spec/linode/avail_spec.rb",
38
+ "spec/linode/domain/resource_spec.rb",
39
+ "spec/linode/domain_spec.rb",
40
+ "spec/linode/linode/config_spec.rb",
41
+ "spec/linode/linode/disk_spec.rb",
42
+ "spec/linode/linode/ip_spec.rb",
43
+ "spec/linode/linode/job_spec.rb",
44
+ "spec/linode/linode_spec.rb",
45
+ "spec/linode/test_spec.rb",
46
+ "spec/linode/user_spec.rb",
47
+ "spec/linode_spec.rb",
48
+ "spec/spec.opts",
49
+ "spec/spec_helper.rb"
50
+ ]
51
+ s.homepage = %q{http://github.com/rick/linode}
52
+ s.rdoc_options = ["--charset=UTF-8"]
53
+ s.require_paths = ["lib"]
54
+ s.rubygems_version = %q{1.3.5}
55
+ s.summary = %q{a Ruby wrapper for the Linode API}
56
+ s.test_files = [
57
+ "spec/linode/avail_spec.rb",
58
+ "spec/linode/domain/resource_spec.rb",
59
+ "spec/linode/domain_spec.rb",
60
+ "spec/linode/linode/config_spec.rb",
61
+ "spec/linode/linode/disk_spec.rb",
62
+ "spec/linode/linode/ip_spec.rb",
63
+ "spec/linode/linode/job_spec.rb",
64
+ "spec/linode/linode_spec.rb",
65
+ "spec/linode/test_spec.rb",
66
+ "spec/linode/user_spec.rb",
67
+ "spec/linode_spec.rb",
68
+ "spec/spec_helper.rb"
69
+ ]
70
+
71
+ if s.respond_to? :specification_version then
72
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
73
+ s.specification_version = 3
74
+
75
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
+ s.add_runtime_dependency(%q<httparty>, [">= 0.4.4"])
77
+ else
78
+ s.add_dependency(%q<httparty>, [">= 0.4.4"])
79
+ end
80
+ else
81
+ s.add_dependency(%q<httparty>, [">= 0.4.4"])
82
+ end
83
+ end
84
+
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'linode'
3
+
4
+ describe Linode::Avail do
5
+ before :each do
6
+ @api_key = 'foo'
7
+ @linode = Linode::Avail.new(:api_key => @api_key)
8
+ end
9
+
10
+ it 'should be a Linode instance' do
11
+ @linode.class.should < Linode
12
+ end
13
+
14
+ %w(datacenters kernels linodeplans distributions).each do |action|
15
+ it "should allow accessing the #{action} API" do
16
+ @linode.should respond_to(action.to_sym)
17
+ end
18
+
19
+ describe "when accessing the #{action} API" do
20
+ it 'should allow a data hash' do
21
+ lambda { @linode.send(action.to_sym, {}) }.should_not raise_error(ArgumentError)
22
+ end
23
+
24
+ it 'should not require arguments' do
25
+ lambda { @linode.send(action.to_sym) }.should_not raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should request the avail.#{action} action" do
29
+ @linode.expects(:send_request).with {|api_action, data| api_action == "avail.#{action}" }
30
+ @linode.send(action.to_sym)
31
+ end
32
+
33
+ it 'should provide the data hash when making its request' do
34
+ @linode.expects(:send_request).with {|api_action, data| data = { :foo => :bar } }
35
+ @linode.send(action.to_sym, {:foo => :bar})
36
+ end
37
+
38
+ it 'should return the result of the request' do
39
+ @linode.expects(:send_request).returns(:bar => :baz)
40
+ @linode.send(action.to_sym).should == { :bar => :baz }
41
+ end
42
+ end
43
+ end
44
+
45
+ end