cloudstack-cli 0.14.1 → 0.15.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/cloudstack-cli/base.rb +23 -0
- data/lib/cloudstack-cli/commands/server.rb +70 -36
- data/lib/cloudstack-cli/commands/stack.rb +1 -25
- data/lib/cloudstack-cli/commands/system_vm.rb +2 -2
- data/lib/cloudstack-cli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 908b98a2dbd0314746a8ab6f4ab5ce2c7993e718
|
|
4
|
+
data.tar.gz: eb50df278d75bab8f5b9051d307fc2c67800b0b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df3f7712ad79ed2976d2bbad453843bec5c7ac680f7646abdaa523ea61cb984a769b35fa63946f01c7a00c8932a7caef259b4758ab487797bcba56d7e4fb7266
|
|
7
|
+
data.tar.gz: 37cc848fb1928bc11ae770707743374cc2f57ce5bf3adb287a52948d11af3610ffc484e773565d7558f44429ce7d47e85620815526285ae47aaaaf7e75e42e96
|
data/Gemfile.lock
CHANGED
data/lib/cloudstack-cli/base.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "thor"
|
|
2
2
|
require "yaml"
|
|
3
|
+
require "open-uri"
|
|
3
4
|
|
|
4
5
|
module CloudstackCli
|
|
5
6
|
class Base < Thor
|
|
@@ -75,6 +76,28 @@ module CloudstackCli
|
|
|
75
76
|
def filter_by(objects, key, value)
|
|
76
77
|
objects.select {|r| r[key].downcase == value.downcase}
|
|
77
78
|
end
|
|
79
|
+
|
|
80
|
+
def parse_file(file, extensions = %w(.json .yaml .yml))
|
|
81
|
+
handler = case File.extname(file)
|
|
82
|
+
when ".json"
|
|
83
|
+
Object.const_get "JSON"
|
|
84
|
+
when ".yaml", ".yml"
|
|
85
|
+
Object.const_get "YAML"
|
|
86
|
+
else
|
|
87
|
+
say "File extension #{File.extname(file)} not supported. Supported extensions are #{extensions.join(', ')}", :red
|
|
88
|
+
exit
|
|
89
|
+
end
|
|
90
|
+
begin
|
|
91
|
+
return handler.load open(file){|f| f.read}
|
|
92
|
+
rescue SystemCallError
|
|
93
|
+
say "Can't find the file #{file}.", :red
|
|
94
|
+
exit 1
|
|
95
|
+
rescue => e
|
|
96
|
+
say "Error parsing #{File.extname(file)} file:", :red
|
|
97
|
+
say e.message
|
|
98
|
+
exit 1
|
|
99
|
+
end
|
|
100
|
+
end
|
|
78
101
|
end
|
|
79
102
|
end
|
|
80
103
|
end
|
|
@@ -9,14 +9,15 @@ class Server < CloudstackCli::Base
|
|
|
9
9
|
option :storage_id, desc: "the storage ID where vm's volumes belong to"
|
|
10
10
|
option :keyword, desc: "filter by keyword"
|
|
11
11
|
option :command,
|
|
12
|
-
desc: "command to execute for
|
|
12
|
+
desc: "command to execute for the given servers",
|
|
13
13
|
enum: %w(START STOP REBOOT)
|
|
14
14
|
option :concurrency, type: :numeric, default: 10, aliases: '-C',
|
|
15
15
|
desc: "number of concurrent command to execute"
|
|
16
|
+
option :format, default: "table",
|
|
17
|
+
enum: %w(table json yaml)
|
|
16
18
|
def list
|
|
17
19
|
if options[:project]
|
|
18
|
-
project_id = find_project['id']
|
|
19
|
-
options[:project_id] = project_id
|
|
20
|
+
options[:project_id] = find_project['id']
|
|
20
21
|
options[:project] = nil
|
|
21
22
|
end
|
|
22
23
|
options[:custom] = { 'storageid' => options[:storage_id] } if options[:storage_id]
|
|
@@ -25,40 +26,25 @@ class Server < CloudstackCli::Base
|
|
|
25
26
|
if servers.size < 1
|
|
26
27
|
puts "No servers found."
|
|
27
28
|
else
|
|
28
|
-
|
|
29
|
-
servers
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
server['state'],
|
|
33
|
-
server['serviceofferingname'],
|
|
34
|
-
server['zonename'],
|
|
35
|
-
project_id ? server['project'] : server['account'],
|
|
36
|
-
server['nic'].map { |nic| nic['ipaddress']}.join(' ')
|
|
37
|
-
]
|
|
38
|
-
end
|
|
39
|
-
print_table table
|
|
40
|
-
say "Total number of servers: #{servers.count}"
|
|
29
|
+
print_servers(servers)
|
|
30
|
+
execute_server_commands(servers) if options[:command]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
end
|
|
58
|
-
puts
|
|
59
|
-
watch_jobs(jobs)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
34
|
+
desc "list_from_file FILE", "list servers from file"
|
|
35
|
+
option :command,
|
|
36
|
+
desc: "command to execute for the given servers",
|
|
37
|
+
enum: %w(START STOP REBOOT)
|
|
38
|
+
option :concurrency, type: :numeric, default: 10, aliases: '-C',
|
|
39
|
+
desc: "number of concurrent command to execute"
|
|
40
|
+
option :format, default: :table, enum: %w(table json yaml)
|
|
41
|
+
def list_from_file(file)
|
|
42
|
+
servers = parse_file(file)["servers"]
|
|
43
|
+
if servers.size < 1
|
|
44
|
+
puts "No servers found."
|
|
45
|
+
else
|
|
46
|
+
print_servers(servers)
|
|
47
|
+
execute_server_commands(servers) if options[:command]
|
|
62
48
|
end
|
|
63
49
|
end
|
|
64
50
|
|
|
@@ -193,4 +179,52 @@ class Server < CloudstackCli::Base
|
|
|
193
179
|
puts
|
|
194
180
|
end
|
|
195
181
|
|
|
182
|
+
no_commands do
|
|
183
|
+
|
|
184
|
+
def print_servers(servers)
|
|
185
|
+
case options[:format].to_sym
|
|
186
|
+
when :yaml
|
|
187
|
+
puts({'servers' => servers}.to_yaml)
|
|
188
|
+
when :json
|
|
189
|
+
say JSON.pretty_generate(servers: servers)
|
|
190
|
+
else
|
|
191
|
+
table = [["Name", "State", "Offering", "Zone", options[:project_id] ? "Project" : "Account", "IP's"]]
|
|
192
|
+
servers.each do |server|
|
|
193
|
+
table << [
|
|
194
|
+
server['name'],
|
|
195
|
+
server['state'],
|
|
196
|
+
server['serviceofferingname'],
|
|
197
|
+
server['zonename'],
|
|
198
|
+
options[:project_id] ? server['project'] : server['account'],
|
|
199
|
+
server['nic'].map { |nic| nic['ipaddress']}.join(' ')
|
|
200
|
+
]
|
|
201
|
+
end
|
|
202
|
+
print_table table
|
|
203
|
+
say "Total number of servers: #{servers.count}"
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def execute_server_commands(servers)
|
|
208
|
+
command = options[:command].downcase
|
|
209
|
+
unless %w(start stop reboot).include?(command)
|
|
210
|
+
say "\nCommand #{options[:command]} not supported.", :red
|
|
211
|
+
exit 1
|
|
212
|
+
end
|
|
213
|
+
exit unless yes?("\n#{command.capitalize} the server(s) above? [y/N]:", :magenta)
|
|
214
|
+
servers.each_slice(options[:concurrency]) do | batch |
|
|
215
|
+
jobs = batch.map do |server|
|
|
216
|
+
args = { sync: true, account: server['account'] }
|
|
217
|
+
args[:project_id] = server['projectid'] if server['projectid']
|
|
218
|
+
{
|
|
219
|
+
id: client.send("#{command}_server", server['name'], args)['jobid'],
|
|
220
|
+
name: "#{command.capitalize} server #{server['name']}"
|
|
221
|
+
}
|
|
222
|
+
end
|
|
223
|
+
puts
|
|
224
|
+
watch_jobs(jobs)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
end # no_commands
|
|
229
|
+
|
|
196
230
|
end
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
require 'open-uri'
|
|
2
|
-
|
|
3
1
|
class Stack < CloudstackCli::Base
|
|
4
2
|
|
|
5
3
|
desc "create STACKFILE", "create a stack of servers"
|
|
6
4
|
def create(stackfile)
|
|
7
|
-
stack =
|
|
5
|
+
stack = parse_file(stackfile)
|
|
8
6
|
say "Create stack #{stack["name"]}...", :green
|
|
9
7
|
projectid = find_project(stack["project"])['id'] if stack["project"]
|
|
10
8
|
jobs = []
|
|
@@ -106,28 +104,6 @@ class Stack < CloudstackCli::Base
|
|
|
106
104
|
end
|
|
107
105
|
|
|
108
106
|
no_commands do
|
|
109
|
-
def parse_stackfile(stackfile)
|
|
110
|
-
handler = case File.extname(stackfile)
|
|
111
|
-
when ".json"
|
|
112
|
-
Object.const_get "JSON"
|
|
113
|
-
when ".yaml", ".yml"
|
|
114
|
-
Object.const_get "YAML"
|
|
115
|
-
else
|
|
116
|
-
say "File extension #{File.extname(stackfile)} not supported. Supported extensions are .json, .yaml or .yml", :red
|
|
117
|
-
exit
|
|
118
|
-
end
|
|
119
|
-
begin
|
|
120
|
-
return handler.load open(stackfile){|f| f.read}
|
|
121
|
-
rescue SystemCallError
|
|
122
|
-
say "Can't find the stack file #{stackfile}.", :red
|
|
123
|
-
exit 1
|
|
124
|
-
rescue => e
|
|
125
|
-
say "Error parsing #{File.extname(stackfile)} file:", :red
|
|
126
|
-
say e.message
|
|
127
|
-
exit 1
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
107
|
def load_string_or_array(item)
|
|
132
108
|
item.is_a?(Array) ? item : [item]
|
|
133
109
|
end
|
|
@@ -10,10 +10,10 @@ class SystemVm < CloudstackCli::Base
|
|
|
10
10
|
if vms.size < 1
|
|
11
11
|
say "No system VM's found."
|
|
12
12
|
else
|
|
13
|
-
table = [
|
|
13
|
+
table = [%w(Name Zone State Type)]
|
|
14
14
|
vms.each do |vm|
|
|
15
15
|
table << [
|
|
16
|
-
vm['
|
|
16
|
+
vm['name'], vm['zonename'], vm['state'], vm['systemvmtype']
|
|
17
17
|
]
|
|
18
18
|
end
|
|
19
19
|
print_table table
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cloudstack-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nik Wolfgramm
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-03-
|
|
11
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rdoc
|