From f37327f3d763f94b323cba1cb6f47290e27bd1e0 Mon Sep 17 00:00:00 2001
From: Peter Souter
Date: Sun, 9 Oct 2016 21:51:15 +0100
Subject: [PATCH] Adds resource of Volumes to Barge
Closes #17
* aka. Block Storage
* List all volumes
* List all volumes by region
* Retrieve volume by ID
* Delete a volume
* Create a volume
* Update README
* Add specs
* Add fixtures
Documentation: https://developers.digitalocean.com/documentation/v2/#block-storage
---
README.md | 33 ++++++++++++++++
lib/barge/client.rb | 4 ++
lib/barge/resource.rb | 1 +
lib/barge/resource/volume.rb | 43 ++++++++++++++++++++
spec/barge/resource/volume_spec.rb | 63 ++++++++++++++++++++++++++++++
spec/fixtures/volumes/all.json | 41 +++++++++++++++++++
spec/fixtures/volumes/create.json | 34 ++++++++++++++++
spec/fixtures/volumes/show.json | 34 ++++++++++++++++
spec/support/shared_contexts.rb | 1 +
9 files changed, 254 insertions(+)
create mode 100644 lib/barge/resource/volume.rb
create mode 100644 spec/barge/resource/volume_spec.rb
create mode 100644 spec/fixtures/volumes/all.json
create mode 100644 spec/fixtures/volumes/create.json
create mode 100644 spec/fixtures/volumes/show.json
diff --git a/README.md b/README.md
index d5994e8..260474c 100644
--- a/README.md
+++ b/README.md
@@ -528,3 +528,36 @@ barge.floating_ip.assign(ip_address, droplet_id: droplet_id)
``` ruby
barge.floating_ip.unassign(ip_address)
```
+
+Volume (aka Block Storage)
+-----------
+
+### Show all volumes
+
+``` ruby
+barge.volume.all
+barge.volume.all(region: 'nyc1')
+```
+
+### Create volume
+
+``` ruby
+barge.volume.create(
+ size_gigabytes: 10,
+ name: "Example",
+ description: "Block store for examples",
+ region: "nyc1"
+)
+```
+
+### Show volume
+
+``` ruby
+barge.volume.show(volume_id)
+```
+
+### Destroy volume
+
+``` ruby
+barge.volume.destroy(volume_id)
+```
diff --git a/lib/barge/client.rb b/lib/barge/client.rb
index 5609a0b..28f2912 100644
--- a/lib/barge/client.rb
+++ b/lib/barge/client.rb
@@ -55,6 +55,10 @@ def floating_ip
@floating_ip ||= Resource::FloatingIP.new(faraday)
end
+ def volume
+ @volume ||= Resource::Volume.new(faraday)
+ end
+
def faraday
@faraday ||= Faraday.new faraday_options do |f|
f.adapter :net_http
diff --git a/lib/barge/resource.rb b/lib/barge/resource.rb
index 08348db..8307e81 100644
--- a/lib/barge/resource.rb
+++ b/lib/barge/resource.rb
@@ -2,6 +2,7 @@
require 'barge/resource/account'
require 'barge/resource/action'
+require 'barge/resource/volume'
require 'barge/resource/domain'
require 'barge/resource/droplet'
require 'barge/resource/floating_ip'
diff --git a/lib/barge/resource/volume.rb b/lib/barge/resource/volume.rb
new file mode 100644
index 0000000..588cc72
--- /dev/null
+++ b/lib/barge/resource/volume.rb
@@ -0,0 +1,43 @@
+module Barge
+ module Resource
+ class Volume
+ include Resource::Base
+
+ def create(options)
+ post('volumes', options.to_json)
+ end
+
+ def all(options = {})
+ get('volumes', options)
+ end
+
+ def show(volume_id)
+ get("volumes/#{volume_id}")
+ end
+
+ def destroy(volume_id)
+ delete("volumes/#{volume_id}")
+ end
+
+ def create_record(volume_id, options)
+ post("volumes/#{volume_id}/records", options.to_json)
+ end
+
+ def records(volume_id, options = {})
+ get("volumes/#{volume_id}/records", options)
+ end
+
+ def show_record(volume_id, record_id)
+ get("volumes/#{volume_id}/records/#{record_id}")
+ end
+
+ def update_record(volume_id, record_id, options)
+ put("volumes/#{volume_id}/records/#{record_id}", options.to_json)
+ end
+
+ def destroy_record(volume_id, record_id)
+ delete("volumes/#{volume_id}/records/#{record_id}")
+ end
+ end
+ end
+end
diff --git a/spec/barge/resource/volume_spec.rb b/spec/barge/resource/volume_spec.rb
new file mode 100644
index 0000000..c1399b5
--- /dev/null
+++ b/spec/barge/resource/volume_spec.rb
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+describe Barge::Resource::Volume do
+ include_context 'resource'
+ it_behaves_like 'a resource'
+
+ describe '#all' do
+ it 'lists all volumes' do
+ stubbed_request =
+ stub_request!(:get, '/volumes')
+ .to_return(body: fixture('volumes/all'), status: 200)
+ expect(volume.all.volumes)
+ .to include a_hash_including(id: "7724db7c-e098-11e5-b522-000f53304e51")
+ expect(stubbed_request).to have_been_requested
+ end
+
+ it 'accepts an options hash' do
+ stubbed_request =
+ stub_request!(:get, '/volumes?page=10&per_page=20®ion=nyc1')
+ .to_return(body: fixture('volumes/all'), status: 200)
+ expect(volume.all(per_page: 20, page: 10, region: 'nyc1').volumes)
+ .to include a_hash_including(id: "7724db7c-e098-11e5-b522-000f53304e51")
+ expect(stubbed_request).to have_been_requested
+ end
+ end
+
+ describe '#create' do
+ it 'creates a volume' do
+ stubbed_request =
+ stub_request!(:post, '/volumes')
+ .to_return(body: fixture('volumes/create'), status: 201)
+ options = {
+ size_gigabytes: 10,
+ name: "Example",
+ description: "Block store for examples",
+ region: "nyc1"
+ }
+ expect(volume.create(options).volume.id).to eql('7724db7c-e098-11e5-b522-000f53304e51')
+ expect(stubbed_request.with(body: options.to_json))
+ .to have_been_requested
+ end
+ end
+
+ describe '#destroy' do
+ it 'destroys a volume' do
+ stubbed_request =
+ stub_request!(:delete, '/volumes/7724db7c-e098-11e5-b522-000f53304e51').to_return(status: 204)
+ expect(volume.destroy('7724db7c-e098-11e5-b522-000f53304e51').success?).to be true
+ expect(stubbed_request).to have_been_requested
+ end
+ end
+
+ describe '#show' do
+ it 'returns information about a given volume' do
+ stubbed_request =
+ stub_request!(:get, '/volumes/7724db7c-e098-11e5-b522-000f53304e51')
+ .to_return(body: fixture('volumes/show'), status: 200)
+ expect(volume.show('7724db7c-e098-11e5-b522-000f53304e51').volume.name).to eq 'Example'
+ expect(stubbed_request).to have_been_requested
+ end
+ end
+
+end
diff --git a/spec/fixtures/volumes/all.json b/spec/fixtures/volumes/all.json
new file mode 100644
index 0000000..9765ff3
--- /dev/null
+++ b/spec/fixtures/volumes/all.json
@@ -0,0 +1,41 @@
+{
+ "volumes": [
+ {
+ "id": "7724db7c-e098-11e5-b522-000f53304e51",
+ "region": {
+ "name": "New York 1",
+ "slug": "nyc1",
+ "sizes": [
+ "512mb",
+ "1gb",
+ "2gb",
+ "4gb",
+ "8gb",
+ "16gb",
+ "32gb",
+ "48gb",
+ "64gb"
+ ],
+ "features": [
+ "private_networking",
+ "backups",
+ "ipv6",
+ "metadata"
+ ],
+ "available": true
+ },
+ "droplet_ids": [
+
+ ],
+ "name": "Example",
+ "description": "Block store for examples",
+ "size_gigabytes": 10,
+ "created_at": "2016-03-02T17:00:49Z"
+ }
+ ],
+ "links": {
+ },
+ "meta": {
+ "total": 1
+ }
+}
diff --git a/spec/fixtures/volumes/create.json b/spec/fixtures/volumes/create.json
new file mode 100644
index 0000000..b117cfc
--- /dev/null
+++ b/spec/fixtures/volumes/create.json
@@ -0,0 +1,34 @@
+{
+ "volume": {
+ "id": "7724db7c-e098-11e5-b522-000f53304e51",
+ "region": {
+ "name": "New York 1",
+ "slug": "nyc1",
+ "sizes": [
+ "512mb",
+ "1gb",
+ "2gb",
+ "4gb",
+ "8gb",
+ "16gb",
+ "32gb",
+ "48gb",
+ "64gb"
+ ],
+ "features": [
+ "private_networking",
+ "backups",
+ "ipv6",
+ "metadata"
+ ],
+ "available": true
+ },
+ "droplet_ids": [
+
+ ],
+ "name": "Example",
+ "description": "Block store for examples",
+ "size_gigabytes": 10,
+ "created_at": "2016-03-02T17:00:49Z"
+ }
+}
diff --git a/spec/fixtures/volumes/show.json b/spec/fixtures/volumes/show.json
new file mode 100644
index 0000000..b117cfc
--- /dev/null
+++ b/spec/fixtures/volumes/show.json
@@ -0,0 +1,34 @@
+{
+ "volume": {
+ "id": "7724db7c-e098-11e5-b522-000f53304e51",
+ "region": {
+ "name": "New York 1",
+ "slug": "nyc1",
+ "sizes": [
+ "512mb",
+ "1gb",
+ "2gb",
+ "4gb",
+ "8gb",
+ "16gb",
+ "32gb",
+ "48gb",
+ "64gb"
+ ],
+ "features": [
+ "private_networking",
+ "backups",
+ "ipv6",
+ "metadata"
+ ],
+ "available": true
+ },
+ "droplet_ids": [
+
+ ],
+ "name": "Example",
+ "description": "Block store for examples",
+ "size_gigabytes": 10,
+ "created_at": "2016-03-02T17:00:49Z"
+ }
+}
diff --git a/spec/support/shared_contexts.rb b/spec/support/shared_contexts.rb
index 083a16c..a6497cc 100644
--- a/spec/support/shared_contexts.rb
+++ b/spec/support/shared_contexts.rb
@@ -3,6 +3,7 @@
let(:account) { barge.account }
let(:action) { barge.action }
+ let(:volume) { barge.volume }
let(:domain) { barge.domain }
let(:droplet) { barge.droplet }
let(:floating_ip) { barge.floating_ip }