pearl 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d6467e461a96b75d2007d98c2d649df5cc46a653
4
+ data.tar.gz: e3159cde72e0b07c87275980bb02a0e50eec0784
5
+ SHA512:
6
+ metadata.gz: 1907733bf543d07eef72e81f8f211e002d6d929fab70b7477db52bcfd247432c5271e86e337e95026c4df4b87ee22d4c0c3ab21aa7c416c777cd0dbb09344b06
7
+ data.tar.gz: 8e3751f899dc90f914c1e44229c8d7ed5a1c6e4d92663a657f957aa57e195f57da4127b0cd5840549d28e2eabd3ee7c18f8184876da6eb655f5f6e0b5dc47c67
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pearl.gemspec
4
+ gemspec
5
+
6
+ gem 'rake', group: [:development, :test]
7
+
8
+ # Development dependencies
9
+ group :development do
10
+ gem 'yard'
11
+ end
12
+
13
+ group :test do
14
+ gem 'minitest'
15
+ gem 'minitest-wscolor' if RUBY_VERSION >= '1.9.3'
16
+ gem 'mocha', require: 'mocha/setup'
17
+ gem 'simplecov', require: false
18
+ gem 'turn'
19
+ gem 'vcr'
20
+ gem 'webmock', require: 'webmock/minitest'
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Manish Valechha
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # Pearl
2
+
3
+ Pearl is a command line interface to DigitlOcean's API.
4
+
5
+ ## Setup
6
+
7
+ Run the following command to install
8
+
9
+ $ gem install pearl
10
+
11
+ Add your client id and api key as enviroment variables
12
+
13
+ ENV['DIGITAL_OCEAN_CLIENT_ID']
14
+ ENV['DIGITAL_OCEAN_API_KEY']
15
+
16
+ ## Usage
17
+
18
+ ### Droplets
19
+
20
+ To see all your droplets
21
+
22
+ $ pearl droplets
23
+
24
+ To view a droplet
25
+
26
+ $ pearl droplet -d <droplet id>
27
+
28
+ To create a droplet
29
+
30
+ $ pearl droplet add 'name' --size <size id> --image <image id> --region <region id>
31
+
32
+ or
33
+
34
+ $ pearl droplet add 'name' -s <size id> -i <image id> -r <region id>
35
+
36
+ Reboot a droplet
37
+
38
+ $ pearl droplet reboot -d <droplet id>
39
+
40
+ Power cycle droplet
41
+
42
+ $ pearl droplet power cycle -d <droplet id>
43
+
44
+ Shutdown droplet
45
+
46
+ $ pearl droplet shutdown -d <droplet id>
47
+
48
+ Power Off droplet
49
+
50
+ $ pearl droplet power off -d <droplet id>
51
+
52
+ Power On droplet
53
+
54
+ $ pearl droplet power_on -d <droplet id>
55
+
56
+ Reset root password
57
+
58
+ $ pearl droplet password_reset -d <droplet id>
59
+
60
+ Resize droplet
61
+
62
+ $ pearl droplet resize -d <droplet id> -s <size id>
63
+
64
+ Take a snapshot
65
+
66
+ $ pearl droplet snapshot 'snapshot_name' -d <droplet id>
67
+
68
+ Restore droplet
69
+
70
+ $ pearl droplet restore -d <droplet id> -i <image id>
71
+
72
+ Rebuild droplet
73
+
74
+ $ pearl droplet rebuild -d <droplet id> -i <image id>
75
+
76
+ Enable automatic backups
77
+
78
+ $ pearl droplet enable backups -d <droplet id>
79
+
80
+ Disable automatic backups
81
+
82
+ $ pearl droplet disable backups -d <droplet id>
83
+
84
+ Destroy droplet
85
+
86
+ $ pearl droplet destroy -d <droplet id>
87
+
88
+ ### Regions
89
+
90
+ Display regions
91
+
92
+ $ pearl regions
93
+
94
+ ### Sizes
95
+
96
+ Display regions
97
+
98
+ $ pearl sizes
99
+
100
+ ### Images
101
+
102
+ Display all images
103
+
104
+ $ pearl images
105
+
106
+ To display your images
107
+
108
+ $ pearl images --filter my
109
+
110
+ To display global images (default)
111
+
112
+ $ pearl images --filter global
113
+
114
+ View a single image
115
+
116
+ $ pearl image -i <image id>
117
+
118
+ To destroy an image
119
+
120
+ $ pearl image destroy -i <image id>
121
+
122
+ ## TODO
123
+
124
+ * Format output instead of just printing the json response.
125
+ * Add SSH resource.
126
+
127
+ ## Contributing
128
+
129
+ 1. Fork it
130
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
131
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
132
+ 4. Push to the branch (`git push origin my-new-feature`)
133
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'test'
7
+ t.pattern = 'test/**/*_test.rb'
8
+ end
9
+ task default: :test
10
+
11
+ begin
12
+ require 'yard'
13
+ YARD::Rake::YardocTask.new(:doc) do |task|
14
+ task.files = ['READEME.md', 'LICENSE.txt', 'lib/**/*.rb']
15
+ task.options = [
16
+ '--output-dir', 'doc',
17
+ '--markup', 'markdown',
18
+ ]
19
+ end
20
+ rescue LoadError
21
+ end
data/bin/pearl ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # resolve bin path, ignoring symlinks
5
+ require "pathname"
6
+ bin_file = Pathname.new(__FILE__).realpath
7
+
8
+ # add self to libpath
9
+ $:.unshift File.expand_path("../../lib", bin_file)
10
+
11
+ require 'pearl/cli'
12
+ Pearl::CLI.execute(*ARGV)
data/lib/pearl/cli.rb ADDED
@@ -0,0 +1,215 @@
1
+ require "optparse"
2
+
3
+ require 'pearl'
4
+
5
+ module Pearl
6
+ module CLI
7
+ # Parse command line arguments
8
+ def self.execute(*args)
9
+ droplet = nil
10
+ image = nil
11
+ region = nil
12
+ size = nil
13
+
14
+ images_filter = nil
15
+
16
+ opts = OptionParser.new do |opts|
17
+ opts.banner = "Usage: pearl [resource] [options]"
18
+
19
+ opts.on('-d', '--droplet [DROPLET ID]', 'Select the droplet with this id') do |d|
20
+ droplet = d
21
+ end
22
+
23
+ opts.on('-f', '--filter', 'Display either your images or global images') do |filter|
24
+ images_filter = filter
25
+ end
26
+
27
+ opts.on('-h', '--help', 'Display this message') do
28
+ puts opts
29
+ exit
30
+ end
31
+
32
+ opts.on('-i', '--image [IMAGE ID]', 'Set the image for the droplet') do |i|
33
+ image = i
34
+ end
35
+
36
+ opts.on('-r', '--region [REGION ID]', 'Set the region for the droplet') do |r|
37
+ region = r
38
+ end
39
+
40
+ opts.on('-s', '--size [SIZE ID]', 'Set the size forthe droplet') do |s|
41
+ size = s
42
+ end
43
+
44
+ opts.on('-v', '--version', 'Display version') do
45
+ puts Pearl::VERSION
46
+ exit
47
+ end
48
+
49
+ begin
50
+ opts.parse!(args)
51
+
52
+ if $stdin.tty? && args[0] != '-'
53
+
54
+ # Print help when args is empty
55
+ if args.empty?
56
+ puts opts
57
+ exit
58
+ end
59
+
60
+ # Join command(s) to make it easier to catch using regex
61
+ command = args.join(' ')
62
+
63
+ case command.to_s
64
+ when /\Adroplets\z/i
65
+ Pearl.droplets
66
+ exit
67
+ when /\Adroplet\z/i
68
+ droplet_id = droplet.to_i
69
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
70
+
71
+ Pearl.droplet(droplet_id)
72
+ exit
73
+ when /\Adroplet add \w{3,}\z/i
74
+ image_id = image.to_i
75
+ raise 'Error: Invalid image id.' if image_id == 0 || !image_id.is_a?(Fixnum)
76
+
77
+ region_id = region.to_i
78
+ raise 'Error: Invalid region id.' if region_id == 0 || !region_id.is_a?(Fixnum)
79
+
80
+ size_id = size.to_i
81
+ raise 'Error: Invalid size id.' if size_id == 0 || !size_id.is_a?(Fixnum)
82
+
83
+ name = command.split(' ', 3)[2]
84
+ raise 'Error: Invalid droplet name.' if name.nil? || name.length <= 0
85
+
86
+ options = { name: name, image_id: image_id, region_id: region_id, size_id: size_id }
87
+
88
+ Pearl.create_droplet(options)
89
+ exit
90
+ when /\Adroplet reboot\z/i
91
+ droplet_id = droplet.to_i
92
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
93
+
94
+ Pearl.reboot(droplet_id)
95
+ exit
96
+ when /\Adroplet power cycle\z/i
97
+ droplet_id = droplet.to_i
98
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
99
+
100
+ Pearl.power_cycle(droplet_id)
101
+ exit
102
+ when /\Adroplet shutdown\z/i
103
+ droplet_id = droplet.to_i
104
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
105
+
106
+ Pearl.shutdown(droplet_id)
107
+ exit
108
+ when /\Adroplet power off\z/i
109
+ droplet_id = droplet.to_i
110
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
111
+
112
+ Pearl.power_off(droplet_id)
113
+ exit
114
+ when /\Adroplet power on\z/i
115
+ droplet_id = droplet.to_i
116
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
117
+
118
+ Pearl.power_on(droplet_id)
119
+ exit
120
+ when /\Adroplet password reset\z/i
121
+ droplet_id = droplet.to_i
122
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
123
+
124
+ Pearl.password_reset(droplet_id)
125
+ exit
126
+ when /\Adroplet resize\z/i
127
+ droplet_id = droplet.to_i
128
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
129
+
130
+ size_id = size.to_i
131
+ raise 'Error: Invalid size id.' if size_id == 0 || !size_id.is_a?(Fixnum)
132
+
133
+ Pearl.resize(droplet_id, size_id)
134
+ exit
135
+ when /\Adroplet snapshot \w{3,}\z/i
136
+ droplet_id = droplet.to_i
137
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
138
+
139
+ name = command.split(' ', 2)
140
+ raise 'Error: Invalid snapshot name.' if name.nil? || name.length <= 0
141
+
142
+ Pearl.snapshot(droplet_id, name)
143
+ exit
144
+ when /\Adroplet restore\z/i
145
+ droplet_id = droplet.to_i
146
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
147
+
148
+ image_id = image.to_i
149
+ raise 'Error: Invalid size id.' if image_id == 0 || !image_id.is_a?(Fixnum)
150
+
151
+ Pearl.restore(droplet_id, image_id)
152
+ exit
153
+ when /\Adroplet rebuild\z/i
154
+ droplet_id = droplet.to_i
155
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
156
+
157
+ image_id = image.to_i
158
+ raise 'Error: Invalid size id.' if image_id == 0 || !image_id.is_a?(Fixnum)
159
+
160
+ Pearl.rebuild(droplet_id, image_id)
161
+ exit
162
+ when /\Adroplet enable backups\z/i
163
+ droplet_id = droplet.to_i
164
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
165
+
166
+ Pearl.enable_backups(droplet_id)
167
+ exit
168
+ when /\Adroplet disable backups\z/i
169
+ droplet_id = droplet.to_i
170
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
171
+
172
+ Pearl.disable_backups(droplet_id)
173
+ exit
174
+ when /\Adroplet (destroy|delete)\z/i
175
+ droplet_id = droplet.to_i
176
+ raise 'Error: Invalid droplet id.' if droplet_id == 0 || !droplet_id.is_a?(Fixnum)
177
+
178
+ Pearl.destroy_droplet(droplet_id)
179
+ exit
180
+ when /\Aimages\z/i
181
+ Pearl.images(images_filter)
182
+ exit
183
+ when /\Aimage\z/i
184
+ image_id = image.to_i
185
+ raise 'Error: Invalid image id.' if image_id == 0 || !image_id.is_a?(Fixnum)
186
+
187
+ Pearl.image(image_id)
188
+ exit
189
+ when /\Aimage (destroy|delete)\z/i
190
+ image_id = image.to_i
191
+ raise 'Error: Invalid image id.' if image_id == 0 || !image_id.is_a?(Fixnum)
192
+
193
+ Pearl.destroy_image(image_id)
194
+ exit
195
+ when /\Aregions\z/i
196
+ Pearl.regions
197
+ exit
198
+ when /\Asizes\z/i
199
+ Pearl.sizes
200
+ exit
201
+ else
202
+ puts "Error: '#{command}' is an invalid command."
203
+ exit
204
+ end
205
+ end
206
+ rescue Interrupt
207
+ error("Command cancelled.")
208
+ rescue => error
209
+ warn error
210
+ puts opts
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,79 @@
1
+ module Pearl
2
+ class Client
3
+
4
+ module Droplets
5
+ def droplets
6
+ puts request("droplets").body
7
+ end
8
+
9
+ def droplet(id)
10
+ puts request("droplets/#{id}").body
11
+ end
12
+
13
+ def create_droplet(options = {})
14
+ params = { name: options[:name],
15
+ size_id: options[:size_id],
16
+ image_id: options[:image_id],
17
+ region_id: options[:region_id]
18
+ }
19
+ puts request("droplets/new", params).body
20
+ end
21
+
22
+ def reboot(id)
23
+ puts request("droplets/#{id}/reboot").body
24
+ end
25
+
26
+ def power_cycle(id)
27
+ puts request("droplets/#{id}/power_cycle").body
28
+ end
29
+
30
+ def shutdown(id)
31
+ puts request("droplets/#{id}/shutdown").body
32
+ end
33
+
34
+ def power_off(id)
35
+ puts request("droplets/#{id}/power_off").body
36
+ end
37
+
38
+ def power_on(id)
39
+ puts request("droplets/#{id}/power_on").body
40
+ end
41
+
42
+ def password_reset(id)
43
+ puts request("droplets/#{id}/password_reset").body
44
+ end
45
+
46
+ def resize(id, size_id)
47
+ params = { size_id: size_id }
48
+ puts request("droplets/#{id}/resize", params).body
49
+ end
50
+
51
+ def snapshot(id, name)
52
+ params = { name: name }
53
+ puts request("droplets/#{id}/snapshot", params).body
54
+ end
55
+
56
+ def restore(id, image_id)
57
+ params = { image_id: image_id }
58
+ puts request("droplets/#{id}/restore", params).body
59
+ end
60
+
61
+ def rebuild(id, image_id)
62
+ params = { image_id: image_id }
63
+ puts request("droplets/#{id}/rebuild", params).body
64
+ end
65
+
66
+ def enable_backups(id)
67
+ puts request("droplets/#{id}/enable_backups").body
68
+ end
69
+
70
+ def disable_backups(id)
71
+ puts request("droplets/#{id}/disable_backups").body
72
+ end
73
+
74
+ def destroy_droplet(id)
75
+ puts request("droplets/#{id}/destroy").body
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,24 @@
1
+ module Pearl
2
+ class Client
3
+
4
+ module Images
5
+ # TODO: image filters
6
+ def images(filter)
7
+ if filter === /\A(my|global)\z/
8
+ params = { filter: name }
9
+ puts request("images", params).body
10
+ else
11
+ puts request("images").body
12
+ end
13
+ end
14
+
15
+ def image(id)
16
+ puts request("images/#{id}").body
17
+ end
18
+
19
+ def destroy_image(id)
20
+ puts request("images/#{id}").body
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ module Pearl
2
+ class Client
3
+
4
+ module Regions
5
+ def regions
6
+ puts request("regions").body
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Pearl
2
+ class Client
3
+
4
+ module Sizes
5
+ def sizes
6
+ puts request("sizes").body
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ require 'pearl/http'
2
+
3
+ module Pearl
4
+ class Client
5
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each { |f| require f }
6
+
7
+ include Droplets
8
+ include Images
9
+ include Regions
10
+ include Sizes
11
+
12
+ attr_reader :client_id
13
+ attr_reader :api_key
14
+ attr_reader :api_host
15
+
16
+ def initialize(options = {})
17
+ @client_id = options[:client_id] || ENV['DIGITAL_OCEAN_CLIENT_ID']
18
+ @api_key = options[:api_key] || ENV['DIGITAL_OCEAN_API_KEY']
19
+ @api_host = options[:api_host] || 'api.digitalocean.com'
20
+
21
+ extend Pearl::HTTP
22
+
23
+ raise 'Error: Invalid client id.' if @client_id.nil?
24
+ raise 'Error: Invalid api key.' if @api_key.nil?
25
+ end
26
+
27
+ def base_url
28
+ "https://#{@api_host}/"
29
+ end
30
+
31
+ def authenticated?
32
+ @client_id != nil && @api_key != nil
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ module Pearl
2
+
3
+ # Standard Pearl Error for rescuing form all Peal errors
4
+ class Error < StandardError; end
5
+
6
+ # Raised when Peal returns a 400 HTTP status code
7
+ class BadRequest < Error; end
8
+
9
+ # Raised when Peal returns a 401 HTTP status code
10
+ class Unauthorized < Error; end
11
+
12
+ # Raised when Peal returns a 403 HTTP status code
13
+ class Forbidden < Error; end
14
+
15
+ # Raised when Peal returns a 404 HTTP status code
16
+ class NotFound < Error; end
17
+
18
+ # Raised when Peal returns a 406 HTTP status code
19
+ class NotAcceptable < Error; end
20
+
21
+ # Raised when Peal returns a 422 HTTP status code
22
+ class UnprocessableEntity < Error; end
23
+
24
+ # Raised when Peal returns a 500 HTTP status code
25
+ class InternalServerError < Error; end
26
+
27
+ # Raised when Peal returns a 501 HTTP status code
28
+ class NotImplemented < Error; end
29
+
30
+ # Raised when Peal returns a 502 HTTP status code
31
+ class BadGateway < Error; end
32
+
33
+ # Raised when Peal returns a 503 HTTP status code
34
+ class ServiceUnavailable < Error; end
35
+ end
data/lib/pearl/http.rb ADDED
@@ -0,0 +1,51 @@
1
+ module Pearl
2
+ module HTTP
3
+ require 'net/https'
4
+ require 'uri'
5
+
6
+ private
7
+ def http
8
+ return @http if @http
9
+
10
+ uri = URI.parse(self.base_url)
11
+ @http = Net::HTTP.new(uri.host, uri.port)
12
+
13
+ @http.use_ssl = true
14
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
15
+
16
+ @http
17
+ end
18
+
19
+ def request(path, params = nil)
20
+ uri = URI.parse("#{self.base_url}#{path}")
21
+
22
+ auth_params = { client_id: self.client_id, api_key: self.api_key }
23
+
24
+ if params.nil? || params.empty?
25
+ params = auth_params
26
+ else
27
+ params.merge!(auth_params)
28
+ end
29
+
30
+ uri.query = URI.encode_www_form(params)
31
+
32
+ request = Net::HTTP::Get.new(uri.request_uri)
33
+
34
+ request['Content-Type'] = 'application/json'
35
+
36
+ response = http.request(request)
37
+
38
+ Response.new(response)
39
+ end
40
+
41
+ class Response
42
+ attr_accessor :code
43
+ attr_accessor :body
44
+
45
+ def initialize(response)
46
+ @code = response.code
47
+ @body = response.body
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module Pearl
2
+ VERSION = "0.0.3"
3
+ end
data/lib/pearl.rb ADDED
@@ -0,0 +1,26 @@
1
+ require "pearl/version"
2
+ require "pearl/error"
3
+ require "pearl/client"
4
+
5
+ module Pearl
6
+ class << self
7
+
8
+ # Alias for Pearl::Client.new
9
+ #
10
+ # @return [Peal::Client]
11
+ def new(options = {})
12
+ Client.new(options)
13
+ end
14
+
15
+ # Delegate to Pearl::Client
16
+ def method_missing(method, *args, &block)
17
+ return super unless new.respond_to?(method)
18
+ new.send(method, *args, &block)
19
+ end
20
+
21
+ # Forward respond_to? to Pearl::Client
22
+ def respond_to?(method, include_private = false)
23
+ new.respond_to?(method, include_private) || super(method, include_private)
24
+ end
25
+ end
26
+ end
data/pearl.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pearl/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pearl"
8
+ spec.version = Pearl::VERSION
9
+ spec.authors = ["Manish Valechha"]
10
+ spec.email = ["manishval@hotmail.com"]
11
+ spec.description = "Command line interface for DigitalOcean's API"
12
+ spec.summary = spec.description
13
+ spec.homepage = "https://github.com/manishval/pearl"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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.executables = "pearl"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class DropletsTest < Pearl::TestCase
4
+ def test_droplets
5
+ end
6
+
7
+ def test_droplet
8
+ end
9
+
10
+ def test_create_droplet
11
+ end
12
+
13
+ def test_reboot
14
+ end
15
+
16
+ def test_power_cycle
17
+ end
18
+
19
+ def test_shutdown
20
+ end
21
+
22
+ def test_power_off
23
+ end
24
+
25
+ def test_power_on
26
+ end
27
+
28
+ def test_password_reset
29
+ end
30
+
31
+ def test_resize
32
+ end
33
+
34
+ def test_snapshot
35
+ end
36
+
37
+ def test_restore
38
+ end
39
+
40
+ def test_rebuild
41
+ end
42
+
43
+ def test_enable_backups
44
+ end
45
+
46
+ def test_disable_backups
47
+ end
48
+
49
+ def test_destroy_droplet
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+
3
+ class ImagesTest < Pearl::TestCase
4
+ def test_images
5
+ end
6
+
7
+ def test_image
8
+ end
9
+
10
+ def test_detroy_image
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ require 'test_helper'
2
+
3
+ class RegionsTest < Pearl::TestCase
4
+ def test_regions
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'test_helper'
2
+
3
+ class SizesTest < Pearl::TestCase
4
+ def test_sizes
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class ClientTest < Pearl::TestCase
4
+ def test_initialization
5
+ client = Pearl::Client.new(client_id: 'qwerty')
6
+ assert_equal 'qwerty', client.client_id
7
+
8
+ client = Pearl::Client.new(api_key: 'ytrewq')
9
+ assert_equal 'ytrewq', client.api_key
10
+
11
+ client = Pearl::Client.new(client_id: 'qwerty', api_key: 'ytrewq')
12
+ assert_equal true, client.authenticated?
13
+
14
+ client = Pearl::Client.new
15
+ refute client.authenticated?
16
+ end
17
+
18
+ def test_base_url
19
+ client = Pearl::Client.new
20
+ assert_equal 'https://api.digitalocean.com/', client.base_url
21
+
22
+ client = Pearl::Client.new(api_host: 'www.example.com')
23
+ assert_equal 'https://www.example.com/', client.base_url
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class PearlTest < Pearl::TestCase
4
+ def test_respond_to
5
+ assert Pearl.respond_to?(:new, true)
6
+ end
7
+
8
+ def test_new
9
+ assert_equal Pearl.new.class, Pearl::Client
10
+ end
11
+
12
+ def test_method_missing
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module ClientMacros
2
+ def local_client
3
+ client = Pearl::Client.new(client_id: 'qwerty',
4
+ api_key: 'qwerty12345')
5
+ end
6
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require :test
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+
8
+ require 'minitest/autorun'
9
+ require 'pearl'
10
+
11
+ # Support files
12
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/support/*.rb"].each do |file|
13
+ require file
14
+ end
15
+
16
+ # VCR
17
+ VCR.configure do |c|
18
+ c.cassette_library_dir = 'test/cassettes'
19
+ c.hook_into :webmock
20
+ end
21
+
22
+ class Pearl::TestCase < MiniTest::Unit::TestCase
23
+ include ::ClientMacros
24
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pearl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Manish Valechha
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Command line interface for DigitalOcean's API
42
+ email:
43
+ - manishval@hotmail.com
44
+ executables:
45
+ - pearl
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/pearl
55
+ - lib/pearl.rb
56
+ - lib/pearl/cli.rb
57
+ - lib/pearl/client.rb
58
+ - lib/pearl/client/droplets.rb
59
+ - lib/pearl/client/images.rb
60
+ - lib/pearl/client/regions.rb
61
+ - lib/pearl/client/sizes.rb
62
+ - lib/pearl/error.rb
63
+ - lib/pearl/http.rb
64
+ - lib/pearl/version.rb
65
+ - pearl.gemspec
66
+ - test/pearl/client/droplets_test.rb
67
+ - test/pearl/client/images_test.rb
68
+ - test/pearl/client/regions_test.rb
69
+ - test/pearl/client/sizes_test.rb
70
+ - test/pearl/client_test.rb
71
+ - test/pearl_test.rb
72
+ - test/support/client_macros.rb
73
+ - test/test_helper.rb
74
+ homepage: https://github.com/manishval/pearl
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.0.0
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Command line interface for DigitalOcean's API
98
+ test_files:
99
+ - test/pearl/client/droplets_test.rb
100
+ - test/pearl/client/images_test.rb
101
+ - test/pearl/client/regions_test.rb
102
+ - test/pearl/client/sizes_test.rb
103
+ - test/pearl/client_test.rb
104
+ - test/pearl_test.rb
105
+ - test/support/client_macros.rb
106
+ - test/test_helper.rb
107
+ has_rdoc: