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.
@@ -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: []