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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22de99d93f1dcc0b6189b27a8f76827c611f85b142f75ac8220725a909f1746b
4
- data.tar.gz: 4d10928a3be79b0c81e103eff8b3fcd2dc9c88eaec980584d275c91c9d341539
3
+ metadata.gz: 3659a8a697bee5226a4b7c322f72968b1c5bad29d08a993baf0c48225c2da733
4
+ data.tar.gz: 0ff944661b1dcd0d225a7308ba1bfb3db6568e0ee559685cdb75d0ab9f010296
5
5
  SHA512:
6
- metadata.gz: 655ef8b565505126a3a20438c1f79699d84f50aba835680cf3ea9ca9565935d27a6456260e5ef14c788ec2eee4fac34f8e2fcf5c8864ef449c5bae4cbe1b4a2d
7
- data.tar.gz: 236e67762ce6e2aa1dbf82d39f795b5f8d612d35d19b3dd14c0d6b4c43e4fbe05bd25c0d691046cf22620bbdc8d6eaf0b1c6e426be6eca76f806835d99121c82
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
  ![Sunzi for Linode](http://farm8.staticflickr.com/7210/6783789868_ab89010d5c.jpg)
@@ -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
@@ -5,18 +5,18 @@ module Sunzi
5
5
  module Vps
6
6
  class Cli < Thor
7
7
 
8
- desc 'init [provider]', 'Generate VPS config file (provider: linode, digital_ocean)'
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]', 'Set up a new instance (provider: linode, digital_ocean)'
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]', 'Tear down an existing instance (provider: linode, digital_ocean)'
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.send(ip_key)
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
- @public_ip = droplet.networks.v4.first.ip_address
44
- say "Done. ip address = #{@public_ip}"
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
- ip_address: @public_ip,
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
- @public_ip = result.first.ipaddress
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 => @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
@@ -4,6 +4,7 @@ module Sunzi
4
4
  [
5
5
  ['linode', '~> 0.7'],
6
6
  ['droplet_kit', '~> 2.2'],
7
+ ['vultr', '~> 0.3'],
7
8
  ].each do |name, version|
8
9
  Sunzi::Dependency.new(name, version)
9
10
  end
@@ -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
@@ -9,6 +9,10 @@ module Sunzi
9
9
  gem: 'droplet_kit',
10
10
  klass: 'DigitalOcean',
11
11
  },
12
+ vultr: {
13
+ gem: 'vultr',
14
+ klass: 'Vultr',
15
+ },
12
16
  }.freeze
13
17
  end
14
18
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'sunzi-vps'
5
- spec.version = '0.1.0' # retrieve this value by: Gem.loaded_specs['sunzi'].version.to_s
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
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  api_key: your_api_key
3
- client_id: your_client_id
4
3
 
5
4
  # add / remove environments
6
5
  environments:
@@ -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.1.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-18 00:00:00.000000000 Z
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