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
@@ -8,7 +8,9 @@ class Volume < CloudstackCli::Base
|
|
8
8
|
option :name, desc: 'name of the disk volume'
|
9
9
|
option :type, desc: 'type of disk volume (ROOT or DATADISK)'
|
10
10
|
def list
|
11
|
-
|
11
|
+
resolve_project
|
12
|
+
resolve_account
|
13
|
+
resolve_zone
|
12
14
|
volumes = client.list_volumes(options)
|
13
15
|
if volumes.size < 1
|
14
16
|
say "No volumes found."
|
@@ -33,8 +35,9 @@ class Volume < CloudstackCli::Base
|
|
33
35
|
desc "show NAME", "show volume details"
|
34
36
|
option :project, desc: 'project of volume'
|
35
37
|
def show(name)
|
38
|
+
resolve_project
|
39
|
+
options[:listall] = true
|
36
40
|
options[:name] = name
|
37
|
-
options[:project_id] = find_project['id'] if options[:project]
|
38
41
|
volumes = client.list_volumes(options)
|
39
42
|
if volumes.size < 1
|
40
43
|
say "No volume with name \"#{name}\" found."
|
@@ -47,5 +50,117 @@ class Volume < CloudstackCli::Base
|
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
53
|
+
desc "create NAME", "create volume"
|
54
|
+
option :project,
|
55
|
+
desc: "project of volume"
|
56
|
+
option :disk_offering,
|
57
|
+
desc: "disk offering for the disk volume. Either disk_offering or snapshot must be passed in"
|
58
|
+
option :snapshot,
|
59
|
+
desc: "snapshot for the disk volume. Either disk_offering or snapshot must be passed in"
|
60
|
+
option :virtual_machine,
|
61
|
+
desc: "Used together with the snapshot option: VM to which the volume gets attached after creation."
|
62
|
+
option :zone,
|
63
|
+
desc: "name of the availability zone"
|
64
|
+
option :size,
|
65
|
+
desc: "size of the volume in GB"
|
66
|
+
def create(name)
|
67
|
+
options[:name] = name
|
68
|
+
resolve_project
|
69
|
+
resolve_zone
|
70
|
+
resolve_disk_offering
|
71
|
+
resolve_snapshot
|
72
|
+
resolve_virtual_machine
|
73
|
+
|
74
|
+
if !options[:disk_offering_id] && !options[:snapshot_id]
|
75
|
+
say "Either disk_offering or snapshot must be passed in.", :yellow
|
76
|
+
exit 1
|
77
|
+
elsif options[:disk_offering_id] && !options[:zone_id]
|
78
|
+
say "Zone is required when deploying with disk-offering.", :yellow
|
79
|
+
exit 1
|
80
|
+
end
|
81
|
+
|
82
|
+
say "Creating volume #{name} "
|
83
|
+
client.create_volume(options)
|
84
|
+
say " OK.", :green
|
85
|
+
sleep 2
|
86
|
+
invoke "volume:show", [name], options
|
87
|
+
end
|
88
|
+
|
89
|
+
desc "attach NAME", "attach volume to VM"
|
90
|
+
option :project, desc: 'project of volume'
|
91
|
+
option :virtual_machine, desc: 'project of volume'
|
92
|
+
def attach(name)
|
93
|
+
resolve_project
|
94
|
+
resolve_virtual_machine
|
95
|
+
|
96
|
+
volume = client.list_volumes(
|
97
|
+
name: name,
|
98
|
+
listall: true,
|
99
|
+
project_id: options[:project_id]
|
100
|
+
).first
|
101
|
+
|
102
|
+
if !volume
|
103
|
+
say "Error: Volume #{name} not found.", :red
|
104
|
+
exit 1
|
105
|
+
elsif volume.has_key?("virtualmachineid")
|
106
|
+
say "Error: Volume #{name} already attached to VM #{volume["vmname"]}.", :red
|
107
|
+
exit 1
|
108
|
+
end
|
109
|
+
|
110
|
+
say "Attach volume #{name} to VM #{options[:virtual_machine]} "
|
111
|
+
client.attach_volume(
|
112
|
+
id: volume['id'],
|
113
|
+
virtualmachine_id: options[:virtual_machine_id]
|
114
|
+
)
|
115
|
+
say " OK.", :green
|
116
|
+
end
|
117
|
+
|
118
|
+
desc "detach NAME", "attach volume to VM"
|
119
|
+
option :project, desc: 'project of volume'
|
120
|
+
def detach(name)
|
121
|
+
resolve_project
|
122
|
+
|
123
|
+
volume = client.list_volumes(
|
124
|
+
name: name,
|
125
|
+
listall: true,
|
126
|
+
project_id: options[:project_id]
|
127
|
+
).first
|
128
|
+
|
129
|
+
if !volume
|
130
|
+
say "Error: Volume #{name} not found.", :red
|
131
|
+
exit 1
|
132
|
+
elsif !volume.has_key?("virtualmachineid")
|
133
|
+
say "Error: Volume #{name} currently not attached to any VM.", :red
|
134
|
+
exit 1
|
135
|
+
end
|
136
|
+
|
137
|
+
say "Detach volume #{name} from VM #{volume["vmname"]} "
|
138
|
+
client.detach_volume id: volume['id']
|
139
|
+
say " OK.", :green
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "delete NAME", "attach volume to VM"
|
143
|
+
option :project, desc: 'project of volume'
|
144
|
+
def delete(name)
|
145
|
+
resolve_project
|
146
|
+
|
147
|
+
volume = client.list_volumes(
|
148
|
+
name: name,
|
149
|
+
listall: true,
|
150
|
+
project_id: options[:project_id]
|
151
|
+
).first
|
152
|
+
|
153
|
+
if !volume
|
154
|
+
say "Error: Volume #{name} not found.", :red
|
155
|
+
exit 1
|
156
|
+
elsif volume.has_key?("virtualmachineid")
|
157
|
+
say "Error: Volume #{name} must be detached before deletion.", :red
|
158
|
+
exit 1
|
159
|
+
end
|
160
|
+
|
161
|
+
say "Delete volume #{name} "
|
162
|
+
client.delete_volume id: volume['id']
|
163
|
+
say " OK.", :green
|
164
|
+
end
|
50
165
|
|
51
166
|
end
|
@@ -6,12 +6,16 @@ class Zone < CloudstackCli::Base
|
|
6
6
|
if zones.size < 1
|
7
7
|
puts "No projects found"
|
8
8
|
else
|
9
|
-
table = [%w(Name Description)]
|
9
|
+
table = [%w(Name Network-Type Description)]
|
10
10
|
zones.each do |zone|
|
11
|
-
table << [
|
11
|
+
table << [
|
12
|
+
zone['name'],
|
13
|
+
zone['networktype'],
|
14
|
+
zone['description']
|
15
|
+
]
|
12
16
|
end
|
13
17
|
end
|
14
18
|
print_table(table)
|
15
19
|
end
|
16
20
|
|
17
|
-
end
|
21
|
+
end
|
@@ -47,7 +47,7 @@ module CloudstackCli
|
|
47
47
|
def update_job_status(jobs)
|
48
48
|
jobs.each do |job|
|
49
49
|
unless job[:status] && job[:status] > 0
|
50
|
-
job[:status] = client.
|
50
|
+
job[:status] = client.query_async_job_result(job_id: job[:id])['jobstatus']
|
51
51
|
end
|
52
52
|
end
|
53
53
|
jobs
|
@@ -68,19 +68,25 @@ module CloudstackCli
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def bootstrap_server(args = {})
|
71
|
-
if args[:project] && project =
|
71
|
+
if args[:project] && project = find_project(args[:project])
|
72
72
|
project_id = project["id"]
|
73
73
|
project_name = project['name']
|
74
74
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
|
76
|
+
if args[:name]
|
77
|
+
args['displayname'] = args[:name]
|
78
|
+
name = args[:name]
|
79
|
+
elsif args[:displayname]
|
80
|
+
name = args[:displayname]
|
81
|
+
end
|
82
|
+
|
83
|
+
unless server = client.list_virtual_machines(name: args[:name], project_id: project_id).first
|
84
|
+
say "Create VM #{name}...", :yellow
|
85
|
+
server = client.deploy_virtual_machine(args)
|
86
|
+
puts
|
87
|
+
say "VM #{name} has been created.", :green
|
82
88
|
else
|
83
|
-
say "
|
89
|
+
say "VM #{name} already exists (#{server["state"]}).", :yellow
|
84
90
|
end
|
85
91
|
|
86
92
|
if args[:port_rules] && args[:port_rules].size > 0
|
@@ -90,13 +96,12 @@ module CloudstackCli
|
|
90
96
|
end
|
91
97
|
|
92
98
|
def create_server(args = {})
|
93
|
-
if args[:project] && project =
|
99
|
+
if args[:project] && project = find_project(args[:project])
|
94
100
|
project_id = project["id"]
|
95
101
|
project_name = project['name']
|
96
102
|
end
|
97
|
-
server = client(
|
98
|
-
|
99
|
-
server = client.create_server(args)
|
103
|
+
unless server = client.list_virtual_machines(name: args[:name], project_id: project_id)
|
104
|
+
server = client.deploy_virtual_machine(args)
|
100
105
|
end
|
101
106
|
server
|
102
107
|
end
|
@@ -105,7 +110,7 @@ module CloudstackCli
|
|
105
110
|
frontendip = nil
|
106
111
|
jobs = []
|
107
112
|
client.verbose = async
|
108
|
-
project_id = server['
|
113
|
+
project_id = server['projectid'] || nil
|
109
114
|
port_rules.each do |pf_rule|
|
110
115
|
ip = pf_rule.split(":")[0]
|
111
116
|
if ip != ''
|
@@ -116,20 +121,23 @@ module CloudstackCli
|
|
116
121
|
end
|
117
122
|
else
|
118
123
|
ip_addr = frontendip ||= client.associate_ip_address(
|
119
|
-
server["nic"].first["networkid"]
|
124
|
+
network_id: server["nic"].first["networkid"]
|
120
125
|
)
|
121
126
|
end
|
122
127
|
port = pf_rule.split(":")[1]
|
128
|
+
args = {
|
129
|
+
ipaddressid: ip_addr["id"],
|
130
|
+
publicport: port,
|
131
|
+
privateport: port,
|
132
|
+
protocol: 'TCP',
|
133
|
+
virtualmachineid: server["id"]
|
134
|
+
}
|
123
135
|
if async
|
124
136
|
say "Create port forwarding rule #{ip_addr['ipaddress']}:#{port} for server #{server["name"]}.", :yellow
|
125
|
-
client.create_port_forwarding_rule(
|
137
|
+
client.create_port_forwarding_rule(args)
|
126
138
|
return
|
127
139
|
else
|
128
|
-
jobs << client.create_port_forwarding_rule(
|
129
|
-
ip_addr["id"],
|
130
|
-
port, 'TCP', port, server["id"],
|
131
|
-
false
|
132
|
-
)['jobid']
|
140
|
+
jobs << client.create_port_forwarding_rule(args, {sync: true})['jobid']
|
133
141
|
end
|
134
142
|
end
|
135
143
|
jobs
|
@@ -146,16 +154,17 @@ module CloudstackCli
|
|
146
154
|
end
|
147
155
|
|
148
156
|
projects = client.list_projects
|
149
|
-
|
150
|
-
|
157
|
+
project_id = nil
|
158
|
+
if projects.size > 0
|
159
|
+
if yes?("Do you want to deploy your VM within a project? (y/N)") && projects.size > 0
|
151
160
|
say "Select a project", :yellow
|
152
161
|
print_options(projects)
|
153
162
|
project = ask_number("Project Nr.: ")
|
163
|
+
project_id = projects[project]['id'] rescue nil
|
154
164
|
end
|
155
|
-
project_id = projects[project]['id'] rescue nil
|
156
165
|
end
|
157
166
|
|
158
|
-
say "Please provide a name for the new
|
167
|
+
say "Please provide a name for the new VM", :yellow
|
159
168
|
say "(spaces or special characters are NOT allowed)"
|
160
169
|
server_name = ask("Server name: ")
|
161
170
|
|
@@ -164,7 +173,7 @@ module CloudstackCli
|
|
164
173
|
print_options(server_offerings)
|
165
174
|
service_offering = ask_number("Offering Nr.: ")
|
166
175
|
|
167
|
-
templates = client.list_templates(project_id: project_id, zone_id: zones[zone]["id"])
|
176
|
+
templates = client.list_templates(project_id: project_id, zone_id: zones[zone]["id"], template_filter: "all")
|
168
177
|
say "Select a template:", :yellow
|
169
178
|
print_options(templates)
|
170
179
|
template = ask_number("Template Nr.: ")
|
@@ -180,24 +189,76 @@ module CloudstackCli
|
|
180
189
|
|
181
190
|
say "You entered the following configuration:", :yellow
|
182
191
|
table = [["Zone", zones[zone]["name"]]]
|
183
|
-
table << ["
|
192
|
+
table << ["VM Name", server_name]
|
184
193
|
table << ["Template", templates[template]["name"]]
|
185
194
|
table << ["Offering", server_offerings[service_offering]["name"]]
|
186
195
|
table << ["Network", networks[network]["name"]]
|
187
196
|
table << ["Project", projects[project]["name"]] if project
|
188
197
|
print_table table
|
189
198
|
|
190
|
-
if yes? "Do you want to deploy this
|
199
|
+
if yes? "Do you want to deploy this VM? (y/N)"
|
191
200
|
bootstrap_server(
|
192
|
-
server_name,
|
193
|
-
zones[zone]["
|
194
|
-
templates[template]["
|
195
|
-
server_offerings[service_offering]["
|
196
|
-
|
197
|
-
|
201
|
+
name: server_name,
|
202
|
+
zone_id: zones[zone]["id"],
|
203
|
+
template_id: templates[template]["id"],
|
204
|
+
serviceoffering_id: server_offerings[service_offering]["id"],
|
205
|
+
network_ids: network ? networks[network]["id"] : nil,
|
206
|
+
project_id: project_id
|
198
207
|
)
|
199
208
|
end
|
200
209
|
end
|
201
210
|
|
211
|
+
##
|
212
|
+
# Finds the public ip for a server
|
213
|
+
|
214
|
+
def get_server_public_ip(server, cached_rules=nil)
|
215
|
+
return nil unless server
|
216
|
+
|
217
|
+
# find the public ip
|
218
|
+
nic = get_server_default_nic(server) || {}
|
219
|
+
if nic['type'] == 'Virtual'
|
220
|
+
ssh_rule = get_ssh_port_forwarding_rule(server, cached_rules)
|
221
|
+
ssh_rule ? ssh_rule['ipaddress'] : nil
|
222
|
+
else
|
223
|
+
nic['ipaddress']
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
##
|
228
|
+
# Gets the SSH port forwarding rule for the specified server.
|
229
|
+
|
230
|
+
def get_ssh_port_forwarding_rule(server, cached_rules=nil)
|
231
|
+
rules = cached_rules || client.list_port_forwarding_rules(project_id: server["projectid"]) || []
|
232
|
+
rules.find_all { |r|
|
233
|
+
r['virtualmachineid'] == server['id'] &&
|
234
|
+
r['privateport'] == '22'&&
|
235
|
+
r['publicport'] == '22'
|
236
|
+
}.first
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# Returns the fully qualified domain name for a server.
|
241
|
+
|
242
|
+
def get_server_fqdn(server)
|
243
|
+
return nil unless server
|
244
|
+
|
245
|
+
nic = get_server_default_nic(server) || {}
|
246
|
+
networks = client.list_networks(project_id: server['projectid']) || {}
|
247
|
+
|
248
|
+
id = nic['networkid']
|
249
|
+
network = networks.select { |net|
|
250
|
+
net['id'] == id
|
251
|
+
}.first
|
252
|
+
return nil unless network
|
253
|
+
|
254
|
+
"#{server['name']}.#{network['networkdomain']}"
|
255
|
+
end
|
256
|
+
|
257
|
+
def get_server_default_nic(server)
|
258
|
+
server['nic'].each do |nic|
|
259
|
+
return nic if nic['isdefault']
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
202
263
|
end
|
203
264
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module CloudstackCli
|
2
|
+
module OptionResolver
|
3
|
+
|
4
|
+
def vm_options_to_params(options = options)
|
5
|
+
resolve_zone(options)
|
6
|
+
resolve_project(options)
|
7
|
+
resolve_compute_offering(options)
|
8
|
+
resolve_template(options)
|
9
|
+
resolve_disk_offering(options)
|
10
|
+
resolve_iso(options)
|
11
|
+
unless options[:template_id]
|
12
|
+
say "Error: Template or ISO is required.", :red
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
resolve_networks(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def resolve_zone(options = options)
|
19
|
+
if options[:zone]
|
20
|
+
zones = client.list_zones
|
21
|
+
zone = zones.find {|z| z['name'] == options[:zone] }
|
22
|
+
if !zone
|
23
|
+
msg = options[:zone] ? "Zone '#{options[:zone]}' is invalid." : "No zone found."
|
24
|
+
say "Error: #{msg}", :red
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
options[:zone_id] = zone['id']
|
28
|
+
end
|
29
|
+
options
|
30
|
+
end
|
31
|
+
|
32
|
+
def resolve_domain(options = options)
|
33
|
+
if options[:domain]
|
34
|
+
if domain = client.list_domains(name: options[:domain]).first
|
35
|
+
options[:domain_id] = domain['id']
|
36
|
+
else
|
37
|
+
say "Error: Domain #{options[:domain]} not found.", :red
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
options
|
42
|
+
end
|
43
|
+
|
44
|
+
def resolve_project(options = options)
|
45
|
+
if options[:project]
|
46
|
+
if %w(ALL -1).include? options[:project]
|
47
|
+
options[:project_id] = "-1"
|
48
|
+
elsif project = client.list_projects(name: options[:project], listall: true).first
|
49
|
+
options[:project_id] = project['id']
|
50
|
+
else
|
51
|
+
say "Error: Project #{options[:project]} not found.", :red
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
options
|
56
|
+
end
|
57
|
+
|
58
|
+
def resolve_account(options = options)
|
59
|
+
if options[:account]
|
60
|
+
if account = client.list_accounts(name: options[:account], listall: true).first
|
61
|
+
options[:account_id] = account['id']
|
62
|
+
options[:domain_id] = account['domainid']
|
63
|
+
else
|
64
|
+
say "Error: Account #{options[:account]} not found.", :red
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
options
|
69
|
+
end
|
70
|
+
|
71
|
+
def resolve_networks(options = options)
|
72
|
+
networks = []
|
73
|
+
if options[:networks]
|
74
|
+
options[:networks].each do |name|
|
75
|
+
network = client.list_networks(
|
76
|
+
name: name,
|
77
|
+
zone_id: options[:zone_id],
|
78
|
+
project_id: options[:project_id]
|
79
|
+
).first
|
80
|
+
if !network
|
81
|
+
say "Error: Network '#{name}' not found.", :red
|
82
|
+
exit 1
|
83
|
+
end
|
84
|
+
networks << network
|
85
|
+
end
|
86
|
+
end
|
87
|
+
if networks.empty?
|
88
|
+
#unless default_network = client.list_networks(project_id: options[:project_id]).find {
|
89
|
+
# |n| n['isdefault'] == true }
|
90
|
+
unless default_network = client.list_networks(project_id: options[:project_id]).first
|
91
|
+
say "Error: No default network found.", :red
|
92
|
+
exit 1
|
93
|
+
end
|
94
|
+
networks << default_network
|
95
|
+
end
|
96
|
+
options[:network_ids] = networks.map {|n| n['id']}.join(',')
|
97
|
+
options
|
98
|
+
end
|
99
|
+
|
100
|
+
def resolve_iso(options = options)
|
101
|
+
if options[:iso]
|
102
|
+
unless iso = client.list_isos(name: options[:iso]).first
|
103
|
+
say "Error: Iso '#{args[:iso]}' is invalid.", :red
|
104
|
+
exit 1
|
105
|
+
end
|
106
|
+
unless options[:diskoffering_id]
|
107
|
+
say "Error: a disk offering is required when using iso.", :red
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
options[:template_id] = iso['id']
|
111
|
+
options['hypervisor'] = (options[:hypervisor] || 'vmware')
|
112
|
+
end
|
113
|
+
options
|
114
|
+
end
|
115
|
+
|
116
|
+
def resolve_template(options = options)
|
117
|
+
if options[:template]
|
118
|
+
if template = client.list_templates(name: options[:template], template_filter: "all").first
|
119
|
+
options[:template_id] = template['id']
|
120
|
+
else
|
121
|
+
say "Error: Template #{options[:template]} not found.", :red
|
122
|
+
exit 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
options
|
126
|
+
end
|
127
|
+
|
128
|
+
def resolve_compute_offering(options = options)
|
129
|
+
if offering = client.list_service_offerings(name: options[:offering]).first
|
130
|
+
options[:service_offering_id] = offering['id']
|
131
|
+
else
|
132
|
+
say "Error: Offering #{options[:offering]} not found.", :red
|
133
|
+
exit 1
|
134
|
+
end
|
135
|
+
options
|
136
|
+
end
|
137
|
+
|
138
|
+
def resolve_disk_offering(options = options)
|
139
|
+
if options[:disk_offering]
|
140
|
+
unless disk_offering = client.list_disk_offerings(name: options[:disk_offering]).first
|
141
|
+
say "Error: Disk offering '#{options[:disk_offering]}' not found.", :red
|
142
|
+
exit 1
|
143
|
+
end
|
144
|
+
options[:disk_offering_id] = disk_offering['id']
|
145
|
+
end
|
146
|
+
options
|
147
|
+
end
|
148
|
+
|
149
|
+
def resolve_virtual_machine(options = options)
|
150
|
+
if options[:virtual_machine]
|
151
|
+
args = { name: options[:virtual_machine], listall: true }
|
152
|
+
args[:project_id] = options[:project_id]
|
153
|
+
unless vm = client.list_virtual_machines(args).first
|
154
|
+
say "Error: VM '#{options[:virtual_machine]}' not found.", :red
|
155
|
+
exit 1
|
156
|
+
end
|
157
|
+
options[:virtual_machine_id] = vm['id']
|
158
|
+
end
|
159
|
+
options
|
160
|
+
end
|
161
|
+
|
162
|
+
def resolve_snapshot(options = options)
|
163
|
+
if options[:snapshot]
|
164
|
+
args = { name: options[:snapshot], listall: true }
|
165
|
+
args[:project_id] = options[:project_id]
|
166
|
+
unless snapshot = client.list_snapshots(args).first
|
167
|
+
say "Error: Snapshot '#{options[:snapshot]}' not found.", :red
|
168
|
+
exit 1
|
169
|
+
end
|
170
|
+
options[:snapshot_id] = snapshot['id']
|
171
|
+
end
|
172
|
+
options
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
data/lib/cloudstack-cli.rb
CHANGED
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: 0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nik Wolfgramm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 1.0.0.rc1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 1.0.0.rc1
|
69
69
|
description: cloudstack-cli is a CloudStack API command line client written in Ruby.
|
70
70
|
email:
|
71
71
|
- nik.wolfgramm@gmail.com
|
@@ -110,7 +110,6 @@ files:
|
|
110
110
|
- lib/cloudstack-cli/commands/region.rb
|
111
111
|
- lib/cloudstack-cli/commands/resource_limit.rb
|
112
112
|
- lib/cloudstack-cli/commands/router.rb
|
113
|
-
- lib/cloudstack-cli/commands/server.rb
|
114
113
|
- lib/cloudstack-cli/commands/snapshot.rb
|
115
114
|
- lib/cloudstack-cli/commands/ssh_key_pairs.rb
|
116
115
|
- lib/cloudstack-cli/commands/stack.rb
|
@@ -118,13 +117,15 @@ files:
|
|
118
117
|
- lib/cloudstack-cli/commands/system_vm.rb
|
119
118
|
- lib/cloudstack-cli/commands/template.rb
|
120
119
|
- lib/cloudstack-cli/commands/user.rb
|
120
|
+
- lib/cloudstack-cli/commands/virtual_machine.rb
|
121
121
|
- lib/cloudstack-cli/commands/volume.rb
|
122
122
|
- lib/cloudstack-cli/commands/zone.rb
|
123
123
|
- lib/cloudstack-cli/helper.rb
|
124
|
+
- lib/cloudstack-cli/option_resolver.rb
|
124
125
|
- lib/cloudstack-cli/version.rb
|
125
126
|
- test/stack_example.json
|
126
127
|
- test/stack_example.yml
|
127
|
-
homepage: http://
|
128
|
+
homepage: http://github.com/niwo/cloudstack-cli
|
128
129
|
licenses:
|
129
130
|
- MIT
|
130
131
|
metadata: {}
|
@@ -141,9 +142,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
142
|
version: 1.9.3
|
142
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
144
|
requirements:
|
144
|
-
- - "
|
145
|
+
- - ">"
|
145
146
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
147
|
+
version: 1.3.1
|
147
148
|
requirements: []
|
148
149
|
rubyforge_project:
|
149
150
|
rubygems_version: 2.2.2
|