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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cloudstack-cli (0.1.1)
4
+ cloudstack-cli (0.1.2)
5
5
  net-ssh (~> 2.6.7)
6
6
  rainbow (~> 1.1.4)
7
7
  thor (~> 0.18.1)
data/README.md CHANGED
@@ -12,19 +12,19 @@ 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
 
19
19
  Example content of the configuration file:
20
20
 
21
21
  :url: "https://my-cloudstack-server/client/api/"
22
- :api_key: "cloudstack-api-key"
23
- :secret_key: "cloudstack-api-secret"
22
+ :api_key: "cloudstack-api-key"
23
+ :secret_key: "cloudstack-api-secret"
24
24
 
25
25
  ## Usage
26
26
 
27
- Please see http://rubydoc.info/gems/cloudstack-cli/0.0.3/frames
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 Zone too):
86
- (This command is helpful if you have to deploy new versions of Cloudstack when using redumdant routers)
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
 
@@ -24,5 +24,4 @@ Gem::Specification.new do |gem|
24
24
 
25
25
  gem.add_dependency('thor', '~> 0.18.1')
26
26
  gem.add_dependency('net-ssh', '~> 2.6.7')
27
- gem.add_dependency('rainbow', '~> 1.1.4')
28
27
  end
@@ -68,11 +68,11 @@ module CloudstackCli
68
68
  desc "network SUBCOMMAND ...ARGS", "Manage networks"
69
69
  subcommand "network", Network
70
70
 
71
- desc "physicalnetwork SUBCOMMAND ...ARGS", "Manage physical networks"
72
- subcommand "physicalnetwork", PhysicalNetwork
71
+ desc "physical_network SUBCOMMAND ...ARGS", "Manage physical networks"
72
+ subcommand "physical_network", PhysicalNetwork
73
73
 
74
- desc "lb SUBCOMMAND ...ARGS", "Manage load balancing rules"
75
- subcommand "lb", Lb
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 "publicip SUBCOMMAND ...ARGS", "Manage public ip addresses"
99
- subcommand "publicip", Publicip
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
@@ -1,4 +1,4 @@
1
- class Lb < CloudstackCli::Base
1
+ class LoadBalancer < CloudstackCli::Base
2
2
 
3
3
  desc "list", "list load balancer rules"
4
4
  option :project
@@ -7,31 +7,34 @@ class Network < CloudstackCli::Base
7
7
 
8
8
  desc "list", "list networks"
9
9
  option :project
10
- option :account, default: ""
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, options[:account] != '' ? options[:account] : nil )
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", "State", "ID"]]
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["state"],
33
- network["id"]
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', 'ID', 'Zone ID']]
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["id"],
17
- network["zoneid"]
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, aliases: :pf,
41
+ option :port_rules, type: :array,
41
42
  default: [],
42
- description: "Port Forwarding Rules [public_ip]:port ..."
43
+ desc: "Port Forwarding Rules [public_ip]:port ..."
43
44
  option :interactive, type: :boolean
44
45
  def create(name)
45
- CloudstackCli::Helper.new(options[:config]).bootstrap_server(
46
- name,
47
- options[:zone],
48
- options[:template],
49
- options[:offering],
50
- options[:networks],
51
- options[:port_rules],
52
- options[:project]
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
- CloudstackCli::Helper.new(options[:config]).bootstrap_server_interactive()
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 "Crate stack #{stack["name"]}..."
7
- puts
7
+ say "Create stack #{stack["name"]}..."
8
+ threads = []
8
9
  stack["servers"].each do |server|
9
- server["name"].split(', ').each do |name|
10
- CloudstackCli::Helper.new(options[:config]).bootstrap_server(
11
- name,
12
- server["zone"] || stack['zone'],
13
- server["template"],
14
- server["offering"],
15
- server["networks"] ? server["networks"].split(', ') : nil,
16
- server["port_rules"] ? server["port_rules"].split(', ') : nil,
17
- stack["project"]
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
- class Helper
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 domains(name = nil)
25
- @cs.list_domains(name)
26
- end
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
- server = @cs.get_server(name)
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
- puts "Create server #{name}...".color(:yellow)
63
- server = @cs.create_server(
64
- name,
65
- offering,
66
- template,
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
- puts "Server #{server["name"]} has been created.".color(:green)
74
- puts
75
- puts "Make sure the server is running...".color(:yellow)
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
- puts "Server #{name} already exists".color(:green)
31
+ say "Server #{name} already exists.", :green
80
32
  end
81
33
 
82
- if pf_rules && pf_rules.size > 0
83
- puts
34
+ if pf_rules && pf_rules.size > 0
35
+ puts
84
36
  frontendip = nil
85
- project = @cs.get_project(project)
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
- ip_addr = @cs.get_public_ip_address(ip)
40
+ ip_addr = client.get_public_ip_address(ip)
90
41
  else
91
- ip_addr = frontendip ||= @cs.associate_ip_address(
92
- @cs.get_network(networks[0], project ? project["id"] : nil)["id"]
42
+ ip_addr = frontendip ||= client.associate_ip_address(
43
+ client.get_network(networks[0], project_id)["id"]
93
44
  )
94
45
  end
95
- port = pf_rule.split(":")[1]
46
+ port = pf_rule.split(":")[1]
96
47
  puts
97
- print "Create port forwarding rule #{ip}:#{port} ".color(:yellow)
98
- @cs.create_port_forwarding_rule(ip_addr["id"], port, 'TCP', port, server["id"])
99
- puts
100
- end
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
- ARGV.clear
133
- puts
134
- puts "We are going to deploy a new server and..."
135
- puts "- assign a public IP address"
136
- puts "- create a firewall rule for SSH and HTTP access"
137
- puts "- connect to the server and install the puppet client}"
138
- puts
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
- puts "Select a template:".background(:blue)
155
- print_options(templates)
156
- template = gets.chomp.to_i - 1
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
- puts "Select a availability zone:".background(:blue)
159
- print_options(zones)
160
- zone = gets.chomp.to_i - 1
161
-
162
- # FIXME: show only networks in selected zone
163
- puts "Select a network:".background(:blue)
164
- project_id = projects[project]['id'] rescue nil
165
- networks = @cs.list_networks(project_id)
166
- print_options(networks)
167
- network = gets.chomp.to_i - 1
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
- bootstrap_server(
170
- server_name,
171
- zones[zone]["name"],
172
- templates[template]["name"],
173
- server_offerings[service_offering]["name"],
174
- [networks[network]["name"]],
175
- projects[project]["name"]
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
@@ -1,3 +1,3 @@
1
1
  module CloudstackCli
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  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(filter, project_id = nil)
422
- filter ||= 'featured'
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(project_id = nil, account = nil)
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 account
492
- domain = list_accounts({name: account})
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
  ##
@@ -6,7 +6,7 @@ module CloudstackClient
6
6
  rescue Exception => e
7
7
  $stderr.puts "Can't find the config file #{config_file}."
8
8
  $stderr.puts "To create a new configuration file run \"cs setup\"."
9
- exit
9
+ exit 1
10
10
  end
11
11
  end
12
12
  end
@@ -1,5 +1,4 @@
1
1
  require 'yaml'
2
- require 'rainbow'
3
2
  require "thor"
4
3
 
5
4
  require "cloudstack-cli/version"
@@ -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": "M_ROOT",
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": "M_ROOT"
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.2
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-02 00:00:00.000000000 Z
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: 2.0.2
142
+ rubygems_version: 1.8.23
146
143
  signing_key:
147
- specification_version: 4
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
@@ -1,8 +0,0 @@
1
- class Publicip < CloudstackCli::Base
2
-
3
- desc "remove ID", "remove public IP address"
4
- def remove(id)
5
- puts "OK" if client.disassociate_ip_address(id)
6
- end
7
-
8
- end