cloudstack-cli 1.5.3 → 1.5.4
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/cloudstack-cli.gemspec +1 -1
- data/lib/cloudstack-cli/commands/stack.rb +50 -41
- data/lib/cloudstack-cli/commands/virtual_machine.rb +5 -7
- data/lib/cloudstack-cli/helper.rb +59 -69
- data/lib/cloudstack-cli/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fc85400b51baea8a039a7d3ff78dd81057bc733
|
4
|
+
data.tar.gz: 850b702b9158cb5f016d90f71207172d7f5dee15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
25
|
+
rake (~> 11.2)
|
26
26
|
|
27
27
|
BUNDLED WITH
|
28
|
-
1.12.
|
28
|
+
1.12.4
|
data/cloudstack-cli.gemspec
CHANGED
@@ -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.
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
61
|
-
|
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
|
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#{
|
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(
|
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
|
-
|
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
|
-
|
175
|
-
if
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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.
|
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.
|
26
|
+
version: '11.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: cloudstack_client
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|