sunzi-vps 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/sunzi/vps/api.rb +5 -0
- data/lib/sunzi/vps/cli.rb +3 -3
- data/lib/sunzi/vps/compute/base.rb +2 -2
- data/lib/sunzi/vps/compute/digital_ocean.rb +3 -7
- data/lib/sunzi/vps/compute/linode.rb +2 -6
- data/lib/sunzi/vps/compute/vultr.rb +91 -0
- data/lib/sunzi/vps/dependency.rb +1 -0
- data/lib/sunzi/vps/dns/vultr.rb +31 -0
- data/lib/sunzi/vps/mapping.rb +4 -0
- data/sunzi-vps.gemspec +2 -1
- data/templates/digital_ocean.yml +0 -1
- data/templates/vultr.yml +17 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3659a8a697bee5226a4b7c322f72968b1c5bad29d08a993baf0c48225c2da733
|
4
|
+
data.tar.gz: 0ff944661b1dcd0d225a7308ba1bfb3db6568e0ee559685cdb75d0ab9f010296
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ccdc5db32aa135bb6049d5d4c7a4aac1a2c91384053d198327c2797e7486689c770a4aefac68636669a48a22ed221f7e32879f603351e74702d7b17e8353458
|
7
|
+
data.tar.gz: 28b16c5384243e6c7f71579bed968f7bbcef804db03022ed43a22425f9f46488664731704f726c28d8e75c85b90ca090524d6ddc92934a0ff337b0d7fae8f720
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
sunzi-vps is a simple command line utility to create and/or destroy VPS instances interactively.
|
4
4
|
|
5
|
+
Works with [Linode](https://www.linode.com/), [DigitalOcean](https://www.digitalocean.com/) and [Vultr](https://www.vultr.com/)
|
6
|
+
|
5
7
|
It works as a plugin for [sunzi](https://github.com/kenn/sunzi), but can be used as a standalone tool.
|
6
8
|
|
7
9
|

|
data/lib/sunzi/vps/api.rb
CHANGED
@@ -3,10 +3,12 @@ require 'sunzi/vps/mapping'
|
|
3
3
|
require 'sunzi/vps/compute/base'
|
4
4
|
require 'sunzi/vps/compute/linode'
|
5
5
|
require 'sunzi/vps/compute/digital_ocean'
|
6
|
+
require 'sunzi/vps/compute/vultr'
|
6
7
|
|
7
8
|
require 'sunzi/vps/dns/base'
|
8
9
|
require 'sunzi/vps/dns/linode'
|
9
10
|
require 'sunzi/vps/dns/digital_ocean'
|
11
|
+
require 'sunzi/vps/dns/vultr'
|
10
12
|
|
11
13
|
module Sunzi
|
12
14
|
module Vps
|
@@ -25,6 +27,9 @@ module Sunzi
|
|
25
27
|
::Linode.new(api_key: config.api_key)
|
26
28
|
when 'digital_ocean'
|
27
29
|
DropletKit::Client.new(access_token: config.api_key)
|
30
|
+
when 'vultr'
|
31
|
+
Vultr.api_key = config.api_key
|
32
|
+
Vultr
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
data/lib/sunzi/vps/cli.rb
CHANGED
@@ -5,18 +5,18 @@ module Sunzi
|
|
5
5
|
module Vps
|
6
6
|
class Cli < Thor
|
7
7
|
|
8
|
-
desc 'init [provider]',
|
8
|
+
desc 'init [provider]', "Generate VPS config file (provider: #{Mapping.keys.join(', ')})"
|
9
9
|
def init(provider)
|
10
10
|
Sunzi::Vps::Init.new.run(provider)
|
11
11
|
end
|
12
12
|
|
13
|
-
desc 'up [provider]',
|
13
|
+
desc 'up [provider]', "Set up a new instance (provider: #{Mapping.keys.join(', ')})"
|
14
14
|
def up(provider)
|
15
15
|
api = Sunzi::Vps::Api.new(provider)
|
16
16
|
api.compute.up
|
17
17
|
end
|
18
18
|
|
19
|
-
desc 'down [provider]',
|
19
|
+
desc 'down [provider]', "Tear down an existing instance (provider: #{Mapping.keys.join(', ')})"
|
20
20
|
def down(provider)
|
21
21
|
api = Sunzi::Vps::Api.new(provider)
|
22
22
|
api.compute.down
|
@@ -36,7 +36,7 @@ module Sunzi
|
|
36
36
|
create_file instance_config_path, YAML.dump(@instance)
|
37
37
|
|
38
38
|
# Register IP to DNS
|
39
|
-
api.dns.add(@fqdn, @public_ip)
|
39
|
+
api.dns.add(@fqdn, @instance[:public_ip])
|
40
40
|
end
|
41
41
|
|
42
42
|
def down
|
@@ -56,7 +56,7 @@ module Sunzi
|
|
56
56
|
do_down
|
57
57
|
|
58
58
|
# Delete DNS record
|
59
|
-
api.dns.delete @instance.
|
59
|
+
api.dns.delete @instance.public_ip
|
60
60
|
|
61
61
|
# Remove the instance config file
|
62
62
|
remove_file instance_config_path
|
@@ -40,8 +40,8 @@ module Sunzi
|
|
40
40
|
droplet = client.droplets.find(id: @droplet_id)
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
say "Done. ip address = #{
|
43
|
+
public_ip = droplet.networks.v4.first.ip_address
|
44
|
+
say "Done. ip address = #{public_ip}"
|
45
45
|
|
46
46
|
@instance = {
|
47
47
|
droplet_id: @droplet_id,
|
@@ -49,7 +49,7 @@ module Sunzi
|
|
49
49
|
host: @host,
|
50
50
|
fqdn: @fqdn,
|
51
51
|
name: @name,
|
52
|
-
|
52
|
+
public_ip: public_ip,
|
53
53
|
size: @attributes[:size],
|
54
54
|
region: @attributes[:region],
|
55
55
|
image: @attributes[:image],
|
@@ -80,10 +80,6 @@ module Sunzi
|
|
80
80
|
say 'deleting droplet...'
|
81
81
|
client.droplets.delete(id: @instance[:droplet_id])
|
82
82
|
end
|
83
|
-
|
84
|
-
def ip_key
|
85
|
-
:ip_address
|
86
|
-
end
|
87
83
|
end
|
88
84
|
end
|
89
85
|
end
|
@@ -74,7 +74,7 @@ module Sunzi
|
|
74
74
|
# Add a private IP
|
75
75
|
say "Adding a private IP..."
|
76
76
|
result = client.linode.ip.list(:LinodeID => @linodeid)
|
77
|
-
|
77
|
+
public_ip = result.first.ipaddress
|
78
78
|
result = client.linode.ip.addprivate(:LinodeID => @linodeid)
|
79
79
|
result = client.linode.ip.list(:LinodeID => @linodeid).find{|i| i.ispublic == 0 }
|
80
80
|
@private_ip = result.ipaddress
|
@@ -98,7 +98,7 @@ module Sunzi
|
|
98
98
|
:root_diskid => @root_diskid,
|
99
99
|
:swap_diskid => @swap_diskid,
|
100
100
|
:config_id => @config_id,
|
101
|
-
:public_ip =>
|
101
|
+
:public_ip => public_ip,
|
102
102
|
:private_ip => @private_ip,
|
103
103
|
}
|
104
104
|
|
@@ -136,10 +136,6 @@ module Sunzi
|
|
136
136
|
client.linode.delete(@linode_id_hash.merge(:skipChecks => 1))
|
137
137
|
end
|
138
138
|
|
139
|
-
def ip_key
|
140
|
-
:public_ip
|
141
|
-
end
|
142
|
-
|
143
139
|
def wait_for(action)
|
144
140
|
begin
|
145
141
|
sleep 3
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Sunzi
|
2
|
+
module Vps
|
3
|
+
class Compute
|
4
|
+
class Vultr < Base
|
5
|
+
|
6
|
+
def do_up
|
7
|
+
result = choose(:plan, client::Plans.list)
|
8
|
+
choose(:region, client::Regions.list, ids: result['available_locations'])
|
9
|
+
|
10
|
+
# Choose an image
|
11
|
+
result = client::OS.list
|
12
|
+
if config.distributions_filter
|
13
|
+
result[:result].reject!{|id, hash| hash['name'] !~ Regexp.new(config.distributions_filter, Regexp::IGNORECASE) }
|
14
|
+
end
|
15
|
+
choose(:os, result)
|
16
|
+
|
17
|
+
# Go ahead?
|
18
|
+
proceed?
|
19
|
+
|
20
|
+
# Create
|
21
|
+
say 'creating a new instance...'
|
22
|
+
result = client::Server.create(
|
23
|
+
label: @name,
|
24
|
+
DCID: @attributes[:region],
|
25
|
+
VPSPLANID: @attributes[:plan],
|
26
|
+
OSID: @attributes[:os]
|
27
|
+
)
|
28
|
+
|
29
|
+
subid = result[:result]['SUBID']
|
30
|
+
|
31
|
+
say "Created a new instance (id: #{subid}). Booting..."
|
32
|
+
|
33
|
+
begin
|
34
|
+
sleep 3
|
35
|
+
result = client::Server.list_ipv4(SUBID: subid)
|
36
|
+
public_ip = result[:result][subid].first['ip']
|
37
|
+
end while public_ip == '0.0.0.0'
|
38
|
+
|
39
|
+
say "Done. ip address = #{public_ip}"
|
40
|
+
|
41
|
+
@instance = {
|
42
|
+
subid: subid,
|
43
|
+
env: @env,
|
44
|
+
host: @host,
|
45
|
+
fqdn: @fqdn,
|
46
|
+
name: @name,
|
47
|
+
public_ip: public_ip,
|
48
|
+
plan: @attributes[:plan],
|
49
|
+
region: @attributes[:region],
|
50
|
+
os: @attributes[:os],
|
51
|
+
}
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def choose(key, result, ids: nil)
|
56
|
+
abort "API returned for #{key}!" if result[:status] != 200
|
57
|
+
result = result[:result].map{|id,hash| hash.merge(id: id) }
|
58
|
+
|
59
|
+
# Filter out items not included in ids
|
60
|
+
if ids
|
61
|
+
ids = ids.map(&:to_s)
|
62
|
+
result.reject!{|h| !ids.include?(h[:id].to_s) }
|
63
|
+
end
|
64
|
+
|
65
|
+
rows = result.map do |h|
|
66
|
+
h.values.map do |v|
|
67
|
+
next v unless v.is_a?(Array)
|
68
|
+
if v.size > 5
|
69
|
+
v.first(5).join(', ') + ', ...'
|
70
|
+
else
|
71
|
+
v.join(', ')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
table = Terminal::Table.new headings: result.first.keys, rows: rows
|
77
|
+
say table
|
78
|
+
|
79
|
+
@attributes[key] = ask("which #{key}?: ", default: result.first[:id], limited_to: result.map{|i| i[:id] })
|
80
|
+
result.find{|i| i[:id].to_s == @attributes[key] }
|
81
|
+
end
|
82
|
+
|
83
|
+
def do_down
|
84
|
+
say 'deleting instance...'
|
85
|
+
result = client::Server.destroy(SUBID: @instance[:subid])
|
86
|
+
abort result[:result] if result[:status] != 200
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/sunzi/vps/dependency.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Sunzi
|
2
|
+
module Vps
|
3
|
+
class DNS
|
4
|
+
class Vultr < Base
|
5
|
+
|
6
|
+
def verify
|
7
|
+
result = client::DNS.list
|
8
|
+
domain = result[:result].find{|h| h['domain'] == @zone }
|
9
|
+
abort_with "zone for #{@zone} was not found on Vultr DNS!" unless domain
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(fqdn, ip)
|
13
|
+
say 'adding the public IP to Vultr DNS...'
|
14
|
+
client::DNS.create_record(domain: @zone, name: fqdn.sub('.' + @zone, ''), type: 'A', data: ip)
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete(ip)
|
18
|
+
say 'deleting the public IP from Vultr DNS...'
|
19
|
+
|
20
|
+
result = client::DNS.records(domain: @zone)
|
21
|
+
hash = result[:result].find{|i| i['type'] == 'A' && i['data'] == ip }
|
22
|
+
|
23
|
+
abort_with "ip address #{ip} was not found on Vultr DNS!" unless hash['RECORDID']
|
24
|
+
|
25
|
+
client::DNS.delete_record(domain: @zone, RECORDID: hash['RECORDID'])
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/sunzi/vps/mapping.rb
CHANGED
data/sunzi-vps.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'sunzi-vps'
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '0.2.0' # retrieve this value by: Gem.loaded_specs['sunzi'].version.to_s
|
6
6
|
spec.authors = ['Kenn Ejima']
|
7
7
|
spec.email = ['kenn.ejima@gmail.com']
|
8
8
|
spec.summary = %q{Sunzi VPS}
|
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'webmock', '~> 3.2'
|
25
25
|
spec.add_development_dependency 'linode', '~> 0.7'
|
26
26
|
spec.add_development_dependency 'droplet_kit', '~> 2.2'
|
27
|
+
spec.add_development_dependency 'vultr', '~> 0.3'
|
27
28
|
end
|
data/templates/digital_ocean.yml
CHANGED
data/templates/vultr.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
api_key: your_api_key
|
3
|
+
|
4
|
+
# add / remove environments
|
5
|
+
environments:
|
6
|
+
- production
|
7
|
+
- staging
|
8
|
+
fqdn:
|
9
|
+
zone: example.com
|
10
|
+
production: '%{host}.example.com'
|
11
|
+
staging: '%{host}.staging.example.com'
|
12
|
+
name:
|
13
|
+
production: 'example-%{host}'
|
14
|
+
staging: 'example-staging-%{host}'
|
15
|
+
|
16
|
+
# filter out large lists by keyword
|
17
|
+
distributions_filter: debian
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sunzi-vps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenn Ejima
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sunzi
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '2.2'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: vultr
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.3'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.3'
|
153
167
|
description: Simple CLI to create and/or destroy VPS instances
|
154
168
|
email:
|
155
169
|
- kenn.ejima@gmail.com
|
@@ -170,15 +184,18 @@ files:
|
|
170
184
|
- lib/sunzi/vps/compute/base.rb
|
171
185
|
- lib/sunzi/vps/compute/digital_ocean.rb
|
172
186
|
- lib/sunzi/vps/compute/linode.rb
|
187
|
+
- lib/sunzi/vps/compute/vultr.rb
|
173
188
|
- lib/sunzi/vps/dependency.rb
|
174
189
|
- lib/sunzi/vps/dns/base.rb
|
175
190
|
- lib/sunzi/vps/dns/digital_ocean.rb
|
176
191
|
- lib/sunzi/vps/dns/linode.rb
|
192
|
+
- lib/sunzi/vps/dns/vultr.rb
|
177
193
|
- lib/sunzi/vps/init.rb
|
178
194
|
- lib/sunzi/vps/mapping.rb
|
179
195
|
- sunzi-vps.gemspec
|
180
196
|
- templates/digital_ocean.yml
|
181
197
|
- templates/linode.yml
|
198
|
+
- templates/vultr.yml
|
182
199
|
homepage: https://github.com/kenn/sunzi-vps
|
183
200
|
licenses:
|
184
201
|
- MIT
|