opennebula-cli 4.0.1 → 4.1.80.beta

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.
@@ -0,0 +1,451 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # -------------------------------------------------------------------------- #
4
+ # Copyright 2010-2013, C12G Labs S.L. #
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
+ # not use this file except in compliance with the License. You may obtain #
8
+ # a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ #--------------------------------------------------------------------------- #
18
+
19
+ ONE_LOCATION=ENV["ONE_LOCATION"]
20
+
21
+ if !ONE_LOCATION
22
+ RUBY_LIB_LOCATION="/usr/lib/one/ruby"
23
+ else
24
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
25
+ end
26
+
27
+ $: << RUBY_LIB_LOCATION
28
+ $: << RUBY_LIB_LOCATION+'/cli'
29
+
30
+ require 'command_parser'
31
+ require 'opennebula/oneflow_client'
32
+
33
+ require 'cli_helper'
34
+ require 'one_helper'
35
+
36
+ require 'json'
37
+
38
+ USER_AGENT = "CLI"
39
+
40
+ # Base Path representing the resource to be used in the requests
41
+ RESOURCE_PATH = '/service_template'
42
+
43
+ #
44
+ # Table
45
+ #
46
+
47
+ TABLE = CLIHelper::ShowTable.new(nil, self) do
48
+ column :ID, "ID", :size=>10 do |d|
49
+ d["ID"]
50
+ end
51
+
52
+ column :USER, "Username", :left, :size=>15 do |d|
53
+ d["UNAME"]
54
+ end
55
+
56
+ column :GROUP, "Group", :left, :size=>15 do |d|
57
+ d["GNAME"]
58
+ end
59
+
60
+ column :NAME, "Name", :left, :size=>37 do |d|
61
+ d["NAME"]
62
+ end
63
+
64
+ default :ID, :USER, :GROUP, :NAME
65
+ end
66
+
67
+
68
+ # Show the service template information. This method is used in top and
69
+ # show commands
70
+ # @param [Service::Client] client
71
+ # @param [Array] args
72
+ # @param [Hash] options
73
+ # @return [[Integer, String], Integer] Returns the exit_code and optionally
74
+ # a String to be printed
75
+ def show_service_template(client, args, options)
76
+ response = client.get("#{RESOURCE_PATH}/#{args[0]}")
77
+
78
+ if CloudClient::is_error?(response)
79
+ [response.code.to_i, response.to_s]
80
+ else
81
+ #[0,response.body]
82
+ if options[:json]
83
+ [0,response.body]
84
+ else
85
+ str="%-20s: %-20s"
86
+ str_h1="%-80s"
87
+
88
+ document_hash = JSON.parse(response.body)
89
+ template = document_hash['DOCUMENT']['TEMPLATE']['BODY']
90
+
91
+ CLIHelper.print_header(str_h1 %
92
+ "SERVICE TEMPLATE #{document_hash['DOCUMENT']['ID']} INFORMATION")
93
+
94
+ puts str % ["ID", document_hash['DOCUMENT']['ID']]
95
+ puts str % ["NAME", document_hash['DOCUMENT']['NAME']]
96
+ puts str % ["USER", document_hash['DOCUMENT']['UNAME']]
97
+ puts str % ["GROUP",document_hash['DOCUMENT']['GNAME']]
98
+
99
+ puts
100
+
101
+ CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
102
+
103
+ ["OWNER", "GROUP", "OTHER"].each { |e|
104
+ mask = "---"
105
+ mask[0] = "u" if document_hash['DOCUMENT']['PERMISSIONS']["#{e}_U"] == "1"
106
+ mask[1] = "m" if document_hash['DOCUMENT']['PERMISSIONS']["#{e}_M"] == "1"
107
+ mask[2] = "a" if document_hash['DOCUMENT']['PERMISSIONS']["#{e}_A"] == "1"
108
+
109
+ puts str % [e, mask]
110
+ }
111
+
112
+ puts
113
+
114
+ CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false)
115
+ puts JSON.pretty_generate(template)
116
+
117
+ 0
118
+ end
119
+ end
120
+ end
121
+
122
+ # List the services. This method is used in top and list commands
123
+ # @param [Service::Client] client
124
+ # @param [Array] args
125
+ # @param [Hash] options
126
+ # @return [[Integer, String], Integer] Returns the exit_code and optionally
127
+ # a String to be printed
128
+ def list_service_templates(client, args, options)
129
+ response = client.get(RESOURCE_PATH)
130
+
131
+ if CloudClient::is_error?(response)
132
+ [response.code.to_i, response.to_s]
133
+ else
134
+ #[0,response.body]
135
+ if options[:json]
136
+ [0,response.body]
137
+ else
138
+ array_list = JSON.parse(response.body)
139
+ TABLE.show(array_list['DOCUMENT_POOL']['DOCUMENT'])
140
+ 0
141
+ end
142
+ end
143
+ end
144
+
145
+ #
146
+ # Commands
147
+ #
148
+
149
+ cmd=CommandParser::CmdParser.new(ARGV) do
150
+ usage "`oneflow-template` <command> [<args>] [<options>]"
151
+ version OpenNebulaHelper::ONE_VERSION
152
+
153
+ set :option, Service::DEFAULT_OPTIONS
154
+ set :option, CommandParser::VERSION
155
+ set :option, CommandParser::HELP
156
+
157
+ #
158
+ # Formatters for arguments
159
+ #
160
+ set :format, :groupid, OpenNebulaHelper.rname_to_id_desc("GROUP") do |arg|
161
+ OpenNebulaHelper.rname_to_id(arg, "GROUP")
162
+ end
163
+
164
+ set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg|
165
+ OpenNebulaHelper.rname_to_id(arg, "USER")
166
+ end
167
+
168
+ set :format, :template_id, Service.rname_to_id_desc("SERVICE TEMPLATE") do |arg|
169
+ Service.rname_to_id(arg, "SERVICE TEMPLATE")
170
+ end
171
+
172
+ set :format, :templateid_list, Service.list_to_id_desc("SERVICE TEMPLATE") do |arg|
173
+ Service.list_to_id(arg, "SERVICE TEMPLATE")
174
+ end
175
+
176
+ #
177
+ # List
178
+ #
179
+
180
+ list_desc = <<-EOT.unindent
181
+ List the available Service Templates
182
+ EOT
183
+
184
+ command :list, list_desc, :options => Service::JSON_FORMAT do
185
+ client = Service::Client.new(
186
+ :username => options[:username],
187
+ :password => options[:password],
188
+ :url => options[:server],
189
+ :user_agent => USER_AGENT)
190
+
191
+ list_service_templates(client, args, options)
192
+ end
193
+
194
+ #
195
+ # Top
196
+ #
197
+
198
+ top_desc = <<-EOT.unindent
199
+ List the available Service Templates continuously
200
+ EOT
201
+
202
+ command :top, top_desc,
203
+ :options => [Service::JSON_FORMAT, Service::TOP, CLIHelper::DELAY] do
204
+ client = Service::Client.new(
205
+ :username => options[:username],
206
+ :password => options[:password],
207
+ :url => options[:server],
208
+ :user_agent => USER_AGENT)
209
+
210
+ delay=options[:delay] ? options[:delay] : 3
211
+
212
+ begin
213
+ while true
214
+ CLIHelper.scr_cls
215
+ CLIHelper.scr_move(0,0)
216
+
217
+ rc, message = list_service_templates(client, args, options)
218
+
219
+ if rc != 0
220
+ raise message
221
+ end
222
+
223
+ sleep delay
224
+ end
225
+ rescue Exception => e
226
+ puts e.message
227
+ -1
228
+ end
229
+ end
230
+
231
+ #
232
+ # Create
233
+ #
234
+
235
+ create_desc = <<-EOT.unindent
236
+ Create a new Service Template
237
+ EOT
238
+
239
+ command :create, create_desc, :file, :options => Service::JSON_FORMAT do
240
+ client = Service::Client.new(
241
+ :username => options[:username],
242
+ :password => options[:password],
243
+ :url => options[:server],
244
+ :user_agent => USER_AGENT)
245
+
246
+ response = client.post(RESOURCE_PATH, File.read(args[0]))
247
+
248
+ if CloudClient::is_error?(response)
249
+ [response.code.to_i, response.to_s]
250
+ else
251
+ if options[:json]
252
+ [0,response.body]
253
+ else
254
+ template = JSON.parse(response.body)
255
+ puts "ID: #{template['DOCUMENT']['ID']}"
256
+ 0
257
+ end
258
+ end
259
+ end
260
+
261
+ #
262
+ # Show
263
+ #
264
+
265
+ show_desc = <<-EOT.unindent
266
+ Show detailed information of a given Service Template
267
+ EOT
268
+
269
+ command :show, show_desc, :template_id, :options => Service::JSON_FORMAT do
270
+ client = Service::Client.new(
271
+ :username => options[:username],
272
+ :password => options[:password],
273
+ :url => options[:server],
274
+ :user_agent => USER_AGENT)
275
+
276
+ show_service_template(client, args, options)
277
+ end
278
+
279
+ #
280
+ # Delete
281
+ #
282
+
283
+ delete_desc = <<-EOT.unindent
284
+ Delete a given Service Template
285
+ EOT
286
+
287
+ command :delete, delete_desc, [:range, :templateid_list] do
288
+ client = Service::Client.new(
289
+ :username => options[:username],
290
+ :password => options[:password],
291
+ :url => options[:server],
292
+ :user_agent => USER_AGENT)
293
+
294
+ Service.perform_actions(args[0]) { |template_id|
295
+ client.delete("#{RESOURCE_PATH}/#{template_id}")
296
+ }
297
+ end
298
+
299
+ #
300
+ # Instantiate
301
+ #
302
+
303
+ instantiate_desc = <<-EOT.unindent
304
+ Instantiate a Service Template
305
+ EOT
306
+
307
+ command :instantiate, instantiate_desc, :template_id,
308
+ :options => [Service::JSON_FORMAT, Service::TOP] do
309
+ client = Service::Client.new(
310
+ :username => options[:username],
311
+ :password => options[:password],
312
+ :url => options[:server],
313
+ :user_agent => USER_AGENT)
314
+
315
+ json_str = Service.build_json_action('instantiate')
316
+
317
+ response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json_str)
318
+
319
+ if CloudClient::is_error?(response)
320
+ [response.code.to_i, response.to_s]
321
+ else
322
+ if options[:json]
323
+ [0,response.body]
324
+ else
325
+ template = JSON.parse(response.body)
326
+ puts "ID: #{template['DOCUMENT']['ID']}"
327
+ 0
328
+ end
329
+ end
330
+ end
331
+
332
+ chgrp_desc = <<-EOT.unindent
333
+ Changes the service template group
334
+ EOT
335
+
336
+ command :chgrp, chgrp_desc, [:range, :templateid_list], :groupid do
337
+ client = Service::Client.new(
338
+ :username => options[:username],
339
+ :password => options[:password],
340
+ :url => options[:server],
341
+ :user_agent => USER_AGENT)
342
+
343
+ Service.perform_actions(args[0]) { |service_id|
344
+ params = Hash.new
345
+ params['group_id'] = args[1].to_i
346
+
347
+ json_action = Service.build_json_action('chgrp', params)
348
+
349
+ client.post("#{RESOURCE_PATH}/#{service_id}/action", json_action)
350
+ }
351
+ end
352
+
353
+ chown_desc = <<-EOT.unindent
354
+ Changes the service template owner and group
355
+ EOT
356
+
357
+ command :chown, chown_desc, [:range, :templateid_list], :userid, [:groupid, nil] do
358
+ client = Service::Client.new(
359
+ :username => options[:username],
360
+ :password => options[:password],
361
+ :url => options[:server],
362
+ :user_agent => USER_AGENT)
363
+
364
+ Service.perform_actions(args[0]) { |service_id|
365
+ params = Hash.new
366
+ params['owner_id'] = args[1]
367
+ params['group_id'] = args[2] if args[2]
368
+
369
+ json_action = Service.build_json_action('chown', params)
370
+
371
+ client.post("#{RESOURCE_PATH}/#{service_id}/action", json_action)
372
+ }
373
+ end
374
+
375
+ chmod_desc = <<-EOT.unindent
376
+ Changes the service template permissions
377
+ EOT
378
+
379
+ command :chmod, chmod_desc, [:range, :templateid_list], :octet do
380
+ client = Service::Client.new(
381
+ :username => options[:username],
382
+ :password => options[:password],
383
+ :url => options[:server],
384
+ :user_agent => USER_AGENT)
385
+
386
+ Service.perform_actions(args[0]) { |service_id|
387
+ params = Hash.new
388
+ params['octet'] = args[1]
389
+
390
+ json_action = Service.build_json_action('chmod', params)
391
+
392
+ client.post("#{RESOURCE_PATH}/#{service_id}/action", json_action)
393
+ }
394
+ end
395
+
396
+ update_desc = <<-EOT.unindent
397
+ Update the template contents. If a path is not provided the editor will
398
+ be launched to modify the current content.
399
+ EOT
400
+
401
+ command :update, update_desc, :templateid, [:file, nil] do
402
+ template_id = args[0]
403
+ client = Service::Client.new(
404
+ :username => options[:username],
405
+ :password => options[:password],
406
+ :url => options[:server],
407
+ :user_agent => USER_AGENT)
408
+
409
+ if args[1]
410
+ path = args[1]
411
+ else
412
+ require 'tempfile'
413
+
414
+ tmp = Tempfile.new(template_id.to_s)
415
+ path = tmp.path
416
+
417
+ response = client.get("#{RESOURCE_PATH}/#{template_id}")
418
+
419
+ if CloudClient::is_error?(response)
420
+ exit_with_code response.code.to_i, response.to_s
421
+ else
422
+ document_hash = JSON.parse(response.body)
423
+ template = document_hash['DOCUMENT']['TEMPLATE']['BODY']
424
+
425
+ tmp << JSON.pretty_generate(template)
426
+ tmp.flush
427
+
428
+ editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : OpenNebulaHelper::EDITOR_PATH
429
+ system("#{editor_path} #{path}")
430
+
431
+ unless $?.exitstatus == 0
432
+ puts "Editor not defined"
433
+ exit -1
434
+ end
435
+
436
+ tmp.close
437
+ end
438
+ end
439
+
440
+ exit_code = 0
441
+
442
+ t_str = File.read(path)
443
+ response = client.put("#{RESOURCE_PATH}/#{template_id}", t_str)
444
+ if CloudClient::is_error?(response)
445
+ puts response.to_s
446
+ exit_code = response.code.to_i
447
+ end
448
+
449
+ exit_code
450
+ end
451
+ end
data/bin/onehost CHANGED
@@ -148,10 +148,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do
148
148
  be launched to modify the current content.
149
149
  EOT
150
150
 
151
- command :update, update_desc, :hostid, [:file, nil] do
152
- helper.perform_action(args[0],options,"updated") do |host|
153
- str = OpenNebulaHelper.update_template(args[0], host, args[1])
154
- host.update(str)
151
+ command :update, update_desc, :hostid, [:file, nil],
152
+ :options=>OpenNebulaHelper::APPEND do
153
+ helper.perform_action(args[0],options,"updated") do |obj|
154
+ if options[:append]
155
+ str = OpenNebulaHelper.append_template(args[0], obj, args[1])
156
+ else
157
+ str = OpenNebulaHelper.update_template(args[0], obj, args[1])
158
+ end
159
+
160
+ obj.update(str, options[:append])
155
161
  end
156
162
  end
157
163