opennebula-cli 5.10.4 → 5.12.0
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/bin/oneacct +2 -1
- data/bin/oneacl +2 -1
- data/bin/onecluster +2 -1
- data/bin/onedatastore +2 -1
- data/bin/oneflow +149 -551
- data/bin/oneflow-template +171 -292
- data/bin/onegroup +2 -1
- data/bin/onehook +2 -1
- data/bin/onehost +76 -9
- data/bin/oneimage +2 -1
- data/bin/onemarket +2 -1
- data/bin/onemarketapp +15 -3
- data/bin/onesecgroup +2 -1
- data/bin/oneshowback +2 -1
- data/bin/onetemplate +2 -1
- data/bin/oneuser +2 -1
- data/bin/onevcenter +2 -1
- data/bin/onevdc +2 -1
- data/bin/onevm +88 -16
- data/bin/onevmgroup +2 -1
- data/bin/onevnet +11 -3
- data/bin/onevntemplate +2 -1
- data/bin/onevrouter +2 -1
- data/bin/onezone +5 -1
- data/lib/cli_helper.rb +54 -30
- data/lib/command_parser.rb +33 -14
- data/lib/one_helper.rb +258 -6
- data/lib/one_helper/oneacct_helper.rb +1 -1
- data/lib/one_helper/oneacl_helper.rb +1 -1
- data/lib/one_helper/onecluster_helper.rb +4 -4
- data/lib/one_helper/onedatastore_helper.rb +1 -1
- data/lib/one_helper/oneflow_helper.rb +419 -0
- data/lib/one_helper/oneflowtemplate_helper.rb +312 -0
- data/lib/one_helper/onegroup_helper.rb +1 -1
- data/lib/one_helper/onehook_helper.rb +1 -1
- data/lib/one_helper/onehost_helper.rb +148 -68
- data/lib/one_helper/oneimage_helper.rb +2 -2
- data/lib/one_helper/onemarket_helper.rb +1 -1
- data/lib/one_helper/onemarketapp_helper.rb +1 -1
- data/lib/one_helper/oneprovision_helper.rb +104 -60
- data/lib/one_helper/onequota_helper.rb +1 -1
- data/lib/one_helper/onesecgroup_helper.rb +1 -1
- data/lib/one_helper/onetemplate_helper.rb +9 -180
- data/lib/one_helper/oneuser_helper.rb +1 -1
- data/lib/one_helper/onevcenter_helper.rb +2 -1
- data/lib/one_helper/onevdc_helper.rb +1 -1
- data/lib/one_helper/onevm_helper.rb +11 -6
- data/lib/one_helper/onevmgroup_helper.rb +1 -1
- data/lib/one_helper/onevnet_helper.rb +1 -1
- data/lib/one_helper/onevntemplate_helper.rb +1 -1
- data/lib/one_helper/onevrouter_helper.rb +1 -1
- data/lib/one_helper/onezone_helper.rb +3 -1
- metadata +8 -6
data/bin/oneflow-template
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
# -------------------------------------------------------------------------- #
|
4
|
-
# Copyright 2002-
|
4
|
+
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
5
5
|
# #
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
7
7
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -20,139 +20,61 @@ ONE_LOCATION = ENV['ONE_LOCATION']
|
|
20
20
|
|
21
21
|
if !ONE_LOCATION
|
22
22
|
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
|
23
|
+
ONEFLOW_LOCATION = '/usr/lib/one/oneflow/lib'
|
23
24
|
GEMS_LOCATION = '/usr/share/one/gems'
|
24
25
|
else
|
25
26
|
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
27
|
+
ONEFLOW_LOCATION = ONE_LOCATION + '/lib/oneflow/lib'
|
26
28
|
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
27
29
|
end
|
28
30
|
|
29
31
|
if File.directory?(GEMS_LOCATION)
|
30
32
|
Gem.use_paths(GEMS_LOCATION)
|
33
|
+
$LOAD_PATH.reject! {|l| l =~ /(vendor|site)_ruby/ }
|
31
34
|
end
|
32
35
|
|
33
36
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
37
|
+
$LOAD_PATH << ONEFLOW_LOCATION
|
34
38
|
$LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
39
|
+
$LOAD_PATH << RUBY_LIB_LOCATION + '/oneflow/lib'
|
40
|
+
|
41
|
+
require 'json'
|
42
|
+
require 'English'
|
43
|
+
require 'tempfile'
|
35
44
|
|
36
45
|
require 'command_parser'
|
37
46
|
require 'opennebula/oneflow_client'
|
38
|
-
require '
|
47
|
+
require 'models'
|
39
48
|
require 'cli_helper'
|
40
|
-
require 'one_helper'
|
41
|
-
|
42
|
-
require 'json'
|
49
|
+
require 'one_helper/oneflowtemplate_helper'
|
43
50
|
|
44
51
|
USER_AGENT = 'CLI'
|
45
52
|
|
46
53
|
# Base Path representing the resource to be used in the requests
|
47
54
|
RESOURCE_PATH = '/service_template'
|
48
55
|
|
49
|
-
#
|
50
|
-
# Table
|
51
|
-
#
|
52
|
-
|
53
|
-
TABLE = CLIHelper::ShowTable.new(nil, self) do
|
54
|
-
column :ID, 'ID', :size => 10 do |d|
|
55
|
-
d['ID']
|
56
|
-
end
|
57
|
-
|
58
|
-
column :USER, 'Username', :left, :size => 15 do |d|
|
59
|
-
d['UNAME']
|
60
|
-
end
|
61
|
-
|
62
|
-
column :GROUP, 'Group', :left, :size => 15 do |d|
|
63
|
-
d['GNAME']
|
64
|
-
end
|
65
|
-
|
66
|
-
column :NAME, 'Name', :left, :size => 37 do |d|
|
67
|
-
d['NAME']
|
68
|
-
end
|
69
|
-
|
70
|
-
default :ID, :USER, :GROUP, :NAME
|
71
|
-
end
|
72
|
-
|
73
|
-
# Show the service template information. This method is used in top and
|
74
|
-
# show commands
|
75
|
-
# @param [Service::Client] client
|
76
|
-
# @param [Array] args
|
77
|
-
# @param [Hash] options
|
78
|
-
# @return [[Integer, String], Integer] Returns the exit_code and optionally
|
79
|
-
# a String to be printed
|
80
|
-
def show_service_template(client, args, options)
|
81
|
-
response = client.get("#{RESOURCE_PATH}/#{args[0]}")
|
82
|
-
|
83
|
-
if CloudClient.is_error?(response)
|
84
|
-
[response.code.to_i, response.to_s]
|
85
|
-
else
|
86
|
-
# [0,response.body]
|
87
|
-
if options[:json]
|
88
|
-
[0, response.body]
|
89
|
-
else
|
90
|
-
str = '%-20s: %-20s'
|
91
|
-
str_h1 = '%-80s'
|
92
|
-
|
93
|
-
document_hash = JSON.parse(response.body)
|
94
|
-
template = document_hash['DOCUMENT']['TEMPLATE']['BODY']
|
95
|
-
|
96
|
-
CLIHelper.print_header(str_h1 %
|
97
|
-
"SERVICE TEMPLATE #{document_hash['DOCUMENT']['ID']} "\
|
98
|
-
'INFORMATION')
|
99
|
-
|
100
|
-
puts Kernel.format str, 'ID', document_hash['DOCUMENT']['ID']
|
101
|
-
puts Kernel.format str, 'NAME', document_hash['DOCUMENT']['NAME']
|
102
|
-
puts Kernel.format str, 'USER', document_hash['DOCUMENT']['UNAME']
|
103
|
-
puts Kernel.format str, 'GROUP', document_hash['DOCUMENT']['GNAME']
|
104
|
-
|
105
|
-
puts
|
106
|
-
|
107
|
-
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
108
|
-
|
109
|
-
%w[OWNER GROUP OTHER].each do |e|
|
110
|
-
mask = '---'
|
111
|
-
permissions_hash = document_hash['DOCUMENT']['PERMISSIONS']
|
112
|
-
mask[0] = 'u' if permissions_hash["#{e}_U"] == '1'
|
113
|
-
mask[1] = 'm' if permissions_hash["#{e}_M"] == '1'
|
114
|
-
mask[2] = 'a' if permissions_hash["#{e}_A"] == '1'
|
115
|
-
|
116
|
-
puts Kernel.format str, e, mask
|
117
|
-
end
|
118
|
-
|
119
|
-
puts
|
120
|
-
|
121
|
-
CLIHelper.print_header(str_h1 % 'TEMPLATE CONTENTS', false)
|
122
|
-
puts JSON.pretty_generate(template)
|
123
|
-
|
124
|
-
0
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# List the services. This method is used in top and list commands
|
130
|
-
# @param [Service::Client] client
|
131
|
-
# @param [Hash] options
|
132
|
-
# @return [[Integer, String], Integer] Returns the exit_code and optionally
|
133
|
-
# a String to be printed
|
134
|
-
def list_service_templates(client, options)
|
135
|
-
response = client.get(RESOURCE_PATH)
|
136
|
-
|
137
|
-
if CloudClient.is_error?(response)
|
138
|
-
[response.code.to_i, response.to_s]
|
139
|
-
else
|
140
|
-
# [0,response.body]
|
141
|
-
if options[:json]
|
142
|
-
[0, response.body]
|
143
|
-
else
|
144
|
-
array_list = JSON.parse(response.body)
|
145
|
-
TABLE.show(array_list['DOCUMENT_POOL']['DOCUMENT'])
|
146
|
-
0
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
#
|
152
|
-
# Commands
|
153
|
-
#
|
154
|
-
|
155
56
|
CommandParser::CmdParser.new(ARGV) do
|
57
|
+
MULTIPLE = {
|
58
|
+
:name => 'multiple',
|
59
|
+
:short => '-m x',
|
60
|
+
:large => '--multiple x',
|
61
|
+
:format => Integer,
|
62
|
+
:description => 'Instance multiple templates'
|
63
|
+
}
|
64
|
+
|
65
|
+
RECURSIVE = {
|
66
|
+
:name => 'recursive',
|
67
|
+
:short => '-r',
|
68
|
+
:large => '--recursive',
|
69
|
+
:description => 'Clone the template recursively (templates and images)'
|
70
|
+
}
|
71
|
+
|
72
|
+
RECURSIVE_TEMPLATES = {
|
73
|
+
:name => 'recursive_templates',
|
74
|
+
:large => '--recursive-templates',
|
75
|
+
:description => 'Clone the template recursively (just templates)'
|
76
|
+
}
|
77
|
+
|
156
78
|
usage '`oneflow-template` <command> [<args>] [<options>]'
|
157
79
|
version OpenNebulaHelper::ONE_VERSION
|
158
80
|
|
@@ -160,9 +82,12 @@ CommandParser::CmdParser.new(ARGV) do
|
|
160
82
|
set :option, CommandParser::VERSION
|
161
83
|
set :option, CommandParser::HELP
|
162
84
|
|
163
|
-
#
|
85
|
+
# create helper object
|
86
|
+
helper = OneFlowTemplateHelper.new
|
87
|
+
|
88
|
+
############################################################################
|
164
89
|
# Formatters for arguments
|
165
|
-
|
90
|
+
############################################################################
|
166
91
|
set :format, :groupid, OpenNebulaHelper.rname_to_id_desc('GROUP') do |arg|
|
167
92
|
OpenNebulaHelper.rname_to_id(arg, 'GROUP')
|
168
93
|
end
|
@@ -181,81 +106,52 @@ CommandParser::CmdParser.new(ARGV) do
|
|
181
106
|
Service.list_to_id(arg, 'SERVICE TEMPLATE')
|
182
107
|
end
|
183
108
|
|
184
|
-
|
185
|
-
# List
|
186
|
-
#
|
109
|
+
###
|
187
110
|
|
188
111
|
list_desc = <<-EOT.unindent
|
189
112
|
List the available Service Templates
|
190
113
|
EOT
|
191
114
|
|
192
115
|
command :list, list_desc, :options => Service::JSON_FORMAT do
|
193
|
-
client
|
194
|
-
:username => options[:username],
|
195
|
-
:password => options[:password],
|
196
|
-
:url => options[:server],
|
197
|
-
:user_agent => USER_AGENT
|
198
|
-
)
|
199
|
-
|
200
|
-
list_service_templates(client, options)
|
116
|
+
helper.list_service_template_pool(helper.client(options), options)
|
201
117
|
end
|
202
118
|
|
203
|
-
|
204
|
-
# Top
|
205
|
-
#
|
119
|
+
###
|
206
120
|
|
207
121
|
top_desc = <<-EOT.unindent
|
208
122
|
List the available Service Templates continuously
|
209
123
|
EOT
|
210
124
|
|
211
|
-
command :top,
|
125
|
+
command :top,
|
126
|
+
top_desc,
|
212
127
|
:options => [Service::JSON_FORMAT,
|
213
128
|
Service::TOP,
|
214
129
|
CLIHelper::DELAY] do
|
215
|
-
|
216
|
-
:username => options[:username],
|
217
|
-
:password => options[:password],
|
218
|
-
:url => options[:server],
|
219
|
-
:user_agent => USER_AGENT
|
220
|
-
)
|
130
|
+
Signal.trap('INT') { exit(-1) }
|
221
131
|
|
222
|
-
options
|
132
|
+
helper.top_service_template_pool(helper.client(options), options)
|
223
133
|
|
224
|
-
|
225
|
-
|
226
|
-
CLIHelper.scr_cls
|
227
|
-
CLIHelper.scr_move(0, 0)
|
134
|
+
0
|
135
|
+
end
|
228
136
|
|
229
|
-
|
137
|
+
###
|
230
138
|
|
231
|
-
|
232
|
-
|
233
|
-
|
139
|
+
show_desc = <<-EOT.unindent
|
140
|
+
Show detailed information of a given Service Template
|
141
|
+
EOT
|
234
142
|
|
235
|
-
|
236
|
-
|
237
|
-
rescue StandardError => e
|
238
|
-
puts e.message
|
239
|
-
-1
|
240
|
-
end
|
143
|
+
command :show, show_desc, :templateid, :options => Service::JSON_FORMAT do
|
144
|
+
helper.format_resource(helper.client(options), args[0], options)
|
241
145
|
end
|
242
146
|
|
243
|
-
|
244
|
-
# Create
|
245
|
-
#
|
147
|
+
###
|
246
148
|
|
247
149
|
create_desc = <<-EOT.unindent
|
248
150
|
Create a new Service Template
|
249
151
|
EOT
|
250
152
|
|
251
153
|
command :create, create_desc, :file, :options => Service::JSON_FORMAT do
|
252
|
-
client
|
253
|
-
:username => options[:username],
|
254
|
-
:password => options[:password],
|
255
|
-
:url => options[:server],
|
256
|
-
:user_agent => USER_AGENT
|
257
|
-
)
|
258
|
-
|
154
|
+
client = helper.client(options)
|
259
155
|
response = client.post(RESOURCE_PATH, File.read(args[0]))
|
260
156
|
|
261
157
|
if CloudClient.is_error?(response)
|
@@ -264,180 +160,178 @@ CommandParser::CmdParser.new(ARGV) do
|
|
264
160
|
if options[:json]
|
265
161
|
[0, response.body]
|
266
162
|
else
|
267
|
-
|
268
|
-
|
163
|
+
puts "ID: #{JSON.parse(response.body)['DOCUMENT']['ID']}"
|
164
|
+
|
269
165
|
0
|
270
166
|
end
|
271
167
|
end
|
272
168
|
end
|
273
169
|
|
274
|
-
|
275
|
-
# Show
|
276
|
-
#
|
277
|
-
|
278
|
-
show_desc = <<-EOT.unindent
|
279
|
-
Show detailed information of a given Service Template
|
280
|
-
EOT
|
281
|
-
|
282
|
-
command :show, show_desc, :templateid, :options => Service::JSON_FORMAT do
|
283
|
-
client = Service::Client.new(
|
284
|
-
:username => options[:username],
|
285
|
-
:password => options[:password],
|
286
|
-
:url => options[:server],
|
287
|
-
:user_agent => USER_AGENT
|
288
|
-
)
|
289
|
-
|
290
|
-
show_service_template(client, args, options)
|
291
|
-
end
|
292
|
-
|
293
|
-
#
|
294
|
-
# Delete
|
295
|
-
#
|
170
|
+
###
|
296
171
|
|
297
172
|
delete_desc = <<-EOT.unindent
|
298
173
|
Delete a given Service Template
|
299
174
|
EOT
|
300
175
|
|
301
176
|
command :delete, delete_desc, [:range, :templateid_list] do
|
302
|
-
client =
|
303
|
-
:username => options[:username],
|
304
|
-
:password => options[:password],
|
305
|
-
:url => options[:server],
|
306
|
-
:user_agent => USER_AGENT
|
307
|
-
)
|
177
|
+
client = helper.client(options)
|
308
178
|
|
309
179
|
Service.perform_actions(args[0]) do |template_id|
|
310
180
|
client.delete("#{RESOURCE_PATH}/#{template_id}")
|
311
181
|
end
|
312
182
|
end
|
313
183
|
|
314
|
-
|
315
|
-
# Instantiate
|
316
|
-
#
|
184
|
+
###
|
317
185
|
|
318
186
|
instantiate_desc = <<-EOT.unindent
|
319
187
|
Instantiate a Service Template
|
320
188
|
EOT
|
321
189
|
|
322
|
-
command :instantiate,
|
323
|
-
|
324
|
-
|
325
|
-
:
|
326
|
-
:
|
327
|
-
|
328
|
-
:user_agent => USER_AGENT
|
329
|
-
)
|
330
|
-
|
190
|
+
command :instantiate,
|
191
|
+
instantiate_desc,
|
192
|
+
:templateid,
|
193
|
+
[:file, nil],
|
194
|
+
:options => [MULTIPLE, Service::JSON_FORMAT, Service::TOP] do
|
195
|
+
number = options[:multiple] || 1
|
331
196
|
params = {}
|
197
|
+
rc = 0
|
332
198
|
|
333
|
-
|
334
|
-
params['merge_template'] =
|
335
|
-
|
199
|
+
number.times do
|
200
|
+
params['merge_template'] = nil
|
201
|
+
params['merge_template'] = JSON.parse(File.read(args[1])) if args[1]
|
336
202
|
|
337
|
-
|
203
|
+
unless params['merge_template']
|
204
|
+
service_template = OpenNebula::ServiceTemplate
|
205
|
+
.new_with_id(args[0],
|
206
|
+
OpenNebula::Client.new)
|
207
|
+
service_template.info
|
338
208
|
|
339
|
-
|
209
|
+
body = JSON.parse(service_template['/DOCUMENT/TEMPLATE/BODY'])
|
340
210
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
[
|
211
|
+
params['merge_template'] = helper.custom_attrs(
|
212
|
+
body['custom_attrs']
|
213
|
+
)
|
214
|
+
|
215
|
+
params['merge_template'] = {} unless params['merge_template']
|
216
|
+
|
217
|
+
vnets = helper.networks(body['networks'])
|
218
|
+
params['merge_template'].merge!(vnets) unless vnets.nil?
|
219
|
+
end
|
220
|
+
|
221
|
+
json = Service.build_json_action('instantiate', params)
|
222
|
+
client = helper.client(options)
|
223
|
+
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json)
|
224
|
+
|
225
|
+
if CloudClient.is_error?(response)
|
226
|
+
rc = [response.code.to_i, response.to_s]
|
227
|
+
break
|
346
228
|
else
|
347
|
-
|
348
|
-
|
349
|
-
|
229
|
+
if options[:json]
|
230
|
+
rc = [0, response.body]
|
231
|
+
break
|
232
|
+
else
|
233
|
+
rc = 0
|
234
|
+
puts "ID: #{JSON.parse(response.body)['DOCUMENT']['ID']}"
|
235
|
+
end
|
350
236
|
end
|
351
237
|
end
|
238
|
+
|
239
|
+
rc
|
352
240
|
end
|
353
241
|
|
242
|
+
###
|
243
|
+
|
354
244
|
chgrp_desc = <<-EOT.unindent
|
355
245
|
Changes the service template group
|
356
246
|
EOT
|
357
247
|
|
358
248
|
command :chgrp, chgrp_desc, [:range, :templateid_list], :groupid do
|
359
|
-
client =
|
360
|
-
:username => options[:username],
|
361
|
-
:password => options[:password],
|
362
|
-
:url => options[:server],
|
363
|
-
:user_agent => USER_AGENT
|
364
|
-
)
|
249
|
+
client = helper.client(options)
|
365
250
|
|
366
251
|
Service.perform_actions(args[0]) do |service_id|
|
367
252
|
params = {}
|
368
253
|
params['group_id'] = args[1].to_i
|
369
254
|
|
370
|
-
|
255
|
+
json = Service.build_json_action('chgrp', params)
|
371
256
|
|
372
|
-
client.post("#{RESOURCE_PATH}/#{service_id}/action",
|
257
|
+
client.post("#{RESOURCE_PATH}/#{service_id}/action", json)
|
373
258
|
end
|
374
259
|
end
|
375
260
|
|
261
|
+
###
|
262
|
+
|
376
263
|
chown_desc = <<-EOT.unindent
|
377
264
|
Changes the service template owner and group
|
378
265
|
EOT
|
379
266
|
|
380
|
-
command :chown,
|
381
|
-
|
382
|
-
|
383
|
-
:
|
384
|
-
:
|
385
|
-
|
386
|
-
:user_agent => USER_AGENT
|
387
|
-
)
|
267
|
+
command :chown,
|
268
|
+
chown_desc,
|
269
|
+
[:range, :templateid_list],
|
270
|
+
:userid,
|
271
|
+
[:groupid, nil] do
|
272
|
+
client = helper.client(options)
|
388
273
|
|
389
274
|
Service.perform_actions(args[0]) do |service_id|
|
390
275
|
params = {}
|
391
276
|
params['owner_id'] = args[1]
|
392
277
|
params['group_id'] = args[2] if args[2]
|
393
278
|
|
394
|
-
|
279
|
+
json = Service.build_json_action('chown', params)
|
395
280
|
|
396
|
-
client.post("#{RESOURCE_PATH}/#{service_id}/action",
|
281
|
+
client.post("#{RESOURCE_PATH}/#{service_id}/action", json)
|
397
282
|
end
|
398
283
|
end
|
399
284
|
|
285
|
+
###
|
286
|
+
|
400
287
|
chmod_desc = <<-EOT.unindent
|
401
288
|
Changes the service template permissions
|
402
289
|
EOT
|
403
290
|
|
404
291
|
command :chmod, chmod_desc, [:range, :templateid_list], :octet do
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
)
|
292
|
+
if !/\A\d+\z/.match(args[1])
|
293
|
+
STDERR.puts "Invalid '#{args[1]}' octed permissions"
|
294
|
+
exit(-1)
|
295
|
+
end
|
296
|
+
|
297
|
+
client = helper.client(options)
|
411
298
|
|
412
299
|
Service.perform_actions(args[0]) do |service_id|
|
413
300
|
params = {}
|
414
301
|
params['octet'] = args[1]
|
415
302
|
|
416
|
-
|
303
|
+
json = Service.build_json_action('chmod', params)
|
417
304
|
|
418
|
-
client.post("#{RESOURCE_PATH}/#{service_id}/action",
|
305
|
+
client.post("#{RESOURCE_PATH}/#{service_id}/action", json)
|
419
306
|
end
|
420
307
|
end
|
421
308
|
|
309
|
+
###
|
310
|
+
|
422
311
|
clone_desc = <<-EOT.unindent
|
423
312
|
Creates a new Service Template from an existing one
|
424
313
|
EOT
|
425
314
|
|
426
|
-
command :clone,
|
427
|
-
|
428
|
-
:
|
429
|
-
:
|
430
|
-
:
|
431
|
-
:user_agent => USER_AGENT
|
432
|
-
)
|
433
|
-
|
315
|
+
command :clone,
|
316
|
+
clone_desc,
|
317
|
+
:templateid,
|
318
|
+
:name,
|
319
|
+
:options => [RECURSIVE, RECURSIVE_TEMPLATES] do
|
434
320
|
params = {}
|
435
321
|
params['name'] = args[1]
|
436
322
|
|
437
|
-
|
323
|
+
if options.key?(:recursive)
|
324
|
+
params['recursive'] = 'all'
|
325
|
+
elsif options.key?(:recursive_templates)
|
326
|
+
params['recurisve'] = 'templates'
|
327
|
+
else
|
328
|
+
params['recursive'] = 'none'
|
329
|
+
end
|
330
|
+
|
331
|
+
json = Service.build_json_action('clone', params)
|
332
|
+
client = helper.client(options)
|
438
333
|
|
439
|
-
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action",
|
440
|
-
json_action)
|
334
|
+
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json)
|
441
335
|
|
442
336
|
if CloudClient.is_error?(response)
|
443
337
|
[response.code.to_i, response.to_s]
|
@@ -445,40 +339,33 @@ CommandParser::CmdParser.new(ARGV) do
|
|
445
339
|
if options[:json]
|
446
340
|
[0, response.body]
|
447
341
|
else
|
448
|
-
|
449
|
-
|
342
|
+
puts "ID: #{JSON.parse(response.body)['DOCUMENT']['ID']}"
|
343
|
+
|
450
344
|
0
|
451
345
|
end
|
452
346
|
end
|
453
347
|
end
|
454
348
|
|
349
|
+
###
|
350
|
+
|
455
351
|
rename_desc = <<-EOT.unindent
|
456
352
|
Renames the Service Template
|
457
353
|
EOT
|
458
354
|
|
459
355
|
command :rename, rename_desc, :templateid, :name do
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
:url => options[:server],
|
464
|
-
:user_agent => USER_AGENT
|
465
|
-
)
|
466
|
-
|
467
|
-
params = {}
|
468
|
-
params['name'] = args[1]
|
469
|
-
|
470
|
-
json_action = Service.build_json_action('rename', params)
|
356
|
+
Service.perform_action(args[0]) do |template_id|
|
357
|
+
params = {}
|
358
|
+
params['name'] = args[1]
|
471
359
|
|
472
|
-
|
473
|
-
|
360
|
+
json = Service.build_json_action('rename', params)
|
361
|
+
client = helper.client(options)
|
474
362
|
|
475
|
-
|
476
|
-
[response.code.to_i, response.to_s]
|
477
|
-
else
|
478
|
-
response.code.to_i
|
363
|
+
client.post("#{RESOURCE_PATH}/#{template_id}/action", json)
|
479
364
|
end
|
480
365
|
end
|
481
366
|
|
367
|
+
###
|
368
|
+
|
482
369
|
update_desc = <<-EOT.unindent
|
483
370
|
Update the template contents. If a path is not provided the editor will
|
484
371
|
be launched to modify the current content.
|
@@ -486,30 +373,23 @@ CommandParser::CmdParser.new(ARGV) do
|
|
486
373
|
|
487
374
|
command :update, update_desc, :templateid, [:file, nil] do
|
488
375
|
template_id = args[0]
|
489
|
-
client
|
490
|
-
:username => options[:username],
|
491
|
-
:password => options[:password],
|
492
|
-
:url => options[:server],
|
493
|
-
:user_agent => USER_AGENT
|
494
|
-
)
|
376
|
+
client = helper.client(options)
|
495
377
|
|
496
378
|
if args[1]
|
497
379
|
path = args[1]
|
498
380
|
else
|
499
|
-
require 'tempfile'
|
500
|
-
|
501
|
-
tmp = Tempfile.new(template_id.to_s)
|
502
|
-
path = tmp.path
|
503
|
-
|
504
381
|
response = client.get("#{RESOURCE_PATH}/#{template_id}")
|
505
382
|
|
506
383
|
if CloudClient.is_error?(response)
|
507
384
|
exit_with_code response.code.to_i, response.to_s
|
508
385
|
else
|
509
|
-
|
510
|
-
template =
|
386
|
+
document = JSON.parse(response.body)['DOCUMENT']
|
387
|
+
template = document['TEMPLATE']['BODY']
|
511
388
|
|
512
|
-
tmp
|
389
|
+
tmp = Tempfile.new(template_id.to_s)
|
390
|
+
path = tmp.path
|
391
|
+
|
392
|
+
tmp.write(JSON.pretty_generate(template))
|
513
393
|
tmp.flush
|
514
394
|
|
515
395
|
if ENV['EDITOR']
|
@@ -517,10 +397,11 @@ CommandParser::CmdParser.new(ARGV) do
|
|
517
397
|
else
|
518
398
|
editor_path = OpenNebulaHelper::EDITOR_PATH
|
519
399
|
end
|
400
|
+
|
520
401
|
system("#{editor_path} #{path}")
|
521
402
|
|
522
403
|
unless $CHILD_STATUS.exitstatus.zero?
|
523
|
-
puts 'Editor not defined'
|
404
|
+
STDERR.puts 'Editor not defined'
|
524
405
|
exit(-1)
|
525
406
|
end
|
526
407
|
|
@@ -528,15 +409,13 @@ CommandParser::CmdParser.new(ARGV) do
|
|
528
409
|
end
|
529
410
|
end
|
530
411
|
|
531
|
-
|
412
|
+
response = client.put("#{RESOURCE_PATH}/#{template_id}",
|
413
|
+
File.read(path))
|
532
414
|
|
533
|
-
t_str = File.read(path)
|
534
|
-
response = client.put("#{RESOURCE_PATH}/#{template_id}", t_str)
|
535
415
|
if CloudClient.is_error?(response)
|
536
|
-
|
537
|
-
|
416
|
+
[response.code.to_i, response.to_s]
|
417
|
+
else
|
418
|
+
0
|
538
419
|
end
|
539
|
-
|
540
|
-
exit_code
|
541
420
|
end
|
542
421
|
end
|