docl 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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: