junos-ez-stdlib 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +12 -4
- data/docs/Facts.md +2 -2
- data/docs/Providers_Resources.md +16 -18
- data/docs/Users.md +105 -0
- data/examples/user.rb +32 -0
- data/lib/junos-ez/provider.rb +1 -1
- data/lib/junos-ez/system.rb +2 -52
- data/lib/junos-ez/system/st_hosts.rb +18 -0
- data/lib/junos-ez/system/st_routes.rb +24 -0
- data/lib/junos-ez/system/syscfg.rb +0 -0
- data/lib/junos-ez/system/user_ssh_keys.rb +113 -0
- data/lib/junos-ez/system/userauths.rb +84 -0
- data/lib/junos-ez/system/users.rb +219 -0
- data/lib/junos-ez/utils/fs.rb +6 -1
- metadata +6 -1
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
# 2013-April
|
2
2
|
|
3
|
-
|
3
|
+
0.0.10: 2013-04-29
|
4
4
|
|
5
|
-
Initial release of code into RubyGems. Code tested on EX and SRX-branch.
|
5
|
+
Initial release of code into RubyGems. Code tested on EX and SRX-branch. Consider this code
|
6
6
|
as "early-adopter". Comments/feedback is welcome and appreciated.
|
7
|
+
|
8
|
+
0.0.11: 2013-04-29
|
9
|
+
|
10
|
+
Updated Junos::Ez::RE::Utils
|
11
|
+
#memory changed :procs from Hash to Array
|
12
|
+
#users changed return from Hash to Array
|
7
13
|
|
8
|
-
|
14
|
+
0.0.12: 2013-04-29 (In-Progress)
|
9
15
|
|
10
|
-
Updated Junos::Ez::
|
16
|
+
Updated Junos::Ez::FS:Utils#ls to include :symlink information
|
17
|
+
Adding Junos::Ez::Users::Provider for login management
|
18
|
+
Adding Junos::Ez::UserAuths::Provider for SSH-key management
|
11
19
|
|
data/docs/Facts.md
CHANGED
data/docs/Providers_Resources.md
CHANGED
@@ -27,14 +27,14 @@ end
|
|
27
27
|
# any L2port resource
|
28
28
|
|
29
29
|
pp port.properties
|
30
|
-
|
31
|
-
|
30
|
+
->
|
31
|
+
[:_exist, :_active, :description, :untagged_vlan, :tagged_vlans, :vlan_tagging]
|
32
32
|
|
33
33
|
# now look at the specific values for this resource by pp the assocaite hash
|
34
34
|
|
35
35
|
pp port.to_h
|
36
|
-
|
37
|
-
|
36
|
+
->
|
37
|
+
{"ge-0/0/0"=>
|
38
38
|
{:_active=>true,
|
39
39
|
:_exist=>true,
|
40
40
|
:vlan_tagging=>true,
|
@@ -70,8 +70,8 @@ You can obtain the entire `@has` property hash has using the `to_h` method. Thi
|
|
70
70
|
port = ndev.l1_ports["ge-0/0/1"]
|
71
71
|
|
72
72
|
pp port.to_h
|
73
|
-
|
74
|
-
|
73
|
+
->
|
74
|
+
{"ge-0/0/1"=>
|
75
75
|
{:_active=>true,
|
76
76
|
:_exist=>true,
|
77
77
|
:admin=>:up,
|
@@ -85,12 +85,10 @@ You can also obtain just a specific property using the `[]` operator:
|
|
85
85
|
|
86
86
|
```ruby
|
87
87
|
pp port[:admin]
|
88
|
-
|
89
|
-
|
88
|
+
->
|
89
|
+
:up
|
90
90
|
```
|
91
91
|
|
92
|
-
|
93
|
-
|
94
92
|
## Modifying Properties
|
95
93
|
|
96
94
|
Modifying the resource property is simply making use of the `[]=` operator. For example,
|
@@ -108,8 +106,8 @@ You can also obtain the `@should` property hash using the `to_h` method and prov
|
|
108
106
|
port[:admin] = :down
|
109
107
|
|
110
108
|
pp port.to_h( :write )
|
111
|
-
|
112
|
-
|
109
|
+
->
|
110
|
+
{"ge-0/0/1"=>{:admin=>:down}}
|
113
111
|
```
|
114
112
|
|
115
113
|
_NOTE: The `@should` property hash only contains the changes that will be applied, not every property value._
|
@@ -216,8 +214,8 @@ When you bind providers to a netconf object, you can always get a list of what e
|
|
216
214
|
|
217
215
|
```ruby
|
218
216
|
pp ndev.providers
|
219
|
-
|
220
|
-
|
217
|
+
->
|
218
|
+
[:l1_ports, :ip_ports, :l2_ports]
|
221
219
|
```
|
222
220
|
|
223
221
|
## Resource List
|
@@ -230,8 +228,8 @@ use `list!` unless you need to force the cache update.
|
|
230
228
|
|
231
229
|
```ruby
|
232
230
|
pp ndev.l2_ports.list
|
233
|
-
|
234
|
-
|
231
|
+
->
|
232
|
+
["fe-0/0/2", "fe-0/0/3", "fe-0/0/6"]
|
235
233
|
```
|
236
234
|
|
237
235
|
## Resource Catalog
|
@@ -242,8 +240,8 @@ work the same as described in the list section above.
|
|
242
240
|
|
243
241
|
```ruby
|
244
242
|
pp ndev.l2_ports.catalog
|
245
|
-
|
246
|
-
|
243
|
+
->
|
244
|
+
{"fe-0/0/2"=>
|
247
245
|
{:_active=>true,
|
248
246
|
:_exist=>true,
|
249
247
|
:vlan_tagging=>true,
|
data/docs/Users.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Junos::Ez::Users::Provider
|
2
|
+
|
3
|
+
Manages the on-target configured users, located under Junos `[edit system login]` stanza.
|
4
|
+
|
5
|
+
# PROPERTIES
|
6
|
+
|
7
|
+
- `:class` - String, The user priviledge class (like "read-only", or "super-user")
|
8
|
+
- `:uid` - Number, User ID (unix). If not provided, Junos will auto-create
|
9
|
+
- `:fullname` - String, User Full Name
|
10
|
+
- `:password` - Junos encrypted password
|
11
|
+
- `:ssh_keys` - SSH keys (READ/ONLY)
|
12
|
+
|
13
|
+
If you need to modify the user's ssh-keys, see the `load_ssh_key!` method in the next section.
|
14
|
+
|
15
|
+
# RESOURCE METHODS
|
16
|
+
|
17
|
+
## password=
|
18
|
+
|
19
|
+
Used to set the user password by providing a plain-text value.
|
20
|
+
```ruby
|
21
|
+
|
22
|
+
Junos::Ez::User::Provider( ndev, :users )
|
23
|
+
|
24
|
+
pp ndev.users.list
|
25
|
+
->
|
26
|
+
["goofy", "jeremy"]
|
27
|
+
|
28
|
+
user = ndev.users["goofy"]
|
29
|
+
user.to_h
|
30
|
+
->
|
31
|
+
{"goofy"=>
|
32
|
+
{:_active=>true,
|
33
|
+
:_exist=>true,
|
34
|
+
:uid=>"3000",
|
35
|
+
:class=>"read-only",
|
36
|
+
:password=>"XRykM8Grm0R0A"}}
|
37
|
+
|
38
|
+
# set the password with plaintext value, then re-read the config from the device
|
39
|
+
user.password = "n3wpassw0rd"
|
40
|
+
user.read!
|
41
|
+
|
42
|
+
user.to_h
|
43
|
+
->
|
44
|
+
{"goofy"=>
|
45
|
+
{:_active=>true,
|
46
|
+
:_exist=>true,
|
47
|
+
:uid=>"3000",
|
48
|
+
:class=>"read-only",
|
49
|
+
:password=>"W05ckLnjLcPCk"}}
|
50
|
+
```
|
51
|
+
## load_ssh_key!( :opts = {} )
|
52
|
+
|
53
|
+
opts[:publickey] - String of public-key
|
54
|
+
opts[:filename] - String, filename on server to public-key file
|
55
|
+
|
56
|
+
This method will create an ssh-key for the user based on the contents of the provided public key. The key will be written to the device, but not committed (just like resource write!). The `Junos::Ez::UserAuths::Provider` resource for this key will be returned.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
user = ndev.users["jeremy"]
|
60
|
+
pp user.to_h
|
61
|
+
->
|
62
|
+
{"jeremy"=>
|
63
|
+
{:_active=>true,
|
64
|
+
:_exist=>true,
|
65
|
+
:uid=>"2008",
|
66
|
+
:class=>"super-user",
|
67
|
+
:password=>"$1$JhZms6TE$dXF8P1ey1u3G.5j/V9FBk0"}}
|
68
|
+
|
69
|
+
# write the key and then re-load user object
|
70
|
+
user.load_ssh_key! :filename=>'/home/jschulman/.ssh/keys/key1.pub'
|
71
|
+
user.read!
|
72
|
+
pp user.to_h
|
73
|
+
->
|
74
|
+
{"jeremy"=>
|
75
|
+
{:_active=>true,
|
76
|
+
:_exist=>true,
|
77
|
+
:uid=>"2008",
|
78
|
+
:class=>"super-user",
|
79
|
+
:password=>"$1$JhZms6TE$dXF8P1ey1u3G.5j/V9FBk0",
|
80
|
+
:ssh_keys=>
|
81
|
+
{"ssh-rsa"=>
|
82
|
+
["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIpOXEUJFfHstdDjVEaTIf5YkTbUliSel6/dsNe"]}}}
|
83
|
+
```
|
84
|
+
## ssh_key( keytype, index = 0 )
|
85
|
+
keytype: ['ssh-rsa', 'ssh-dsa']
|
86
|
+
|
87
|
+
This method will return a formulate name Hash for the specified key. This name can then be used in conjunction
|
88
|
+
with the `Junos::Ez::UserAuth::Provider` class.
|
89
|
+
|
90
|
+
The `index` parameter is used to select a key in the event that there is more than one in use.
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
key_name = user.ssh_key( 'ssh-rsa' )
|
94
|
+
->
|
95
|
+
{:user=>"jeremy",
|
96
|
+
:keytype=>"ssh-rsa",
|
97
|
+
:publickey=>
|
98
|
+
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIpOXEUJFfHstdDjVEaTIf5YkTbUliSel6/dsNe"}
|
99
|
+
|
100
|
+
# bind :auths as so we can directly access ssh-keys ...
|
101
|
+
Junos::Ez::UserAuths::Provider( ndev, :auths )
|
102
|
+
|
103
|
+
# now delete the key from the user.
|
104
|
+
ndev.auths[ key_name ].delete!
|
105
|
+
```
|
data/examples/user.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'yaml'
|
3
|
+
require 'net/netconf/jnpr'
|
4
|
+
require 'junos-ez/stdlib'
|
5
|
+
require 'junos-ez/srx'
|
6
|
+
|
7
|
+
unless ARGV[0]
|
8
|
+
puts "You must specify a target"
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
|
12
|
+
# login information for NETCONF session
|
13
|
+
login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
|
14
|
+
|
15
|
+
## create a NETCONF object to manage the device and open the connection ...
|
16
|
+
|
17
|
+
ndev = Netconf::SSH.new( login )
|
18
|
+
$stdout.print "Connecting to device #{login[:target]} ... "
|
19
|
+
ndev.open
|
20
|
+
$stdout.puts "OK!"
|
21
|
+
|
22
|
+
Junos::Ez::Provider( ndev )
|
23
|
+
Junos::Ez::Users::Provider( ndev, :users )
|
24
|
+
Junos::Ez::UserAuths::Provider( ndev, :sshkeys )
|
25
|
+
Junos::Ez::Config::Utils( ndev, :cu )
|
26
|
+
|
27
|
+
user = ndev.users["jeremy"]
|
28
|
+
user.load_ssh_key! :filename=>'/home/jschulman/.ssh/keys/key1.pub'
|
29
|
+
|
30
|
+
binding.pry
|
31
|
+
|
32
|
+
ndev.close
|
data/lib/junos-ez/provider.rb
CHANGED
data/lib/junos-ez/system.rb
CHANGED
@@ -1,59 +1,9 @@
|
|
1
1
|
|
2
2
|
require "junos-ez/provider"
|
3
|
-
|
4
|
-
### -----------------------------------------------------------------
|
5
|
-
### manage static host entries, kinda like "/etc/hosts"
|
6
|
-
### -----------------------------------------------------------------
|
7
|
-
|
8
|
-
module Junos::Ez::StaticHosts
|
9
|
-
|
10
|
-
PROPERTIES = [
|
11
|
-
:ip, # ipv4 address :String
|
12
|
-
:ip6, # ipv6 address :String
|
13
|
-
]
|
14
|
-
|
15
|
-
def self.Provider( ndev, varsym )
|
16
|
-
newbie = Junos::Ez::StaticHosts::Provider.new( ndev )
|
17
|
-
newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
|
18
|
-
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
19
|
-
end
|
20
|
-
|
21
|
-
class Provider < Junos::Ez::Provider::Parent
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
3
|
require 'junos-ez/system/st_hosts'
|
27
|
-
|
28
|
-
### -----------------------------------------------------------------
|
29
|
-
### manage static route entries
|
30
|
-
### -----------------------------------------------------------------
|
31
|
-
|
32
|
-
module Junos::Ez::StaticRoutes
|
33
|
-
|
34
|
-
PROPERTIES = [
|
35
|
-
:gateway, # next-hop gateway, could be single or Array
|
36
|
-
:metric, # number or nil
|
37
|
-
:action, # one-of [ :reject, :discard, :receive ]
|
38
|
-
:active, # flag [ true, nil | false ]
|
39
|
-
:retain, # no-flag [ nil, true, false ]
|
40
|
-
:install, # no-flag [ nil, true, false ]
|
41
|
-
:readvertise, # no-flag [ nil, true, false ]
|
42
|
-
:resolve, # no-flag [ nil, true, false ]
|
43
|
-
]
|
44
|
-
|
45
|
-
def self.Provider( ndev, varsym )
|
46
|
-
newbie = Junos::Ez::StaticRoutes::Provider.new( ndev )
|
47
|
-
newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
|
48
|
-
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
49
|
-
end
|
50
|
-
|
51
|
-
class Provider < Junos::Ez::Provider::Parent
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
4
|
require 'junos-ez/system/st_routes'
|
5
|
+
require 'junos-ez/system/users'
|
6
|
+
require 'junos-ez/system/userauths'
|
57
7
|
|
58
8
|
### -----------------------------------------------------------------
|
59
9
|
### the 'syscfg' is a work in progress, do not use ...
|
@@ -1,3 +1,21 @@
|
|
1
|
+
module Junos::Ez::StaticHosts
|
2
|
+
|
3
|
+
PROPERTIES = [
|
4
|
+
:ip, # ipv4 address :String
|
5
|
+
:ip6, # ipv6 address :String
|
6
|
+
]
|
7
|
+
|
8
|
+
def self.Provider( ndev, varsym )
|
9
|
+
newbie = Junos::Ez::StaticHosts::Provider.new( ndev )
|
10
|
+
newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
|
11
|
+
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
12
|
+
end
|
13
|
+
|
14
|
+
class Provider < Junos::Ez::Provider::Parent
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
1
19
|
class Junos::Ez::StaticHosts::Provider
|
2
20
|
|
3
21
|
### ---------------------------------------------------------------
|
@@ -1,3 +1,27 @@
|
|
1
|
+
module Junos::Ez::StaticRoutes
|
2
|
+
|
3
|
+
PROPERTIES = [
|
4
|
+
:gateway, # next-hop gateway, could be single or Array
|
5
|
+
:metric, # number or nil
|
6
|
+
:action, # one-of [ :reject, :discard, :receive ]
|
7
|
+
:active, # flag [ true, nil | false ]
|
8
|
+
:retain, # no-flag [ nil, true, false ]
|
9
|
+
:install, # no-flag [ nil, true, false ]
|
10
|
+
:readvertise, # no-flag [ nil, true, false ]
|
11
|
+
:resolve, # no-flag [ nil, true, false ]
|
12
|
+
]
|
13
|
+
|
14
|
+
def self.Provider( ndev, varsym )
|
15
|
+
newbie = Junos::Ez::StaticRoutes::Provider.new( ndev )
|
16
|
+
newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
|
17
|
+
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
18
|
+
end
|
19
|
+
|
20
|
+
class Provider < Junos::Ez::Provider::Parent
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
1
25
|
class Junos::Ez::StaticRoutes::Provider
|
2
26
|
|
3
27
|
### ---------------------------------------------------------------
|
File without changes
|
@@ -0,0 +1,113 @@
|
|
1
|
+
=begin
|
2
|
+
* Puppet Module : junos-stdlib
|
3
|
+
* Author : Jeremy Schulman
|
4
|
+
* File : junos_user.rb
|
5
|
+
* Version : 2013-03-20
|
6
|
+
* Platform : All
|
7
|
+
* Description :
|
8
|
+
*
|
9
|
+
*
|
10
|
+
* Copyright (c) 2013 Juniper Networks. All Rights Reserved.
|
11
|
+
*
|
12
|
+
* YOU MUST ACCEPT THE TERMS OF THIS DISCLAIMER TO USE THIS SOFTWARE,
|
13
|
+
* IN ADDITION TO ANY OTHER LICENSES AND TERMS REQUIRED BY JUNIPER NETWORKS.
|
14
|
+
*
|
15
|
+
* JUNIPER IS WILLING TO MAKE THE INCLUDED SCRIPTING SOFTWARE AVAILABLE TO YOU
|
16
|
+
* ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS
|
17
|
+
* DISCLAIMER. PLEASE READ THE TERMS AND CONDITIONS OF THIS DISCLAIMER
|
18
|
+
* CAREFULLY.
|
19
|
+
*
|
20
|
+
* THE SOFTWARE CONTAINED IN THIS FILE IS PROVIDED "AS IS." JUNIPER MAKES NO
|
21
|
+
* WARRANTIES OF ANY KIND WHATSOEVER WITH RESPECT TO SOFTWARE. ALL EXPRESS OR
|
22
|
+
* IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY WARRANTY
|
23
|
+
* OF NON-INFRINGEMENT OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR A
|
24
|
+
* PARTICULAR PURPOSE, ARE HEREBY DISCLAIMED AND EXCLUDED TO THE EXTENT
|
25
|
+
* ALLOWED BY APPLICABLE LAW.
|
26
|
+
*
|
27
|
+
* IN NO EVENT WILL JUNIPER BE LIABLE FOR ANY DIRECT OR INDIRECT DAMAGES,
|
28
|
+
* INCLUDING BUT NOT LIMITED TO LOST REVENUE, PROFIT OR DATA, OR
|
29
|
+
* FOR DIRECT, SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES
|
30
|
+
* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY ARISING OUT OF THE
|
31
|
+
* USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF JUNIPER HAS BEEN ADVISED OF
|
32
|
+
* THE POSSIBILITY OF SUCH DAMAGES.
|
33
|
+
=end
|
34
|
+
|
35
|
+
require 'puppet/provider/junos/junos_parent'
|
36
|
+
|
37
|
+
class Puppet::Provider::Junos::SSH_auth_key < Puppet::Provider::Junos
|
38
|
+
|
39
|
+
### --------------------------------------------------------------------
|
40
|
+
### triggered by provider #exists?
|
41
|
+
### --------------------------------------------------------------------
|
42
|
+
|
43
|
+
def netdev_res_exists?
|
44
|
+
|
45
|
+
# cannot manage the 'active' parameter from the puppet manifest since the
|
46
|
+
# type definition is compiled on the server, and doesn't include this :-(
|
47
|
+
# so fake it here, set to true always. this way if someone deactivated
|
48
|
+
# it apriori, then this puppet-run will make it active again.
|
49
|
+
|
50
|
+
return false unless (auth = get_junos_config)
|
51
|
+
|
52
|
+
got_key = auth.text.strip
|
53
|
+
got_key_skip = got_key.index(' ') + 1
|
54
|
+
got_key = got_key[ got_key_skip .. -1 ]
|
55
|
+
|
56
|
+
@ndev_res[:key] = got_key
|
57
|
+
@ndev_res[:user] = resource[:user]
|
58
|
+
@ndev_res[:type] = resource[:type]
|
59
|
+
@ndev_res[:target] = resource[:target]
|
60
|
+
@ndev_res[:options] = resource[:options]
|
61
|
+
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
|
65
|
+
### ---------------------------------
|
66
|
+
### ---> override parent method <----
|
67
|
+
### ---------------------------------
|
68
|
+
|
69
|
+
def netdev_resxml_top( xml )
|
70
|
+
xml.user {
|
71
|
+
xml.name resource[:user]
|
72
|
+
xml.authentication {
|
73
|
+
xml.send(:'ssh-rsa') {
|
74
|
+
xml.name 'ssh-rsa ' + resource[:key]
|
75
|
+
return xml
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_junos_config
|
82
|
+
|
83
|
+
@ndev_res ||= NetdevJunos::Resource.new( self, 'system/login', 'user' )
|
84
|
+
@ndev_res[:unmanaged_active] = true
|
85
|
+
|
86
|
+
return nil unless (ndev_config = @ndev_res.getconfig)
|
87
|
+
return nil unless auth_config = ndev_config.xpath("//user/authentication/ssh-rsa")[0]
|
88
|
+
@ndev_res.set_active_state( auth_config )
|
89
|
+
|
90
|
+
return auth_config
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
##### ------------------------------------------------------------
|
95
|
+
##### XML builder routines, one for each property
|
96
|
+
##### ------------------------------------------------------------
|
97
|
+
|
98
|
+
def xml_change_type( xml )
|
99
|
+
end
|
100
|
+
|
101
|
+
def xml_change_key( xml )
|
102
|
+
end
|
103
|
+
|
104
|
+
def xml_change_user( xml )
|
105
|
+
end
|
106
|
+
|
107
|
+
def xml_change_target( xml )
|
108
|
+
end
|
109
|
+
|
110
|
+
def xml_change_options( xml )
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
=begin
|
2
|
+
=end
|
3
|
+
|
4
|
+
module Junos::Ez::UserAuths
|
5
|
+
|
6
|
+
VALID_KEY_TYPES = ['ssh-rsa','ssh-dsa']
|
7
|
+
|
8
|
+
def self.Provider( ndev, varsym )
|
9
|
+
newbie = Junos::Ez::UserAuths::Provider.new( ndev )
|
10
|
+
newbie.properties = Junos::Ez::Provider::PROPERTIES
|
11
|
+
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
12
|
+
end
|
13
|
+
|
14
|
+
class Provider < Junos::Ez::Provider::Parent
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
##### ---------------------------------------------------------------
|
20
|
+
##### Resource Property Methods
|
21
|
+
##### ---------------------------------------------------------------
|
22
|
+
|
23
|
+
class Junos::Ez::UserAuths::Provider
|
24
|
+
|
25
|
+
### ---------------------------------------------------------------
|
26
|
+
### XML top placement
|
27
|
+
### ---------------------------------------------------------------
|
28
|
+
|
29
|
+
def xml_at_top
|
30
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
31
|
+
x.system { x.login { x.user {
|
32
|
+
x.name @name[:user]
|
33
|
+
x.authentication {
|
34
|
+
x.send( @name[:keytype].to_sym ) {
|
35
|
+
x.name @name[:publickey]
|
36
|
+
return x
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}}}
|
40
|
+
}}
|
41
|
+
end
|
42
|
+
|
43
|
+
### ---------------------------------------------------------------
|
44
|
+
### XML readers
|
45
|
+
### ---------------------------------------------------------------
|
46
|
+
|
47
|
+
def xml_get_has_xml( xml )
|
48
|
+
@should[:_active] = true # mark it so it will write!
|
49
|
+
xml.xpath('//user/authentication/*')[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def xml_read_parser( as_xml, as_hash )
|
53
|
+
set_has_status( as_xml, as_hash )
|
54
|
+
end
|
55
|
+
|
56
|
+
### ---------------------------------------------------------------
|
57
|
+
### XML writers
|
58
|
+
### ---------------------------------------------------------------
|
59
|
+
|
60
|
+
## !! since we're not actually modifying any properties, we need
|
61
|
+
## !! to overload the xml_build_change method to simply return
|
62
|
+
## !! the config at-top (includes ssh name)
|
63
|
+
|
64
|
+
def xml_build_change( xml_at_here = nil )
|
65
|
+
xml_at_top.doc.root
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
##### ---------------------------------------------------------------
|
71
|
+
##### Provider Collection Methods
|
72
|
+
##### ---------------------------------------------------------------
|
73
|
+
|
74
|
+
class Junos::Ez::UserAuths::Provider
|
75
|
+
def build_list
|
76
|
+
[]
|
77
|
+
end
|
78
|
+
|
79
|
+
def build_catalog
|
80
|
+
{}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
@@ -0,0 +1,219 @@
|
|
1
|
+
=begin
|
2
|
+
=end
|
3
|
+
|
4
|
+
require 'junos-ez/system/userauths'
|
5
|
+
|
6
|
+
module Junos::Ez::Users
|
7
|
+
|
8
|
+
PROPERTIES = [
|
9
|
+
:uid, # User-ID, Number
|
10
|
+
:class, # User Class, String
|
11
|
+
:fullname, # Full Name, String
|
12
|
+
:password, # Encrypted password
|
13
|
+
:ssh_keys, # READ-ONLY, Hash of SSH public keys
|
14
|
+
]
|
15
|
+
|
16
|
+
def self.Provider( ndev, varsym )
|
17
|
+
newbie = Junos::Ez::Users::Provider.new( ndev )
|
18
|
+
newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
|
19
|
+
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
20
|
+
end
|
21
|
+
|
22
|
+
class Provider < Junos::Ez::Provider::Parent; end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
##### ---------------------------------------------------------------
|
28
|
+
##### Provider Resource Methods
|
29
|
+
##### ---------------------------------------------------------------
|
30
|
+
|
31
|
+
class Junos::Ez::Users::Provider
|
32
|
+
|
33
|
+
### ---------------------------------------------------------------
|
34
|
+
### XML top placement
|
35
|
+
### ---------------------------------------------------------------
|
36
|
+
|
37
|
+
def xml_at_top
|
38
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
39
|
+
x.system { x.login { x.user {
|
40
|
+
x.name @name
|
41
|
+
return x
|
42
|
+
}}}}}
|
43
|
+
end
|
44
|
+
|
45
|
+
### ---------------------------------------------------------------
|
46
|
+
### XML readers
|
47
|
+
### ---------------------------------------------------------------
|
48
|
+
|
49
|
+
def xml_get_has_xml( xml )
|
50
|
+
xml.xpath('//user')[0]
|
51
|
+
end
|
52
|
+
|
53
|
+
def xml_read_parser( as_xml, as_hash )
|
54
|
+
set_has_status( as_xml, as_hash )
|
55
|
+
|
56
|
+
as_hash[:uid] = as_xml.xpath('uid').text
|
57
|
+
as_hash[:class] = as_xml.xpath('class').text
|
58
|
+
|
59
|
+
xml_when_item(as_xml.xpath('full-name')) {|i|
|
60
|
+
as_hash[:fullname] = i.text
|
61
|
+
}
|
62
|
+
|
63
|
+
xml_when_item(as_xml.xpath('authentication/encrypted-password')) {|i|
|
64
|
+
as_hash[:password] = i.text
|
65
|
+
}
|
66
|
+
|
67
|
+
# READ-ONLY capture the keys
|
68
|
+
unless (keys = as_xml.xpath('authentication/ssh-rsa')).empty?
|
69
|
+
@has[:ssh_keys] ||= {}
|
70
|
+
@has[:ssh_keys]['ssh-rsa'] = keys.collect{|key| key.text.strip}
|
71
|
+
end
|
72
|
+
unless (keys = as_xml.xpath('authentication/ssh-dsa')).empty?
|
73
|
+
@has[:ssh_keys] ||= {}
|
74
|
+
@has[:ssh_keys]['ssh-dsa'] = keys.collect{|key| key.text.strip}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
### ---------------------------------------------------------------
|
79
|
+
### XML writers
|
80
|
+
### ---------------------------------------------------------------
|
81
|
+
|
82
|
+
def xml_change_password( xml )
|
83
|
+
xml.authentication {
|
84
|
+
xml_set_or_delete( xml, 'encrypted-password', @should[:password] )
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def xml_change_fullname( xml )
|
89
|
+
xml_set_or_delete( xml, 'full-name', @should[:fullname] )
|
90
|
+
end
|
91
|
+
|
92
|
+
# changing the 'gid' is changing the Junos 'class' element
|
93
|
+
# so, what is tough here is that the Nokogiri Builder mech
|
94
|
+
# won't allow us to use the string 'class' since it conflicts
|
95
|
+
# with the Ruby language. So we need to add the 'class' element
|
96
|
+
# the hard way, yo! ...
|
97
|
+
|
98
|
+
def xml_change_class( xml )
|
99
|
+
par = xml.instance_variable_get(:@parent)
|
100
|
+
doc = xml.instance_variable_get(:@doc)
|
101
|
+
user_class = Nokogiri::XML::Node.new('class', doc )
|
102
|
+
user_class.content = @should[:class]
|
103
|
+
par.add_child( user_class )
|
104
|
+
end
|
105
|
+
|
106
|
+
def xml_change_uid( xml )
|
107
|
+
xml_set_or_delete( xml, 'uid', @should[:uid] )
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
##### ---------------------------------------------------------------
|
113
|
+
##### Provider Collection Methods
|
114
|
+
##### ---------------------------------------------------------------
|
115
|
+
|
116
|
+
class Junos::Ez::Users::Provider
|
117
|
+
|
118
|
+
def build_list
|
119
|
+
@ndev.rpc.get_configuration{ |x| x.system {
|
120
|
+
x.login {
|
121
|
+
x.user({:recurse => 'false'})
|
122
|
+
}
|
123
|
+
}}
|
124
|
+
.xpath('//user/name').collect{ |i| i.text }
|
125
|
+
end
|
126
|
+
|
127
|
+
def build_catalog
|
128
|
+
@catalog = {}
|
129
|
+
@ndev.rpc.get_configuration{ |x| x.system {
|
130
|
+
x.login {
|
131
|
+
x.user
|
132
|
+
}
|
133
|
+
}}
|
134
|
+
.xpath('//user').each do |user|
|
135
|
+
name = user.xpath('name').text
|
136
|
+
@catalog[name] = {}
|
137
|
+
xml_read_parser( user, @catalog[name] )
|
138
|
+
end
|
139
|
+
@catalog
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
##### ---------------------------------------------------------------
|
145
|
+
##### Resource Methods
|
146
|
+
##### ---------------------------------------------------------------
|
147
|
+
|
148
|
+
class Junos::Ez::Users::Provider
|
149
|
+
|
150
|
+
## ----------------------------------------------------------------
|
151
|
+
## change the password by providing it in plain-text
|
152
|
+
## ----------------------------------------------------------------
|
153
|
+
|
154
|
+
def password=(plain_text)
|
155
|
+
xml = xml_at_top
|
156
|
+
xml.authentication {
|
157
|
+
xml.send(:'plain-text-password-value', plain_text)
|
158
|
+
}
|
159
|
+
@ndev.rpc.load_configuration( xml )
|
160
|
+
return true
|
161
|
+
end
|
162
|
+
|
163
|
+
## ----------------------------------------------------------------
|
164
|
+
## get a Hash that is used as the 'name' for obtaining a resource
|
165
|
+
## for Junos::Ez::UserAuths::Provider
|
166
|
+
## ----------------------------------------------------------------
|
167
|
+
|
168
|
+
def ssh_key( keytype, index = 0 )
|
169
|
+
return nil unless @has[:ssh_keys]
|
170
|
+
return nil unless @has[:ssh_keys][keytype]
|
171
|
+
ret_h = {:user => @name, :keytype => keytype}
|
172
|
+
ret_h[:publickey] = @has[:ssh_keys][keytype][index]
|
173
|
+
ret_h
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
## @@ need to move this code into the main provider
|
178
|
+
## @@ as a utility ...
|
179
|
+
##
|
180
|
+
|
181
|
+
def get_userauth_provd
|
182
|
+
@ndev.providers.each do |p|
|
183
|
+
obj = @ndev.send(p)
|
184
|
+
return obj if obj.class == Junos::Ez::UserAuths::Provider
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
## ----------------------------------------------------------------
|
189
|
+
## load an SSH public key & return the resulting key object.
|
190
|
+
## You can provide the publickey either as :publickey or
|
191
|
+
## contents will be read from :filename
|
192
|
+
## ----------------------------------------------------------------
|
193
|
+
|
194
|
+
def load_ssh_key!( opts = {} )
|
195
|
+
publickey = opts[:publickey] || File.read( opts[:filename] ).strip
|
196
|
+
raise ArgumentError, "no public-key specified" unless publickey
|
197
|
+
|
198
|
+
# nab the provider for handling ssh-keys, since we'll use that
|
199
|
+
# for key resource management
|
200
|
+
|
201
|
+
@auth_provd ||= get_userauth_provd
|
202
|
+
raise StandardError, "No Junos::Ez::UserAuths::Provider" unless @auth_provd
|
203
|
+
|
204
|
+
# extract the key-type from the public key.
|
205
|
+
keytype = publickey[0..6]
|
206
|
+
keytype = 'ssh-dsa' if keytype == 'ssh-dss'
|
207
|
+
raise ArgumentError, "Unknown ssh key-type #{keytype}" unless Junos::Ez::UserAuths::VALID_KEY_TYPES.include? keytype
|
208
|
+
|
209
|
+
# ok, we've got everything we need to add the key, so here we go.
|
210
|
+
key_name = {:user => @name, :keytype => keytype, :publickey => publickey }
|
211
|
+
key = @auth_provd[ key_name ]
|
212
|
+
key.write!
|
213
|
+
|
214
|
+
# return the key in case the caller wants it
|
215
|
+
key
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
data/lib/junos-ez/utils/fs.rb
CHANGED
@@ -160,6 +160,10 @@ class Junos::Ez::FS::Provider < Junos::Ez::Provider::Parent
|
|
160
160
|
f_h[:links] = file.xpath('file-links').text.to_i
|
161
161
|
f_h[:size] = file.xpath('file-size').text.to_i
|
162
162
|
|
163
|
+
xml_when_item(file.xpath('file-symlink-target')) { |i|
|
164
|
+
f_h[:symlink] = i.text.strip
|
165
|
+
}
|
166
|
+
|
163
167
|
fp = file.xpath('file-permissions')[0]
|
164
168
|
f_h[:permissions_text] = fp.attribute('format').value
|
165
169
|
f_h[:permissions] = fp.text.to_i
|
@@ -172,7 +176,8 @@ class Junos::Ez::FS::Provider < Junos::Ez::Provider::Parent
|
|
172
176
|
ls_hash[ dir_name ] = dir_hash
|
173
177
|
end # each directory
|
174
178
|
|
175
|
-
ls_hash
|
179
|
+
return nil if ls_hash.empty?
|
180
|
+
ls_hash
|
176
181
|
end # method: ls
|
177
182
|
|
178
183
|
### -------------------------------------------------------------
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: junos-ez-stdlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -57,6 +57,9 @@ files:
|
|
57
57
|
- lib/junos-ez/system/st_hosts.rb
|
58
58
|
- lib/junos-ez/system/st_routes.rb
|
59
59
|
- lib/junos-ez/system/syscfg.rb
|
60
|
+
- lib/junos-ez/system/userauths.rb
|
61
|
+
- lib/junos-ez/system/users.rb
|
62
|
+
- lib/junos-ez/system/user_ssh_keys.rb
|
60
63
|
- lib/junos-ez/system.rb
|
61
64
|
- lib/junos-ez/utils/config.rb
|
62
65
|
- lib/junos-ez/utils/fs.rb
|
@@ -73,6 +76,7 @@ files:
|
|
73
76
|
- examples/re_utils.rb
|
74
77
|
- examples/simple.rb
|
75
78
|
- examples/st_hosts.rb
|
79
|
+
- examples/user.rb
|
76
80
|
- examples/vlans.rb
|
77
81
|
- docs/Config_Utils.md
|
78
82
|
- docs/Facts.md
|
@@ -84,6 +88,7 @@ files:
|
|
84
88
|
- docs/RE_utils.md
|
85
89
|
- docs/StaticHosts.md
|
86
90
|
- docs/StaticRoutes.md
|
91
|
+
- docs/Users.md
|
87
92
|
- docs/Vlans.md
|
88
93
|
homepage: https://github.com/jeremyschulman/ruby-junos-ez-stdlib
|
89
94
|
licenses: []
|