droppper 0.1.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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/README.md +19 -0
- data/Rakefile +1 -0
- data/bin/droppper +51 -0
- data/droppper.gemspec +29 -0
- data/lib/droppper.rb +63 -0
- data/lib/droppper/commands/droplets.rb +48 -0
- data/lib/droppper/commands/ssh.rb +14 -0
- data/lib/droppper/utils.rb +49 -0
- data/lib/droppper/version.rb +3 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d00c6930b33d61b10304c6f22866d59fffc9515
|
4
|
+
data.tar.gz: 24f9f5d6504cce0a322ff6a4b35c122327503846
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3bcebe5092bc70bb95f410fed1a502b2cd694f48fbe7a9d3de9e6d8de2bed188c5a3bba33911f92945cdb8aa551fd608e6c9425369e4be8c916a2f2c8507b677
|
7
|
+
data.tar.gz: aaeb0c898cba2f93d0bd6e44ed2f198afbc932e714b91e3d31d34076750bbfc7db0785611f156f4478ff6d7013c166509849b7eb29dc334700dde57530354db9
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
*.gem
|
11
|
+
*.rbc
|
12
|
+
.config
|
13
|
+
InstalledFiles
|
14
|
+
rdoc
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
*.bundle
|
18
|
+
*.so
|
19
|
+
*.o
|
20
|
+
*.a
|
21
|
+
mkmf.log
|
22
|
+
.droppper
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Droppper
|
2
|
+
|
3
|
+
Droppper is a CLI for DigitalOcean using DigitalOcean's API v2
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install droppper
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
droppper help
|
12
|
+
|
13
|
+
## Contributing
|
14
|
+
|
15
|
+
1. Fork it ( https://github.com/cristianbica/droppper/fork )
|
16
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
17
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
18
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
19
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/droppper
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
Signal.trap("INT") { exit 1 }
|
4
|
+
|
5
|
+
require 'gli'
|
6
|
+
require 'droppper'
|
7
|
+
|
8
|
+
include GLI::App
|
9
|
+
|
10
|
+
subcommand_option_handling :normal
|
11
|
+
|
12
|
+
program_desc 'Droppper is a CLI for your DigitalOcean cloud'
|
13
|
+
sort_help :manually
|
14
|
+
|
15
|
+
flag [:token], desc: "DigitalOcean Token", arg_name: "token", optional: true
|
16
|
+
|
17
|
+
# This gem commands
|
18
|
+
commands = Dir[File.join(File.expand_path("../../lib", __FILE__), "**", "commands", "*.rb")]
|
19
|
+
|
20
|
+
# Commands from other gems
|
21
|
+
Gem::Specification.latest_specs.select{|g| g.name =~ /droppper-/ }.each do |g|
|
22
|
+
begin
|
23
|
+
g.full_require_paths.each do |path|
|
24
|
+
Dir[File.join(path, "**", "commands", "*.rb")].each do |commands_files|
|
25
|
+
commands += commands_files
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
commands.each do |file|
|
33
|
+
require file
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
pre do |global,command,options,args|
|
38
|
+
token = global[:token] || Droppper::Utils.find_token
|
39
|
+
help_now! "You must provide a DigitalOcean API v2 token. You can specify it in the command line or write it in a .droppper file. When running droppper it will try to use the 'nearest' .droppper file (in current dir or parent dir and so on; it defaults to ~/.droppper) " unless token
|
40
|
+
Droppper.client = DropletKit::Client.new(access_token: token)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
post do |global,command,options,args|
|
45
|
+
end
|
46
|
+
|
47
|
+
on_error do |exception|
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
exit run(ARGV)
|
data/droppper.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'droppper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "droppper"
|
8
|
+
spec.version = Droppper::VERSION
|
9
|
+
spec.authors = ["Cristian Bica"]
|
10
|
+
spec.email = ["cristian.bica@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{DigitalOcean CLI.}
|
13
|
+
spec.description = %q{DigitalOcean CLI using DigitalOcean's API v2.}
|
14
|
+
spec.homepage = "https://github.com/cristianbica/droppper"
|
15
|
+
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "gli", ">= 2.0"
|
23
|
+
spec.add_dependency "highline"
|
24
|
+
spec.add_dependency "table_print"
|
25
|
+
spec.add_dependency "droplet_kit"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
data/lib/droppper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "droppper/version"
|
2
|
+
require "droppper/utils"
|
3
|
+
require "droplet_kit"
|
4
|
+
require 'table_print'
|
5
|
+
require 'highline/import'
|
6
|
+
|
7
|
+
module Droppper
|
8
|
+
class << self
|
9
|
+
def client
|
10
|
+
@client
|
11
|
+
end
|
12
|
+
|
13
|
+
def client=(client)
|
14
|
+
@client = client
|
15
|
+
end
|
16
|
+
|
17
|
+
def droplets(*args)
|
18
|
+
args = args.flatten
|
19
|
+
data = client.droplets.all.to_a
|
20
|
+
if args.size > 0
|
21
|
+
data = data.select do |d|
|
22
|
+
(args.size==1 and (d.id.to_s == args[0] or d.name == args[0])) or (d.name =~ Regexp.new(args.join(".*")))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
data
|
26
|
+
end
|
27
|
+
|
28
|
+
def droplet(*args)
|
29
|
+
list = droplets(*args)
|
30
|
+
if list.size == 0
|
31
|
+
puts "Cannot find droplet"
|
32
|
+
elsif list.size == 1
|
33
|
+
list.first
|
34
|
+
else
|
35
|
+
select_droplet(list)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def select_droplet(list)
|
40
|
+
choose do |menu|
|
41
|
+
menu.prompt = "Multiple droplets found. Select one:"
|
42
|
+
list.each do |droplet|
|
43
|
+
menu.choice droplet.name do droplet end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def ssh(droplet, options={})
|
49
|
+
cmd_options = [
|
50
|
+
"-o", "IdentitiesOnly=yes",
|
51
|
+
"-o", "LogLevel=ERROR",
|
52
|
+
"-o", "StrictHostKeyChecking=no",
|
53
|
+
"-o", "UserKnownHostsFile=/dev/null",
|
54
|
+
"-i", "#{Dir.home}/.ssh/id_rsa"
|
55
|
+
]
|
56
|
+
cmd_options.push "-l", "#{options[:user]}" if options[:user]
|
57
|
+
cmd_options.push "-p", "#{options[:port]}" if options[:port]
|
58
|
+
cmd_options << droplet.public_ip
|
59
|
+
# puts "Executing: ssh #{cmd_options.join(" ")}"
|
60
|
+
Kernel.exec("ssh", *cmd_options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
desc "Manage your DigitalOcean droplets"
|
2
|
+
command :droplets do |c|
|
3
|
+
c.default_command :list
|
4
|
+
|
5
|
+
c.desc "List droplets"
|
6
|
+
c.arg "search_string"
|
7
|
+
c.command :list do |list|
|
8
|
+
list.action do |global,options,args|
|
9
|
+
data = Droppper.droplets(args)
|
10
|
+
if data.size == 0
|
11
|
+
puts "No droplets found"
|
12
|
+
else
|
13
|
+
tp data, {id: {display_name: "ID"}},
|
14
|
+
{name: {display_name: "NAME"}},
|
15
|
+
{"region.slug" => {display_name: "REGION"}},
|
16
|
+
{"size_slug" => {display_name: "SIZE"}},
|
17
|
+
:status,
|
18
|
+
:locked
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
c.desc "Show a droplet details"
|
24
|
+
c.arg "droplet_id_or_search_string"
|
25
|
+
c.command :show do |show|
|
26
|
+
show.action do |global,options,args|
|
27
|
+
droplet = Droppper.droplet(args)
|
28
|
+
puts Droppper::Utils.print_hash droplet.as_json
|
29
|
+
puts ""
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# c.desc "Create a droplet"
|
34
|
+
# c.command :create do |create|
|
35
|
+
# create.flag :name, desc: "Hostname"
|
36
|
+
# create.flag :region, desc: "Region slug"
|
37
|
+
# create.flag :size, desc: "Droplet size slug"
|
38
|
+
# create.flag :image, desc: "Image ID or slug"
|
39
|
+
# create.flag :ssh_keys, desc: "Comma separated SSH keys IDs or names or fingerprint. Pass 'all' to enable all SSH keys", default: "all"
|
40
|
+
# create.switch :backups, default: true, desc: "Enable backups"
|
41
|
+
# create.switch :ipv6, default: true, desc: "Enable IPv6"
|
42
|
+
# create.switch :private_networking, default: true, desc: "Enable private networking"
|
43
|
+
|
44
|
+
# create.action do |global,options,args|
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
desc "SSH to your DigitalOcean droplets"
|
2
|
+
command :ssh do |cmd|
|
3
|
+
cmd.flag [:u, :user], desc: "SSH Username", default_value: 'deploy'
|
4
|
+
cmd.flag [:p, :port], desc: "SSH Port", default_value: '22'
|
5
|
+
|
6
|
+
cmd.action do |global,options,args|
|
7
|
+
droplet = Droppper.droplet(args)
|
8
|
+
if droplet
|
9
|
+
Droppper.ssh droplet, user: options[:user], port: options[:port]
|
10
|
+
else
|
11
|
+
puts "Cannot find any droplet"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Droppper
|
2
|
+
module Utils extend self
|
3
|
+
def find_token
|
4
|
+
f = find_dot_dropper_file
|
5
|
+
File.open(f).read.strip if f
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_dot_dropper_file
|
9
|
+
find_nearest_dot_dropper_file || default_drop_droppper_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_nearest_dot_dropper_file(root=Dir.pwd)
|
13
|
+
f = File.expand_path ".droppper", root
|
14
|
+
return f if File.exists?(f)
|
15
|
+
return nil if root=='/'
|
16
|
+
find_nearest_dot_dropper_file(File.expand_path("..", root))
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_drop_droppper_file
|
20
|
+
f = File.join(File.expand_path("~"), ".droppper")
|
21
|
+
return f if File.exists?(f)
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_hash(hash, include_empty=false)
|
25
|
+
lines = []
|
26
|
+
recursive_flatten_hash(hash).each do |key, value|
|
27
|
+
lines << "#{key.upcase}: #{value}" if include_empty || value.present?
|
28
|
+
end
|
29
|
+
lines.join("\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
def recursive_flatten_hash(hash)
|
33
|
+
h = {}
|
34
|
+
hash.each do |key, value|
|
35
|
+
if value.is_a?(Array)
|
36
|
+
value = value.map.with_index{|v, i| {i => v} }.inject(&:merge)
|
37
|
+
end
|
38
|
+
if value.is_a?(Hash)
|
39
|
+
recursive_flatten_hash(value).each do |key2, value2|
|
40
|
+
h["#{key}.#{key2}"] = value2
|
41
|
+
end
|
42
|
+
else
|
43
|
+
h[key] = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
h
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: droppper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cristian Bica
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gli
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: highline
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: table_print
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: droplet_kit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.10'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.10'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
description: DigitalOcean CLI using DigitalOcean's API v2.
|
98
|
+
email:
|
99
|
+
- cristian.bica@gmail.com
|
100
|
+
executables:
|
101
|
+
- droppper
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- Gemfile
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- bin/droppper
|
110
|
+
- droppper.gemspec
|
111
|
+
- lib/droppper.rb
|
112
|
+
- lib/droppper/commands/droplets.rb
|
113
|
+
- lib/droppper/commands/ssh.rb
|
114
|
+
- lib/droppper/utils.rb
|
115
|
+
- lib/droppper/version.rb
|
116
|
+
homepage: https://github.com/cristianbica/droppper
|
117
|
+
licenses: []
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.4.5
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: DigitalOcean CLI.
|
139
|
+
test_files: []
|
140
|
+
has_rdoc:
|