cloudstack-cli 0.15.1 → 1.0.0.rc1
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 +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
|