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.
@@ -1,11 +1,19 @@
1
1
  # 2013-April
2
2
 
3
- - 0.0.10: 2013-04-29
3
+ 0.0.10: 2013-04-29
4
4
 
5
- Initial release of code into RubyGems. Code tested on EX and SRX-branch. Consider this code
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
- - 0.0.11: 2013-04-29
14
+ 0.0.12: 2013-04-29 (In-Progress)
9
15
 
10
- Updated Junos::Ez::RE::Utils. #memory changed :procs from Hash to Array. #users changed return from Hash to Array
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
 
@@ -42,8 +42,8 @@ Junos::Ez::Provider( ndev )
42
42
  # do a quick dump of all facts
43
43
 
44
44
  pp ndev.facts.catalog
45
-
46
- -> {:hardwaremodel=>"SRX210H",
45
+ ->
46
+ {:hardwaremodel=>"SRX210H",
47
47
  :serialnumber=>"AD2909AA0096",
48
48
  :hostname=>"srx210",
49
49
  :domain=>"",
@@ -27,14 +27,14 @@ end
27
27
  # any L2port resource
28
28
 
29
29
  pp port.properties
30
-
31
- -> [:_exist, :_active, :description, :untagged_vlan, :tagged_vlans, :vlan_tagging]
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
- -> {"ge-0/0/0"=>
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
- -> {"ge-0/0/1"=>
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
- -> :up
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
- -> {"ge-0/0/1"=>{:admin=>:down}}
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
- -> [:l1_ports, :ip_ports, :l2_ports]
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
- -> ["fe-0/0/2", "fe-0/0/3", "fe-0/0/6"]
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
- -> {"fe-0/0/2"=>
243
+ ->
244
+ {"fe-0/0/2"=>
247
245
  {:_active=>true,
248
246
  :_exist=>true,
249
247
  :vlan_tagging=>true,
@@ -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
+ ```
@@ -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
@@ -9,7 +9,7 @@ module Junos; end
9
9
 
10
10
  module Junos::Ez
11
11
 
12
- VERSION = "0.0.11"
12
+ VERSION = "0.0.12"
13
13
 
14
14
  ### ---------------------------------------------------------------
15
15
  ### rpc_errors - decodes the XML into an array of error/Hash
@@ -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
+
@@ -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.11
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: []