docl 0.0.4 → 0.0.5

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
- !binary "U0hBMQ==":
3
- metadata.gz: fd8567515ced970e31f68664650daa5e5040ab2a
4
- data.tar.gz: 2850796769b6f9be205ebbff4ebc17ff5ba2d6e4
2
+ SHA1:
3
+ metadata.gz: ccdb9a0251a9ffcaf96c58284d879bf86604327b
4
+ data.tar.gz: e6a70f76a9dcad631752bde424cba09f8a41f03f
5
5
  SHA512:
6
- metadata.gz: 726f31020e44d163cf397de89e92b4552f58947f39d66ec6c7c6a662499aeea7c59f6d83922cb3eae9bc13a2bf6972a58615c6a1dcf6eaa52c43c27a6d29717b
7
- data.tar.gz: 855672c17d31968308b5eab476c4d55df003beaf61a0dfcf048eef4395e86fb0c693501e3621390a7934335e9141c22ee687df98b8a565a958677afe159dad1c
6
+ metadata.gz: 4dd9c615bd3dc0d6a5a970030f63705e8bd0f7c7fed1fd5d94b8ea234f3828978f42b36aa2167e0896ff85fe1dce6bb478d9ed1024cc076c3f81acc15caf07b6
7
+ data.tar.gz: 35cff01a914c59a8e8b4459e0df27d09898b50787c51b460637c916eb6b820fd2a5f73b474bbf99ce0da4893aff1a5551d81a81f75f23d9367ead9da126b8ffc
data/.gitignore CHANGED
@@ -1 +1 @@
1
- Gemfile.lock
1
+ Gemfile.lock
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source 'https://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
  gemspec
data/LICENSE CHANGED
@@ -1,22 +1,22 @@
1
- Copyright (c) 2014 Nathan Samson <nathan AT nathansamson DOT be>
2
-
3
- Permission is hereby granted, free of charge, to any person
4
- obtaining a copy of this software and associated documentation
5
- files (the "Software"), to deal in the Software without
6
- restriction, including without limitation the rights to use,
7
- copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the
9
- Software is furnished to do so, subject to the following
10
- conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2014 Nathan Samson <nathan AT nathansamson DOT be>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # DOCL (DigitalOcean Command Line)
2
-
3
- A command line tool for interacting with DigitalOcean.
4
-
5
- ## Installation
6
- gem install docl
7
-
8
- ## Status
9
- Currently it only supports a very limited subset of oeprations.
10
-
11
- ## Documentation
12
- Run `docl help` or `docl command help` to get help.
13
-
14
- ## Contributing
15
- To test the code run `bundle exec docl ...` which will include your code changes.
1
+ # DOCL (DigitalOcean Command Line)
2
+
3
+ A command line tool for interacting with DigitalOcean.
4
+
5
+ ## Installation
6
+ gem install docl
7
+
8
+ ## Status
9
+ Currently it only supports a very limited subset of operations.
10
+
11
+ ## Documentation
12
+ Run `docl help` or `docl command help` to get help.
13
+
14
+ ## Contributing
15
+ To test the code run `bundle exec docl ...` which will include your code changes.
data/bin/docl CHANGED
@@ -1,5 +1,5 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'docl'
4
-
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'docl'
4
+
5
5
  DOCL::CLI.start
@@ -1,24 +1,24 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'docl/version'
4
-
5
- Gem::Specification.new do |gem|
6
- gem.name = "docl"
7
- gem.version = DOCL::VERSION
8
- gem.authors = ["Nathan Samson"]
9
- gem.email = ["nathan@nathansamson.be"]
10
- gem.license = "MIT"
11
- gem.description = %q{A command line tool for interacting with your DigitalOcean droplets.}
12
- gem.summary = %q{A command line tool for interacting with your DigitalOcean droplets.}
13
- gem.homepage = "https://github.com/nathansamson/docl"
14
-
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
19
- gem.required_ruby_version = ">= 1.9.3"
20
-
21
- gem.add_dependency "thor", "~> 0.19.1"
22
- gem.add_dependency "barge", "~> 0.10.0"
23
- gem.add_dependency "json", "~> 1.8.1"
24
- end
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'docl/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "docl"
7
+ gem.version = DOCL::VERSION
8
+ gem.authors = ["Nathan Samson"]
9
+ gem.email = ["nathan@nathansamson.be"]
10
+ gem.license = "MIT"
11
+ gem.description = %q{A command line tool for interacting with your DigitalOcean droplets.}
12
+ gem.summary = %q{A command line tool for interacting with your DigitalOcean droplets.}
13
+ gem.homepage = "https://github.com/nathansamson/docl"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.required_ruby_version = ">= 1.9.3"
20
+
21
+ gem.add_dependency "thor", "~> 0.19.1"
22
+ gem.add_dependency "barge", "~> 0.11.0"
23
+ gem.add_dependency "json", "~> 1.8.1"
24
+ end
@@ -1,8 +1,8 @@
1
- require 'barge'
2
- require 'json'
3
- require 'thor'
4
-
5
- module DOCL
6
- end
7
-
1
+ require 'barge'
2
+ require 'json'
3
+ require 'thor'
4
+
5
+ module DOCL
6
+ end
7
+
8
8
  require 'docl/cli'
@@ -1,147 +1,173 @@
1
- class DOCL::CLI < Thor
2
- desc "authorize", "Authrorize docl to read / modify your DO info"
3
- def authorize
4
- puts "You'll need to enter your DigitalOcean Private Access Token."
5
- puts "To be able to create / modify droplets, it needs to be read / write."
6
- puts "You can create a token on the DO website vite the Apps & API menu."
7
-
8
- print "Enter your DO Token: "
9
- token = $stdin.gets.chomp
10
-
11
- f = File.open(config_path, 'w')
12
- f.write(token)
13
- f.close
14
- File.chmod(0600, config_path)
15
- end
16
-
17
- desc "images", "List all images"
18
- method_option :public, type: :boolean, default: false, aliases: '-p'
19
- def images()
20
- images = barge.image.all.images
21
- images = images.select { |image| image.public == options.public }
22
- images = images.sort { |a, b| a.name <=> b.name }
23
- images.each do |image|
24
- if !image.slug.nil?
25
- puts "#{image.name} (#{image.slug}, id: #{image.id})"
26
- else
27
- puts "#{image.name} (id: #{image.id})"
28
- end
29
- end
30
- end
31
-
32
- desc "upload_key [name] [public_key_path]", "Upload a key"
33
- def upload_key(name, public_key_path)
34
- response = barge.key.create(name: name,
35
- public_key: File.read(public_key_path))
36
-
37
- if response.message
38
- puts response.message
39
- exit(1)
40
- else
41
- puts "Public Key uploaded with ID: #{response.ssh_key.id}"
42
- end
43
- end
44
-
45
- desc "keys", "List all keys"
46
- def keys()
47
- barge.key.all.ssh_keys.each do |key|
48
- puts "#{key.name} (id: #{key.id})"
49
- end
50
- end
51
-
52
- desc "regions", "List regions"
53
- method_option :metadata, type: :boolean, default: false
54
- method_option :private_networking, type: :boolean, default: false
55
- method_option :backups, type: :boolean, default: false
56
- method_option :ipv6, type: :boolean, default: false
57
- def regions()
58
- regions = barge.region.all.regions
59
- regions = regions.select do |region|
60
- if options.ipv6 && !region.features.include?('ipv6')
61
- next false
62
- end
63
-
64
- if options.metadata && !region.features.include?('metadata')
65
- next false
66
- end
67
-
68
- if options.private_networking && !region.features.include?('private_networking')
69
- next false
70
- end
71
-
72
- if options.backups && !region.features.include?('backups')
73
- next false
74
- end
75
-
76
- next true
77
- end
78
- regions.sort { |a, b| a.name <=> b.name }.each do |region|
79
- puts "#{region.name} (#{region.slug})"
80
- end
81
- end
82
-
83
- desc "create [name] [image] [size] [region]", "Create a droplet"
84
- method_option :key, type: :string, default: nil
85
- method_option :user_data, type: :string, default: nil
86
- method_option :private_networking, type: :boolean, default: true
87
- method_option :enable_backups, type: :boolean, default: false
88
- method_option :ipv6, type: :boolean, default: false
89
- method_option :wait, type: :boolean, default: false
90
- def create(name, image, size, region)
91
- call_options = {
92
- name: name,
93
- image: image,
94
- region: region,
95
- size: size,
96
- private_networking: options.private_networking,
97
- enable_backups: options.enable_backups,
98
- ipv6: options.ipv6,
99
- }
100
- if options[:key]
101
- call_options[:ssh_keys] = [options[:key]]
102
- end
103
- if options.user_data
104
- call_options[:user_data] = File.read(options.user_data)
105
- end
106
-
107
- response = barge.droplet.create(call_options)
108
- if response.id == 'unprocessable_entity'
109
- puts response.message
110
- exit(1)
111
- end
112
-
113
- if options.wait
114
- print "Waiting for droplet to become available"
115
- action_link = response.links.actions.first
116
- begin
117
- print '.'
118
- sleep 1
119
- action = barge.action.show(action_link.id).action
120
- end until action.status != 'in-progress'
121
- puts "Completed"
122
-
123
- droplet = barge.droplet.show(response.droplet.id).droplet
124
- network_types = [droplet.networks.v4]
125
- network_types << droplet.networks.v6 if droplet.networks.v6
126
-
127
- puts "You can connect to your Droplet via"
128
- network_types.flatten.select { |nw| nw.type == 'public' }.each do |network|
129
- puts network.ip_address
130
- end
131
- end
132
- end
133
-
134
- private
135
- def config_path
136
- File.expand_path('~/.docl-access-token')
137
- end
138
-
139
- def barge
140
- if !File.exist?(config_path)
141
- puts 'Please run docl authorize first.'
142
- exit(1)
143
- end
144
-
145
- @barge ||= Barge::Client.new(access_token: File.read(config_path))
146
- end
147
- end
1
+ class DOCL::CLI < Thor
2
+ desc "authorize", "Authrorize docl to read / modify your DO info"
3
+ def authorize
4
+ puts "You'll need to enter your DigitalOcean Private Access Token."
5
+ puts "To be able to create / modify droplets, it needs to be read / write."
6
+ puts "You can create a token on the DO website vite the Apps & API menu."
7
+
8
+ print "Enter your DO Token: "
9
+ token = $stdin.gets.chomp
10
+
11
+ f = File.open(config_path, 'w')
12
+ f.write(token)
13
+ f.close
14
+ File.chmod(0600, config_path)
15
+ end
16
+
17
+ desc "images", "List all images"
18
+ method_option :public, type: :boolean, default: false, aliases: '-p'
19
+ def images()
20
+ image_response = barge.image.all
21
+ display_failure(image_response) and return if failure?(image_response)
22
+ images = image_response.images.select { |image| image.public == options.public }
23
+ images = images.sort { |a, b| a.name <=> b.name }
24
+ images.each do |image|
25
+ if !image.slug.nil?
26
+ puts "#{image.name} (#{image.slug}, id: #{image.id})"
27
+ else
28
+ puts "#{image.name} (id: #{image.id})"
29
+ end
30
+ end
31
+ end
32
+
33
+ desc "keys", "List all keys"
34
+ def keys()
35
+ key_response = barge.key.all
36
+ display_failure(key_response) and return if failure?(key_response)
37
+ key_response.ssh_keys.each do |key|
38
+ puts "#{key.name} (id: #{key.id})"
39
+ end
40
+ end
41
+
42
+ desc "regions", "List regions"
43
+ method_option :metadata, type: :boolean, default: false
44
+ method_option :private_networking, type: :boolean, default: false
45
+ method_option :backups, type: :boolean, default: false
46
+ method_option :ipv6, type: :boolean, default: false
47
+ def regions()
48
+ region_response = barge.region.all
49
+ display_failure(region_response) and return if failure?(region_response)
50
+ regions = region_response.regions.select do |region|
51
+ if options.ipv6 && !region.features.include?('ipv6')
52
+ next false
53
+ end
54
+
55
+ if options.metadata && !region.features.include?('metadata')
56
+ next false
57
+ end
58
+
59
+ if options.private_networking && !region.features.include?('private_networking')
60
+ next false
61
+ end
62
+
63
+ if options.backups && !region.features.include?('backups')
64
+ next false
65
+ end
66
+
67
+ next true
68
+ end
69
+ regions.sort { |a, b| a.name <=> b.name }.each do |region|
70
+ puts "#{region.name} (#{region.slug})"
71
+ end
72
+ end
73
+
74
+ desc "create [name] [image] [size] [region]", "Create a droplet"
75
+ method_option :key, type: :string, default: nil
76
+ method_option :user_data, type: :string, default: nil
77
+ method_option :private_networking, type: :boolean, default: true
78
+ method_option :enable_backups, type: :boolean, default: false
79
+ method_option :ipv6, type: :boolean, default: false
80
+ method_option :wait, type: :boolean, default: false
81
+ def create(name, image, size, region)
82
+ call_options = {
83
+ name: name,
84
+ image: image,
85
+ region: region,
86
+ size: size,
87
+ private_networking: options.private_networking,
88
+ enable_backups: options.enable_backups,
89
+ ipv6: options.ipv6,
90
+ }
91
+ if options[:key]
92
+ call_options[:ssh_keys] = [options[:key]]
93
+ end
94
+ if options.user_data
95
+ call_options[:user_data] = File.read(options.user_data)
96
+ end
97
+
98
+ response = barge.droplet.create(call_options)
99
+ display_failure(response) and return if failure?(response)
100
+
101
+ if options.wait
102
+ print "Waiting for droplet to become available"
103
+ action_link = response.links.actions.first
104
+ begin
105
+ print '.'
106
+ sleep 1
107
+ action = barge.action.show(action_link.id).action
108
+ end until action.status != 'in-progress'
109
+ puts "Completed"
110
+
111
+ puts "You can connect to your Droplet via"
112
+ droplet = barge.droplet.show(response.droplet.id).droplet
113
+ ip_addresses(droplet).each(&method(:puts))
114
+ end
115
+ end
116
+
117
+ desc 'droplets', 'List all droplets'
118
+ def droplets
119
+ droplet_response = barge.droplet.all
120
+ display_failure(droplet_response) and return if failure?(droplet_response)
121
+ max_name_width = droplet_response.droplets.map { |droplet| droplet.name.length }.max
122
+ format = "%-10s %-10s %-#{max_name_width + 2}s %-10s %-8s %-8s %-6s %-40s"
123
+ puts format % ["Image", "ID", "Name", "Status", "Region", "Memory", "Disk", "IP Address"]
124
+ droplet_response.droplets.each do |droplet|
125
+ ips = ip_addresses(droplet).join(", ")
126
+ puts format % [droplet.image.distribution, droplet.id, droplet.name,
127
+ droplet.status, droplet.region.slug,
128
+ droplet.size_slug.upcase, "#{droplet.disk}GB", ips]
129
+ end
130
+ end
131
+
132
+ desc 'destroy [droplet-id]', 'Destroy a droplet and scrub its data'
133
+ def destroy(droplet_id)
134
+ if !yes?('This is irreversible, are you sure? (y/n)')
135
+ return
136
+ end
137
+ response = barge.droplet.destroy(droplet_id)
138
+ display_failure(response) and return if failure?(response)
139
+ puts 'Successfully destroyed droplet'
140
+ end
141
+
142
+ private
143
+ def config_path
144
+ File.expand_path('~/.docl-access-token')
145
+ end
146
+
147
+ def barge
148
+ if !File.exist?(config_path)
149
+ puts 'Please run docl authorize first.'
150
+ exit(1)
151
+ end
152
+
153
+ @barge ||= Barge::Client.new(access_token: File.read(config_path))
154
+ end
155
+
156
+ def ip_addresses(droplet)
157
+ network_types = [droplet.networks.v4]
158
+ network_types << droplet.networks.v6 if droplet.networks.v6
159
+
160
+ network_types.flatten.select { |nw| nw.type == 'public' }.map { |nw| nw.ip_address }
161
+ end
162
+
163
+ def display_failure(response)
164
+ puts "!" * 60
165
+ puts response.message
166
+ puts "!" * 60
167
+ true # Make sure to return true-ish value to allow "and return" to work
168
+ end
169
+
170
+ def failure?(response)
171
+ response.id && response.message
172
+ end
173
+ end
@@ -1,3 +1,3 @@
1
- module DOCL
2
- VERSION = '0.0.4'
3
- end
1
+ module DOCL
2
+ VERSION = '0.0.5'
3
+ end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Samson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-11 00:00:00.000000000 Z
11
+ date: 2015-06-03 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: barge
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.10.0
33
+ version: 0.11.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
- version: 0.10.0
40
+ version: 0.11.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.8.1
48
48
  type: :runtime
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: 1.8.1
55
55
  description: A command line tool for interacting with your DigitalOcean droplets.
@@ -60,7 +60,7 @@ executables:
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - .gitignore
63
+ - ".gitignore"
64
64
  - Gemfile
65
65
  - LICENSE
66
66
  - README.md
@@ -79,19 +79,18 @@ require_paths:
79
79
  - lib
80
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ! '>='
82
+ - - ">="
83
83
  - !ruby/object:Gem::Version
84
84
  version: 1.9.3
85
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
91
  rubyforge_project:
92
- rubygems_version: 2.1.11
92
+ rubygems_version: 2.4.5
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: A command line tool for interacting with your DigitalOcean droplets.
96
96
  test_files: []
97
- has_rdoc: