docli 0.0.2.pre.alpha.pre.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.byebug_history +142 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +18 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dev-build.sh +4 -0
- data/docli.gemspec +54 -0
- data/example/new-droplets.yaml +20 -0
- data/example/resources.template +231 -0
- data/exe/docli +5 -0
- data/lib/cmd/account.rb +12 -0
- data/lib/cmd/actions.rb +15 -0
- data/lib/cmd/certificates.rb +1 -0
- data/lib/cmd/domain_records.rb +1 -0
- data/lib/cmd/domains.rb +13 -0
- data/lib/cmd/droplets.rb +1 -0
- data/lib/cmd/floating_ips.rb +1 -0
- data/lib/cmd/images.rb +1 -0
- data/lib/cmd/loadbalancers.rb +1 -0
- data/lib/cmd/regions.rb +1 -0
- data/lib/cmd/sizes.rb +1 -0
- data/lib/cmd/snapshots.rb +1 -0
- data/lib/cmd/sshkeys.rb +1 -0
- data/lib/cmd/tags.rb +1 -0
- data/lib/cmd/volume.rb +52 -0
- data/lib/docli/create.rb +52 -0
- data/lib/docli/delete.rb +4 -0
- data/lib/docli/get.rb +43 -0
- data/lib/docli/get_user_information.rb +1 -0
- data/lib/docli/list_all_domains.rb +10 -0
- data/lib/docli/subcommand_base.rb +11 -0
- data/lib/docli/utils.rb +14 -0
- data/lib/docli/version.rb +3 -0
- data/lib/docli.rb +127 -0
- metadata +449 -0
data/exe/docli
ADDED
data/lib/cmd/account.rb
ADDED
data/lib/cmd/actions.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# List all action of user
|
2
|
+
module Cmd
|
3
|
+
class Actions
|
4
|
+
@client = Docli.client
|
5
|
+
def self.list_all_actions
|
6
|
+
return @client.action.all
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.retrieve_existing_action action_id
|
10
|
+
return @client.actions.find(id: action_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
# DigitalOcean Certificates actions
|
@@ -0,0 +1 @@
|
|
1
|
+
# Domain records actions
|
data/lib/cmd/domains.rb
ADDED
data/lib/cmd/droplets.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Droplets actions
|
@@ -0,0 +1 @@
|
|
1
|
+
# Floating actions
|
data/lib/cmd/images.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Images actions
|
@@ -0,0 +1 @@
|
|
1
|
+
# Loadbalancer actions
|
data/lib/cmd/regions.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Region information
|
data/lib/cmd/sizes.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Size informations
|
@@ -0,0 +1 @@
|
|
1
|
+
# Snapshots informations
|
data/lib/cmd/sshkeys.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# SSHkeys actions and informations
|
data/lib/cmd/tags.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Tags actions and informations
|
data/lib/cmd/volume.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Block storage actions and informations
|
2
|
+
|
3
|
+
|
4
|
+
module CMD
|
5
|
+
class Volumes
|
6
|
+
@client = Docli.client
|
7
|
+
# volume_options = {
|
8
|
+
# :size_gigabytes => integer,
|
9
|
+
# :name => string,
|
10
|
+
# :description => string,
|
11
|
+
# :region => string,
|
12
|
+
# :snapshot_id => string
|
13
|
+
# }
|
14
|
+
def self.create_new_volume volume_options
|
15
|
+
new_volume = DropletKit::Volume.new(
|
16
|
+
size_gigabytes: volume_options[size_gigabytes],
|
17
|
+
name: volume_options[:name],
|
18
|
+
description: volume_options[:description],
|
19
|
+
region: volume_options[:region],
|
20
|
+
snapshot_id: volume_options[:snapshot_id]
|
21
|
+
)
|
22
|
+
return @client.volumes.create(new_volume)
|
23
|
+
end
|
24
|
+
|
25
|
+
# options = {
|
26
|
+
# volume_id => string / volume_name => string
|
27
|
+
# droplet_id => integer
|
28
|
+
# region =>
|
29
|
+
# }
|
30
|
+
def self.attach_volume_to_droplet options
|
31
|
+
return @client.volume_actions.attach(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.list_all_volumes
|
35
|
+
return @client.volumes.all
|
36
|
+
end
|
37
|
+
|
38
|
+
# options = {
|
39
|
+
# volume_id => string / volume_name => string
|
40
|
+
# droplet_id => integer
|
41
|
+
# region =>
|
42
|
+
# }
|
43
|
+
def self.attach_volume_to_droplet options
|
44
|
+
return @client.volume_actions.detach(options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.retrieve_existing_volume volume_id
|
48
|
+
return @client.volumes.find(id: volume_id)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/docli/create.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Docli
|
2
|
+
class Create < SubcommandBase
|
3
|
+
def self.help(*args)
|
4
|
+
super
|
5
|
+
puts <<-INSTRUCTION
|
6
|
+
Examples:
|
7
|
+
docli create -f resources.yaml # Create resources from YAML file
|
8
|
+
|
9
|
+
INSTRUCTION
|
10
|
+
end
|
11
|
+
|
12
|
+
method_option :filename, aliases: '-f', desc: 'Filename to use to create the resource'
|
13
|
+
|
14
|
+
def initialize(args = [], local_options = {}, config = {})
|
15
|
+
puts "`create droplet` called with options: #{options}" if Docli.debug?
|
16
|
+
super
|
17
|
+
if options[:filename]
|
18
|
+
puts "create -f called with options: #{options}" if Docli.debug?
|
19
|
+
config = YAML.load(File.open(options[:filename]))
|
20
|
+
puts "YAML Loaded:"
|
21
|
+
puts config
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'droplet', 'Create a droplet'
|
27
|
+
method_option :name , aliases: '-n', desc: 'droplet name (require for the hostname of droplets', required: true
|
28
|
+
method_option :region , aliases: '-r', desc: 'droplet region', default: 'NYC1'
|
29
|
+
method_option :size , aliases: '-s', desc: 'size of droplet, ex: 512mb, 1gb ...', default: '512mb'
|
30
|
+
method_option :image , aliases: '-i', desc: 'mage name or image id', default: 'Ubuntu 16x04'
|
31
|
+
method_option :user_data , aliases: '-u', desc: 'add command or cloud config on first boot'
|
32
|
+
method_option :ipv6 , desc: 'turn on or off ipv6', type: :boolean, default: true
|
33
|
+
method_option :private_networking, aliases: '-p', desc: 'turn on or off private networking', type: :boolean, lazy_default: true
|
34
|
+
method_option :monitoring , aliases: '-m', desc: 'turn on or off monitoring', type: :boolean, lazy_default: true
|
35
|
+
method_option :backups , aliases: '-b', desc: 'turn on or off auto backup', type: :boolean, lazy_default: true
|
36
|
+
method_option :tags , aliases: '-t', desc: 'add tags', type: :array
|
37
|
+
|
38
|
+
# method_options :volumes, :ssh_keys .... # TODO: consider to enable these options
|
39
|
+
|
40
|
+
def droplet
|
41
|
+
droplet_obj = DropletKit::Droplet.new(options)
|
42
|
+
Docli.client.droplets.create(droplet_obj)
|
43
|
+
tp(
|
44
|
+
:id => droplet_obj.id,
|
45
|
+
:name => droplet_obj.name,
|
46
|
+
:region => droplet_obj.region.name,
|
47
|
+
:size => droplet_obj.size,
|
48
|
+
:status => droplet_obj.status
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/docli/delete.rb
ADDED
data/lib/docli/get.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Docli
|
2
|
+
class Get < SubcommandBase
|
3
|
+
desc 'droplets', 'List droplets'
|
4
|
+
method_option :tag_name, aliases: '-t', desc: 'filter by tag name', type: :string
|
5
|
+
def droplets(droplet_id = nil)
|
6
|
+
## Sometime user confuse with `docli get droplet` and `docli get droplets`
|
7
|
+
## This enabled: docli get droplets DROPLET_ID
|
8
|
+
## IMPROVEMENT: Consider to enable or disable this feature
|
9
|
+
return invoke :droplet if droplet_id
|
10
|
+
##
|
11
|
+
puts "`get droplets` called with options: #{options}" if Docli.debug?
|
12
|
+
droplet_objects = Docli.client.droplets.all(options.symbolize_keys)
|
13
|
+
tp(
|
14
|
+
droplet_objects.map do |drlet|
|
15
|
+
{
|
16
|
+
id: drlet.id,
|
17
|
+
name: drlet.name,
|
18
|
+
ipv4: drlet.networks.v4.find { |v| v.type == 'public' }.ip_address,
|
19
|
+
region: drlet.region.slug,
|
20
|
+
size: drlet.size_slug,
|
21
|
+
status: Docli::Utils.colorize(drlet.status)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'droplet', 'Show a droplet by id'
|
28
|
+
def droplet(droplet_id)
|
29
|
+
puts "`get droplet` called with params: #{droplet_id}, options: #{options}" if Docli.debug?
|
30
|
+
drlet = Docli.client.droplets.find(id: droplet_id)
|
31
|
+
puts "Droplet ID: #{drlet.id}"
|
32
|
+
{
|
33
|
+
name: drlet.name,
|
34
|
+
ipv4: drlet.networks.v4.find { |v| v.type == 'public' }.ip_address,
|
35
|
+
region: "#{drlet.region.name} (#{drlet.region.slug})",
|
36
|
+
size: drlet.size_slug,
|
37
|
+
status: drlet.status
|
38
|
+
}.each do |k,v|
|
39
|
+
puts "\t#{k}: #{v}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# User account information
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Docli
|
2
|
+
class SubcommandBase < Thor
|
3
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
4
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.subcommand_prefix
|
8
|
+
self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/docli/utils.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Docli
|
2
|
+
module Utils
|
3
|
+
class << self
|
4
|
+
COLORIZE_MAPPING = {
|
5
|
+
green: %w{active},
|
6
|
+
red: %w{}
|
7
|
+
}
|
8
|
+
def colorize(text)
|
9
|
+
color = COLORIZE_MAPPING.find { |color, values| values.include?(text) }
|
10
|
+
color ? text.method(color[0]).call : text
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/docli.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
def require_all(path)
|
2
|
+
glob = File.join(File.dirname(__FILE__), path, "*.rb")
|
3
|
+
Dir[glob].sort.each do |f|
|
4
|
+
require f
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'thor'
|
9
|
+
require 'droplet_kit'
|
10
|
+
require 'colorize'
|
11
|
+
require 'json'
|
12
|
+
require 'table_print'
|
13
|
+
require 'yaml'
|
14
|
+
require 'byebug'
|
15
|
+
require 'fileutils'
|
16
|
+
|
17
|
+
require 'docli/version'
|
18
|
+
require 'docli/subcommand_base'
|
19
|
+
require 'docli/utils'
|
20
|
+
require 'docli/create'
|
21
|
+
require 'docli/delete'
|
22
|
+
require 'docli/get'
|
23
|
+
|
24
|
+
|
25
|
+
module Docli
|
26
|
+
|
27
|
+
CONFIG_FILE = ENV['HOME'] + '/.docli/config'
|
28
|
+
|
29
|
+
@@client = nil
|
30
|
+
|
31
|
+
def self.client=(client)
|
32
|
+
@@client = client
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.client
|
36
|
+
@@client
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.debug?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
class Main < Thor
|
44
|
+
|
45
|
+
def self.start(*args)
|
46
|
+
super
|
47
|
+
rescue DropletKit::Error => ex
|
48
|
+
puts 'Error occured'.red + ": #{ex.message}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(args = [], local_options = {}, config = {})
|
52
|
+
require_config! unless %w{help init version}.include? config[:current_command].name
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
map %w[--version -v] => :version
|
57
|
+
|
58
|
+
desc 'version', 'Show version information'
|
59
|
+
def version
|
60
|
+
puts "DigitalOcean CommandLine Interface version #{Docli::VERSION}"
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'config', 'Init or update config'
|
64
|
+
def config
|
65
|
+
access_token = nil
|
66
|
+
current_config = configured? ? read_config : {}
|
67
|
+
current_access_token = current_config[:access_token]
|
68
|
+
new_access_token = ask "Your DigitalOcean access token [#{current_access_token}]: "
|
69
|
+
new_access_token = nil if new_access_token.blank?
|
70
|
+
unless access_token = new_access_token || current_access_token
|
71
|
+
puts 'Failed to config, empty access token !'
|
72
|
+
exit
|
73
|
+
else
|
74
|
+
write_config(:access_token => access_token)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'create', 'Create a resource by filename or stdin'
|
79
|
+
subcommand 'create', Create
|
80
|
+
|
81
|
+
desc 'get', 'Display one or many resource'
|
82
|
+
subcommand 'get', Get
|
83
|
+
|
84
|
+
desc 'delete', 'Delete resources by filenames, stdin, resources and names, or by resources and label selector'
|
85
|
+
subcommand 'delete', Delete
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def configured?
|
90
|
+
File.exists?(Docli::CONFIG_FILE)
|
91
|
+
end
|
92
|
+
|
93
|
+
def require_config!
|
94
|
+
unless configured?
|
95
|
+
puts "Missing config, run #{'docli config'.yellow} to init your"
|
96
|
+
exit
|
97
|
+
end
|
98
|
+
Docli.client ||= DropletKit::Client.new(access_token: read_config[:access_token])
|
99
|
+
end
|
100
|
+
|
101
|
+
def read_config
|
102
|
+
result = {}
|
103
|
+
File.read(Docli::CONFIG_FILE).split("\n").map do |line|
|
104
|
+
k, v = line.split("=").map(&:strip)
|
105
|
+
result[k.to_sym] = v
|
106
|
+
end
|
107
|
+
result
|
108
|
+
end
|
109
|
+
|
110
|
+
def write_config(config = {})
|
111
|
+
dir = Docli::CONFIG_FILE.split('/')[0..-2].join('/')
|
112
|
+
unless File.directory?(dir)
|
113
|
+
FileUtils::mkdir dir
|
114
|
+
FileUtils.touch Docli::CONFIG_FILE
|
115
|
+
puts 'Create ' + Docli::CONFIG_FILE.green
|
116
|
+
end
|
117
|
+
File.open(Docli::CONFIG_FILE, 'w+') do |file|
|
118
|
+
file.write config.map { |k,v| "#{k} = #{v}" }.join
|
119
|
+
end
|
120
|
+
puts "Config updated !"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
module CMD
|
126
|
+
require_all 'cmd'
|
127
|
+
end
|