cloudstack-cli 0.15.1 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -5
- data/cloudstack-cli.gemspec +2 -2
- data/lib/cloudstack-cli/base.rb +6 -16
- data/lib/cloudstack-cli/cli.rb +16 -4
- data/lib/cloudstack-cli/commands/account.rb +2 -4
- data/lib/cloudstack-cli/commands/affinity_group.rb +2 -1
- data/lib/cloudstack-cli/commands/capacity.rb +27 -26
- data/lib/cloudstack-cli/commands/cluster.rb +6 -3
- data/lib/cloudstack-cli/commands/compute_offer.rb +13 -11
- data/lib/cloudstack-cli/commands/configuration.rb +5 -6
- data/lib/cloudstack-cli/commands/disk_offer.rb +4 -3
- data/lib/cloudstack-cli/commands/domain.rb +6 -6
- data/lib/cloudstack-cli/commands/host.rb +16 -2
- data/lib/cloudstack-cli/commands/ip_address.rb +23 -14
- data/lib/cloudstack-cli/commands/iso.rb +23 -21
- data/lib/cloudstack-cli/commands/job.rb +15 -13
- data/lib/cloudstack-cli/commands/load_balancer.rb +63 -25
- data/lib/cloudstack-cli/commands/network.rb +25 -70
- data/lib/cloudstack-cli/commands/physical_network.rb +4 -4
- data/lib/cloudstack-cli/commands/pod.rb +3 -1
- data/lib/cloudstack-cli/commands/port_rule.rb +23 -17
- data/lib/cloudstack-cli/commands/project.rb +11 -12
- data/lib/cloudstack-cli/commands/resource_limit.rb +8 -12
- data/lib/cloudstack-cli/commands/router.rb +35 -42
- data/lib/cloudstack-cli/commands/snapshot.rb +5 -2
- data/lib/cloudstack-cli/commands/ssh_key_pairs.rb +20 -6
- data/lib/cloudstack-cli/commands/stack.rb +49 -39
- data/lib/cloudstack-cli/commands/storage_pool.rb +4 -3
- data/lib/cloudstack-cli/commands/system_vm.rb +11 -14
- data/lib/cloudstack-cli/commands/template.rb +11 -14
- data/lib/cloudstack-cli/commands/user.rb +4 -9
- data/lib/cloudstack-cli/commands/virtual_machine.rb +243 -0
- data/lib/cloudstack-cli/commands/volume.rb +117 -2
- data/lib/cloudstack-cli/commands/zone.rb +7 -3
- data/lib/cloudstack-cli/helper.rb +96 -35
- data/lib/cloudstack-cli/option_resolver.rb +176 -0
- data/lib/cloudstack-cli/version.rb +1 -1
- data/lib/cloudstack-cli.rb +2 -1
- metadata +9 -8
- data/lib/cloudstack-cli/commands/server.rb +0 -230
@@ -1,10 +1,12 @@
|
|
1
1
|
class SshKeyPair < CloudstackCli::Base
|
2
2
|
|
3
3
|
desc "list", 'list ssh key pairs'
|
4
|
-
option :listall
|
4
|
+
option :listall, default: true
|
5
5
|
option :account
|
6
6
|
option :project
|
7
7
|
def list
|
8
|
+
resolve_account
|
9
|
+
resolve_project
|
8
10
|
pairs = client.list_ssh_key_pairs(options)
|
9
11
|
if pairs.size < 1
|
10
12
|
say "No ssh key pairs found."
|
@@ -21,7 +23,10 @@ class SshKeyPair < CloudstackCli::Base
|
|
21
23
|
option :account
|
22
24
|
option :project
|
23
25
|
def create(name)
|
24
|
-
|
26
|
+
resolve_account
|
27
|
+
resolve_project
|
28
|
+
options[:name] = name
|
29
|
+
pair = client.create_ssh_key_pair(options)
|
25
30
|
say "Name : #{pair['name']}"
|
26
31
|
say "Fingerprint : #{pair['fingerprint']}"
|
27
32
|
say "Privatekey:"
|
@@ -33,17 +38,23 @@ class SshKeyPair < CloudstackCli::Base
|
|
33
38
|
option :project
|
34
39
|
option :public_key, required: true, desc: "path to public_key file"
|
35
40
|
def register(name)
|
41
|
+
resolve_account
|
42
|
+
resolve_project
|
43
|
+
options[:name] = name
|
36
44
|
if File.exist?(options[:public_key])
|
37
45
|
public_key = IO.read(options[:public_key])
|
38
46
|
else
|
39
47
|
say("Can't open public key #{options[:public_key]}", :red)
|
40
48
|
exit 1
|
41
49
|
end
|
42
|
-
pair = client.register_ssh_key_pair(
|
50
|
+
pair = client.register_ssh_key_pair(options)
|
43
51
|
say "Name : #{pair['name']}"
|
44
52
|
say "Fingerprint : #{pair['fingerprint']}"
|
45
53
|
say "Privatekey:"
|
46
54
|
say pair['privatekey']
|
55
|
+
rescue => e
|
56
|
+
say "Failed to register key: #{e.message}", :red
|
57
|
+
exit 1
|
47
58
|
end
|
48
59
|
|
49
60
|
desc 'delete NAME', 'delete ssh key pair'
|
@@ -51,8 +62,11 @@ class SshKeyPair < CloudstackCli::Base
|
|
51
62
|
option :project
|
52
63
|
option :force, aliases: '-f', desc: "delete without asking"
|
53
64
|
def delete(name)
|
65
|
+
resolve_account
|
66
|
+
resolve_project
|
67
|
+
options[:name] = name
|
54
68
|
if options[:force] || yes?("Delete ssh key pair #{name}?", :yellow)
|
55
|
-
if client.delete_ssh_key_pair(
|
69
|
+
if client.delete_ssh_key_pair(options)['success'] == "true"
|
56
70
|
say("OK", :green)
|
57
71
|
else
|
58
72
|
say("Failed", :red)
|
@@ -60,5 +74,5 @@ class SshKeyPair < CloudstackCli::Base
|
|
60
74
|
end
|
61
75
|
end
|
62
76
|
end
|
63
|
-
|
64
|
-
end
|
77
|
+
|
78
|
+
end
|
@@ -1,42 +1,44 @@
|
|
1
1
|
class Stack < CloudstackCli::Base
|
2
2
|
|
3
|
-
desc "create STACKFILE", "create a stack of
|
3
|
+
desc "create STACKFILE", "create a stack of VMs"
|
4
4
|
def create(stackfile)
|
5
5
|
stack = parse_file(stackfile)
|
6
|
+
project_id = find_project_by_name(stack["project"])
|
7
|
+
|
6
8
|
say "Create stack #{stack["name"]}...", :green
|
7
|
-
projectid = find_project(stack["project"])['id'] if stack["project"]
|
8
9
|
jobs = []
|
9
|
-
client.verbose = false
|
10
10
|
stack["servers"].each do |instance|
|
11
11
|
string_to_array(instance["name"]).each do |name|
|
12
|
-
server = client.
|
12
|
+
server = client.list_virtual_machines(name: name, project_id: project_id).first
|
13
13
|
if server
|
14
|
-
say "
|
14
|
+
say "VM #{name} (#{server["state"]}) already exists.", :yellow
|
15
15
|
jobs << {
|
16
16
|
id: 0,
|
17
|
-
name: "Create
|
17
|
+
name: "Create VM #{name}",
|
18
18
|
status: 1
|
19
19
|
}
|
20
20
|
else
|
21
|
+
options = {
|
22
|
+
name: name,
|
23
|
+
displayname: instance["decription"],
|
24
|
+
zone: instance["zone"] || stack["zone"],
|
25
|
+
template: instance["template"],
|
26
|
+
iso: instance["iso"] ,
|
27
|
+
offering: instance["offering"],
|
28
|
+
networks: load_string_or_array(instance["networks"]),
|
29
|
+
project: stack["project"],
|
30
|
+
disk_offering: instance["disk_offering"],
|
31
|
+
size: instance["disk_size"],
|
32
|
+
group: instance["group"] || stack["group"],
|
33
|
+
keypair: instance["keypair"] || stack["keypair"],
|
34
|
+
sync: true
|
35
|
+
}
|
21
36
|
jobs << {
|
22
|
-
id: client.
|
23
|
-
|
24
|
-
|
25
|
-
displayname: instance["decription"],
|
26
|
-
zone: instance["zone"] || stack["zone"],
|
27
|
-
template: instance["template"],
|
28
|
-
iso: instance["iso"] ,
|
29
|
-
offering: instance["offering"],
|
30
|
-
networks: load_string_or_array(instance["networks"]),
|
31
|
-
project: stack["project"],
|
32
|
-
disk_offering: instance["disk_offering"],
|
33
|
-
disk_size: instance["disk_size"],
|
34
|
-
group: instance["group"] || stack["group"],
|
35
|
-
keypair: instance["keypair"] || stack["keypair"],
|
36
|
-
sync: true
|
37
|
-
}
|
37
|
+
id: client.deploy_virtual_machine(
|
38
|
+
vm_options_to_params(options),
|
39
|
+
{sync: true}
|
38
40
|
)['jobid'],
|
39
|
-
name: "Create
|
41
|
+
name: "Create VM #{name}"
|
40
42
|
}
|
41
43
|
end
|
42
44
|
end
|
@@ -48,11 +50,11 @@ class Stack < CloudstackCli::Base
|
|
48
50
|
stack["servers"].each do |instance|
|
49
51
|
string_to_array(instance["name"]).each do |name|
|
50
52
|
if port_rules = string_to_array(instance["port_rules"])
|
51
|
-
server = client(
|
53
|
+
server = client.list_virtual_machines(name: name, project_id: project_id).first
|
52
54
|
create_port_rules(server, port_rules, false).each_with_index do |job_id, index|
|
53
55
|
jobs << {
|
54
56
|
id: job_id,
|
55
|
-
name: "Create port forwarding rules (#{port_rules[index]}) for
|
57
|
+
name: "Create port forwarding rules (#{port_rules[index]}) for VM #{name}"
|
56
58
|
}
|
57
59
|
end
|
58
60
|
end
|
@@ -62,39 +64,35 @@ class Stack < CloudstackCli::Base
|
|
62
64
|
say "Finished.", :green
|
63
65
|
end
|
64
66
|
|
65
|
-
desc "destroy STACKFILE", "destroy a stack of
|
67
|
+
desc "destroy STACKFILE", "destroy a stack of VMs"
|
66
68
|
option :force,
|
67
69
|
desc: "destroy without asking",
|
68
70
|
type: :boolean,
|
69
71
|
default: false,
|
70
72
|
aliases: '-f'
|
71
73
|
option :expunge,
|
72
|
-
desc: "expunge
|
74
|
+
desc: "expunge VMs immediately",
|
73
75
|
type: :boolean,
|
74
76
|
default: false,
|
75
77
|
aliases: '-E'
|
76
78
|
def destroy(stackfile)
|
77
|
-
stack =
|
78
|
-
|
79
|
-
client.verbose = false
|
79
|
+
stack = parse_file(stackfile)
|
80
|
+
project_id = find_project_by_name(stack["project"])
|
80
81
|
servers = []
|
81
82
|
stack["servers"].each do |server|
|
82
83
|
string_to_array(server["name"]).each {|name| servers << name}
|
83
84
|
end
|
84
85
|
|
85
|
-
if options[:force] || yes?("Destroy the following
|
86
|
+
if options[:force] || yes?("Destroy the following VM #{servers.join(', ')}? [y/N]:", :yellow)
|
86
87
|
jobs = []
|
87
88
|
servers.each do |name|
|
88
|
-
server = client(
|
89
|
-
if server
|
89
|
+
if server = client.list_virtual_machines(name: name, project_id: project_id).first
|
90
90
|
jobs << {
|
91
|
-
id: client.
|
92
|
-
server['id'],
|
93
|
-
|
94
|
-
expunge: options[:expunge]
|
95
|
-
}
|
91
|
+
id: client.destroy_virtual_machine(
|
92
|
+
{ id: server['id'], expunge: options[:expunge] },
|
93
|
+
{ sync: true }
|
96
94
|
)['jobid'],
|
97
|
-
name: "Destroy
|
95
|
+
name: "Destroy VM #{name}"
|
98
96
|
}
|
99
97
|
end
|
100
98
|
end
|
@@ -104,6 +102,18 @@ class Stack < CloudstackCli::Base
|
|
104
102
|
end
|
105
103
|
|
106
104
|
no_commands do
|
105
|
+
def find_project_by_name(name)
|
106
|
+
if name
|
107
|
+
unless project_id = client.list_projects(name: name).first['id']
|
108
|
+
say "Error: Project '#{name}' not found.", :red
|
109
|
+
exit 1
|
110
|
+
end
|
111
|
+
else
|
112
|
+
project_id = nil
|
113
|
+
end
|
114
|
+
project_id
|
115
|
+
end
|
116
|
+
|
107
117
|
def load_string_or_array(item)
|
108
118
|
item.is_a?(Array) ? item : [item]
|
109
119
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
class StoragePool < CloudstackCli::Base
|
2
2
|
|
3
|
-
desc 'list', 'list
|
3
|
+
desc 'list', 'list storage_pools'
|
4
4
|
option :zone, desc: "zone name for the storage pool"
|
5
5
|
option :name, desc: "name of the storage pool"
|
6
6
|
option :keyword, desc: "list by keyword"
|
7
|
-
option :state, desc: "filter by state (Up, Maintenance)"
|
7
|
+
option :state, desc: "filter by state (Up, Maintenance)"
|
8
8
|
def list
|
9
|
+
resolve_zone
|
9
10
|
storage_pools = client.list_storage_pools(options)
|
10
11
|
if storage_pools.size < 1
|
11
12
|
say "No storage pools found."
|
@@ -35,4 +36,4 @@ class StoragePool < CloudstackCli::Base
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
end
|
39
|
+
end
|
@@ -6,6 +6,7 @@ class SystemVm < CloudstackCli::Base
|
|
6
6
|
option :type, desc: "the system VM type.",
|
7
7
|
enum: %w(consoleproxy secondarystoragevm)
|
8
8
|
def list
|
9
|
+
resolve_zone
|
9
10
|
vms = client.list_system_vms(options)
|
10
11
|
if vms.size < 1
|
11
12
|
say "No system VM's found."
|
@@ -23,8 +24,7 @@ class SystemVm < CloudstackCli::Base
|
|
23
24
|
|
24
25
|
desc 'show NAME', 'show system VM'
|
25
26
|
def show(name)
|
26
|
-
|
27
|
-
unless vm = filter_by(vms, 'name', name).first
|
27
|
+
unless vm = client.list_system_vms(name: name).first
|
28
28
|
say "No system vm with name #{name} found."
|
29
29
|
else
|
30
30
|
table = vm.map do |key, value|
|
@@ -36,37 +36,34 @@ class SystemVm < CloudstackCli::Base
|
|
36
36
|
|
37
37
|
desc "start NAME", "start a system VM"
|
38
38
|
def start(name)
|
39
|
-
|
40
|
-
unless vm = filter_by(vms, 'name', name).first
|
39
|
+
unless vm = client.list_system_vms(name: name).first
|
41
40
|
say "No system vm with name #{name} found."
|
42
41
|
else
|
43
42
|
say("Starting system VM #{name}", :magenta)
|
44
|
-
client.start_system_vm(vm['id'])
|
45
|
-
|
43
|
+
client.start_system_vm(id: vm['id'])
|
44
|
+
say " OK.", :green
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
48
|
desc "stop NAME", "stop a system VM"
|
50
49
|
def stop(name)
|
51
|
-
|
52
|
-
unless vm = filter_by(vms, 'name', name).first
|
50
|
+
unless vm = client.list_system_vms(name: name).first
|
53
51
|
say "No system vm with name #{name} found."
|
54
52
|
else
|
55
53
|
exit unless options[:force] || yes?("Stop system VM #{name}? [y/N]:", :magenta)
|
56
|
-
client.stop_system_vm(vm['id'])
|
57
|
-
|
54
|
+
client.stop_system_vm(id: vm['id'])
|
55
|
+
say " OK.", :green
|
58
56
|
end
|
59
57
|
end
|
60
58
|
|
61
59
|
desc "reboot NAME", "reboot a system VM"
|
62
60
|
def reboot(name)
|
63
|
-
|
64
|
-
unless vm = filter_by(vms, 'name', name).first
|
61
|
+
unless vm = client.list_system_vms(name: name).first
|
65
62
|
say "No system vm with name #{name} found."
|
66
63
|
else
|
67
64
|
exit unless options[:force] || yes?("Reboot system VM #{name}? [y/N]:", :magenta)
|
68
|
-
client.reboot_system_vm(vm['id'])
|
69
|
-
|
65
|
+
client.reboot_system_vm(id: vm['id'])
|
66
|
+
say " OK.", :green
|
70
67
|
end
|
71
68
|
end
|
72
69
|
|
@@ -1,24 +1,21 @@
|
|
1
1
|
class Template < CloudstackCli::Base
|
2
2
|
|
3
|
-
desc 'list
|
3
|
+
desc 'list', 'list templates'
|
4
4
|
option :project
|
5
5
|
option :zone
|
6
|
+
option :type,
|
7
|
+
enum: %w(featured self self-executable executable community all),
|
8
|
+
default: "featured"
|
6
9
|
def list(type='featured')
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
zone = client.get_zone(options[:zone]) if options[:zone]
|
13
|
-
templates = client.list_templates(
|
14
|
-
filter: type,
|
15
|
-
project_id: project ? project['id'] : nil,
|
16
|
-
zone_id: zone ? zone['id'] : nil
|
17
|
-
)
|
10
|
+
resolve_project
|
11
|
+
resolve_zone
|
12
|
+
options[:template_filter] = options[:type]
|
13
|
+
options.delete(:filter)
|
14
|
+
templates = client.list_templates(options)
|
18
15
|
if templates.size < 1
|
19
16
|
puts "No templates found."
|
20
17
|
else
|
21
|
-
table = [
|
18
|
+
table = [%w(Name Zone Format)]
|
22
19
|
templates.each do |template|
|
23
20
|
table << [template['name'], template['zonename'], template['format']]
|
24
21
|
end
|
@@ -27,4 +24,4 @@ class Template < CloudstackCli::Base
|
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
30
|
-
end
|
27
|
+
end
|
@@ -1,15 +1,10 @@
|
|
1
1
|
class User < CloudstackCli::Base
|
2
2
|
|
3
|
-
USER_TYPES = {
|
4
|
-
0 => 'user',
|
5
|
-
1 => 'domain-admin',
|
6
|
-
2 => 'admin'
|
7
|
-
}
|
8
|
-
|
9
3
|
desc 'list', 'list users'
|
10
4
|
option :listall
|
11
5
|
option :account
|
12
6
|
def list
|
7
|
+
resolve_account
|
13
8
|
users = client.list_users(options)
|
14
9
|
if users.size < 1
|
15
10
|
say "No users found."
|
@@ -17,7 +12,7 @@ class User < CloudstackCli::Base
|
|
17
12
|
table = [["Account", "Type", "Name", "Email", "State", "Domain"]]
|
18
13
|
users.each do |user|
|
19
14
|
table << [
|
20
|
-
user['account'],
|
15
|
+
user['account'], Account::TYPES[user['accounttype']], "#{user['firstname']} #{user['lastname']}",
|
21
16
|
user['email'], user['state'], user['domain']
|
22
17
|
]
|
23
18
|
end
|
@@ -25,5 +20,5 @@ class User < CloudstackCli::Base
|
|
25
20
|
say "Total number of users: #{users.size}"
|
26
21
|
end
|
27
22
|
end
|
28
|
-
|
29
|
-
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
class VirtualMachine < CloudstackCli::Base
|
2
|
+
|
3
|
+
desc "list", "list virtual machines"
|
4
|
+
option :account, desc: "name of the account"
|
5
|
+
option :project, desc: "name of the project"
|
6
|
+
option :zone, desc: "the name of the availability zone"
|
7
|
+
option :state, desc: "state of the virtual machine"
|
8
|
+
option :listall, desc: "list all virtual machines", default: true
|
9
|
+
option :storage_id, desc: "the storage ID where vm's volumes belong to"
|
10
|
+
option :keyword, desc: "filter by keyword"
|
11
|
+
option :command,
|
12
|
+
desc: "command to execute for the given virtual machines",
|
13
|
+
enum: %w(START STOP REBOOT)
|
14
|
+
option :concurrency, type: :numeric, default: 10, aliases: '-C',
|
15
|
+
desc: "number of concurrent command to execute"
|
16
|
+
option :format, default: "table",
|
17
|
+
enum: %w(table json yaml)
|
18
|
+
def list
|
19
|
+
resolve_account
|
20
|
+
resolve_project
|
21
|
+
resolve_zone
|
22
|
+
command = options[:command].downcase if options[:command]
|
23
|
+
options.delete(:command)
|
24
|
+
virtual_machines = client.list_virtual_machines(options)
|
25
|
+
if virtual_machines.size < 1
|
26
|
+
puts "No virtual_machines found."
|
27
|
+
else
|
28
|
+
print_virtual_machines(virtual_machines)
|
29
|
+
execute_virtual_machines_commands(command, virtual_machines) if command
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "list_from_file FILE", "list virtual machines from file"
|
34
|
+
option :command,
|
35
|
+
desc: "command to execute for the given virtual machines",
|
36
|
+
enum: %w(START STOP REBOOT)
|
37
|
+
option :concurrency, type: :numeric, default: 10, aliases: '-C',
|
38
|
+
desc: "number of concurrent command to execute"
|
39
|
+
option :format, default: :table, enum: %w(table json yaml)
|
40
|
+
def list_from_file(file)
|
41
|
+
virtual_machines = parse_file(file)["virtual_machines"]
|
42
|
+
if virtual_machines.size < 1
|
43
|
+
puts "No virtual machines found."
|
44
|
+
else
|
45
|
+
print_virtual_machines(virtual_machines)
|
46
|
+
execute_virtual_machines_commands(virtual_machines) if options[:command]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "show NAME", "show detailed infos about a virtual machine"
|
51
|
+
option :project
|
52
|
+
def show(name)
|
53
|
+
resolve_project
|
54
|
+
options[:name] = name
|
55
|
+
unless virtual_machine = client.list_virtual_machines(options).first
|
56
|
+
puts "No virtual machine found."
|
57
|
+
else
|
58
|
+
table = virtual_machine.map do |key, value|
|
59
|
+
[ set_color("#{key}:", :yellow), "#{value}" ]
|
60
|
+
end
|
61
|
+
print_table table
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "create NAME [NAME2 ...]", "create virtual machine(s)"
|
66
|
+
option :template, aliases: '-t', desc: "name of the template"
|
67
|
+
option :iso, desc: "name of the iso template"
|
68
|
+
option :offering, aliases: '-o', required: true, desc: "computing offering name"
|
69
|
+
option :zone, aliases: '-z', required: true, desc: "availability zone name"
|
70
|
+
option :networks, aliases: '-n', type: :array, desc: "network names"
|
71
|
+
option :project, aliases: '-p', desc: "project name"
|
72
|
+
option :port_rules, aliases: '-pr', type: :array,
|
73
|
+
default: [],
|
74
|
+
desc: "Port Forwarding Rules [public_ip]:port ..."
|
75
|
+
option :disk_offering, desc: "disk offering (data disk for template, root disk for iso)"
|
76
|
+
option :disk_size, desc: "disk size in GB"
|
77
|
+
option :hypervisor, desc: "only used for iso deployments, default: vmware"
|
78
|
+
option :keypair, desc: "the name of the ssh keypair to use"
|
79
|
+
option :group, desc: "group name"
|
80
|
+
option :account, desc: "account name"
|
81
|
+
def create(*names)
|
82
|
+
vm_options_to_params
|
83
|
+
|
84
|
+
say "Start deploying virtual machine#{ "s" if names.size > 1 }...", :green
|
85
|
+
jobs = names.map do |name|
|
86
|
+
if virtual_machine = client.list_virtual_machines(name: name, project_id: options[:project_id]).first
|
87
|
+
say "virtual_machine #{name} (#{virtual_machine["state"]}) already exists.", :yellow
|
88
|
+
job = {
|
89
|
+
id: 0,
|
90
|
+
name: "Create virtual machine #{name}",
|
91
|
+
status: 1
|
92
|
+
}
|
93
|
+
else
|
94
|
+
job = {
|
95
|
+
id: client.deploy_virtual_machine(options, {sync: true})['jobid'],
|
96
|
+
name: "Create virtual_machine #{name}"
|
97
|
+
}
|
98
|
+
end
|
99
|
+
job
|
100
|
+
end
|
101
|
+
watch_jobs(jobs)
|
102
|
+
if options[:port_rules].size > 0
|
103
|
+
say "Create port forwarding rules...", :green
|
104
|
+
jobs = []
|
105
|
+
names.each do |name|
|
106
|
+
virtual_machine = client.list_virtual_machine(name: name, project_id: options[:project_id]).first
|
107
|
+
create_port_rules(virtual_machine, options[:port_rules], false).each_with_index do |job_id, index|
|
108
|
+
jobs << {
|
109
|
+
id: job_id,
|
110
|
+
name: "Create port forwarding ##{index + 1} rules for virtual machine #{virtual_machine['name']}"
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
watch_jobs(jobs)
|
115
|
+
end
|
116
|
+
say "Finished.", :green
|
117
|
+
end
|
118
|
+
|
119
|
+
desc "destroy NAME [NAME2 ..]", "destroy virtual_machine(s)"
|
120
|
+
option :project
|
121
|
+
option :force, desc: "destroy without asking", type: :boolean, aliases: '-f'
|
122
|
+
option :expunge, desc: "expunge virtual_machine immediately", type: :boolean, default: false, aliases: '-E'
|
123
|
+
def destroy(*names)
|
124
|
+
resolve_project
|
125
|
+
names.each do |name|
|
126
|
+
unless virtual_machine = client.list_virtual_machines(options.merge(name: name, listall: true)).first
|
127
|
+
say "Virtual machine #{name} not found.", :red
|
128
|
+
else
|
129
|
+
ask = "Destroy #{name} (#{virtual_machine['state']})? [y/N]:"
|
130
|
+
if options[:force] || yes?(ask, :yellow)
|
131
|
+
say "destroying #{name} "
|
132
|
+
client.destroy_virtual_machine(
|
133
|
+
id: virtual_machine["id"],
|
134
|
+
expunge: options[:expunge]
|
135
|
+
)
|
136
|
+
puts
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "create_interactive", "interactive creation of a virtual_machine with network access"
|
143
|
+
def create_interactive
|
144
|
+
bootstrap_server_interactive
|
145
|
+
end
|
146
|
+
|
147
|
+
desc "stop NAME", "stop a virtual_machine"
|
148
|
+
option :project
|
149
|
+
option :force
|
150
|
+
def stop(name)
|
151
|
+
resolve_project
|
152
|
+
options[:name] = name
|
153
|
+
options[:listall] = true
|
154
|
+
exit unless options[:force] || yes?("Stop virtual machine #{name}? [y/N]:", :magenta)
|
155
|
+
unless virtual_machine = client.list_virtual_machines(options).first
|
156
|
+
say "Virtual machine #{name} not found.", :red
|
157
|
+
exit 1
|
158
|
+
end
|
159
|
+
client.stop_virtual_machine(id: virtual_machine['id'])
|
160
|
+
puts
|
161
|
+
end
|
162
|
+
|
163
|
+
desc "start NAME", "start a virtual_machine"
|
164
|
+
option :project
|
165
|
+
def start(name)
|
166
|
+
resolve_project
|
167
|
+
options[:name] = name
|
168
|
+
options[:listall] = true
|
169
|
+
unless virtual_machine = client.list_virtual_machines(options).first
|
170
|
+
say "Virtual machine #{name} not found.", :red
|
171
|
+
exit 1
|
172
|
+
end
|
173
|
+
say("Starting virtual_machine #{name}", :magenta)
|
174
|
+
client.start_virtual_machine(id: virtual_machine['id'])
|
175
|
+
puts
|
176
|
+
end
|
177
|
+
|
178
|
+
desc "reboot NAME", "reboot a virtual_machine"
|
179
|
+
option :project
|
180
|
+
option :force
|
181
|
+
def reboot(name)
|
182
|
+
resolve_project
|
183
|
+
options[:name] = name
|
184
|
+
options[:listall] = true
|
185
|
+
unless virtual_machine = client.list_virtual_machines(options).first
|
186
|
+
say "Virtual machine #{name} not found.", :red
|
187
|
+
exit 1
|
188
|
+
end
|
189
|
+
exit unless options[:force] || yes?("Reboot virtual_machine #{name}? [y/N]:", :magenta)
|
190
|
+
client.reboot_virtual_machine(id: virtual_machine['id'])
|
191
|
+
puts
|
192
|
+
end
|
193
|
+
|
194
|
+
no_commands do
|
195
|
+
|
196
|
+
def print_virtual_machines(virtual_machines)
|
197
|
+
case options[:format].to_sym
|
198
|
+
when :yaml
|
199
|
+
puts({'virtual_machines' => virtual_machines}.to_yaml)
|
200
|
+
when :json
|
201
|
+
say JSON.pretty_generate(virtual_machines: virtual_machines)
|
202
|
+
else
|
203
|
+
table = [["Name", "State", "Offering", "Zone", options[:project_id] ? "Project" : "Account", "IP's"]]
|
204
|
+
virtual_machines.each do |virtual_machine|
|
205
|
+
table << [
|
206
|
+
virtual_machine['name'],
|
207
|
+
virtual_machine['state'],
|
208
|
+
virtual_machine['serviceofferingname'],
|
209
|
+
virtual_machine['zonename'],
|
210
|
+
options[:project_id] ? virtual_machine['project'] : virtual_machine['account'],
|
211
|
+
virtual_machine['nic'].map { |nic| nic['ipaddress']}.join(' ')
|
212
|
+
]
|
213
|
+
end
|
214
|
+
print_table table
|
215
|
+
say "Total number of virtual_machines: #{virtual_machines.count}"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def execute_virtual_machines_commands(command, virtual_machines)
|
220
|
+
unless %w(start stop reboot).include?(command)
|
221
|
+
say "\nCommand #{options[:command]} not supported.", :red
|
222
|
+
exit 1
|
223
|
+
end
|
224
|
+
exit unless yes?("\n#{command.capitalize} the virtual_machine(s) above? [y/N]:", :magenta)
|
225
|
+
virtual_machines.each_slice(options[:concurrency]) do | batch |
|
226
|
+
jobs = batch.map do |virtual_machine|
|
227
|
+
{
|
228
|
+
id: client.send(
|
229
|
+
"#{command}_virtual_machine",
|
230
|
+
{ id: virtual_machine['id'] },
|
231
|
+
{ sync: true }
|
232
|
+
)['jobid'],
|
233
|
+
name: "#{command.capitalize} virtual_machine #{virtual_machine['name']}"
|
234
|
+
}
|
235
|
+
end
|
236
|
+
puts
|
237
|
+
watch_jobs(jobs)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
end # no_commands
|
242
|
+
|
243
|
+
end
|