cloudstack-cli 0.1.2 → 0.1.3
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 -1
- data/README.md +6 -6
- data/cloudstack-cli.gemspec +0 -1
- data/lib/cloudstack-cli/cli.rb +9 -9
- data/lib/cloudstack-cli/commands/ip_address.rb +33 -0
- data/lib/cloudstack-cli/commands/load_balancer.rb +1 -1
- data/lib/cloudstack-cli/commands/network.rb +10 -7
- data/lib/cloudstack-cli/commands/physical_network.rb +4 -3
- data/lib/cloudstack-cli/commands/port_rule.rb +66 -0
- data/lib/cloudstack-cli/commands/server.rb +30 -13
- data/lib/cloudstack-cli/commands/stack.rb +16 -12
- data/lib/cloudstack-cli/commands/template.rb +1 -1
- data/lib/cloudstack-cli/commands/volume.rb +1 -1
- data/lib/cloudstack-cli/helper.rb +89 -147
- data/lib/cloudstack-cli/version.rb +1 -1
- data/lib/cloudstack-client/client.rb +45 -14
- data/lib/cloudstack-client/helper.rb +1 -1
- data/lib/cloudstack_cli.rb +0 -1
- data/test/stack_example.json +2 -2
- metadata +21 -24
- checksums.yaml +0 -7
- data/lib/cloudstack-cli/commands/publicip.rb +0 -8
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -12,19 +12,19 @@ Install the cloudstack-cli gem:
|
|
12
12
|
|
13
13
|
Create the initial configuration:
|
14
14
|
|
15
|
-
|
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
|
|
19
19
|
Example content of the configuration file:
|
20
20
|
|
21
21
|
:url: "https://my-cloudstack-server/client/api/"
|
22
|
-
|
23
|
-
|
22
|
+
:api_key: "cloudstack-api-key"
|
23
|
+
:secret_key: "cloudstack-api-secret"
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
27
|
+
For additional documentation find the RubyDoc [here](http://rubydoc.info/gems/cloudstack-cli/).
|
28
28
|
|
29
29
|
See the help screen:
|
30
30
|
|
@@ -82,8 +82,8 @@ Sort all computing offerings by CPU and Memory grouped my Domain:
|
|
82
82
|
|
83
83
|
### Example 5
|
84
84
|
|
85
|
-
Stop all virtual routers of project Demo (you could filter by
|
86
|
-
(This command is helpful if you have to deploy new versions of Cloudstack when using
|
85
|
+
Stop all virtual routers of project Demo (you could filter by zone too):
|
86
|
+
(This command is helpful if you have to deploy new versions of Cloudstack when using redundant routers)
|
87
87
|
|
88
88
|
$ cs router list --project Demo --status running --redundant-state BACKUP --command stop
|
89
89
|
|
data/cloudstack-cli.gemspec
CHANGED
data/lib/cloudstack-cli/cli.rb
CHANGED
@@ -68,11 +68,11 @@ module CloudstackCli
|
|
68
68
|
desc "network SUBCOMMAND ...ARGS", "Manage networks"
|
69
69
|
subcommand "network", Network
|
70
70
|
|
71
|
-
desc "
|
72
|
-
subcommand "
|
71
|
+
desc "physical_network SUBCOMMAND ...ARGS", "Manage physical networks"
|
72
|
+
subcommand "physical_network", PhysicalNetwork
|
73
73
|
|
74
|
-
desc "
|
75
|
-
subcommand "
|
74
|
+
desc "load_balancer SUBCOMMAND ...ARGS", "Manage load balancing rules"
|
75
|
+
subcommand "load_balancer", LoadBalancer
|
76
76
|
|
77
77
|
desc "template SUBCOMMAND ...ARGS", "Manage template"
|
78
78
|
subcommand "template", Template
|
@@ -80,9 +80,6 @@ module CloudstackCli
|
|
80
80
|
desc "router SUBCOMMAND ...ARGS", "Manage virtual routers"
|
81
81
|
subcommand "router", Router
|
82
82
|
|
83
|
-
desc "router SUBCOMMAND ...ARGS", "Manage virtual routers"
|
84
|
-
subcommand "router", Router
|
85
|
-
|
86
83
|
desc "volume SUBCOMMAND ...ARGS", "Manage volumes"
|
87
84
|
subcommand "volume", Volume
|
88
85
|
|
@@ -95,10 +92,13 @@ module CloudstackCli
|
|
95
92
|
desc "domain SUBCOMMAND ...ARGS", "Manage domains"
|
96
93
|
subcommand "domain", Domain
|
97
94
|
|
98
|
-
desc "
|
99
|
-
subcommand "
|
95
|
+
desc "ip_address SUBCOMMAND ...ARGS", "Manage ip addresses"
|
96
|
+
subcommand "ip_address", IpAddress
|
100
97
|
|
101
98
|
desc "capacity SUBCOMMAND ...ARGS", "Lists all the system wide capacities"
|
102
99
|
subcommand "capacity", Capacity
|
100
|
+
|
101
|
+
desc "port_rules SUBCOMMAND ...ARGS", "Manage portforwarding rules"
|
102
|
+
subcommand "port_rule", PortRule
|
103
103
|
end
|
104
104
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class IpAddress < CloudstackCli::Base
|
2
|
+
|
3
|
+
desc "release ID", "release public IP address"
|
4
|
+
def release(id)
|
5
|
+
puts "OK" if client.disassociate_ip_address(id)
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "assign NETWORK", "assign a public IP address"
|
9
|
+
option :project
|
10
|
+
def assign(network)
|
11
|
+
project = find_project if options[:project]
|
12
|
+
unless network = client.get_network(network, project ? project["id"] : nil)
|
13
|
+
error "Network #{network} not found."
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
ip = client.associate_ip_address(network["id"])
|
17
|
+
puts
|
18
|
+
say ip['ipaddress']
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "list", "list public IP address"
|
22
|
+
option :project
|
23
|
+
option :account
|
24
|
+
option :listall
|
25
|
+
def list
|
26
|
+
table = [["Address", "Account", "Zone"]]
|
27
|
+
client.list_public_ip_addresses(options).each do |address|
|
28
|
+
table << [address["ipaddress"], address["account"], address["zonename"]]
|
29
|
+
end
|
30
|
+
print_table table
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -7,31 +7,34 @@ class Network < CloudstackCli::Base
|
|
7
7
|
|
8
8
|
desc "list", "list networks"
|
9
9
|
option :project
|
10
|
-
option :account
|
10
|
+
option :account
|
11
|
+
option :showid, type: :boolean
|
11
12
|
def list
|
12
13
|
project = find_project if options[:project]
|
13
|
-
|
14
14
|
networks = []
|
15
15
|
if project
|
16
16
|
networks = client.list_networks(project['id'])
|
17
|
+
elsif options[:account]
|
18
|
+
networks = client.list_networks(account: options[:account])
|
17
19
|
else
|
18
|
-
networks = client.list_networks(-1
|
19
|
-
networks + client.list_networks(nil, options[:account] != '' ? options[:account] : nil )
|
20
|
+
networks = client.list_networks(project_id: -1)
|
20
21
|
end
|
21
22
|
|
22
23
|
if networks.size < 1
|
23
24
|
puts "No networks found"
|
24
25
|
else
|
25
|
-
table = [["Name", "Displaytext", "Account", "Project", "
|
26
|
+
table = [["Name", "Displaytext", "Account", "Project", "Domain", "State"]]
|
27
|
+
table[0] << "ID" if options[:showid]
|
26
28
|
networks.each do |network|
|
27
29
|
table << [
|
28
30
|
network["name"],
|
29
31
|
network["displaytext"],
|
30
32
|
network["account"],
|
31
33
|
network["project"],
|
32
|
-
network["
|
33
|
-
network["
|
34
|
+
network["domain"],
|
35
|
+
network["state"]
|
34
36
|
]
|
37
|
+
table[-1] << network["id"] if options[:showid]
|
35
38
|
end
|
36
39
|
print_table table
|
37
40
|
end
|
@@ -5,16 +5,17 @@ class PhysicalNetwork < CloudstackCli::Base
|
|
5
5
|
def list
|
6
6
|
project = find_project if options[:project]
|
7
7
|
networks = client.list_physical_networks
|
8
|
+
zones = client.list_zones
|
8
9
|
if networks.size < 1
|
9
10
|
puts "No networks found"
|
10
11
|
else
|
11
|
-
table = [['Name', 'State', '
|
12
|
+
table = [['Name', 'State', 'Zone', 'ID']]
|
12
13
|
networks.each do |network|
|
13
14
|
table << [
|
14
15
|
network["name"],
|
15
16
|
network["state"],
|
16
|
-
network["
|
17
|
-
network["
|
17
|
+
zones.select{|zone| zone['id'] == network["zoneid"]}.first["name"],
|
18
|
+
network["id"]
|
18
19
|
]
|
19
20
|
end
|
20
21
|
print_table table
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class PortRule < CloudstackCli::Base
|
2
|
+
|
3
|
+
desc "create SERVER", "create portforwarding rules"
|
4
|
+
option :rules, type: :array,
|
5
|
+
required: true,
|
6
|
+
desc: "Port Forwarding Rules [public_ip]:port ...",
|
7
|
+
aliases: '-r'
|
8
|
+
option :network, required: true, aliases: '-n'
|
9
|
+
option :project
|
10
|
+
def create(server_name)
|
11
|
+
unless server = client.get_server(server_name)
|
12
|
+
error "Server #{server_name} not found."
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
frontendip = nil
|
16
|
+
project = client.get_project(project)
|
17
|
+
options[:rules].each do |pf_rule|
|
18
|
+
ip = pf_rule.split(":")[0]
|
19
|
+
if ip != ''
|
20
|
+
ip_addr = client.get_public_ip_address(ip)
|
21
|
+
else
|
22
|
+
ip_addr = frontendip ||= client.associate_ip_address(
|
23
|
+
client.get_network(options[:network], project ? project["id"] : nil)["id"]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
port = pf_rule.split(":")[1]
|
27
|
+
puts
|
28
|
+
say "Create port forwarding rule #{ip_addr["ipaddress"]}:#{port} for server #{server_name}.", :yellow
|
29
|
+
client.create_port_forwarding_rule(ip_addr["id"], port, 'TCP', port, server["id"])
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "list", "list portforwarding rules"
|
35
|
+
option :project
|
36
|
+
def list
|
37
|
+
project_id = find_project['id'] if options[:project]
|
38
|
+
rules = client.list_port_forwarding_rules(ip_address_id=nil, project_id)
|
39
|
+
if rules.size < 1
|
40
|
+
puts "No rules found."
|
41
|
+
else
|
42
|
+
table = [["IP", "Server", "Public-Port", "Private-Port", "Protocol", "State"]]
|
43
|
+
rules.each do |rule|
|
44
|
+
table << [
|
45
|
+
rule['ipaddress'],
|
46
|
+
rule['virtualmachinename'],
|
47
|
+
print_ports(rule, 'public'),
|
48
|
+
print_ports(rule, 'private'),
|
49
|
+
rule['protocol'],
|
50
|
+
rule['state']
|
51
|
+
]
|
52
|
+
end
|
53
|
+
print_table table
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
no_commands do
|
58
|
+
def print_ports(rule, type)
|
59
|
+
if rule["#{type}port"] == rule["#{type}endport"]
|
60
|
+
return rule["#{type}port"]
|
61
|
+
else
|
62
|
+
return rule["#{type}port"] + "-" + rule["#{type}endport"]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Server < CloudstackCli::Base
|
2
|
+
include CloudstackCli::Helper
|
2
3
|
|
3
4
|
desc "list", "list servers"
|
4
5
|
option :project
|
@@ -14,7 +15,7 @@ class Server < CloudstackCli::Base
|
|
14
15
|
end
|
15
16
|
servers = client.list_servers(options)
|
16
17
|
if servers.size < 1
|
17
|
-
puts "No servers found"
|
18
|
+
puts "No servers found."
|
18
19
|
else
|
19
20
|
table = [["Name", "State", "Offering", "Zone", options[:project] ? "Project" : "Account", "IP's"]]
|
20
21
|
servers.each do |server|
|
@@ -37,20 +38,36 @@ class Server < CloudstackCli::Base
|
|
37
38
|
option :offering, required: true
|
38
39
|
option :networks, type: :array, required: true
|
39
40
|
option :project
|
40
|
-
option :port_rules, type: :array,
|
41
|
+
option :port_rules, type: :array,
|
41
42
|
default: [],
|
42
|
-
|
43
|
+
desc: "Port Forwarding Rules [public_ip]:port ..."
|
43
44
|
option :interactive, type: :boolean
|
44
45
|
def create(name)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
if project = @cs.get_project(project)
|
47
|
+
project_id = project["id"]
|
48
|
+
end
|
49
|
+
server = client.get_server(name, project_id)
|
50
|
+
unless server
|
51
|
+
say "Create server #{name}...", :yellow
|
52
|
+
server = client.create_server(
|
53
|
+
name, options[:offering], options[:template],
|
54
|
+
options[:zone], options[:networks], options[:project]
|
55
|
+
)
|
56
|
+
puts
|
57
|
+
say "Server #{name} has been created.", :green
|
58
|
+
client.wait_for_server_state(server["id"], "Running")
|
59
|
+
say "Server #{name} is running.", :green
|
60
|
+
else
|
61
|
+
say "Server #{name} already exists.", :green
|
62
|
+
# TODO: check status of server
|
63
|
+
end
|
64
|
+
|
65
|
+
if options[:port_rules] && options[:port_rules].size > 0
|
66
|
+
invoke "port_rule:create", name,
|
67
|
+
project: options[:project],
|
68
|
+
network: options[:networks].first,
|
69
|
+
rules: options[:port_rules]
|
70
|
+
end
|
54
71
|
end
|
55
72
|
|
56
73
|
desc "destroy NAME [NAME2 ..]", "destroy a server"
|
@@ -76,7 +93,7 @@ class Server < CloudstackCli::Base
|
|
76
93
|
|
77
94
|
desc "bootstrap", "interactive creation of a server with network access"
|
78
95
|
def bootstrap
|
79
|
-
|
96
|
+
bootstrap_server_interactive
|
80
97
|
end
|
81
98
|
|
82
99
|
desc "stop NAME", "stop a server"
|
@@ -1,23 +1,27 @@
|
|
1
1
|
class Stack < CloudstackCli::Base
|
2
|
+
include CloudstackCli::Helper
|
2
3
|
|
3
4
|
desc "create STACKFILE", "create a stack of servers"
|
4
5
|
def create(stackfile)
|
5
6
|
stack = parse_stackfile(stackfile)
|
6
|
-
say "
|
7
|
-
|
7
|
+
say "Create stack #{stack["name"]}..."
|
8
|
+
threads = []
|
8
9
|
stack["servers"].each do |server|
|
9
|
-
server["name"].split(', ').
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
server["name"].split(', ').each_with_index do |name, i|
|
11
|
+
threads << Thread.new(i) {
|
12
|
+
bootstrap_server(
|
13
|
+
name,
|
14
|
+
server["zone"] || stack["zone"],
|
15
|
+
server["template"],
|
16
|
+
server["offering"],
|
17
|
+
server["networks"] ? server["networks"].split(', ') : nil,
|
18
|
+
server["port_rules"] ? server["port_rules"].split(', ') : nil,
|
19
|
+
stack["project"]
|
20
|
+
)
|
21
|
+
}
|
19
22
|
end
|
20
23
|
end
|
24
|
+
threads.each {|t| t.join }
|
21
25
|
end
|
22
26
|
|
23
27
|
desc "destroy STACKFILE", "destroy a stack of servers"
|
@@ -8,7 +8,7 @@ class Template < CloudstackCli::Base
|
|
8
8
|
say "unsupported template type '#{type}'", :red
|
9
9
|
exit 1
|
10
10
|
end
|
11
|
-
templates = client.list_templates(type, project ? project['id'] : nil)
|
11
|
+
templates = client.list_templates(type: type, project_id: project ? project['id'] : nil)
|
12
12
|
if templates.size < 1
|
13
13
|
puts "No templates found"
|
14
14
|
else
|
@@ -4,7 +4,7 @@ class Volume < CloudstackCli::Base
|
|
4
4
|
option :project
|
5
5
|
def list
|
6
6
|
project = find_project if options[:project]
|
7
|
-
networks = client.list_networks(project ? project['id'] : nil)
|
7
|
+
networks = client.list_networks(project_id: project ? project['id'] : nil)
|
8
8
|
if networks.size < 1
|
9
9
|
puts "No networks found"
|
10
10
|
else
|
@@ -1,179 +1,121 @@
|
|
1
1
|
module CloudstackCli
|
2
|
-
|
3
|
-
attr_reader :cs
|
4
|
-
|
5
|
-
def initialize(config_file)
|
6
|
-
@config_file = config_file
|
7
|
-
@cs = CloudstackClient::Connection.new(
|
8
|
-
options[:url],
|
9
|
-
options[:api_key],
|
10
|
-
options[:secret_key]
|
11
|
-
)
|
12
|
-
end
|
13
|
-
|
14
|
-
def options
|
15
|
-
@options ||= CloudstackClient::ConnectionHelper.load_configuration(@config_file)
|
16
|
-
end
|
17
|
-
|
2
|
+
module Helper
|
18
3
|
def print_options(options, attr = 'name')
|
19
4
|
options.to_enum.with_index(1).each do |option, i|
|
20
5
|
puts "#{i}: #{option[attr]}"
|
21
6
|
end
|
22
7
|
end
|
23
8
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def server_offerings(domain = nil)
|
29
|
-
@server_offerings ||= @cs.list_service_offerings(domain)
|
30
|
-
end
|
31
|
-
|
32
|
-
def templates(type = 'featured', project_id = -1)
|
33
|
-
@templates ||= @cs.list_templates(type, project_id)
|
34
|
-
end
|
35
|
-
|
36
|
-
def projects
|
37
|
-
@projects ||= @cs.list_projects
|
38
|
-
end
|
39
|
-
|
40
|
-
def zones
|
41
|
-
@zones ||= @cs.list_zones
|
42
|
-
end
|
43
|
-
|
44
|
-
def networks(project_id = nil)
|
45
|
-
@cs.list_networks(project_id)
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
def volumes(project_id = nil)
|
50
|
-
@cs.list_volumes(project_id)
|
51
|
-
end
|
52
|
-
|
53
|
-
def virtual_machines(options = {})
|
54
|
-
@cs.list_servers(options)
|
9
|
+
def ask_number(question)
|
10
|
+
number = ask(question).to_i - 1
|
11
|
+
number < 0 ? 0 : number
|
55
12
|
end
|
56
13
|
|
57
14
|
def bootstrap_server(name, zone, template, offering, networks, pf_rules = [], project = nil)
|
58
|
-
|
59
|
-
|
60
|
-
|
15
|
+
if project = client.get_project(project)
|
16
|
+
project_id = project["id"]
|
17
|
+
project_name = project['name']
|
18
|
+
end
|
19
|
+
server = client.get_server(name, project_id)
|
61
20
|
unless server
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
zone,
|
68
|
-
networks,
|
69
|
-
project
|
70
|
-
)
|
71
|
-
|
21
|
+
say "Create server #{name}..."
|
22
|
+
server = client.create_server(
|
23
|
+
name, offering, template,
|
24
|
+
zone, networks, project_name
|
25
|
+
)
|
72
26
|
puts
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@cs.wait_for_server_state(server["id"], "Running")
|
77
|
-
puts "OK!".color(:green)
|
27
|
+
say "Server #{server["name"]} has been created.", :green
|
28
|
+
client.wait_for_server_state(server["id"], "Running")
|
29
|
+
say "Server #{server["name"]} is running.", :green
|
78
30
|
else
|
79
|
-
|
31
|
+
say "Server #{name} already exists.", :green
|
80
32
|
end
|
81
33
|
|
82
|
-
|
83
|
-
|
34
|
+
if pf_rules && pf_rules.size > 0
|
35
|
+
puts
|
84
36
|
frontendip = nil
|
85
|
-
|
86
|
-
pf_rules.each do |pf_rule|
|
37
|
+
pf_rules.each do |pf_rule|
|
87
38
|
ip = pf_rule.split(":")[0]
|
88
39
|
if ip != ''
|
89
|
-
|
40
|
+
ip_addr = client.get_public_ip_address(ip)
|
90
41
|
else
|
91
|
-
ip_addr = frontendip ||=
|
92
|
-
|
42
|
+
ip_addr = frontendip ||= client.associate_ip_address(
|
43
|
+
client.get_network(networks[0], project_id)["id"]
|
93
44
|
)
|
94
45
|
end
|
95
|
-
|
46
|
+
port = pf_rule.split(":")[1]
|
96
47
|
puts
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
puts
|
104
|
-
puts "Complete!".color(:green)
|
105
|
-
end
|
106
|
-
|
107
|
-
def list_accounts(name = nil)
|
108
|
-
@cs.list_accounts({ name: name })
|
109
|
-
end
|
110
|
-
|
111
|
-
def list_load_balancer_rules(project = nil)
|
112
|
-
@cs.list_load_balancer_rules(project)
|
113
|
-
end
|
114
|
-
|
115
|
-
def create_load_balancer_rule(name, ip, private_port, public_port, options = {})
|
116
|
-
puts "Create rule #{name}...".color(:yellow)
|
117
|
-
@cs.create_load_balancer_rule(name, ip, private_port, public_port, options = {})
|
118
|
-
puts "OK!".color(:green)
|
119
|
-
end
|
120
|
-
|
121
|
-
def assign_to_load_balancer_rule(id, names)
|
122
|
-
puts "Add #{names.join(', ')} to rule #{id}...".color(:yellow)
|
123
|
-
rule = @cs.assign_to_load_balancer_rule(id, names)
|
124
|
-
if rule['success']
|
125
|
-
puts "OK!".color(:green)
|
126
|
-
else
|
127
|
-
puts "Failed!".color(:red)
|
48
|
+
say "Create port forwarding rule #{ip}:#{port} ", :yellow
|
49
|
+
client.create_port_forwarding_rule(ip_addr["id"], port, 'TCP', port, server["id"])
|
50
|
+
puts
|
51
|
+
end
|
128
52
|
end
|
53
|
+
puts
|
129
54
|
end
|
130
55
|
|
131
56
|
def bootstrap_server_interactive
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
print "Please provide a name for the new server".background(:blue)
|
141
|
-
puts " (spaces or special characters are NOT allowed): "
|
142
|
-
server_name = gets.chomp
|
143
|
-
|
144
|
-
if projects.size > 0
|
145
|
-
puts "Select a project".background(:blue)
|
146
|
-
print_options(projects)
|
147
|
-
project = gets.chomp.to_i - 1
|
148
|
-
end
|
149
|
-
|
150
|
-
puts "Select a computing offering:".background(:blue)
|
151
|
-
print_options(server_offerings)
|
152
|
-
service_offering = gets.chomp.to_i - 1
|
57
|
+
zones = client.list_zones
|
58
|
+
if zones.size > 1
|
59
|
+
say "Select a availability zone:", :yellow
|
60
|
+
print_options(zones)
|
61
|
+
zone = ask_number("Zone Nr.: ")
|
62
|
+
else
|
63
|
+
zone = 0
|
64
|
+
end
|
153
65
|
|
154
|
-
|
155
|
-
|
156
|
-
|
66
|
+
projects = client.list_projects
|
67
|
+
if yes?("Do you want to deploy your server within a project?") && projects.size > 0
|
68
|
+
if projects.size > 0
|
69
|
+
say "Select a project", :yellow
|
70
|
+
print_options(projects)
|
71
|
+
project = ask_number("Project Nr.: ")
|
72
|
+
end
|
73
|
+
project_id = projects[project]['id'] rescue nil
|
74
|
+
end
|
157
75
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
76
|
+
say "Please provide a name for the new server", :yellow
|
77
|
+
say "(spaces or special characters are NOT allowed)"
|
78
|
+
server_name = ask("Server name: ")
|
79
|
+
|
80
|
+
server_offerings = client.list_service_offerings
|
81
|
+
say "Select a computing offering:", :yellow
|
82
|
+
print_options(server_offerings)
|
83
|
+
service_offering = ask_number("Offering Nr.: ")
|
84
|
+
|
85
|
+
templates = client.list_templates(project_id: project_id, zone_id: zones[zone]["id"])
|
86
|
+
say "Select a template:", :yellow
|
87
|
+
print_options(templates)
|
88
|
+
template = ask_number("Template Nr.: ")
|
89
|
+
|
90
|
+
networks = client.list_networks(project_id: project_id, zone_id: zones[zone]["id"])
|
91
|
+
if networks.size > 1
|
92
|
+
say "Select a network:", :yellow
|
93
|
+
print_options(networks)
|
94
|
+
network = ask_number("Network Nr.: ")
|
95
|
+
else
|
96
|
+
network = 0
|
97
|
+
end
|
168
98
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
99
|
+
say "You entered the following configuration:", :yellow
|
100
|
+
table = [["Zone", zones[zone]["name"]]]
|
101
|
+
table << ["Server Name", server_name]
|
102
|
+
table << ["Template", templates[template]["name"]]
|
103
|
+
table << ["Offering", server_offerings[service_offering]["name"]]
|
104
|
+
table << ["Network", networks[network]["name"]]
|
105
|
+
table << ["Project", projects[project]["name"]] if project
|
106
|
+
print_table table
|
107
|
+
|
108
|
+
if yes? "Do you want to deploy this server?"
|
109
|
+
bootstrap_server(
|
110
|
+
server_name,
|
111
|
+
zones[zone]["name"],
|
112
|
+
templates[template]["name"],
|
113
|
+
server_offerings[service_offering]["name"],
|
114
|
+
[networks[network]["name"]], nil,
|
115
|
+
project ? projects[project]["name"] : nil
|
116
|
+
)
|
117
|
+
end
|
177
118
|
end
|
119
|
+
|
178
120
|
end
|
179
121
|
end
|
@@ -103,7 +103,7 @@ module CloudstackClient
|
|
103
103
|
return nil unless server
|
104
104
|
|
105
105
|
nic = get_server_default_nic(server) || {}
|
106
|
-
networks = list_networks(server['projectid']) || {}
|
106
|
+
networks = list_networks(project_id: server['projectid']) || {}
|
107
107
|
|
108
108
|
id = nic['networkid']
|
109
109
|
network = networks.select { |net|
|
@@ -418,13 +418,14 @@ module CloudstackClient
|
|
418
418
|
# * executable - all templates that can be used to deploy a new VM
|
419
419
|
# * community - templates that are public
|
420
420
|
|
421
|
-
def list_templates(
|
422
|
-
filter
|
421
|
+
def list_templates(args = {})
|
422
|
+
filter = args[:filter] || 'featured'
|
423
423
|
params = {
|
424
424
|
'command' => 'listTemplates',
|
425
425
|
'templateFilter' => filter
|
426
426
|
}
|
427
|
-
params['projectid'] = project_id if project_id
|
427
|
+
params['projectid'] = args[:project_id] if args[:project_id]
|
428
|
+
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
428
429
|
|
429
430
|
json = send_request(params)
|
430
431
|
json['template'] || []
|
@@ -449,7 +450,6 @@ module CloudstackClient
|
|
449
450
|
return n
|
450
451
|
end
|
451
452
|
}
|
452
|
-
|
453
453
|
nil
|
454
454
|
end
|
455
455
|
|
@@ -482,19 +482,20 @@ module CloudstackClient
|
|
482
482
|
##
|
483
483
|
# Lists all available networks.
|
484
484
|
|
485
|
-
def list_networks(
|
485
|
+
def list_networks(args = {})
|
486
486
|
params = {
|
487
487
|
'command' => 'listNetworks',
|
488
488
|
'listall' => true,
|
489
489
|
}
|
490
|
-
params['projectid'] = project_id if project_id
|
491
|
-
if
|
492
|
-
|
490
|
+
params['projectid'] = args[:project_id] if args[:project_id]
|
491
|
+
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
492
|
+
if args[:account]
|
493
|
+
domain = list_accounts(name: args[:account])
|
493
494
|
if domain.size > 0
|
494
|
-
params['account'] = account
|
495
|
+
params['account'] = args[:account]
|
495
496
|
params['domainid'] = domain.first["domainid"]
|
496
497
|
else
|
497
|
-
puts "Account #{account} not found."
|
498
|
+
puts "Account #{args[:account]} not found."
|
498
499
|
end
|
499
500
|
end
|
500
501
|
json = send_request(params)
|
@@ -575,6 +576,33 @@ module CloudstackClient
|
|
575
576
|
json['zone'] || []
|
576
577
|
end
|
577
578
|
|
579
|
+
##
|
580
|
+
# Lists the public ip addresses.
|
581
|
+
|
582
|
+
def list_public_ip_addresses(args = {})
|
583
|
+
params = {
|
584
|
+
'command' => 'listPublicIpAddresses',
|
585
|
+
'isrecursive' => true
|
586
|
+
}
|
587
|
+
if args[:project]
|
588
|
+
project = get_project(args[:project])
|
589
|
+
params['projectid'] = project['id']
|
590
|
+
end
|
591
|
+
if args[:account]
|
592
|
+
account = list_accounts({name: args[:account]}).first
|
593
|
+
unless account
|
594
|
+
puts "Error: Account #{args[:account]} not found."
|
595
|
+
exit 1
|
596
|
+
end
|
597
|
+
params['domainid'] = account["domainid"]
|
598
|
+
params['account'] = args[:account]
|
599
|
+
end
|
600
|
+
params['listall'] = args[:listall] if args[:listall]
|
601
|
+
|
602
|
+
json = send_request(params)
|
603
|
+
json['publicipaddress'] || []
|
604
|
+
end
|
605
|
+
|
578
606
|
##
|
579
607
|
# Finds the public ip address for a given ip address string.
|
580
608
|
|
@@ -621,13 +649,16 @@ module CloudstackClient
|
|
621
649
|
##
|
622
650
|
# Lists all port forwarding rules.
|
623
651
|
|
624
|
-
def list_port_forwarding_rules(ip_address_id=nil)
|
652
|
+
def list_port_forwarding_rules(ip_address_id=nil, project_id)
|
625
653
|
params = {
|
626
|
-
'command' => 'listPortForwardingRules'
|
654
|
+
'command' => 'listPortForwardingRules',
|
655
|
+
'listall' => true,
|
656
|
+
'isrecursive' => true
|
627
657
|
}
|
628
658
|
params['ipAddressId'] = ip_address_id if ip_address_id
|
659
|
+
params['projectid'] = project_id if project_id
|
629
660
|
json = send_request(params)
|
630
|
-
json['portforwardingrule']
|
661
|
+
json['portforwardingrule'] || []
|
631
662
|
end
|
632
663
|
|
633
664
|
##
|
data/lib/cloudstack_cli.rb
CHANGED
data/test/stack_example.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"description": "Web nodes",
|
11
11
|
"template": "CentOS-6.4-x64-v1.2",
|
12
12
|
"offering": "1cpu_1gb",
|
13
|
-
"networks": "
|
13
|
+
"networks": "M_PLAY",
|
14
14
|
"port_rules": ":80, :443"
|
15
15
|
},
|
16
16
|
{
|
@@ -18,7 +18,7 @@
|
|
18
18
|
"description": "PostgreSQL Master",
|
19
19
|
"template": "CentOS-6.4-x64-v1.2",
|
20
20
|
"offering": "2cpu_4gb",
|
21
|
-
"networks": "
|
21
|
+
"networks": "M_PLAY"
|
22
22
|
}
|
23
23
|
]
|
24
24
|
}
|
metadata
CHANGED
@@ -1,32 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudstack-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Nik Wolfgramm
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-06 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rdoc
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :development
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '0'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: rake
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: thor
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,6 +62,7 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: net-ssh
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
@@ -62,24 +70,11 @@ dependencies:
|
|
62
70
|
type: :runtime
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
75
|
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: 2.6.7
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rainbow
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 1.1.4
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ~>
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 1.1.4
|
83
78
|
description: cloudstack-cli is a CloudStack API client written in Ruby.
|
84
79
|
email:
|
85
80
|
- nik.wolfgramm@gmail.com
|
@@ -101,12 +96,13 @@ files:
|
|
101
96
|
- lib/cloudstack-cli/commands/account.rb
|
102
97
|
- lib/cloudstack-cli/commands/capacity.rb
|
103
98
|
- lib/cloudstack-cli/commands/domain.rb
|
99
|
+
- lib/cloudstack-cli/commands/ip_address.rb
|
104
100
|
- lib/cloudstack-cli/commands/load_balancer.rb
|
105
101
|
- lib/cloudstack-cli/commands/network.rb
|
106
102
|
- lib/cloudstack-cli/commands/offering.rb
|
107
103
|
- lib/cloudstack-cli/commands/physical_network.rb
|
104
|
+
- lib/cloudstack-cli/commands/port_rule.rb
|
108
105
|
- lib/cloudstack-cli/commands/project.rb
|
109
|
-
- lib/cloudstack-cli/commands/publicip.rb
|
110
106
|
- lib/cloudstack-cli/commands/router.rb
|
111
107
|
- lib/cloudstack-cli/commands/server.rb
|
112
108
|
- lib/cloudstack-cli/commands/stack.rb
|
@@ -123,7 +119,6 @@ files:
|
|
123
119
|
- test/stack_example.json
|
124
120
|
homepage: https://bitbucket.org/swisstxt/cloudstack-cli
|
125
121
|
licenses: []
|
126
|
-
metadata: {}
|
127
122
|
post_install_message:
|
128
123
|
rdoc_options:
|
129
124
|
- --line-numbers
|
@@ -131,20 +126,22 @@ rdoc_options:
|
|
131
126
|
require_paths:
|
132
127
|
- lib
|
133
128
|
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
134
130
|
requirements:
|
135
|
-
- - '>='
|
131
|
+
- - ! '>='
|
136
132
|
- !ruby/object:Gem::Version
|
137
133
|
version: 1.9.3
|
138
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
139
136
|
requirements:
|
140
|
-
- - '>='
|
137
|
+
- - ! '>='
|
141
138
|
- !ruby/object:Gem::Version
|
142
139
|
version: '0'
|
143
140
|
requirements: []
|
144
141
|
rubyforge_project:
|
145
|
-
rubygems_version:
|
142
|
+
rubygems_version: 1.8.23
|
146
143
|
signing_key:
|
147
|
-
specification_version:
|
144
|
+
specification_version: 3
|
148
145
|
summary: cloudstack-cli CloudStack API client
|
149
146
|
test_files:
|
150
147
|
- test/stack_example.json
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 71a5b85637b159d9b71b76d9c5703ec7eff903c9
|
4
|
-
data.tar.gz: 92774b4af91e17a60e84156c8532ec5eafad2fb2
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: ee45344f2a30049f4de0c8c9aa5cd884faaf6b3a7535656880c9357832846cd197c8ab4c5459ccb703dbda51f2b28098086b51d7fb5840e36352e51ea4c7f648
|
7
|
-
data.tar.gz: 6edfcef7302b4dfd45ddef2ab998c01d908084b1d3f33df872ff7402a4a0951ba38f827a97023f38838c4bb4aa99173b8e125c482394c38d36c6eeb8a8fa75fe
|