cloudstack-cli 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|