em-digitalocean 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 83254f7d7f018f7c6a0fa01acc4c343ac2e265b7
4
+ data.tar.gz: 9b408c53d2fe2ccb6ad78f4b70dc8430065bda85
5
+ SHA512:
6
+ metadata.gz: 598fb05608b7074769acbec16d2805edecc05ca3e7350cc8a3fc2be0e6d700cec9a00aef8cbfe28e781ee13f06a797d3482c40f65e00fabb9bbaf6705567c75d
7
+ data.tar.gz: 28c0557667215611d63725e2cc4306536f1da6113f9882c3683f57197b39b247ba8ba250689cd97bfdc4bafaf2e0207f4d4a044a6108852b259a911b13034d69
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ /TOKEN
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in em-digitalocean.gemspec
4
+ gemspec
@@ -0,0 +1,73 @@
1
+ # Digitalocean API
2
+
3
+
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'em-digitalocean'
11
+ ```
12
+
13
+ Then `require 'digitalocean'`
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install em-digitalocean
22
+
23
+ ## Usage
24
+
25
+ https://cloud.digitalocean.com/settings/applications
26
+
27
+ ```ruby
28
+ api = Digitalocean::API.new(token: 'TOKEN')
29
+ ```
30
+
31
+ ## API
32
+
33
+ ```ruby
34
+ api = Digitalocean::API.new(token: 'TOKEN')
35
+ droplets = api.droplets.all.sync
36
+ # {:droplets=>[{:id=>0, :name=>"droplet", :memory=>512, :vcpus=>1, :disk=>20, :locked=>false ...}]}
37
+ droplet = api.droplets.show(droplets[:droplets].first[:id]).sync
38
+ # {:droplet=>{:id=>0, :name=>"droplet", :memory=>512, :vcpus=>1, :disk=>20, :locked=>false, :status=>"active", ...}}
39
+ ```
40
+
41
+ ## Droplet Actions
42
+
43
+ * `api.droplets.disable_backups(id).sync`
44
+ * `api.droplets.reboot(id).sync`
45
+ * `api.droplets.power_cycle(id).sync`
46
+ * `api.droplets.shutdown(id).sync`
47
+ * `api.droplets.power_off(id).sync`
48
+ * `api.droplets.power_on(id).sync`
49
+ * `api.droplets.restore(id, image).sync`
50
+ * `api.droplets.password_reset(id).sync`
51
+ * `api.droplets.resize(id, disk, size).sync`
52
+ * `api.droplets.rebuild(id, image).sync`
53
+ * `api.droplets.rename(id, name).sync`
54
+ * `api.droplets.change_kernel(id, kernel).sync`
55
+ * `api.droplets.enable_ipv6(id, kernel).sync`
56
+ * `api.droplets.enable_private_networking(id, kernel).sync`
57
+ * `api.droplets.snapshot(id).sync`
58
+ * `api.droplets.upgrade(id).sync`
59
+ * `api.droplets.retrive_action(id, action).sync`
60
+
61
+ ## Raise
62
+
63
+ config/initializers/digitalocean.rb
64
+ ```ruby
65
+ require 'digitalocean'
66
+ Digitalocean.api = Digitalocean::API.new(token: 'TOKEN')
67
+ ```
68
+
69
+ Request:
70
+
71
+ ```ruby
72
+ actions = Digitalocean.api.actions.sync
73
+ ```
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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 'digitalocean/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "em-digitalocean"
8
+ spec.version = Digitalocean::VERSION
9
+ spec.authors = ["inre"]
10
+ spec.email = ["inre.storm@gmail.com"]
11
+
12
+ spec.summary = %q{DigitalOcean API EventMachine-based}
13
+ #spec.description = %q{TODO: Write a longer description or delete this line.}
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "emmy-machine"
21
+ spec.add_dependency "emmy-http", '>= 0.2.2'
22
+ spec.add_dependency "emmy-http-client", '>= 0.1.7'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.9"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
@@ -0,0 +1,12 @@
1
+ require 'event_object'
2
+ require 'emmy_http'
3
+ require 'emmy_http/client'
4
+ require 'digitalocean/version'
5
+ require 'digitalocean/concerns/class_methods'
6
+ require 'digitalocean/api'
7
+ require 'digitalocean/operation'
8
+ require 'digitalocean/requests'
9
+ require 'digitalocean/errors'
10
+
11
+ module Digitalocean
12
+ end
@@ -0,0 +1,190 @@
1
+ module Digitalocean
2
+ class API
3
+ using EventObject
4
+ extend ClassMethods
5
+
6
+ attr_accessor :token
7
+ attr_accessor :username
8
+ attr_accessor :password
9
+
10
+ def initialize(token: nil, username: nil, password: nil)
11
+ @token = token
12
+ @username = username
13
+ @password = password
14
+ end
15
+
16
+ def operation(request)
17
+ Operation.new(self, request)
18
+ end
19
+
20
+ def op(r)
21
+ operation(r)
22
+ end
23
+
24
+ ns :account do |api|
25
+ bind self, Account
26
+ end
27
+
28
+ ns :account_keys do |api|
29
+ bind self, Account::Keys
30
+ end
31
+
32
+ ns :actions do |api|
33
+ bind self, Actions
34
+ end
35
+
36
+ ns :domains do |api|
37
+ bind self, Domains
38
+ end
39
+
40
+ ns :domain_records do |api|
41
+ bind self, Domains::Records
42
+ end
43
+
44
+ ns :droplets do |api|
45
+ # Droplet Actions
46
+ self.def :execute_action do |id, params|
47
+ api.op.call Droplets.execute_action(params: {id: id}, json: params)
48
+ end
49
+
50
+ # Disable Backups
51
+ self.def :disable_backups do |id|
52
+ execute_action(id, type: 'disable_backups')
53
+ end
54
+
55
+ # Reboot a Droplet
56
+ self.def :reboot do |id|
57
+ execute_action(id, type: 'reboot')
58
+ end
59
+
60
+ # Power Cycle a Droplet
61
+ self.def :power_cycle do |id|
62
+ execute_action(id, type: 'power_cycle')
63
+ end
64
+
65
+ # Shutdown a Droplet
66
+ self.def :shutdown do |id|
67
+ execute_action(id, type: 'shutdown')
68
+ end
69
+
70
+ # Power Off a Droplet
71
+ self.def :power_off do |id|
72
+ execute_action(id, type: 'power_off')
73
+ end
74
+
75
+ # Power Off a Droplet
76
+ self.def :power_on do |id|
77
+ execute_action(id, type: 'power_on')
78
+ end
79
+
80
+ # Restore a Droplet
81
+ self.def :restore do |id, image|
82
+ execute_action(id, type: 'power_on', image: image)
83
+ end
84
+
85
+ # Password reset a Droplet
86
+ self.def :password_reset do |id|
87
+ execute_action(id, type: 'password_reset')
88
+ end
89
+
90
+ # Resize a Droplet
91
+ self.def :resize do |id, disk, size|
92
+ execute_action(id, type: 'resize', disk: disk, size: size)
93
+ end
94
+
95
+ # Rebuild a Droplet
96
+ self.def :rebuild do |id, image|
97
+ execute_action(id, type: 'rebuild', image: image)
98
+ end
99
+
100
+ # Rename a Droplet
101
+ self.def :rename do |id, name|
102
+ execute_action(id, type: 'rename', name: name)
103
+ end
104
+
105
+ # Change the Kernel
106
+ self.def :change_kernel do |id, kernel|
107
+ execute_action(id, type: 'change_kernel', kernel: kernel)
108
+ end
109
+
110
+ # Enable IPv6
111
+ self.def :enable_ipv6 do |id|
112
+ execute_action(id, type: 'enable_ipv6')
113
+ end
114
+
115
+ # Enable Private Networking
116
+ self.def :enable_private_networking do |id|
117
+ execute_action(id, type: 'enable_private_networking')
118
+ end
119
+
120
+ # Snapshot a Droplet
121
+ self.def :snapshot do |id|
122
+ execute_action(id, type: 'snapshot')
123
+ end
124
+
125
+ # Upgrade a Droplet
126
+ self.def :upgrade do |id|
127
+ execute_action(id, type: 'upgrade')
128
+ end
129
+
130
+ # Retrieve a Droplet Action
131
+ self.def :retrive_action do |id, action|
132
+ Droplets.retrieve_action(params: {id: id, action: action})
133
+ end
134
+
135
+ # Other API methods
136
+ bind self, Droplets
137
+ end
138
+
139
+ ns :images do |api|
140
+ bind self, Images
141
+ end
142
+
143
+ ns :regions do |api|
144
+ bind self, Regions
145
+ end
146
+
147
+ ns :sizes do |api|
148
+ bind self, Sizes
149
+ end
150
+
151
+ =begin
152
+ def droplet
153
+ @droplet ||= begin
154
+ droplet = Object.new
155
+ op = method(:operation)
156
+
157
+ # Droplet Actions
158
+ droplet.def :execute_action do |id, params|
159
+ op.call Droplet.execute_action(params: {id: id}, json: params)
160
+ end
161
+
162
+ # Disable Backups
163
+ droplet.def :disable_backups do |id|
164
+ op.call Droplet.execute_action
165
+ end
166
+
167
+ Droplet.api.each do |name, params|
168
+ variables = Addressable::Template.new(params[:path]).variables
169
+
170
+ if variables.empty? && !droplet.respond_to?(name)
171
+ droplet.def name do
172
+ op.call Droplet.send(name)
173
+ end
174
+ end
175
+
176
+ if variables.include?('id')
177
+ droplet.def name do |id|
178
+ op.call Droplet.send(name, params: {id: id})
179
+ end
180
+ end
181
+ end
182
+
183
+ droplet
184
+ end
185
+ end
186
+ =end
187
+
188
+ #<<<
189
+ end
190
+ end
@@ -0,0 +1,53 @@
1
+ module Digitalocean
2
+ module ClassMethods
3
+ using EventObject
4
+ extend self
5
+
6
+ def ns(name, &b)
7
+ self.def name do
8
+ this = self
9
+ Object.new.tap do |ob|
10
+ ob.def :bind do |object, klass|
11
+ ClassMethods.bind this, object, klass
12
+ end
13
+ ob.instance_exec(self, &b)
14
+ end
15
+ end
16
+ end
17
+
18
+ def bind(api, object, klass)
19
+ raise "#{klass} is not API object" unless klass.respond_to?(:api)
20
+
21
+ klass.api.each do |name, params|
22
+ variables = Addressable::Template.new(params[:path]).variables
23
+
24
+ # auto-bind for no variables
25
+ if variables.empty? && !object.respond_to?(name)
26
+ object.def name do
27
+ api.op klass.send(name)
28
+ end
29
+ end
30
+
31
+ # auto-bind for id variable
32
+ if variables.size == 1
33
+ var_name = variables.first
34
+
35
+ object.def name do |value|
36
+ api.op klass.send(name, params: {var_name => value})
37
+ end
38
+ end
39
+
40
+ if variables.size == 2
41
+ var_name1 = variables.first
42
+ var_name2 = variables.last
43
+
44
+ object.def name do |var1, var2|
45
+ api.op klass.send(name, params: { var_name1 => var1, var_name2 => var2 })
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ #<<<
52
+ end
53
+ end
@@ -0,0 +1,42 @@
1
+ module Digitalocean
2
+ # Base Error
3
+ class Error < RuntimeError
4
+ attr_accessor :code
5
+
6
+ def initialize(data=nil)
7
+ @message = case data
8
+ when Hash
9
+ @code = data[:code]
10
+ data[:message]
11
+ else
12
+ data
13
+ end
14
+ end
15
+
16
+ def message
17
+ code ? "(#{code}) #{@message}" : @message
18
+ end
19
+
20
+ def to_s
21
+ message
22
+ end
23
+ end
24
+
25
+ # Internal Server Error
26
+ class ServerError < Error
27
+ end
28
+
29
+ class ClientError < Error
30
+ attr_accessor :id
31
+
32
+ def initialize(response)
33
+ @message = response.json["message"]
34
+ @id = response.json["id"]
35
+ @code = response.status
36
+ rescue StandardError
37
+ @message = "Uncatched Error"
38
+ end
39
+ end
40
+
41
+ #<<<
42
+ end
@@ -0,0 +1,73 @@
1
+ module Digitalocean
2
+ class Operation
3
+ using EventObject
4
+
5
+ attr_accessor :api
6
+ attr_accessor :request # EmmyHttp::Client::Request
7
+ attr_accessor :operation # EmmyHttp::Client::Operation
8
+
9
+ events :success, :error
10
+
11
+ def initialize(api, request)
12
+ @api = api
13
+ @request = request
14
+ auth
15
+ new_operation
16
+ end
17
+
18
+ def connect(*a)
19
+ operation.connect(*a)
20
+ end
21
+
22
+ def sync
23
+ connect
24
+
25
+ Fiber.sync do |f|
26
+ on :success do |response, operation, conn|
27
+ f.resume response.json(symbolize_names: true)
28
+ end
29
+
30
+ on :error do |error, operation, conn|
31
+ f.leave error
32
+ end
33
+ end
34
+ end
35
+
36
+ def to_a
37
+ operation.to_a
38
+ end
39
+
40
+ protected
41
+
42
+ def auth
43
+ if api.token
44
+ request.headers["Authorization"] = "Bearer #{api.token}"
45
+ elsif api.user && api.password
46
+ request.user = api.user
47
+ request.password = api.password
48
+ end
49
+ end
50
+
51
+ def new_operation
52
+ @operation = request.new_operation
53
+ @operation.on :success do |res, op, conn|
54
+ # success
55
+ case res.status
56
+ when 200...300
57
+ success!(res, self, conn)
58
+ when 400...500
59
+ error!(Digitalocean::ClientError.new(res), self, conn)
60
+ else
61
+ error!(Digitalocean::ServerError.new({message: "Internal Server Error", code: res.status}), self, conn)
62
+ end
63
+ end
64
+
65
+ @operation.on :error do |message, op, conn|
66
+ # error
67
+ error!(message, self, conn)
68
+ end
69
+ end
70
+
71
+ #<<<
72
+ end
73
+ end
@@ -0,0 +1,120 @@
1
+ module Digitalocean
2
+ class Base
3
+ include EmmyHttp::Model
4
+ adapter EmmyHttp::Client::Adapter
5
+ url "https://api.digitalocean.com"
6
+ end
7
+
8
+ class Account < Base
9
+ # Get User Information
10
+ get '/v2/account', as: 'info'
11
+ # SSH Keys
12
+ class Keys < Base
13
+ # List all Keys
14
+ get '/v2/account/keys', as: 'all'
15
+ # Create a new Key
16
+ post '/v2/account/keys', as: 'new'
17
+ # Retrieve an existing Key
18
+ get '/v2/account/keys/{/id}', as: 'retrieve'
19
+ # Update a Key
20
+ put '/v2/account/keys/{/id}', as: 'update'
21
+ # Destroy a Key
22
+ delete '/v2/account/keys/{/id}', as: 'destroy'
23
+ end
24
+ end
25
+
26
+ class Actions < Base
27
+ # List all Actions
28
+ get '/v2/actions', as: 'all'
29
+ # Retrieve an existing Action
30
+ get '/v2/actions/{/id}', as: 'retrieve'
31
+ end
32
+
33
+ class Domains < Base
34
+ # List all Domains
35
+ get '/v2/domains', as: 'all'
36
+ # Create a new Domain
37
+ post '/v2/domains', as: 'new'
38
+ # Retrieve an existing Domain
39
+ get '/v2/domains/{/name}', as: 'retrieve'
40
+ # Delete a Domain
41
+ delete '/v2/domains/{/name}', as: 'delete'
42
+
43
+ class Records < Base
44
+ # List all Domain Records
45
+ get '/v2/domains/{/name}/records', as: 'all'
46
+ # Create a new Domain Record
47
+ post '/v2/domains/{/name}/records', as: 'new'
48
+ # Retrieve an existing Domain Record
49
+ get '/v2/domains/{/name}/records/{/record}', as: 'retrieve'
50
+ # Update a Domain Record
51
+ put '/v2/domains/{/name}/records/{/record}', as: 'update'
52
+ # Delete a Domain Record
53
+ delete '/v2/domains/{/name}/records/{/record}', as: 'delete'
54
+ end
55
+ end
56
+
57
+ class Droplets < Base
58
+ # Create a new Droplet
59
+ post '/v2/droplets', as: 'new'
60
+ # Retrieve an existing Droplet by id
61
+ get '/v2/droplets/{/id}', as: 'show'
62
+ # List all Droplets
63
+ get '/v2/droplets', as: 'all'
64
+ # List all available Kernels for a Droplet
65
+ get '/v2/droplets/{/id}/kernels', as: 'kernels'
66
+ # List snapshots for a Droplet
67
+ get '/v2/droplets/{/id}/snapshots', as: 'snapshots'
68
+ # List backups for a Droplet
69
+ get '/v2/droplets/{/id}/backups', as: 'backups'
70
+ # List actions for a Droplet
71
+ get '/v2/droplets/{/id}/actions', as: 'actions'
72
+ # Delete a Droplet
73
+ delete '/v2/droplets/{/id}', as: 'delete'
74
+ # List Neighbors for a Droplet
75
+ get '/v2/droplets/{/id}/neighbors', as: 'neighbors'
76
+ # List all Droplet Neighbors
77
+ get '/v2/reports/droplet_neighbors', as: 'droplet_neightbors'
78
+ # List Droplet Upgrades
79
+ get '/v2/droplet_upgrades', as: 'droplet_upgrades'
80
+ # Execute an Action
81
+ post '/v2/droplets/{/id}/actions', as: 'execute_action'
82
+ # Retrive a Droplet Action
83
+ post '/v2/droplets/{/id}/actions/{/action}', as: 'retrieve_action'
84
+ end
85
+
86
+ class Images < Base
87
+ # List all images
88
+ get '/v2/images', as: 'all'
89
+ # List all Distribution Images
90
+ get '/v2/images?type=distribution', as: 'distribution_images'
91
+ # List all Application Images
92
+ get '/v2/images?type=application', as: 'application_images'
93
+ # List a User's Images
94
+ get '/v2/images?private=true', as: 'private_images'
95
+ # Retrieve an existing Image by id
96
+ get '/v2/images/{/id}', as: 'retrieve'
97
+ # Retrieve on existing Image by slug
98
+ get '/v2/images/{/slug}', as: 'retrieve_by_slug'
99
+ # List all actions for an image
100
+ get '/v2/images/{/id}/actions', as: 'actions'
101
+ # Update an Image
102
+ put '/v2/images/{/id}', as: 'update'
103
+ # Delete an Image
104
+ delete '/v2/images/{/id}', as: 'delete'
105
+ # Execute an Action
106
+ post '/v2/images/{/id}/actions', as: 'execute_action'
107
+ # Retrieve an existing Image Action
108
+ get '/v2/images/{/id}/actions/{/image}', as: 'retrieve_action'
109
+ end
110
+
111
+ class Regions < Base
112
+ # List all Regions
113
+ get '/v2/regions', as: 'all'
114
+ end
115
+
116
+ class Sizes < Base
117
+ # List all Sizes
118
+ get '/v2/sizes', as: 'all'
119
+ end
120
+ end
@@ -0,0 +1,3 @@
1
+ module Digitalocean
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-digitalocean
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - inre
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: emmy-machine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: emmy-http
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: emmy-http-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description:
84
+ email:
85
+ - inre.storm@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - em-digitalocean.gemspec
97
+ - lib/digitalocean.rb
98
+ - lib/digitalocean/api.rb
99
+ - lib/digitalocean/concerns/class_methods.rb
100
+ - lib/digitalocean/errors.rb
101
+ - lib/digitalocean/operation.rb
102
+ - lib/digitalocean/requests.rb
103
+ - lib/digitalocean/version.rb
104
+ homepage:
105
+ licenses: []
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.3
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: DigitalOcean API EventMachine-based
127
+ test_files: []