profitbricks-sdk-ruby 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +202 -0
  5. data/README.md +44 -0
  6. data/Rakefile +7 -0
  7. data/docs/guide.md +223 -0
  8. data/docs/reference.md +376 -0
  9. data/lib/profitbricks/config.rb +30 -0
  10. data/lib/profitbricks/datacenter.rb +113 -0
  11. data/lib/profitbricks/firewall.rb +65 -0
  12. data/lib/profitbricks/image.rb +51 -0
  13. data/lib/profitbricks/ipblock.rb +74 -0
  14. data/lib/profitbricks/lan.rb +75 -0
  15. data/lib/profitbricks/loadbalancer.rb +126 -0
  16. data/lib/profitbricks/location.rb +28 -0
  17. data/lib/profitbricks/model.rb +116 -0
  18. data/lib/profitbricks/nic.rb +86 -0
  19. data/lib/profitbricks/profitbricks.rb +137 -0
  20. data/lib/profitbricks/request.rb +36 -0
  21. data/lib/profitbricks/server.rb +165 -0
  22. data/lib/profitbricks/snapshot.rb +78 -0
  23. data/lib/profitbricks/version.rb +3 -0
  24. data/lib/profitbricks/volume.rb +199 -0
  25. data/lib/profitbricks/wait_for.rb +16 -0
  26. data/lib/profitbricks.rb +24 -0
  27. data/profitbricks-sdk-ruby.gemspec +26 -0
  28. data/spec/datacenter_spec.rb +230 -0
  29. data/spec/firewall_spec.rb +95 -0
  30. data/spec/image_spec.rb +49 -0
  31. data/spec/ipblock_spec.rb +52 -0
  32. data/spec/lan_spec.rb +70 -0
  33. data/spec/loadbalancer_spec.rb +117 -0
  34. data/spec/location_spec.rb +20 -0
  35. data/spec/nic_spec.rb +88 -0
  36. data/spec/profitbricks_spec.rb +1 -0
  37. data/spec/request_spec.rb +37 -0
  38. data/spec/server_spec.rb +209 -0
  39. data/spec/snapshot_spec.rb +113 -0
  40. data/spec/spec_helper.rb +18 -0
  41. data/spec/support/resource_helper.rb +64 -0
  42. data/spec/volume_spec.rb +113 -0
  43. metadata +172 -0
@@ -0,0 +1,165 @@
1
+ module ProfitBricks
2
+ # Server class
3
+ class Server < ProfitBricks::Model
4
+
5
+ # Delete the server.
6
+ def delete
7
+ ProfitBricks.request(
8
+ method: :delete,
9
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}",
10
+ expects: 202
11
+ )
12
+ end
13
+
14
+ # Update the server.
15
+ def update(options = {})
16
+ response = ProfitBricks.request(
17
+ method: :patch,
18
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}",
19
+ expects: 202,
20
+ body: options.to_json
21
+ )
22
+ if response
23
+ @properties = @properties.merge(response['properties'])
24
+ end
25
+ self
26
+ end
27
+
28
+ # Start the server.
29
+ def start
30
+ server_control('start')
31
+ end
32
+
33
+ # Stop the server.
34
+ def stop
35
+ server_control('stop')
36
+ end
37
+
38
+ # Reboot the server.
39
+ def reboot
40
+ server_control('reboot')
41
+ end
42
+
43
+ # List server volumes.
44
+ def list_volumes
45
+ ProfitBricks::Volume.list(self.datacenterId, self.id)
46
+ end
47
+
48
+ # Retrieve server volume.
49
+ def get_volume(volume_id)
50
+ ProfitBricks::Volume.get(self.datacenterId, self.id, volume_id)
51
+ end
52
+
53
+ # Attach volume to server.
54
+ def attach_volume(volume_id)
55
+ volume = ProfitBricks::Volume.get(self.datacenterId, nil, volume_id)
56
+ volume.attach(self.id)
57
+ end
58
+
59
+ # Detach volume from server.
60
+ def detach_volume(volume_id)
61
+ volume = ProfitBricks::Volume.get(self.datacenterId, nil, volume_id)
62
+ volume.detach(self.id)
63
+ end
64
+
65
+ def list_cdroms
66
+ response = ProfitBricks.request(
67
+ method: :get,
68
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}/cdroms",
69
+ expects: 200
70
+ )
71
+ self.class.instantiate_objects(response)
72
+ end
73
+
74
+ def get_cdrom(cdrom_id)
75
+ response = ProfitBricks.request(
76
+ method: :get,
77
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}/cdroms/#{cdrom_id}",
78
+ expects: 200
79
+ )
80
+ self.class.instantiate_objects(response)
81
+ end
82
+
83
+ def attach_cdrom(cdrom_id)
84
+ response = ProfitBricks.request(
85
+ method: :post,
86
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}/cdroms",
87
+ expects: 202,
88
+ body: { id: cdrom_id }.to_json
89
+ )
90
+ self.class.instantiate_objects(response)
91
+ end
92
+
93
+ def detach_cdrom(cdrom_id)
94
+ ProfitBricks.request(
95
+ method: :delete,
96
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}/cdroms/#{cdrom_id}",
97
+ expects: 202
98
+ )
99
+ end
100
+
101
+ # List server NICs.
102
+ def list_nics
103
+ ProfitBricks::NIC.list(self.datacenterId, self.id)
104
+ end
105
+
106
+ # Retrieve server NIC.
107
+ def get_nic(nic_id)
108
+ ProfitBricks::NIC.get(self.datacenterId, self.id, nic_id)
109
+ end
110
+
111
+ # Create server NIC.
112
+ def create_nic(options = {})
113
+ ProfitBricks::NIC.create(self.datacenterId, self.id, options)
114
+ end
115
+
116
+ alias_method :nics, :list_nics
117
+ alias_method :nic, :get_nic
118
+
119
+ class << self
120
+ # Create a new server.
121
+ def create(datacenter_id, options = {})
122
+ response = ProfitBricks.request(
123
+ method: :post,
124
+ path: "/datacenters/#{datacenter_id}/servers",
125
+ expects: 202,
126
+ body: { properties: options }.to_json
127
+ )
128
+ add_parent_identities(response)
129
+ instantiate_objects(response)
130
+ end
131
+
132
+ # List all servers by datacenter.
133
+ def list(datacenter_id)
134
+ response = ProfitBricks.request(
135
+ method: :get,
136
+ path: "/datacenters/#{datacenter_id}/servers",
137
+ expects: 200
138
+ )
139
+ add_parent_identities(response)
140
+ instantiate_objects(response)
141
+ end
142
+
143
+ def get(datacenter_id, server_id)
144
+ response = ProfitBricks.request(
145
+ method: :get,
146
+ path: "/datacenters/#{datacenter_id}/servers/#{server_id}",
147
+ expects: 200
148
+ )
149
+ add_parent_identities(response)
150
+ instantiate_objects(response)
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ def server_control(operation)
157
+ ProfitBricks.request(
158
+ method: :post,
159
+ path: "/datacenters/#{self.datacenterId}/servers/#{self.id}/#{operation}",
160
+ headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
161
+ expects: 202
162
+ )
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,78 @@
1
+ module ProfitBricks
2
+ # Snapshot class
3
+ class Snapshot < ProfitBricks::Model
4
+
5
+ # Delete the snapshot.
6
+ def delete
7
+ ProfitBricks.request(
8
+ method: :delete,
9
+ path: "/snapshots/#{self.id}",
10
+ expects: 202
11
+ )
12
+ end
13
+
14
+ # Update the snapshot.
15
+ def update(options = {})
16
+ response = ProfitBricks.request(
17
+ method: :patch,
18
+ path: "/snapshots/#{self.id}",
19
+ expects: 202,
20
+ body: options.to_json
21
+ )
22
+ if response
23
+ @properties = @properties.merge(response['properties'])
24
+ end
25
+ self
26
+ end
27
+
28
+ # Restore snapshot to volume.
29
+ def restore(datacenter_id, volume_id)
30
+ volume = ProfitBricks::Volume.get(datacenter_id, nil, volume_id)
31
+ volume.restore_snapshot(self.id)
32
+ end
33
+
34
+ class << self
35
+
36
+ # Create snapshot from volume.
37
+ def create(datacenter_id, volume_id, options = {})
38
+ volume = ProfitBricks::Volume.get(datacenter_id, nil, volume_id)
39
+ volume.create_snapshot(options)
40
+ end
41
+
42
+ # Testing snapshot create from within Snapshot class, but currently
43
+ # relying on Volume class due to lack of datacenter ID in response.
44
+ #
45
+ # def create(datacenter_id, volume_id, options = {})
46
+ # response = ProfitBricks.request(
47
+ # method: :post,
48
+ # path: "/datacenters/#{datacenter_id}/volumes/#{volume_id}/create-snapshot",
49
+ # expects: 202,
50
+ # headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
51
+ # body: URI.encode_www_form(options)
52
+ # )
53
+ # add_parent_identities(response)
54
+ # instatiate_objects(response)
55
+ # end
56
+
57
+ # List all snapshots.
58
+ def list
59
+ response = ProfitBricks.request(
60
+ method: :get,
61
+ path: '/snapshots',
62
+ expects: 200
63
+ )
64
+ instantiate_objects(response)
65
+ end
66
+
67
+ # Retrieve an snapshot.
68
+ def get(snapshot_id)
69
+ response = ProfitBricks.request(
70
+ method: :get,
71
+ path: "/snapshots/#{snapshot_id}",
72
+ expects: 200
73
+ )
74
+ instantiate_objects(response)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module ProfitBricks
2
+ VERSION = "1.0.2"
3
+ end
@@ -0,0 +1,199 @@
1
+ module ProfitBricks
2
+ # Volume class
3
+ class Volume < ProfitBricks::Model
4
+
5
+ # Delete the volume.
6
+ def delete
7
+ ProfitBricks.request(
8
+ method: :delete,
9
+ path: "/datacenters/#{self.datacenterId}/volumes/#{self.id}",
10
+ expects: 202
11
+ )
12
+ end
13
+
14
+ # Update the volume.
15
+ def update(options = {})
16
+ response = ProfitBricks.request(
17
+ method: :patch,
18
+ path: "/datacenters/#{self.datacenterId}/volumes/#{self.id}",
19
+ expects: 202,
20
+ body: options.to_json
21
+ )
22
+ if response
23
+ @properties = @properties.merge(response['properties'])
24
+ end
25
+ self
26
+ end
27
+
28
+ # Attach volume to server.
29
+ def attach(server_id)
30
+ response = ProfitBricks.request(
31
+ method: :post,
32
+ path: "/datacenters/#{self.datacenterId}/servers/#{server_id}/volumes",
33
+ expects: 202,
34
+ body: { id: self.id }.to_json
35
+ )
36
+ self
37
+ end
38
+
39
+ # Detach volume from server.
40
+ def detach(server_id)
41
+ ProfitBricks.request(
42
+ method: :delete,
43
+ path: "/datacenters/#{self.datacenterId}/servers/#{server_id}/volumes/#{self.id}",
44
+ expects: 202
45
+ )
46
+ end
47
+
48
+ # Create volume snapshot.
49
+ #
50
+ # ==== Parameters
51
+ # * +options+<Hash>:
52
+ # - +name+<String> - *Optional*, name of the snapshot
53
+ # - +description+<String> - *Optional*, description of the snapshot
54
+ #
55
+ # ==== Returns
56
+ # * +id+<String> - Universally unique identifer of resource
57
+ # * +type+<String> - Resource type
58
+ # * +href+<String> - Resource URL representation
59
+ # * +metadata+<Hash>:
60
+ # - +lastModifiedDate+
61
+ # - +lastModifiedBy+
62
+ # - +createdDate+
63
+ # - +createdBy+
64
+ # - +state+
65
+ # - +etag+
66
+ # * +properties+<Hash>:
67
+ # - +name+<Integer>
68
+ # - +description+<Array>
69
+ # - +location+<String>
70
+ # - +cpuHotPlug+<Boolean>
71
+ # - +cpuHotUnPlug+<Boolean>
72
+ # - +ramHotPlug+<Boolean>
73
+ # - +ramHotUnPlug+<Boolean>
74
+ # - +nicHotPlug+<Boolean>
75
+ # - +nicHotUnPlug+<Boolean>
76
+ # - +discVirtioHotPlug+<Boolean>
77
+ # - +discVirtioHotUnPlug+<Boolean>
78
+ # - +discScsiHotPlug+<Boolean>
79
+ # - +discScsiHotUnPlug+<Boolean>
80
+ # - +licenceType+<String>
81
+ #
82
+ def create_snapshot(options = {})
83
+ response = ProfitBricks.request(
84
+ method: :post,
85
+ path: "/datacenters/#{self.datacenterId}/volumes/#{self.id}/create-snapshot",
86
+ headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
87
+ expects: 202,
88
+ body: URI.encode_www_form(options)
89
+ )
90
+ ProfitBricks::Snapshot.new(response)
91
+ end
92
+
93
+ # Restore snapshot to volume.
94
+ #
95
+ # ==== Parameters
96
+ # * +snapshot_id+<String>: Universally unique identifer of snapshot resource
97
+ #
98
+ # ==== Returns
99
+ # * +true+<Boolean>
100
+ #
101
+ def restore_snapshot(snapshot_id)
102
+ ProfitBricks.request(
103
+ method: :post,
104
+ path: "/datacenters/#{self.datacenterId}/volumes/#{self.id}/restore-snapshot",
105
+ headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
106
+ expects: 202,
107
+ body: URI.encode_www_form(snapshotId: snapshot_id)
108
+ )
109
+ end
110
+
111
+ class << self
112
+
113
+ # Create a new volume.
114
+ #
115
+ # ==== Parameters
116
+ # * +options+<Hash>:
117
+ # - +name+<String> - *Optional*, name of the volume
118
+ # - +size+<Integer> - *Required*, size of the volume in GB
119
+ # - +bus+<String> - *Optional*, the bus type of the volume
120
+ # * +VIRTIO+ - *Default*
121
+ # * +IDE+
122
+ # - +image+<String> - *Optional*, image or snapshot ID
123
+ #
124
+ # ==== Returns
125
+ # * +id+<String> - Universally unique identifer of resource
126
+ # * +type+<String> - Resource type
127
+ # * +href+<String> - Resource URL representation
128
+ # * +metadata+<Hash>:
129
+ # - +lastModifiedDate+
130
+ # - +lastModifiedBy+
131
+ # - +createdDate+
132
+ # - +createdBy+
133
+ # - +state+
134
+ # - +etag+
135
+ # * +properties+<Hash>:
136
+ # - +name+<String>
137
+ # - +size+<Integer>
138
+ # - +bus+<String>
139
+ # - +image+<String>
140
+ # - +imagePassword+<String>
141
+ # - +type+<String>
142
+ # - +licenseType+<String>
143
+ # - +cpuHotPlug+<Boolean>
144
+ # - +cpuHotUnPlug+<Boolean>
145
+ # - +ramHotPlug+<Boolean>
146
+ # - +ramHotUnPlug+<Boolean>
147
+ # - +nicHotPlug+<Boolean>
148
+ # - +nicHotUnPlug+<Boolean>
149
+ # - +discVirtioHotPlug+<Boolean>
150
+ # - +discVirtioHotUnPlug+<Boolean>
151
+ # - +discScsiHotPlug+<Boolean>
152
+ # - +discScsiHotUnPlug+<Boolean>
153
+ #
154
+ def create(datacenter_id, options = {})
155
+ options[:licenceType] ||= 'UNKNOWN'
156
+ response = ProfitBricks.request(
157
+ method: :post,
158
+ path: "/datacenters/#{datacenter_id}/volumes",
159
+ expects: 202,
160
+ body: { properties: options }.to_json
161
+ )
162
+ add_parent_identities(response)
163
+ instantiate_objects(response)
164
+ end
165
+
166
+ # List all datacenter volumes.
167
+ def list(datacenter_id, server_id = nil)
168
+ if server_id.nil?
169
+ path = "/datacenters/#{datacenter_id}/volumes"
170
+ else
171
+ path = "/datacenters/#{datacenter_id}/servers/#{server_id}/volumes"
172
+ end
173
+ response = ProfitBricks.request(
174
+ method: :get,
175
+ path: path,
176
+ expects: 200
177
+ )
178
+ add_parent_identities(response)
179
+ instantiate_objects(response)
180
+ end
181
+
182
+ # Retrieve a datacenter volume.
183
+ def get(datacenter_id, server_id = nil, volume_id)
184
+ if server_id.nil?
185
+ path = "/datacenters/#{datacenter_id}/volumes/#{volume_id}"
186
+ else
187
+ path = "/datacenters/#{datacenter_id}/servers/#{server_id}/volumes/#{volume_id}"
188
+ end
189
+ response = ProfitBricks.request(
190
+ method: :get,
191
+ path: path,
192
+ expects: 200
193
+ )
194
+ add_parent_identities(response)
195
+ instantiate_objects(response)
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,16 @@
1
+ module ProfitBricks
2
+ def self.wait_for(timeout = ProfitBricks::Config.timeout, interval = ProfitBricks::Config.interval, &_block)
3
+ duration = 0
4
+ start = Time.now
5
+ retries = 0
6
+ until yield || duration > timeout
7
+ sleep(interval.respond_to?(:call) ? interval.call(retries += 1).to_f : interval.to_f)
8
+ duration = Time.now - start
9
+ end
10
+ if duration > timeout
11
+ raise StandardError, "The specified wait_for timeout (#{timeout} seconds) was exceeded"
12
+ else
13
+ { :duration => duration }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require 'excon'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ # Top-level module
6
+ module ProfitBricks
7
+ require 'profitbricks/version'
8
+ require 'profitbricks/config'
9
+ require 'profitbricks/profitbricks'
10
+ require 'profitbricks/model'
11
+ require 'profitbricks/datacenter'
12
+ require 'profitbricks/server'
13
+ require 'profitbricks/volume'
14
+ require 'profitbricks/snapshot'
15
+ require 'profitbricks/nic'
16
+ require 'profitbricks/firewall'
17
+ require 'profitbricks/lan'
18
+ require 'profitbricks/loadbalancer'
19
+ require 'profitbricks/ipblock'
20
+ require 'profitbricks/image'
21
+ require 'profitbricks/location'
22
+ require 'profitbricks/request'
23
+ require 'profitbricks/wait_for'
24
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'profitbricks/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "profitbricks-sdk-ruby"
8
+ spec.version = ProfitBricks::VERSION
9
+ spec.authors = ["Ethan Devenport"]
10
+ spec.email = ["ethand@stackpointcloud.com"]
11
+ spec.summary = %q{Official ProfitBricks SDK for Ruby}
12
+ spec.description = %q{The ProfitBricks SDK for Ruby provides integration with the ProfitBricks cloud environment over the available REST API.}
13
+ spec.homepage = "https://github.com/profitbricks/profitbricks-sdk-ruby"
14
+ spec.license = "Apache"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "excon", "~> 0.44"
22
+ spec.add_runtime_dependency "json", "~> 1.8"
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake", "~> 10.4"
25
+ spec.add_development_dependency "rspec", "~> 3.2"
26
+ end