junos-ez-stdlib 0.0.11 → 0.0.12
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.
- 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: []
|