cloudstack-cli 0.0.5 → 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.
- data/Gemfile.lock +1 -5
- data/README.md +6 -6
- data/cloudstack-cli.gemspec +0 -1
- data/lib/cloudstack-cli/base.rb +36 -0
- data/lib/cloudstack-cli/cli.rb +20 -19
- data/lib/cloudstack-cli/commands/account.rb +12 -5
- data/lib/cloudstack-cli/commands/capacity.rb +34 -0
- data/lib/cloudstack-cli/commands/domain.rb +6 -5
- data/lib/cloudstack-cli/commands/load_balancer.rb +24 -30
- data/lib/cloudstack-cli/commands/network.rb +28 -49
- data/lib/cloudstack-cli/commands/offering.rb +18 -29
- data/lib/cloudstack-cli/commands/project.rb +7 -5
- data/lib/cloudstack-cli/commands/publicip.rb +3 -4
- data/lib/cloudstack-cli/commands/router.rb +44 -62
- data/lib/cloudstack-cli/commands/server.rb +39 -32
- data/lib/cloudstack-cli/commands/stack.rb +3 -11
- data/lib/cloudstack-cli/commands/template.rb +10 -12
- data/lib/cloudstack-cli/commands/volume.rb +9 -10
- data/lib/cloudstack-cli/commands/zone.rb +6 -5
- data/lib/cloudstack-cli/helper.rb +8 -86
- data/lib/cloudstack-cli/version.rb +1 -1
- data/lib/cloudstack-client/client.rb +18 -11
- data/lib/cloudstack_cli.rb +2 -3
- metadata +23 -23
- checksums.yaml +0 -7
data/Gemfile.lock
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cloudstack-cli (0.0.
|
5
|
-
command_line_reporter (~> 3.2.1)
|
4
|
+
cloudstack-cli (0.0.5)
|
6
5
|
net-ssh (~> 2.6.7)
|
7
6
|
rainbow (~> 1.1.4)
|
8
7
|
thor (~> 0.18.1)
|
@@ -10,9 +9,6 @@ PATH
|
|
10
9
|
GEM
|
11
10
|
remote: https://rubygems.org/
|
12
11
|
specs:
|
13
|
-
colored (1.2)
|
14
|
-
command_line_reporter (3.2.1)
|
15
|
-
colored (>= 1.2)
|
16
12
|
json (1.8.0)
|
17
13
|
net-ssh (2.6.8)
|
18
14
|
rainbow (1.1.4)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Cloudstack CLI
|
2
2
|
|
3
|
-
Cloudstack CLI
|
3
|
+
Cloudstack CLI is a [CloudStack](http://cloudstack.apache.org/) API client written in Ruby.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -12,7 +12,7 @@ Install the cloudstack-cli gem:
|
|
12
12
|
|
13
13
|
Create the initial configuration:
|
14
14
|
|
15
|
-
cs setup
|
15
|
+
$ cs setup
|
16
16
|
|
17
17
|
cloudstack-cli expects to find a configuartion file with the API URL and your CloudStack credentials in your home directory named .cloudstack-cli.yml. If the file is located elsewhere you can specify the loaction using the --config option.
|
18
18
|
|
@@ -40,24 +40,24 @@ Bootsrap a server:
|
|
40
40
|
|
41
41
|
Run a custom API command:
|
42
42
|
|
43
|
-
cs command listAlerts type=8
|
43
|
+
$ cs command listAlerts type=8
|
44
44
|
|
45
45
|
### Example 3
|
46
46
|
|
47
47
|
Sort all computing offerings by CPU and Memory grouped my Domain:
|
48
48
|
|
49
|
-
cs offering sort
|
49
|
+
$ cs offering sort
|
50
50
|
|
51
51
|
### Example 4
|
52
52
|
|
53
53
|
Stop all virtual routers of project Demo (you could filter by Zone too):
|
54
54
|
(This command is helpful if you have to deploy new versions of Cloudstack when using redumdant routers)
|
55
55
|
|
56
|
-
cs router list --project Demo --status running --redundant-state BACKUP --command stop
|
56
|
+
$ cs router list --project Demo --status running --redundant-state BACKUP --command stop
|
57
57
|
|
58
58
|
Hint: You can watch the status of the command with watch.
|
59
59
|
|
60
|
-
watch -n cs router list --project Demo
|
60
|
+
$ watch -n cs router list --project Demo
|
61
61
|
|
62
62
|
|
63
63
|
## References
|
data/cloudstack-cli.gemspec
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
module CloudstackCli
|
2
|
+
class Base < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
# catch control-c and exit
|
7
|
+
trap("SIGINT") {
|
8
|
+
puts
|
9
|
+
puts "bye"
|
10
|
+
exit!
|
11
|
+
}
|
12
|
+
|
13
|
+
no_commands do
|
14
|
+
def client
|
15
|
+
@config ||= CloudstackClient::ConnectionHelper.load_configuration(options[:config])
|
16
|
+
@client ||= CloudstackClient::Connection.new(
|
17
|
+
@config[:url],
|
18
|
+
@config[:api_key],
|
19
|
+
@config[:secret_key]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_project(project_name = options[:project])
|
24
|
+
unless project = client.get_project(project_name)
|
25
|
+
say "Project '#{options[:project]}' not found", :red
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
project
|
29
|
+
end
|
30
|
+
|
31
|
+
def filter_by(objects, tag_name, tag)
|
32
|
+
objects.select {|r| r[tag_name].downcase == tag }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/cloudstack-cli/cli.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module CloudstackCli
|
2
|
-
|
3
|
-
|
4
|
-
class Cli < Thor
|
2
|
+
class Cli < CloudstackCli::Base
|
5
3
|
include Thor::Actions
|
6
4
|
|
7
5
|
package_name "cloudstack-cli"
|
@@ -24,8 +22,8 @@ module CloudstackCli
|
|
24
22
|
def setup(file = options[:config])
|
25
23
|
config = {}
|
26
24
|
unless options[:url]
|
27
|
-
say "What's the URL of your Cloudstack API?", :
|
28
|
-
say "Example: https://my-cloudstack-server/client/api/", :
|
25
|
+
say "What's the URL of your Cloudstack API?", :yellow
|
26
|
+
say "Example: https://my-cloudstack-server/client/api/", :yellow
|
29
27
|
config[:url] = ask("URL:", :magenta)
|
30
28
|
end
|
31
29
|
|
@@ -55,46 +53,49 @@ module CloudstackCli
|
|
55
53
|
puts JSON.pretty_generate(client.cs.send_request params)
|
56
54
|
end
|
57
55
|
|
58
|
-
desc "zone SUBCOMMAND ...ARGS", "
|
56
|
+
desc "zone SUBCOMMAND ...ARGS", "Manage zones"
|
59
57
|
subcommand "zone", Zone
|
60
58
|
|
61
|
-
desc "project SUBCOMMAND ...ARGS", "
|
59
|
+
desc "project SUBCOMMAND ...ARGS", "Manage servers"
|
62
60
|
subcommand "project", Project
|
63
61
|
|
64
|
-
desc "server SUBCOMMAND ...ARGS", "
|
62
|
+
desc "server SUBCOMMAND ...ARGS", "Manage servers"
|
65
63
|
subcommand "server", Server
|
66
64
|
|
67
|
-
desc "offering SUBCOMMAND ...ARGS", "
|
65
|
+
desc "offering SUBCOMMAND ...ARGS", "Manage offerings"
|
68
66
|
subcommand "offering", Offering
|
69
67
|
|
70
|
-
desc "network SUBCOMMAND ...ARGS", "
|
68
|
+
desc "network SUBCOMMAND ...ARGS", "Manage networks"
|
71
69
|
subcommand "network", Network
|
72
70
|
|
73
|
-
desc "lb SUBCOMMAND ...ARGS", "
|
71
|
+
desc "lb SUBCOMMAND ...ARGS", "Manage load balancing rules"
|
74
72
|
subcommand "lb", Lb
|
75
73
|
|
76
|
-
desc "template SUBCOMMAND ...ARGS", "
|
74
|
+
desc "template SUBCOMMAND ...ARGS", "Manage template"
|
77
75
|
subcommand "template", Template
|
78
76
|
|
79
|
-
desc "router SUBCOMMAND ...ARGS", "
|
77
|
+
desc "router SUBCOMMAND ...ARGS", "Manage virtual routers"
|
80
78
|
subcommand "router", Router
|
81
79
|
|
82
|
-
desc "router SUBCOMMAND ...ARGS", "
|
80
|
+
desc "router SUBCOMMAND ...ARGS", "Manage virtual routers"
|
83
81
|
subcommand "router", Router
|
84
82
|
|
85
|
-
desc "volume SUBCOMMAND ...ARGS", "
|
83
|
+
desc "volume SUBCOMMAND ...ARGS", "Manage volumes"
|
86
84
|
subcommand "volume", Volume
|
87
85
|
|
88
|
-
desc "stack SUBCOMMAND ...ARGS", "
|
86
|
+
desc "stack SUBCOMMAND ...ARGS", "Manage stacks"
|
89
87
|
subcommand "stack", Stack
|
90
88
|
|
91
|
-
desc "account SUBCOMMAND ...ARGS", "
|
89
|
+
desc "account SUBCOMMAND ...ARGS", "Manage accounts"
|
92
90
|
subcommand "account", Account
|
93
91
|
|
94
|
-
desc "domain SUBCOMMAND ...ARGS", "
|
92
|
+
desc "domain SUBCOMMAND ...ARGS", "Manage domains"
|
95
93
|
subcommand "domain", Domain
|
96
94
|
|
97
|
-
desc "publicip SUBCOMMAND ...ARGS", "
|
95
|
+
desc "publicip SUBCOMMAND ...ARGS", "Manage public ip addresses"
|
98
96
|
subcommand "publicip", Publicip
|
97
|
+
|
98
|
+
desc "capacity SUBCOMMAND ...ARGS", "Lists all the system wide capacities"
|
99
|
+
subcommand "capacity", Capacity
|
99
100
|
end
|
100
101
|
end
|
@@ -1,15 +1,22 @@
|
|
1
|
-
class Account <
|
1
|
+
class Account < CloudstackCli::Base
|
2
2
|
|
3
|
-
|
3
|
+
TYPES = {
|
4
|
+
0 => 'user',
|
5
|
+
1 => 'domain-admin',
|
6
|
+
2 => 'admin'
|
7
|
+
}
|
8
|
+
|
9
|
+
desc 'list [NAME]', 'list accounts'
|
4
10
|
def list(name = nil)
|
5
|
-
|
6
|
-
accounts = cs_cli.list_accounts(name)
|
11
|
+
accounts = client.list_accounts({name: name})
|
7
12
|
if accounts.size < 1
|
8
13
|
puts "No accounts found"
|
9
14
|
else
|
15
|
+
table = [["Name", "Type", "Domain"]]
|
10
16
|
accounts.each do |account|
|
11
|
-
|
17
|
+
table << [account['name'], TYPES[account['accounttype']], account['domain']]
|
12
18
|
end
|
19
|
+
print_table table
|
13
20
|
end
|
14
21
|
end
|
15
22
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Capacity < CloudstackCli::Base
|
2
|
+
TYPES = {
|
3
|
+
0 => "Memory",
|
4
|
+
1 => "CPU",
|
5
|
+
2 => "Storage",
|
6
|
+
3 => "Storage Allocated",
|
7
|
+
4 => "Public IP's",
|
8
|
+
5 => "Private IP's",
|
9
|
+
6 => "Secondary Storage",
|
10
|
+
7 => "VLAN",
|
11
|
+
8 => "Direct Attached Public IP's",
|
12
|
+
9 => "Local Storage"
|
13
|
+
}
|
14
|
+
|
15
|
+
desc "list", "list system capacity"
|
16
|
+
option :zone
|
17
|
+
def list
|
18
|
+
capacities = client.list_capacity
|
19
|
+
table = []
|
20
|
+
header = ["Zone", "Type", "Capacity Used", "Capacity Total", "Used"]
|
21
|
+
capacities.each do |c|
|
22
|
+
table << [
|
23
|
+
c['zonename'],
|
24
|
+
TYPES[c['type']],
|
25
|
+
c['capacityused'],
|
26
|
+
c['capacitytotal'],
|
27
|
+
"#{c['percentused']}%"
|
28
|
+
]
|
29
|
+
end
|
30
|
+
table = table.sort {|a, b| [a[0], a[1]] <=> [b[0], b[1]]}.insert(0, header)
|
31
|
+
print_table table
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -1,15 +1,16 @@
|
|
1
|
-
class Domain <
|
1
|
+
class Domain < CloudstackCli::Base
|
2
2
|
|
3
|
-
desc '
|
3
|
+
desc 'list [NAME]', 'list domains'
|
4
4
|
def list(name = nil)
|
5
|
-
|
6
|
-
domains = cs_cli.domains(name)
|
5
|
+
domains = client.list_domains(name)
|
7
6
|
if domains.size < 1
|
8
7
|
puts "No domains found"
|
9
8
|
else
|
9
|
+
table = [["Name", "Path"]]
|
10
10
|
domains.each do |domain|
|
11
|
-
|
11
|
+
table << [domain['name'], domain['path']]
|
12
12
|
end
|
13
|
+
print_table table
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -1,59 +1,53 @@
|
|
1
|
-
class Lb <
|
1
|
+
class Lb < CloudstackCli::Base
|
2
2
|
|
3
|
-
desc "
|
3
|
+
desc "list", "list load balancer rules"
|
4
4
|
option :project
|
5
5
|
def list
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
rules = cs_cli.list_load_balancer_rules(project ? project['id'] : nil)
|
6
|
+
project = find_project if options[:project]
|
7
|
+
rules = client.list_load_balancer_rules(
|
8
|
+
{ project_name: project ? project['name'] : nil }
|
9
|
+
)
|
13
10
|
if rules.size < 1
|
14
11
|
puts "No load balancer rules found"
|
15
12
|
else
|
13
|
+
table = [["Name", "Public-IP", "Public-Port"]]
|
16
14
|
rules.each do |rule|
|
17
|
-
|
15
|
+
table << [rule['name'], rule['publicip'], rule['publicport']]
|
18
16
|
end
|
17
|
+
print_table table
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
|
-
desc "
|
21
|
+
desc "create NAME", "create load balancer rule"
|
23
22
|
option :project
|
24
|
-
option :ip, :
|
25
|
-
option :public_port, :
|
23
|
+
option :ip, required: true
|
24
|
+
option :public_port, required: true
|
26
25
|
option :private_port
|
27
26
|
def create(name)
|
28
|
-
|
29
|
-
if options[:project]
|
30
|
-
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
31
|
-
exit_now! "Project '#{options[:project]}' not found" unless project
|
32
|
-
end
|
33
|
-
|
27
|
+
project = find_project
|
34
28
|
options[:private_port] = options[:public_port] if options[:private_port] == nil
|
35
|
-
|
36
|
-
rule =
|
29
|
+
say "Create rule #{name}...", :yellow
|
30
|
+
rule = client.create_load_balancer_rule(
|
37
31
|
name,
|
38
32
|
options[:ip],
|
39
33
|
options[:private_port],
|
40
34
|
options[:public_port],
|
41
35
|
)
|
36
|
+
say "OK!", :green
|
42
37
|
end
|
43
38
|
|
44
|
-
desc "
|
45
|
-
option :project
|
39
|
+
desc "add NAME", "assign servers to balancer rule"
|
46
40
|
option :servers, required: true, type: :array, description: 'server names'
|
47
41
|
def add(name)
|
48
|
-
|
49
|
-
|
50
|
-
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
51
|
-
exit_now! "Project '#{options[:project]}' not found" unless project
|
52
|
-
end
|
53
|
-
|
54
|
-
rule = cs_cli.assign_to_load_balancer_rule(
|
42
|
+
say "Add #{names.join(', ')} to rule #{id}...", :yellow
|
43
|
+
rule = client.assign_to_load_balancer_rule(
|
55
44
|
name,
|
56
45
|
options[:servers],
|
57
46
|
)
|
47
|
+
if rule['success']
|
48
|
+
say "OK!", :green
|
49
|
+
else
|
50
|
+
say "Failed!", :red
|
51
|
+
end
|
58
52
|
end
|
59
53
|
end
|
@@ -1,71 +1,50 @@
|
|
1
|
-
class Network <
|
2
|
-
include CommandLineReporter
|
1
|
+
class Network < CloudstackCli::Base
|
3
2
|
|
4
|
-
desc "
|
3
|
+
desc "create NAME", "create network"
|
5
4
|
def create(name)
|
6
|
-
|
7
|
-
|
5
|
+
# TODO
|
8
6
|
end
|
9
7
|
|
10
|
-
desc "
|
8
|
+
desc "list", "list networks"
|
11
9
|
option :project
|
12
10
|
option :physical, type: :boolean
|
13
11
|
def list
|
14
|
-
|
15
|
-
if options[:project]
|
16
|
-
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
17
|
-
raise "Project '#{options[:project]}' not found" unless project
|
18
|
-
end
|
19
|
-
|
12
|
+
project = find_project if options[:project]
|
20
13
|
if options[:physical]
|
21
|
-
networks =
|
14
|
+
networks = client.list_physical_networks
|
22
15
|
if networks.size < 1
|
23
16
|
puts "No networks found"
|
24
17
|
else
|
25
|
-
table
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
row do
|
34
|
-
column network["id"]
|
35
|
-
column network["name"]
|
36
|
-
column network["zoneid"]
|
37
|
-
column network["state"]
|
38
|
-
end
|
39
|
-
end
|
18
|
+
table = [['Name', 'State', 'ID', 'Zone ID']]
|
19
|
+
networks.each do |network|
|
20
|
+
table << [
|
21
|
+
network["name"],
|
22
|
+
network["state"],
|
23
|
+
network["id"],
|
24
|
+
network["zoneid"]
|
25
|
+
]
|
40
26
|
end
|
27
|
+
print_table table
|
41
28
|
end
|
42
29
|
else
|
43
|
-
networks =
|
30
|
+
networks = client.list_networks(project ? project['id'] : -1)
|
44
31
|
if networks.size < 1
|
45
32
|
puts "No networks found"
|
46
33
|
else
|
47
|
-
table
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
row do
|
58
|
-
column network["id"]
|
59
|
-
column network["name"]
|
60
|
-
column network["displaytext"]
|
61
|
-
column network["account"] unless options[:project]
|
62
|
-
column network["project"] if options[:listall] || options[:project]
|
63
|
-
column network["state"]
|
64
|
-
end
|
65
|
-
end
|
34
|
+
table = [["Name", "Displaytext", "Account", "Project", "State", "ID"]]
|
35
|
+
networks.each do |network|
|
36
|
+
table << [
|
37
|
+
network["name"],
|
38
|
+
network["displaytext"],
|
39
|
+
network["account"],
|
40
|
+
network["project"],
|
41
|
+
network["state"],
|
42
|
+
network["id"]
|
43
|
+
]
|
66
44
|
end
|
45
|
+
print_table table
|
67
46
|
end
|
68
47
|
end
|
69
|
-
|
70
48
|
end
|
49
|
+
|
71
50
|
end
|