opennebula-cli 4.0.1 → 4.1.80.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -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