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 +4 -4
- data/bin/oneuser +248 -25
- data/bin/onevcenter +29 -70
- data/lib/cli_helper.rb +23 -2
- data/lib/one_helper.rb +21 -0
- data/lib/one_helper/oneuser_helper.rb +143 -24
- data/lib/one_helper/onevnet_helper.rb +1 -0
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5918a18eb88bc2dd352bda44bef92b4e1311ff04
|
4
|
+
data.tar.gz: 91eca333217510670bbb7d4746b329421db599a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
-
|
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
|
-
|
414
|
-
|
501
|
+
user_hash = user.to_hash
|
502
|
+
client = @client
|
415
503
|
|
416
|
-
|
504
|
+
gid = user['GID']
|
505
|
+
tokens = [user_hash['USER']['LOGIN_TOKEN']].flatten.compact
|
417
506
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
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
|
-
|
425
|
-
|
514
|
+
column :EGID, "", :left, :size=>5 do |d|
|
515
|
+
d["EGID"].to_i == -1 ? "*" + gid : d["EGID"]
|
516
|
+
end
|
426
517
|
|
427
|
-
|
428
|
-
|
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.
|
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-
|
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.
|
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.
|
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
|
-
-
|
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:
|
117
|
+
version: 1.3.1
|
118
118
|
requirements: []
|
119
119
|
rubyforge_project:
|
120
120
|
rubygems_version: 2.5.1
|