puddle 0.1.0 → 0.2.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.
- checksums.yaml +13 -5
- data/.travis.yml +9 -1
- data/README.md +2 -0
- data/lib/puddle.rb +25 -51
- data/lib/puddle/cli/base_cli.rb +20 -1
- data/lib/puddle/cli/main.rb +2 -27
- data/lib/puddle/http_adapter.rb +70 -0
- data/lib/puddle/resources.rb +5 -0
- data/lib/puddle/resources/show_account.rb +30 -0
- data/lib/puddle/version.rb +1 -1
- data/puddle.gemspec +2 -1
- metadata +28 -24
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZWIwMmI5NGQ1ODQxZjdmY2FmOWU3YjFjM2EzYzY0NWJiMzFiZmJiMg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDcwYWQ3MWRjZWZjZDdhM2EyZWQ0YWZjODA5NjI0MmM5OTAxNTQ1OQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTgxY2YyMzA0YjBkNmEzNmFhNWUzMDE1NWM4NDAxMGM2YTlhMmVjZjhjMzAz
|
10
|
+
NTc3MzIyYzgyZWU3ZTQ2NTIyODEwYmM5NmQ1NDU3ODkzOWU4YzAyMDI5NDNl
|
11
|
+
ZDZhNGRlMmY5M2RiNWNhNjAyNzA4MTUwYjIxZTQwNTU2NjhkMmU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODI4YzY1OWU4NzkwZWRlNWYxNGVhMGM2ZTNiYjA3ODExMzFlZDhiODZjZGI5
|
14
|
+
MDkzNDAyMjgwZjg2ZTM5YzZjNmM2MzEzNmZhMTMyM2E2Mjc5NGQxNWRhNjg5
|
15
|
+
YmZmODRkYTMzYzViMjdjMWM4Yzg2NzAzZmQyOTQ3YmZlYTJhZTA=
|
data/.travis.yml
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
|
3
|
+
- 2.2.2
|
4
4
|
before_install: gem install bundler -v 1.10.4
|
5
5
|
sudo: false
|
6
6
|
addons:
|
7
7
|
code_climate:
|
8
8
|
repo_token: 06a46ea5905e034f5b40db072d078c2208b89a15463f663842ba7019af7ae5cc
|
9
|
+
deploy:
|
10
|
+
provider: rubygems
|
11
|
+
api_key:
|
12
|
+
secure: fC99W7XARIsWfbFLWmRL+0W3t0s0wshZWrMMYiK6+Xmy+DVmaKevTmyCpfrU7l9fpcJawnXwGFNYQQ+qsMHbJp2DYmYOvVbugrApQtoD7THYYOmtOMYj45B+rDX/TvxBbAjggxPUpGBg4PhillqeDU1jlNgtSVTJdb8GM5m2koI=
|
13
|
+
gem: puddle
|
14
|
+
on:
|
15
|
+
tags: true
|
16
|
+
repo: rsb/puddle
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
[](https://codeclimate.com/github/rsb/puddle)
|
2
|
+
[](https://codeclimate.com/github/rsb/puddle/coverage)
|
2
3
|
[](https://travis-ci.org/rsb/puddle)
|
4
|
+
[](http://badge.fury.io/rb/puddle)
|
3
5
|
# Puddle
|
4
6
|
Puddle can be used in two different ways. Firstly, it is a command line utility
|
5
7
|
that simplifies creating, destroying or modifying digital ocean droplets, ssh
|
data/lib/puddle.rb
CHANGED
@@ -1,66 +1,40 @@
|
|
1
|
-
require 'json'
|
2
1
|
require 'puddle/version'
|
3
|
-
require
|
4
|
-
|
2
|
+
require "puddle/cli"
|
3
|
+
require "puddle/http_adapter"
|
4
|
+
require "puddle/resources"
|
5
|
+
require 'pp'
|
5
6
|
module Puddle
|
6
|
-
DO_API_BASE = 'https://api.digitalocean.com'
|
7
|
-
DO_API_VERSION = 'v2'
|
8
|
-
|
9
7
|
class << self
|
10
|
-
attr_accessor :api_token
|
11
|
-
def digital_ocean_api_url
|
12
|
-
"#{DO_API_BASE}/#{DO_API_VERSION}"
|
13
|
-
end
|
14
8
|
|
15
|
-
def
|
16
|
-
'
|
9
|
+
def validate_token(settings = {})
|
10
|
+
token = settings['token'] || ENV['DO_API_TOKEN']
|
11
|
+
fail 'api token is required but missing' unless token
|
12
|
+
token
|
17
13
|
end
|
18
14
|
|
19
|
-
def
|
20
|
-
|
15
|
+
def create_adapter(token, settings = {})
|
16
|
+
class_constant = settings['http_adapter_class'] || HttpAdapter
|
17
|
+
class_constant.new(token, settings)
|
21
18
|
end
|
22
19
|
|
23
|
-
def
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def user_agent_header
|
28
|
-
'Puddle'
|
29
|
-
end
|
20
|
+
def load_resource(name)
|
21
|
+
class_name = name.to_s.split(/_/).map{|word| word.capitalize}.join('')
|
30
22
|
|
31
|
-
|
32
|
-
'gzip, deflate'
|
23
|
+
Puddle::Resources.const_get(class_name)
|
33
24
|
end
|
34
25
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
26
|
+
def digital_ocean(name, settings = {})
|
27
|
+
results = {}
|
28
|
+
begin
|
29
|
+
token = validate_token(settings)
|
30
|
+
adapter = create_adapter(token, settings)
|
31
|
+
resource = load_resource(name).new(adapter, settings)
|
32
|
+
results[:content] = resource.execute
|
33
|
+
rescue Exception => e
|
34
|
+
results[:error] = e
|
35
|
+
end
|
43
36
|
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def account
|
48
|
-
result = digital_ocean(:get, 'account')
|
49
|
-
JSON.parse(result)
|
50
|
-
end
|
51
|
-
|
52
|
-
def digital_ocean(method, endpoint, options = {})
|
53
|
-
headers = build_headers(options[:headers] || {})
|
54
|
-
timeout = options[:timeout] || 10
|
55
|
-
url = "#{digital_ocean_api_url}/#{endpoint}"
|
56
|
-
RestClient::Request.execute(
|
57
|
-
method: method,
|
58
|
-
url: url,
|
59
|
-
headers: headers,
|
60
|
-
timeout: timeout
|
61
|
-
)
|
37
|
+
return results
|
62
38
|
end
|
63
39
|
end
|
64
|
-
|
65
|
-
require "puddle/cli"
|
66
40
|
end
|
data/lib/puddle/cli/base_cli.rb
CHANGED
@@ -4,14 +4,33 @@ module Puddle
|
|
4
4
|
module Cli
|
5
5
|
class BaseCli < Thor
|
6
6
|
class_option :token
|
7
|
-
class_option :
|
7
|
+
class_option :format, type: :string, default: 'cli'
|
8
8
|
|
9
9
|
map %w[--version -v] => :__display_version
|
10
10
|
|
11
|
+
def self.exit_on_failure?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
11
15
|
desc "--version", "prints the current version"
|
12
16
|
def __display_version
|
13
17
|
$stdout.puts Puddle::VERSION
|
14
18
|
end
|
19
|
+
|
20
|
+
no_commands do
|
21
|
+
def print_results(results)
|
22
|
+
if results[:error]
|
23
|
+
str = if results[:error].respond_to?(:message)
|
24
|
+
results[:error].message
|
25
|
+
else
|
26
|
+
results[:error].to_s
|
27
|
+
end
|
28
|
+
raise Thor::Error, str
|
29
|
+
end
|
30
|
+
|
31
|
+
$stdout.puts results[:content]
|
32
|
+
end
|
33
|
+
end
|
15
34
|
end
|
16
35
|
end
|
17
36
|
end
|
data/lib/puddle/cli/main.rb
CHANGED
@@ -3,33 +3,8 @@ module Puddle
|
|
3
3
|
class Main < BaseCli
|
4
4
|
desc 'account', 'show account details'
|
5
5
|
def account
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
begin
|
10
|
-
result = Puddle.account
|
11
|
-
rescue RestClient::Unauthorized => e
|
12
|
-
$stderr.puts "#{e.message} invalid token"
|
13
|
-
exit 1
|
14
|
-
end
|
15
|
-
|
16
|
-
unless result.has_key?('account')
|
17
|
-
$stderr.puts 'no account found'
|
18
|
-
exit 1
|
19
|
-
end
|
20
|
-
|
21
|
-
result = result['account']
|
22
|
-
if options.json?
|
23
|
-
puts result.to_json
|
24
|
-
return
|
25
|
-
end
|
26
|
-
|
27
|
-
data = ""
|
28
|
-
data << sprintf("droplet limit: %-s\n", result['droplet_limit'])
|
29
|
-
data << sprintf("email: %-s\n", result['email'])
|
30
|
-
data << sprintf("uuid: %-s\n", result['uuid'])
|
31
|
-
data << sprintf("email verified: %-s\n", result['email_verified'])
|
32
|
-
puts data
|
6
|
+
results = Puddle.digital_ocean(:show_account, options)
|
7
|
+
print_results(results)
|
33
8
|
end
|
34
9
|
end
|
35
10
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Puddle
|
5
|
+
class HttpAdapter
|
6
|
+
DO_API_BASE = 'https://api.digitalocean.com'
|
7
|
+
DO_API_VERSION = 'v2'
|
8
|
+
|
9
|
+
attr_reader :token, :headers, :timeout
|
10
|
+
|
11
|
+
def self.digital_ocean_api_url
|
12
|
+
"#{DO_API_BASE}/#{DO_API_VERSION}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.endpoint_url(endpoint)
|
16
|
+
"#{digital_ocean_api_url}/#{endpoint}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(api_token, options = {})
|
20
|
+
@token = api_token
|
21
|
+
@headers = build_headers(options[:headers] || {})
|
22
|
+
@timeout = options[:timeout] || 10
|
23
|
+
end
|
24
|
+
|
25
|
+
def content_type_header
|
26
|
+
'application/json'
|
27
|
+
end
|
28
|
+
|
29
|
+
def accept_header
|
30
|
+
'*/*; q=0.5, application/json'
|
31
|
+
end
|
32
|
+
|
33
|
+
def authorization_header
|
34
|
+
"Bearer #{token}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def user_agent_header
|
38
|
+
'Puddle'
|
39
|
+
end
|
40
|
+
|
41
|
+
def accept_encoding_header
|
42
|
+
'gzip, deflate'
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_headers(headers = {})
|
46
|
+
defaults = {
|
47
|
+
'Accept' => accept_header,
|
48
|
+
'Accept-Encoding' => accept_encoding_header,
|
49
|
+
'Authorization' => authorization_header,
|
50
|
+
'Content-Type' => content_type_header,
|
51
|
+
'User-Agent' => user_agent_header,
|
52
|
+
}
|
53
|
+
|
54
|
+
defaults.merge(headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
def api(method, endpoint, options = {})
|
58
|
+
headers = build_headers(options['headers'] || {})
|
59
|
+
result = RestClient::Request.execute(
|
60
|
+
method: method,
|
61
|
+
url: self.class.endpoint_url(endpoint),
|
62
|
+
headers: headers,
|
63
|
+
timeout: timeout
|
64
|
+
)
|
65
|
+
|
66
|
+
return result if options['format'] == 'json'
|
67
|
+
JSON.parse(result)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Puddle
|
2
|
+
module Resources
|
3
|
+
class ShowAccount
|
4
|
+
attr_reader :adapter, :options
|
5
|
+
|
6
|
+
def initialize(http_adapter, options = {})
|
7
|
+
@adapter = http_adapter
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
results = adapter.api(:get, 'account', options)
|
13
|
+
return results if options['format'] == 'json'
|
14
|
+
|
15
|
+
cli_format(results)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cli_format(results)
|
19
|
+
results = results['account']
|
20
|
+
|
21
|
+
data = ''
|
22
|
+
data << sprintf("droplet limit: %-s\n", results['droplet_limit'])
|
23
|
+
data << sprintf("email: %-s\n", results['email'])
|
24
|
+
data << sprintf("uuid: %-s\n", results['uuid'])
|
25
|
+
data << sprintf("email verified: %-s\n", results['email_verified'])
|
26
|
+
data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/puddle/version.rb
CHANGED
data/puddle.gemspec
CHANGED
@@ -10,13 +10,14 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["rsb.code@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{api wrapper to simplify managing droplets, ssh keys, domains etc...}
|
13
|
+
spec.description = spec.summary
|
13
14
|
spec.homepage = "https://github.com/rsb/puddle"
|
14
15
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test|spec|features)/})}
|
16
17
|
spec.bindir = "exe"
|
17
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
19
|
spec.require_paths = ["lib"]
|
19
|
-
|
20
|
+
spec.licenses = ['MIT']
|
20
21
|
spec.add_dependency "thor", "~> 0.19.1"
|
21
22
|
spec.add_dependency "rest-client", "~> 1.8.0"
|
22
23
|
|
metadata
CHANGED
@@ -1,114 +1,114 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Scott-Buccleuch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.19.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.19.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rest-client
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.8.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.8.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 0.10.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.10.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: webmock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.21.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.21.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.10'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.10'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ~>
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '3.3'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ~>
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '3.3'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ~>
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '10.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ~>
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '10.0'
|
111
|
-
description:
|
111
|
+
description: api wrapper to simplify managing droplets, ssh keys, domains etc...
|
112
112
|
email:
|
113
113
|
- rsb.code@gmail.com
|
114
114
|
executables:
|
@@ -116,9 +116,9 @@ executables:
|
|
116
116
|
extensions: []
|
117
117
|
extra_rdoc_files: []
|
118
118
|
files:
|
119
|
-
-
|
120
|
-
-
|
121
|
-
-
|
119
|
+
- .gitignore
|
120
|
+
- .rspec
|
121
|
+
- .travis.yml
|
122
122
|
- CODE_OF_CONDUCT.md
|
123
123
|
- Gemfile
|
124
124
|
- README.md
|
@@ -130,10 +130,14 @@ files:
|
|
130
130
|
- lib/puddle/cli.rb
|
131
131
|
- lib/puddle/cli/base_cli.rb
|
132
132
|
- lib/puddle/cli/main.rb
|
133
|
+
- lib/puddle/http_adapter.rb
|
134
|
+
- lib/puddle/resources.rb
|
135
|
+
- lib/puddle/resources/show_account.rb
|
133
136
|
- lib/puddle/version.rb
|
134
137
|
- puddle.gemspec
|
135
138
|
homepage: https://github.com/rsb/puddle
|
136
|
-
licenses:
|
139
|
+
licenses:
|
140
|
+
- MIT
|
137
141
|
metadata: {}
|
138
142
|
post_install_message:
|
139
143
|
rdoc_options: []
|
@@ -141,17 +145,17 @@ require_paths:
|
|
141
145
|
- lib
|
142
146
|
required_ruby_version: !ruby/object:Gem::Requirement
|
143
147
|
requirements:
|
144
|
-
- -
|
148
|
+
- - ! '>='
|
145
149
|
- !ruby/object:Gem::Version
|
146
150
|
version: '0'
|
147
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
152
|
requirements:
|
149
|
-
- -
|
153
|
+
- - ! '>='
|
150
154
|
- !ruby/object:Gem::Version
|
151
155
|
version: '0'
|
152
156
|
requirements: []
|
153
157
|
rubyforge_project:
|
154
|
-
rubygems_version: 2.4.
|
158
|
+
rubygems_version: 2.4.5
|
155
159
|
signing_key:
|
156
160
|
specification_version: 4
|
157
161
|
summary: api wrapper to simplify managing droplets, ssh keys, domains etc...
|