cloudstack-cli 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b75da05246b3ab3ac85f5ca8e93a28db01f8968
4
- data.tar.gz: fc2d98e9c509876350509db6da5b5e7ab3b900b2
3
+ metadata.gz: 1fc85400b51baea8a039a7d3ff78dd81057bc733
4
+ data.tar.gz: 850b702b9158cb5f016d90f71207172d7f5dee15
5
5
  SHA512:
6
- metadata.gz: 573c55dfed55ed68409424ef04562a9cd0dca835d23a458ce031c3f5fc0653fc87326f05cfd45c18e76ccbdb409dba6a90a1a5098f4c779ff81065514d50c804
7
- data.tar.gz: 22dd3887d463b7b3e08792b1396ec08002ba65bf1a94d9bec2090f72776a64a6b03630cd4dc6c5dd363281d195550cceb991e1677c11b2bf6fe02935c2e6a982
6
+ metadata.gz: ceb5a646a675bbd3f49bd27b772d1aad9cc3fa9ffa44130069619af7f8eefbe611036ff2b72257ce71aa6b96815b3019e3e1803005cdbb910991febc326817a5
7
+ data.tar.gz: 195edfdec98780452c0a121f9902cd1540169fcb35a2fab348b2c9ce20ec922b6a0f57f00a9ee21bc55ab6f5a75765514506c09b91bd7147830867c000ef8ff8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../cloudstack_client/
3
3
  specs:
4
- cloudstack_client (1.4.1)
4
+ cloudstack_client (1.4.3)
5
5
 
6
6
  PATH
7
7
  remote: .
@@ -13,7 +13,7 @@ PATH
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
- rake (11.1.2)
16
+ rake (11.2.0)
17
17
  thor (0.19.1)
18
18
 
19
19
  PLATFORMS
@@ -22,7 +22,7 @@ PLATFORMS
22
22
  DEPENDENCIES
23
23
  cloudstack-cli!
24
24
  cloudstack_client!
25
- rake (~> 11.1)
25
+ rake (~> 11.2)
26
26
 
27
27
  BUNDLED WITH
28
- 1.12.0
28
+ 1.12.4
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
21
21
  gem.require_paths = %w(lib)
22
22
  gem.rdoc_options = %w[--line-numbers --inline-source]
23
23
 
24
- gem.add_development_dependency('rake', '~> 11.1')
24
+ gem.add_development_dependency('rake', '~> 11.2')
25
25
 
26
26
  gem.add_dependency('cloudstack_client', '~> 1.4')
27
27
  gem.add_dependency('thor', '~> 0.19')
@@ -1,49 +1,52 @@
1
1
  class Stack < CloudstackCli::Base
2
2
 
3
- desc "create STACKFILE", "create a stack of VMs"
3
+ desc "create STACKFILE", "create a stack of VM's"
4
+ option :limit, type: :array, aliases: '-l',
5
+ desc: "Limit on specific server names."
4
6
  option :skip_forwarding_rules, default: false,
5
7
  type: :boolean, aliases: '-s',
6
8
  desc: "Skip creation of port forwarding rules."
7
9
  def create(stackfile)
8
10
  stack = parse_file(stackfile)
9
11
  project_id = find_project_by_name(stack["project"])
10
-
11
12
  say "Create stack #{stack["name"]}...", :green
12
13
  jobs = []
13
14
  stack["servers"].each do |instance|
14
15
  string_to_array(instance["name"]).each do |name|
15
- server = client.list_virtual_machines(name: name, project_id: project_id).first
16
- if server
17
- say "VM #{name} (#{server["state"]}) already exists.", :yellow
18
- jobs << {
19
- id: 0,
20
- name: "Create VM #{name}",
21
- status: 1
22
- }
23
- else
24
- options.merge!({
25
- name: name,
26
- displayname: instance["decription"],
27
- zone: instance["zone"] || stack["zone"],
28
- project: stack["project"],
29
- template: instance["template"],
30
- iso: instance["iso"] ,
31
- offering: instance["offering"],
32
- networks: load_string_or_array(instance["networks"]),
33
- ip_network_list: instance["ip_network_list"],
34
- disk_offering: instance["disk_offering"],
35
- size: instance["disk_size"],
36
- group: instance["group"] || stack["group"],
37
- keypair: instance["keypair"] || stack["keypair"],
38
- ip_address: instance["ip_address"]
39
- })
40
- jobs << {
41
- id: client.deploy_virtual_machine(
42
- vm_options_to_params,
43
- {sync: true}
44
- )['jobid'],
45
- name: "Create VM #{name}"
46
- }
16
+ if options[:limit].include?(name)
17
+ server = client.list_virtual_machines(name: name, project_id: project_id).first
18
+ if server
19
+ say "VM #{name} (#{server["state"]}) already exists.", :yellow
20
+ jobs << {
21
+ id: 0,
22
+ name: "Create VM #{name}",
23
+ status: 1
24
+ }
25
+ else
26
+ options.merge!({
27
+ name: name,
28
+ displayname: instance["decription"],
29
+ zone: instance["zone"] || stack["zone"],
30
+ project: stack["project"],
31
+ template: instance["template"],
32
+ iso: instance["iso"] ,
33
+ offering: instance["offering"],
34
+ networks: load_string_or_array(instance["networks"]),
35
+ ip_network_list: instance["ip_network_list"],
36
+ disk_offering: instance["disk_offering"],
37
+ size: instance["disk_size"],
38
+ group: instance["group"] || stack["group"],
39
+ keypair: instance["keypair"] || stack["keypair"],
40
+ ip_address: instance["ip_address"]
41
+ })
42
+ jobs << {
43
+ id: client.deploy_virtual_machine(
44
+ vm_options_to_params,
45
+ {sync: true}
46
+ )['jobid'],
47
+ name: "Create VM #{name}"
48
+ }
49
+ end
47
50
  end
48
51
  end
49
52
  end
@@ -54,20 +57,17 @@ class Stack < CloudstackCli::Base
54
57
  jobs = []
55
58
  stack["servers"].each do |instance|
56
59
  string_to_array(instance["name"]).each do |name|
57
- if port_rules = string_to_array(instance["port_rules"])
60
+ if options[:limit].include?(name) && port_rules = string_to_array(instance["port_rules"])
58
61
  server = client.list_virtual_machines(name: name, project_id: project_id).first
59
62
  create_port_rules(server, port_rules, false).each_with_index do |job_id, index|
60
- jobs << {
61
- id: job_id,
62
- name: "Create port forwarding rules (#{port_rules[index]}) for VM #{name}"
63
- }
63
+ job_name = "Create port forwarding rules (#{port_rules[index]}) for VM #{name}"
64
+ jobs << {id: job_id, name: job_name}
64
65
  end
65
66
  end
66
67
  end
67
68
  end
68
69
  watch_jobs(jobs)
69
70
  end
70
-
71
71
  say "Finished.", :green
72
72
  end
73
73
 
@@ -82,12 +82,21 @@ class Stack < CloudstackCli::Base
82
82
  type: :boolean,
83
83
  default: false,
84
84
  aliases: '-E'
85
+ option :limit, type: :array, aliases: '-l',
86
+ desc: "Limit on specific server names."
85
87
  def destroy(stackfile)
86
88
  stack = parse_file(stackfile)
87
89
  project_id = find_project_by_name(stack["project"])
88
90
  servers = []
89
91
  stack["servers"].each do |server|
90
- string_to_array(server["name"]).each {|name| servers << name}
92
+ string_to_array(server["name"]).each do |name|
93
+ servers << name if options[:limit].include?(name)
94
+ end
95
+ end
96
+
97
+ if servers.size == 0
98
+ say "No servers in stack selected.", :yellow
99
+ exit
91
100
  end
92
101
 
93
102
  if options[:force] || yes?("Destroy the following VM #{servers.join(', ')}? [y/N]:", :yellow)
@@ -102,15 +102,13 @@ class VirtualMachine < CloudstackCli::Base
102
102
  end
103
103
 
104
104
  vm_options_to_params
105
- say "Start deploying virtual machine#{ "s" if names.size > 1 }...", :green
105
+ say "Start deploying virtual machine#{"s" if names.size > 1}...", :green
106
106
  jobs = names.map do |name|
107
- if virtual_machine = client.list_virtual_machines(name: name, project_id: options[:project_id]).first
107
+ if virtual_machine = client.list_virtual_machines(
108
+ name: name, project_id: options[:project_id]
109
+ ).first
108
110
  say "virtual machine #{name} (#{virtual_machine["state"]}) already exists.", :yellow
109
- job = {
110
- id: 0,
111
- name: "Create virtual machine #{name}",
112
- status: 1
113
- }
111
+ job = {id: 0, name: "Create virtual machine #{name}", status: 1}
114
112
  else
115
113
  job = {
116
114
  id: client.deploy_virtual_machine(options.merge(name: name), {sync: true})['jobid'],
@@ -166,37 +166,63 @@ module CloudstackCli
166
166
  end
167
167
 
168
168
  def create_port_rules(server, port_rules, async = true)
169
- frontendip = nil
169
+ frontendip_id = nil
170
170
  jobs = []
171
171
  client.verbose = async
172
172
  project_id = server['projectid'] || nil
173
173
  port_rules.each do |pf_rule|
174
- ip = pf_rule.split(":")[0]
175
- if ip != ''
176
- ip_addr = client.get_public_ip_address(ip, project_id)
177
- unless ip_addr
178
- say "Error: IP #{ip} not found.", :red
174
+ pf_rule = pf_rule_to_object(pf_rule)
175
+ if pf_rule[:ipaddress]
176
+ pub_ip = client.list_public_ip_addresses(
177
+ network_id: get_server_default_nic(server)["networkid"],
178
+ project_id: project_id,
179
+ ipaddress: pf_rule[:ipaddress]
180
+ )
181
+ ip_addr = pub_ip.find { |addr| addr['ipaddress'] == pf_rule[:ipaddress]} if pub_ip
182
+ if ip_addr
183
+ frontendip = ip_addr['id']
184
+ else
185
+ say "Error: IP #{pf_rule[:ipaddress]} not found.", :red
179
186
  next
180
187
  end
181
- else
182
- ip_addr = frontendip ||= client.associate_ip_address(
183
- network_id: server["nic"].first["networkid"]
184
- )["ipaddress"]
185
188
  end
186
- port = pf_rule.split(":")[1]
187
- args = {
188
- ipaddressid: ip_addr["id"],
189
- publicport: port,
190
- privateport: port,
191
- protocol: 'TCP',
192
- virtualmachineid: server["id"]
193
- }
194
- if async
195
- say "Create port forwarding rule #{ip_addr['ipaddress']}:#{port} for server #{server["name"]}.", :yellow
196
- client.create_port_forwarding_rule(args)
197
- return
189
+
190
+ # check if there is already an existing rule
191
+ rules = client.list_port_forwarding_rules(
192
+ networkid: get_server_default_nic(server)["networkid"],
193
+ ipaddressid: frontendip_id,
194
+ projectid: project_id
195
+ )
196
+ existing_pf_rules = rules.find do |rule|
197
+ # remember matching address for additional rules
198
+ frontendip_id = rule['ipaddressid'] if rule['virtualmachineid'] == server['id']
199
+
200
+ rule['virtualmachineid'] == server['id'] &&
201
+ rule['publicport'] == pf_rule[:publicport] &&
202
+ rule['privateport'] == pf_rule[:privateport] &&
203
+ rule['protocol'] == pf_rule[:protocol]
204
+ end
205
+
206
+ if existing_pf_rules
207
+ say "Port forwarding rule on port #{pf_rule[:privateport]} for VM #{server["name"]} already exists.", :yellow
198
208
  else
199
- jobs << client.create_port_forwarding_rule(args, {sync: true})['jobid']
209
+ unless frontendip_id
210
+ frontendip_id = client.associate_ip_address(
211
+ network_id: get_server_default_nic(server)["networkid"],
212
+ project_id: project_id
213
+ )['ipaddress']['id']
214
+ end
215
+ args = pf_rule.merge({
216
+ ipaddressid: frontendip_id,
217
+ virtualmachineid: server["id"]
218
+ })
219
+ if async
220
+ say "Create port forwarding rule #{pf_rule[:ipaddress]}:#{port} for VM #{server["name"]}.", :yellow
221
+ client.create_port_forwarding_rule(args)
222
+ return
223
+ else
224
+ jobs << client.create_port_forwarding_rule(args, {sync: true})['jobid']
225
+ end
200
226
  end
201
227
  end
202
228
  jobs
@@ -267,57 +293,21 @@ module CloudstackCli
267
293
  end
268
294
  end
269
295
 
270
- ##
271
- # Finds the public ip for a server
272
-
273
- def get_server_public_ip(server, cached_rules=nil)
274
- return nil unless server
275
-
276
- # find the public ip
277
- nic = get_server_default_nic(server) || {}
278
- if nic['type'] == 'Virtual'
279
- ssh_rule = get_ssh_port_forwarding_rule(server, cached_rules)
280
- ssh_rule ? ssh_rule['ipaddress'] : nil
281
- else
282
- nic['ipaddress']
283
- end
284
- end
285
-
286
- ##
287
- # Gets the SSH port forwarding rule for the specified server.
288
-
289
- def get_ssh_port_forwarding_rule(server, cached_rules=nil)
290
- rules = cached_rules || client.list_port_forwarding_rules(project_id: server["projectid"]) || []
291
- rules.find_all { |r|
292
- r['virtualmachineid'] == server['id'] &&
293
- r['privateport'] == '22'&&
294
- r['publicport'] == '22'
295
- }.first
296
- end
297
-
298
- ##
299
- # Returns the fully qualified domain name for a server.
300
-
301
- def get_server_fqdn(server)
302
- return nil unless server
303
-
304
- nic = get_server_default_nic(server) || {}
305
- networks = client.list_networks(project_id: server['projectid']) || {}
306
-
307
- id = nic['networkid']
308
- network = networks.select { |net|
309
- net['id'] == id
310
- }.first
311
- return nil unless network
312
-
313
- "#{server['name']}.#{network['networkdomain']}"
314
- end
315
-
316
296
  def get_server_default_nic(server)
317
297
  server['nic'].each do |nic|
318
298
  return nic if nic['isdefault']
319
299
  end
320
300
  end
321
301
 
302
+ def pf_rule_to_object(pf_rule)
303
+ pf_rule = pf_rule.split(":")
304
+ {
305
+ ipaddress: (pf_rule[0] == '' ? nil : pf_rule[0]),
306
+ privateport: pf_rule[1],
307
+ publicport: (pf_rule[2] || pf_rule[1]),
308
+ protocol: (pf_rule[3] || 'tcp').downcase
309
+ }
310
+ end
311
+
322
312
  end
323
313
  end
@@ -1,3 +1,3 @@
1
1
  module CloudstackCli
2
- VERSION = "1.5.3"
2
+ VERSION = "1.5.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudstack-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nik Wolfgramm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-04 00:00:00.000000000 Z
11
+ date: 2016-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '11.1'
19
+ version: '11.2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '11.1'
26
+ version: '11.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: cloudstack_client
29
29
  requirement: !ruby/object:Gem::Requirement