opennebula-cli 5.0.2 → 5.1.80.beta1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10038339d922cdf1ab6992aa381ed432f3965149
4
- data.tar.gz: 11cc0ef4f6ddb062f2ed6641a0fdd7babc6d697a
3
+ metadata.gz: 5918a18eb88bc2dd352bda44bef92b4e1311ff04
4
+ data.tar.gz: 91eca333217510670bbb7d4746b329421db599a1
5
5
  SHA512:
6
- metadata.gz: 058178f751626c5ef3d2839be154e26539cef81bb368076605eefbd0626712bbdb26fd22f3f33d52d159b5e71d632961ec5b9f9ddd28c8a5548a498a63b980fe
7
- data.tar.gz: 859c40a5741d92f33108dc8b892a38761095b96c60b42f68aa380c0a56b902e99694bc3fdd4dce09cb351ee9e877b7cb3dfc305c6ddc6b2d42f7a7c51ec9260e
6
+ metadata.gz: e2d80b573fcc114f130fbee620504dbb92cd9dca78b033a7fc9358f383d685baef15cc55620e902c35ea2e956060612db4b608ab3a607a2fed376044f9611984
7
+ data.tar.gz: 015e5537a21a89848a682ef1be2dcd30266e6abc9f9a764c106af402f42808d302b9344267e336af4feb2ba8d9a7cb942b7b8aa4556cea72e28dee54467ffab0
data/bin/oneuser CHANGED
@@ -140,8 +140,49 @@ cmd=CommandParser::CmdParser.new(ARGV) do
140
140
  :description => "Force one_auth file rewrite"
141
141
  }
142
142
 
143
+ TOKEN = {
144
+ :name => "token",
145
+ :large => "--token token_hint",
146
+ :format => String,
147
+ :description => "The Token to be loaded."
148
+ }
149
+
150
+ GROUP = {
151
+ :name => "group",
152
+ :large => "--group id|name" ,
153
+ :description => "Effective GID to use with this token.",
154
+ :format => String,
155
+ :proc => lambda { |o, options|
156
+ OpenNebulaHelper.rname_to_id(o, "GROUP")
157
+ }
158
+ }
159
+
160
+ GLOBAL = {
161
+ :name => "global",
162
+ :large => "--global" ,
163
+ :description => "Find a global Token."
164
+ }
165
+
166
+ STDIN_PASSWORD = {
167
+ :name => "stdin_password",
168
+ :large => "--stdin_password",
169
+ :description => "enable stdin password"
170
+ }
171
+
143
172
  create_options = [READ_FILE, SHA1, SSH, X509, KEY, CERT, DRIVER]
144
- login_options = [SSH, X509, X509_PROXY, KEY, CERT, PROXY, TIME, FORCE]
173
+
174
+ login_options = [SSH,
175
+ X509,
176
+ X509_PROXY,
177
+ KEY,
178
+ CERT,
179
+ PROXY,
180
+ TIME,
181
+ FORCE,
182
+ GROUP,
183
+ STDIN_PASSWORD]
184
+
185
+ set_options = [TOKEN, GLOBAL]
145
186
 
146
187
  ########################################################################
147
188
  # Formatters for arguments
@@ -328,31 +369,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do
328
369
  end
329
370
 
330
371
  login_desc = <<-EOT.unindent
331
- Creates the login token for authentication. The token can be used
332
- together with any authentication driver. The token will be stored in
333
- $HOME/.one/one_auth, and can be used subsequently to authenticate with
334
- oned through API, CLI or Sunstone.
335
-
336
- Example, request a valid token for a generic driver (e.g. core auth, LDAP...):
337
- oneuser login my_user --time 3600
338
-
339
- Example, generate and set a token for SSH based authentication:
340
- oneuser login my_user --ssh --key /tmp/id_rsa --time 72000
341
-
342
- Example, same using X509 certificates:
343
- oneuser login my_user --x509 --cert /tmp/my_cert.pem
344
- --key /tmp/my_key.pk --time 72000
345
-
346
- Example, now with a X509 proxy certificate
347
- oneuser login my_user --x509_proxy --proxy /tmp/my_cert.pem
348
- --time 72000
372
+ Alias of token-create.
349
373
  EOT
350
374
 
351
- command :login, login_desc, :username, :options=>login_options do
352
-
353
- options[:time] ||= 36000
354
-
355
- helper.login(args[0], options)
375
+ command :login, login_desc, [:username, nil], :options=>login_options do
376
+ helper.token_create(args, options)
356
377
  end
357
378
 
358
379
  key_desc = <<-EOT.unindent
@@ -375,7 +396,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
375
396
  exit_with_code 0
376
397
  end
377
398
 
378
-
379
399
  delete_desc = <<-EOT.unindent
380
400
  Deletes the given User
381
401
  EOT
@@ -530,4 +550,207 @@ cmd=CommandParser::CmdParser.new(ARGV) do
530
550
 
531
551
  helper.list_pool(options)
532
552
  end
553
+
554
+ token_add_desc = <<-EOT.unindent
555
+ Creates the login token for authentication. The token can be used
556
+ together with any authentication driver. The token will be stored in
557
+ $HOME/.one/one_auth, and can be used subsequently to authenticate with
558
+ oned through API, CLI or Sunstone.
559
+
560
+ If <username> is ommited, it will infer it from the ONE_AUTH file.
561
+
562
+ Example, request a valid token for a generic driver (e.g. core auth, LDAP...):
563
+ oneuser token-create my_user --time 3600
564
+
565
+ Example, request a group spefici token (new resources will be created in that
566
+ group and only resources that belong to that group will be listed):
567
+ oneuser token-create my_user --group <id|group>
568
+
569
+ Example, generate and set a token for SSH based authentication:
570
+ oneuser token-create my_user --ssh --key /tmp/id_rsa --time 72000
571
+
572
+ Example, same using X509 certificates:
573
+ oneuser token-create my_user --x509 --cert /tmp/my_cert.pem
574
+ --key /tmp/my_key.pk --time 72000
575
+
576
+ Example, now with a X509 proxy certificate
577
+ oneuser token-create my_user --x509_proxy --proxy /tmp/my_cert.pem
578
+ --time 72000
579
+ EOT
580
+
581
+ command :"token-create", token_add_desc, [:username, nil],
582
+ :options=>login_options do
583
+
584
+ helper.token_create(args, options)
585
+ end
586
+
587
+ token_set_desc = <<-EOT.unindent
588
+ Generates a ONE_AUTH file that contains the token.
589
+
590
+ You must provide one (and only one) of the following options:
591
+
592
+ --token <token> searches for a token that starts with that string. It must be
593
+ unique
594
+
595
+ --group <id|group> returns the most durable token that provides access to that
596
+ specific group.
597
+
598
+ --global returns the most durable global token (non group specific).
599
+
600
+ The argument 'username' is optional, if omitted it is inferred from the ONE_AUTH
601
+ file.
602
+
603
+ Example, set a token:
604
+ $ oneuser token-set my_user --token 1d47
605
+ export ONE_AUTH=/var/lib/one/.one/<file>.token; export ONE_EGID=-1
606
+
607
+ You can copy & paste the output of the command and will load the proper
608
+ environment variables.
609
+ EOT
610
+
611
+ command :"token-set", token_set_desc, [:username, nil],
612
+ :options=>login_options+set_options do
613
+
614
+ username = args[0]
615
+
616
+ if username
617
+ if username =~ /^\d+$/
618
+ exit_with_code 1, "The argument should be the username, not the ID."
619
+ end
620
+
621
+ helper.client = helper.get_login_client(username, options)
622
+ end
623
+
624
+ user = helper.retrieve_resource(OpenNebula::User::SELF)
625
+
626
+ rc = user.info
627
+ if OpenNebula.is_error?(rc)
628
+ puts rc.message
629
+ exit_with_code 1, rc.message
630
+ end
631
+
632
+ # Process the options
633
+ if options[:token]
634
+ token_hint = options[:token]
635
+ group = nil
636
+ elsif options[:group]
637
+ token_hint = nil
638
+ group = options[:group]
639
+ elsif options[:global]
640
+ token_hint = nil
641
+ group = -1
642
+ else
643
+ exit_with_code 1, "One of these options must be supplied:\n" <<
644
+ "[--token <token>] [--group <id|group>] [--global]"
645
+ end
646
+
647
+ tokens = helper.find_token(user, token_hint, group, false)
648
+
649
+ if tokens.length == 0
650
+ exit_with_code 1, "No valid tokens found."
651
+ end
652
+
653
+ if token_hint && tokens.length > 1
654
+ msg = "More than one token starting with '#{token_hint}' found."
655
+ exit_with_code 1, msg
656
+ end
657
+
658
+ token = tokens[0]["TOKEN"]
659
+
660
+ egid = user["LOGIN_TOKEN[TOKEN='#{token}']/EGID"]
661
+
662
+ auth_string = "#{user['NAME']}:#{token}"
663
+ auth_file = helper.auth_file(auth_string)
664
+
665
+ begin
666
+ FileUtils.mkdir_p(File.dirname(auth_file))
667
+ rescue Errno::EEXIST
668
+ end
669
+
670
+ file = File.open(auth_file, "w")
671
+ file.write(auth_string)
672
+ file.close
673
+
674
+ File.chmod(0600, auth_file)
675
+
676
+ msg ="export ONE_AUTH=" + auth_file
677
+ msg << "; export ONE_EGID=#{egid}" if egid
678
+
679
+ exit_with_code 0, msg
680
+ end
681
+
682
+ token_delete_desc = <<-EOT.unindent
683
+ Expires a token and removes the associated ONE_AUTH file if present.
684
+ EOT
685
+
686
+ command :"token-delete", token_delete_desc, [:username, nil], :token,
687
+ :options=>login_options do
688
+
689
+ if args.length == 1
690
+ token_hint = args[0]
691
+ else
692
+ username, token_hint = args
693
+ end
694
+
695
+ if username
696
+ helper.client = helper.get_login_client(username, options)
697
+ end
698
+
699
+ user = helper.retrieve_resource(OpenNebula::User::SELF)
700
+
701
+ rc = user.info
702
+ if OpenNebula.is_error?(rc)
703
+ puts rc.message
704
+ exit_with_code 1, rc.message
705
+ end
706
+
707
+ token = helper.find_token(user, token_hint, nil, true)
708
+
709
+ if token.count > 1
710
+ exit_with_code 1, "More than one token starting with '#{token_hint}' found."
711
+ elsif token.count == 0
712
+ exit_with_code 1, "No tokens found."
713
+ end
714
+
715
+ token = token[0]["TOKEN"]
716
+
717
+ rc = user.login(user['NAME'], token, 0)
718
+
719
+ if OpenNebula.is_error?(rc)
720
+ puts rc.message
721
+ exit_with_code 1, rc.message
722
+ else
723
+ puts "Token removed."
724
+ end
725
+
726
+ auth_string = "#{user['NAME']}:#{token}"
727
+ auth_file = helper.auth_file(auth_string)
728
+
729
+ begin
730
+ File.unlink(auth_file)
731
+ puts "Removing #{auth_file}"
732
+ rescue Errno::ENOENT
733
+ end
734
+
735
+ 0
736
+ end
737
+
738
+ token_delete_all = <<-EOT.unindent
739
+ Delete all the tokens of a user. This command is intented to be executed by a
740
+ user that has MANAGE permissions of the target user.
741
+ EOT
742
+
743
+ command :"token-delete-all", token_delete_all, :username,
744
+ :options=>login_options do
745
+
746
+ username = args[0]
747
+
748
+ if username =~ /^\d+$/
749
+ exit_with_code 1, "The argument should be the username, not the ID."
750
+ end
751
+
752
+ helper.perform_action(username, options, "Tokens expired") do |user|
753
+ user.login(username, "", 0)
754
+ end
755
+ end
533
756
  end
data/bin/onevcenter CHANGED
@@ -35,6 +35,25 @@ require 'one_helper/onehost_helper'
35
35
  require 'one_helper/onecluster_helper'
36
36
  require 'vcenter_driver'
37
37
 
38
+ def connection_options(object_name, options)
39
+ if options[:vuser].nil? ||
40
+ options[:vcenter].nil?
41
+ STDERR.puts "vCenter connection parameters are mandatory to import"\
42
+ " #{object_name}:\n"\
43
+ "\t --vcenter vCenter hostname\n"\
44
+ "\t --vuser username to login in vcenter"
45
+ exit -1
46
+ end
47
+
48
+ password = options[:vpass] || OpenNebulaHelper::OneHelper.get_password
49
+
50
+ {
51
+ :user => options[:vuser],
52
+ :password => password,
53
+ :host => options[:vcenter]
54
+ }
55
+ end
56
+
38
57
  cmd=CommandParser::CmdParser.new(ARGV) do
39
58
 
40
59
  usage "`onevcenter` <command> [<args>] [<options>]"
@@ -82,24 +101,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
82
101
  EOT
83
102
 
84
103
  command :hosts, hosts_desc, :options=>[ VCENTER, USER, PASS ] do
85
- if options[:vuser].nil? ||
86
- options[:vpass].nil? ||
87
- options[:vcenter].nil?
88
- STDERR.puts "vCenter connection parameters are mandatory to import"\
89
- " host:\n"\
90
- "\t --vcenter vCenter hostname\n"\
91
- "\t --vuser username to login in vcenter\n"\
92
- "\t --vpass password for the user"
93
- exit -1
94
- end
104
+ con_ops = connection_options("Hosts", options)
95
105
 
96
106
  begin
97
107
  STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
98
108
 
99
- vc = VCenterDriver::VIClient.new_connection(
100
- :user => options[:vuser],
101
- :password => options[:vpass],
102
- :host => options[:vcenter])
109
+ vc = VCenterDriver::VIClient.new_connection(con_ops)
103
110
 
104
111
  STDOUT.print "done!\n\n"
105
112
 
@@ -149,24 +156,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
149
156
  EOT
150
157
 
151
158
  command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do
152
- if options[:vuser].nil? ||
153
- options[:vpass].nil? ||
154
- options[:vcenter].nil?
155
- STDERR.puts "vCenter connection parameters are mandatory to import"\
156
- " VM templates:\n"\
157
- "\t --vcenter vCenter hostname\n"\
158
- "\t --vuser username to login in vcenter\n"\
159
- "\t --vpass password for the user"
160
- exit -1
161
- end
159
+ con_ops = connection_options("VM Templates", options)
162
160
 
163
161
  begin
164
162
  STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
165
163
 
166
- vc = VCenterDriver::VIClient.new_connection(
167
- :user => options[:vuser],
168
- :password => options[:vpass],
169
- :host => options[:vcenter])
164
+ vc = VCenterDriver::VIClient.new_connection(con_ops)
170
165
 
171
166
  STDOUT.print "done!\n\n"
172
167
 
@@ -373,24 +368,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
373
368
  EOT
374
369
 
375
370
  command :networks, network_desc, :options=>[ VCENTER, USER, PASS ] do
376
- if options[:vuser].nil? ||
377
- options[:vpass].nil? ||
378
- options[:vcenter].nil?
379
- STDERR.puts "vCenter connection parameters are mandatory to import"\
380
- " vCenter networks:\n"\
381
- "\t --vcenter vCenter hostname\n"\
382
- "\t --vuser username to login in vcenter\n"\
383
- "\t --vpass password for the user"
384
- exit -1
385
- end
371
+ con_ops = connection_options("Networks", options)
386
372
 
387
373
  begin
388
374
  STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
389
375
 
390
- vc = VCenterDriver::VIClient.new_connection(
391
- :user => options[:vuser],
392
- :password => options[:vpass],
393
- :host => options[:vcenter])
376
+ vc = VCenterDriver::VIClient.new_connection(con_ops)
394
377
 
395
378
  STDOUT.print "done!\n\n"
396
379
 
@@ -516,24 +499,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
516
499
  EOT
517
500
 
518
501
  command :datastores, datastores_desc, :options=>[ VCENTER, USER, PASS ] do
519
- if options[:vuser].nil? ||
520
- options[:vpass].nil? ||
521
- options[:vcenter].nil?
522
- STDERR.puts "vCenter connection parameters are mandatory to import"\
523
- " Datastores:\n"\
524
- "\t --vcenter vCenter hostname\n"\
525
- "\t --vuser username to login in vcenter\n"\
526
- "\t --vpass password for the user"
527
- exit -1
528
- end
502
+ con_ops = connection_options("Datastores", options)
529
503
 
530
504
  begin
531
505
  STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
532
506
 
533
- vc = VCenterDriver::VIClient.new_connection(
534
- :user => options[:vuser],
535
- :password => options[:vpass],
536
- :host => options[:vcenter])
507
+ vc = VCenterDriver::VIClient.new_connection(con_ops)
537
508
 
538
509
  STDOUT.print "done!\n\n"
539
510
 
@@ -600,24 +571,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
600
571
  exit -1
601
572
  end
602
573
 
603
- if options[:vuser].nil? ||
604
- options[:vpass].nil? ||
605
- options[:vcenter].nil?
606
- STDERR.puts "vCenter connection parameters are mandatory to import"\
607
- " Datastores:\n"\
608
- "\t --vcenter vCenter hostname\n"\
609
- "\t --vuser username to login in vcenter\n"\
610
- "\t --vpass password for the user"
611
- exit -1
612
- end
574
+ con_ops = connection_options("Images", options)
613
575
 
614
576
  begin
615
577
  STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
616
578
 
617
- vc = VCenterDriver::VIClient.new_connection(
618
- :user => options[:vuser],
619
- :password => options[:vpass],
620
- :host => options[:vcenter])
579
+ vc = VCenterDriver::VIClient.new_connection(con_ops)
621
580
 
622
581
  STDOUT.print "done!\n\n"
623
582
 
data/lib/cli_helper.rb CHANGED
@@ -25,6 +25,14 @@ module CLIHelper
25
25
  :description => "Selects columns to display with list command"
26
26
  }
27
27
 
28
+ LISTCONF = {
29
+ :name => "listconf",
30
+ :short => "-c conf",
31
+ :large => "--listconf conf",
32
+ :format => String,
33
+ :description => "Selects a predefined column list"
34
+ }
35
+
28
36
  CSV_OPT = {
29
37
  :name => "csv",
30
38
  :large => "--csv",
@@ -64,7 +72,7 @@ module CLIHelper
64
72
  }
65
73
 
66
74
  #OPTIONS = [LIST, ORDER, FILTER, HEADER, DELAY]
67
- OPTIONS = [LIST, DELAY, FILTER, CSV_OPT]
75
+ OPTIONS = [LIST, LISTCONF, DELAY, FILTER, CSV_OPT]
68
76
 
69
77
  # Sets bold font
70
78
  def CLIHelper.scr_bold
@@ -320,7 +328,20 @@ module CLIHelper
320
328
  config = YAML.load_file(@conf)
321
329
 
322
330
  default = config.delete(:default)
323
- @default_columns = default unless default.empty?
331
+ default_conf = config.delete(:default_conf) || {}
332
+ listconf = options[:listconf]
333
+
334
+ listconf = default_conf[listconf.to_sym] if listconf
335
+
336
+ if !listconf && ENV['ONE_LISTCONF']
337
+ listconf = default_conf[ENV['ONE_LISTCONF'].to_sym]
338
+ end
339
+
340
+ if listconf
341
+ @default_columns = listconf
342
+ else
343
+ @default_columns = default unless default.empty?
344
+ end
324
345
 
325
346
  # Filter show options with available columns
326
347
  @default_columns &= @columns.keys
data/lib/one_helper.rb CHANGED
@@ -936,6 +936,27 @@ EOT
936
936
 
937
937
  objects.each do |obj|
938
938
  obj, *extra_attributes = obj.split(":")
939
+
940
+ # When extra attributes do not contain = character include
941
+ # them in the previous value. Fixes adding MAC addresses. These
942
+ # contain ":" character also used as extra attributes separator.
943
+ #
944
+ # It may be needed to strip the value from start and end quotes
945
+ # as the value could be written as this:
946
+ #
947
+ # --nic 'some_net:mac="00:0A:12:34:56:78"'
948
+ #
949
+ attrs = []
950
+ extra_attributes.each do |str|
951
+ if str.include?("=")
952
+ attrs << str
953
+ else
954
+ attrs.last << ":#{str}"
955
+ end
956
+ end
957
+
958
+ extra_attributes = attrs
959
+
939
960
  res=parse_user_object(obj)
940
961
  return [-1, "#{section.capitalize} \"#{obj}\" malformed"] if !res
941
962
  user, object=*res
@@ -17,6 +17,8 @@
17
17
  require 'one_helper'
18
18
  require 'one_helper/onequota_helper'
19
19
 
20
+ require 'digest/md5'
21
+
20
22
  # Interface for OpenNebula generated tokens.
21
23
  class TokenAuth
22
24
  def login_token(username, expire)
@@ -26,7 +28,7 @@ end
26
28
 
27
29
  class OneUserHelper < OpenNebulaHelper::OneHelper
28
30
 
29
- ONE_AUTH = ENV['HOME']+'/.one/one_auth'
31
+ ONE_AUTH = ENV['HOME']+'/.one/one_auth'
30
32
 
31
33
  def self.rname
32
34
  "USER"
@@ -100,11 +102,12 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
100
102
  return 0, auth.password
101
103
  end
102
104
 
103
- ############################################################################
104
- # Generates a token and stores it in ONE_AUTH path as defined in this class
105
- ############################################################################
106
- def login(username, options)
105
+ def auth_file(auth_string)
106
+ auth_filename = Digest::MD5.hexdigest(auth_string)
107
+ ENV['HOME'] + "/.one/#{auth_filename}.token"
108
+ end
107
109
 
110
+ def get_login_client(username, options)
108
111
  #-----------------------------------------------------------------------
109
112
  # Init the associated Authentication class to generate the token.
110
113
  #-----------------------------------------------------------------------
@@ -172,14 +175,30 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
172
175
  sync = true
173
176
  end
174
177
 
175
- token = auth.login_token(username, options[:time])
176
- login_client = OpenNebula::Client.new("#{username}:#{token}",
177
- nil,
178
- :sync => sync)
178
+ if options[:stdin_password]
179
+ token = STDIN.read.strip
180
+ else
181
+ token = auth.login_token(username, options[:time])
182
+ end
183
+
184
+ OpenNebula::Client.new("#{username}:#{token}", nil, :sync => sync)
185
+ end
186
+
187
+ ############################################################################
188
+ # Generates a token and stores it in ONE_AUTH path as defined in this class
189
+ ############################################################################
190
+ def login(username, options, use_client=false)
191
+ if use_client
192
+ login_client = OpenNebulaHelper::OneHelper.get_client
193
+ else
194
+ login_client = self.get_login_client(username, options)
195
+ end
179
196
 
180
197
  user = OpenNebula::User.new(User.build_xml, login_client)
181
198
 
182
- token_oned = user.login(username, "", options[:time])
199
+ egid = options[:group] || -1
200
+
201
+ token_oned = user.login(username, "", options[:time], egid)
183
202
 
184
203
  return -1, token_oned.message if OpenNebula.is_error?(token_oned)
185
204
 
@@ -378,6 +397,72 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
378
397
  table
379
398
  end
380
399
 
400
+ def find_token(user, token, group=nil, show_expired=false)
401
+ user_hash = user.to_hash
402
+
403
+ valid_tokens = [user_hash["USER"]["LOGIN_TOKEN"]].flatten.compact
404
+
405
+ return [] if valid_tokens.empty?
406
+
407
+ valid_tokens.map! do |e|
408
+ if token
409
+ next if !e["TOKEN"].start_with?(token)
410
+ end
411
+
412
+ exp_time = e["EXPIRATION_TIME"].to_i
413
+ if group
414
+ next if e["EGID"].to_i != group.to_i
415
+ end
416
+
417
+ if !show_expired
418
+ next if exp_time != -1 && Time.now > Time.at(exp_time)
419
+ end
420
+
421
+ e
422
+ end.compact!
423
+
424
+ # Sort the tokens so it returns first the one that will expire the
425
+ # latest.
426
+
427
+ valid_tokens.sort! do |a,b|
428
+ a_exp = a["EXPIRATION_TIME"].to_i
429
+ b_exp = b["EXPIRATION_TIME"].to_i
430
+
431
+ if a_exp == -1 || b_exp == -1
432
+ a_exp <=> b_exp
433
+ else
434
+ b_exp <=> a_exp
435
+ end
436
+ end
437
+
438
+ valid_tokens
439
+ end
440
+
441
+ def get_client_user
442
+ user = self.retrieve_resource(OpenNebula::User::SELF)
443
+ rc = user.info
444
+ if OpenNebula.is_error?(rc)
445
+ puts rc.message
446
+ exit_with_code 1, rc.message
447
+ end
448
+ user
449
+ end
450
+
451
+ def token_create(args, options)
452
+ options[:time] ||= 36000
453
+
454
+ if args[0]
455
+ username = args[0]
456
+ use_client = false
457
+ else
458
+ user = self.get_client_user
459
+ username = user['NAME']
460
+ use_client = true
461
+ end
462
+
463
+ self.login(username, options, use_client)
464
+ end
465
+
381
466
  private
382
467
 
383
468
  def factory(id=nil)
@@ -409,31 +494,64 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
409
494
  puts str % ["SECONDARY GROUPS", groups.join(',') ] if groups.size > 1
410
495
  puts str % ["PASSWORD", user['PASSWORD']]
411
496
  puts str % ["AUTH_DRIVER", user['AUTH_DRIVER']]
497
+ puts str % ["ENABLED",
498
+ OpenNebulaHelper.boolean_to_str(user['ENABLED'])]
499
+ puts
412
500
 
413
- if !user['LOGIN_TOKEN/TOKEN'].nil?
414
- puts str % ["LOGIN_TOKEN", user['LOGIN_TOKEN/TOKEN']]
501
+ user_hash = user.to_hash
502
+ client = @client
415
503
 
416
- etime = user['LOGIN_TOKEN/EXPIRATION_TIME']
504
+ gid = user['GID']
505
+ tokens = [user_hash['USER']['LOGIN_TOKEN']].flatten.compact
417
506
 
418
- validity_str = case etime
419
- when nil then ""
420
- when "-1" then "forever"
421
- else "not after #{Time.at(etime.to_i)}"
422
- end
507
+ CLIHelper.print_header(str_h1 % "TOKENS",false)
508
+ if tokens && !tokens.empty?
509
+ CLIHelper::ShowTable.new(nil, self) do
510
+ column :ID, "", :size=>7 do |d|
511
+ d["TOKEN"]
512
+ end
423
513
 
424
- puts str % ["TOKEN VALIDITY", validity_str ]
425
- end
514
+ column :EGID, "", :left, :size=>5 do |d|
515
+ d["EGID"].to_i == -1 ? "*" + gid : d["EGID"]
516
+ end
426
517
 
427
- puts str % ["ENABLED",
428
- OpenNebulaHelper.boolean_to_str(user['ENABLED'])]
518
+ column :EGROUP, "", :left, :size=>10 do |d|
519
+ client = OpenNebulaHelper::OneHelper.get_client
520
+
521
+ egid = d["EGID"].to_i == -1 ? gid : d["EGID"]
522
+
523
+ group = Group.new_with_id(egid, client)
524
+ rc = group.info
525
+
526
+ if OpenNebula.is_error?(rc)
527
+ "-"
528
+ else
529
+ group['NAME']
530
+ end
531
+ end
532
+
533
+ column :EXPIRATION, "", :left, :size=>20 do |d|
534
+ etime = d["EXPIRATION_TIME"]
535
+ expired = Time.now >= Time.at(d["EXPIRATION_TIME"].to_i)
536
+ case etime
537
+ when nil then ""
538
+ when "-1" then "forever"
539
+ else
540
+ if expired
541
+ "expired"
542
+ else
543
+ Time.at(etime.to_i).to_s
544
+ end
545
+ end
546
+ end
547
+ end.show(tokens,{})
548
+ end
429
549
 
430
550
  puts
431
551
 
432
552
  CLIHelper.print_header(str_h1 % "USER TEMPLATE",false)
433
553
  puts user.template_str
434
554
 
435
- user_hash = user.to_hash
436
-
437
555
  default_quotas = nil
438
556
 
439
557
  user.each('/USER/DEFAULT_USER_QUOTAS') { |elem|
@@ -443,4 +561,5 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
443
561
  helper = OneQuotaHelper.new
444
562
  helper.format_quota(user_hash['USER'], default_quotas, user.id)
445
563
  end
564
+
446
565
  end
@@ -254,6 +254,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
254
254
  puts str % ["SIZE", ar["SIZE"]]
255
255
  puts str % ["LEASES", ar["USED_LEASES"]]
256
256
  puts str % ["VN_MAD", ar["VN_MAD"]] if ar["VN_MAD"]
257
+ puts str % ["IPAM_MAD", ar["IPAM_MAD"]] if ar["IPAM_MAD"]
257
258
  puts
258
259
 
259
260
  format = "%-10s %34s %34s"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opennebula-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.2
4
+ version: 5.1.80.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenNebula
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-21 00:00:00.000000000 Z
11
+ date: 2016-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opennebula
@@ -16,18 +16,19 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.2
19
+ version: 5.1.80.beta1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.2
26
+ version: 5.1.80.beta1
27
27
  description: Commands used to talk to OpenNebula
28
28
  email: contact@opennebula.org
29
29
  executables:
30
30
  - oneuser.backup
31
+ - oneacct
31
32
  - oneacl
32
33
  - onecluster
33
34
  - onedatastore
@@ -35,20 +36,19 @@ executables:
35
36
  - oneflow-template
36
37
  - onegroup
37
38
  - onehost
39
+ - oneimage
38
40
  - onemarket
39
41
  - onemarketapp
40
42
  - onesecgroup
41
43
  - oneshowback
42
44
  - onetemplate
43
45
  - onevdc
46
+ - onevm
44
47
  - onevnet
48
+ - onevrouter
45
49
  - onezone
46
- - oneimage
47
- - onevm
48
- - oneacct
49
- - onevcenter
50
50
  - oneuser
51
- - onevrouter
51
+ - onevcenter
52
52
  extensions: []
53
53
  extra_rdoc_files: []
54
54
  files:
@@ -112,9 +112,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
112
  version: '0'
113
113
  required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - ">"
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: 1.3.1
118
118
  requirements: []
119
119
  rubyforge_project:
120
120
  rubygems_version: 2.5.1