opennebula-cli 5.0.2 → 5.1.80.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|