rbeapi 0.1.0

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.
Files changed (60) hide show
  1. data/.gitignore +35 -0
  2. data/Gemfile +25 -0
  3. data/Guardfile +15 -0
  4. data/LICENSE +28 -0
  5. data/README.md +218 -0
  6. data/Rakefile +12 -0
  7. data/lib/rbeapi.rb +32 -0
  8. data/lib/rbeapi/api.rb +135 -0
  9. data/lib/rbeapi/api/aaa.rb +410 -0
  10. data/lib/rbeapi/api/dns.rb +198 -0
  11. data/lib/rbeapi/api/interfaces.rb +1193 -0
  12. data/lib/rbeapi/api/ipinterfaces.rb +328 -0
  13. data/lib/rbeapi/api/logging.rb +157 -0
  14. data/lib/rbeapi/api/mlag.rb +519 -0
  15. data/lib/rbeapi/api/ntp.rb +201 -0
  16. data/lib/rbeapi/api/ospf.rb +214 -0
  17. data/lib/rbeapi/api/prefixlists.rb +98 -0
  18. data/lib/rbeapi/api/radius.rb +317 -0
  19. data/lib/rbeapi/api/radius.rb.old +399 -0
  20. data/lib/rbeapi/api/routemaps.rb +100 -0
  21. data/lib/rbeapi/api/snmp.rb +427 -0
  22. data/lib/rbeapi/api/staticroutes.rb +88 -0
  23. data/lib/rbeapi/api/stp.rb +381 -0
  24. data/lib/rbeapi/api/switchports.rb +272 -0
  25. data/lib/rbeapi/api/system.rb +87 -0
  26. data/lib/rbeapi/api/tacacs.rb +236 -0
  27. data/lib/rbeapi/api/varp.rb +181 -0
  28. data/lib/rbeapi/api/vlans.rb +338 -0
  29. data/lib/rbeapi/client.rb +454 -0
  30. data/lib/rbeapi/eapilib.rb +334 -0
  31. data/lib/rbeapi/netdev/snmp.rb +370 -0
  32. data/lib/rbeapi/utils.rb +70 -0
  33. data/lib/rbeapi/version.rb +37 -0
  34. data/rbeapi.gemspec +32 -0
  35. data/spec/fixtures/dut.conf +5 -0
  36. data/spec/spec_helper.rb +22 -0
  37. data/spec/support/fixtures.rb +114 -0
  38. data/spec/support/shared_examples_for_api_modules.rb +124 -0
  39. data/spec/system/api_ospf_interfaces_spec.rb +58 -0
  40. data/spec/system/api_ospf_spec.rb +111 -0
  41. data/spec/system/api_varp_interfaces_spec.rb +60 -0
  42. data/spec/system/api_varp_spec.rb +44 -0
  43. data/spec/system/rbeapi/api/dns_spec.rb +77 -0
  44. data/spec/system/rbeapi/api/interfaces_base_spec.rb +94 -0
  45. data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +135 -0
  46. data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +188 -0
  47. data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +115 -0
  48. data/spec/system/rbeapi/api/ipinterfaces_spec.rb +97 -0
  49. data/spec/system/rbeapi/api/logging_spec.rb +65 -0
  50. data/spec/system/rbeapi/api/mlag_interfaces_spec.rb +80 -0
  51. data/spec/system/rbeapi/api/mlag_spec.rb +94 -0
  52. data/spec/system/rbeapi/api/ntp_spec.rb +76 -0
  53. data/spec/system/rbeapi/api/snmp_spec.rb +68 -0
  54. data/spec/system/rbeapi/api/stp_instances_spec.rb +61 -0
  55. data/spec/system/rbeapi/api/stp_interfaces_spec.rb +71 -0
  56. data/spec/system/rbeapi/api/stp_spec.rb +57 -0
  57. data/spec/system/rbeapi/api/switchports_spec.rb +135 -0
  58. data/spec/system/rbeapi/api/system_spec.rb +38 -0
  59. data/spec/system/rbeapi/api/vlans_spec.rb +121 -0
  60. metadata +274 -0
@@ -0,0 +1,317 @@
1
+ #
2
+ # Copyright (c) 2014, Arista Networks, Inc.
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # Neither the name of Arista Networks nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
24
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+ require 'rbeapi/api'
33
+
34
+
35
+ module Rbeapi
36
+ ##
37
+ # Eos is module namesapce for working with the EOS command API
38
+ module Api
39
+ ##
40
+ # Radius provides instance methods to retrieve and set radius configuration
41
+ # values.
42
+ class Radius < Entity
43
+
44
+ DEFAULT_KEY_FORMAT = 0
45
+ DEFAULT_KEY = nil
46
+
47
+ # Regular expression to extract a radius server's attributes from the
48
+ # running-configuration text. The explicit [ ] spaces enable line
49
+ # wrappping and indentation with the /x flag.
50
+ SERVER_REGEXP = /radius-server[ ]host[ ](.*?)
51
+ (?:[ ]vrf[ ]([^\s]+))?
52
+ (?:[ ]auth-port[ ](\d+))?
53
+ (?:[ ]acct-port[ ](\d+))?
54
+ (?:[ ]timeout[ ](\d+))?
55
+ (?:[ ]retransmit[ ](\d+))?
56
+ (?:[ ]key[ ](\d+)[ ](\w+))?\s/x
57
+
58
+ ##
59
+ # get Returns an Array with a single resource Hash describing the
60
+ # current state of the global radius configuration on the target device.
61
+ # This method is intended to be used by a provider's instances class
62
+ # method.
63
+ #
64
+ # The resource hash returned contains the following information:
65
+ # * key: (String) the key either in plaintext or hashed format
66
+ # * key_format: (Fixnum) e.g. 0 or 7
67
+ # * timeout: (Fixnum) seconds before the timeout period ends
68
+ # * retransmit: (Fixnum), e.g. 3, attempts after first timeout expiry.
69
+ # * servers: (Array),
70
+ #
71
+ # @api public
72
+ #
73
+ # @return [Array<Hash>] Single element Array of resource hashes
74
+ def get
75
+ global = {}
76
+ global.merge!(parse_global_timeout)
77
+ global.merge!(parse_global_retransmit)
78
+ global.merge!(parse_global_key)
79
+ resource = { global: global, servers: parse_servers }
80
+ resource
81
+ end
82
+
83
+ ##
84
+ # parse_time scans the nodes current configuraiton and parse the
85
+ # radius-server timeout value. The timeout value is expected to always
86
+ # be present in the config
87
+ #
88
+ # @api private
89
+ #
90
+ # @return [Hash<Symbol, Object>] resource hash attribute
91
+ def parse_global_timeout
92
+ value = config.scan(/radius-server timeout (\d+)/).first
93
+ { timeout: value.first.to_i }
94
+ end
95
+ private :parse_global_timeout
96
+
97
+ ##
98
+ # parse_retransmit scans the cnodes current configuration and parses the
99
+ # radius-server retransmit value. the retransmist value is expected to
100
+ # always be present in the config
101
+ #
102
+ # @api private
103
+ #
104
+ # @return [Hash<Symbol, Object>] resource hash attribute
105
+ def parse_global_retransmit
106
+ value = config.scan(/radius-server retransmit (\d+)/).first
107
+ { retransmit: value.first.to_i }
108
+ end
109
+ private :parse_global_retransmit
110
+
111
+ ##
112
+ # parse_key scans the current nodes running configuration and parse the
113
+ # global radius-server key and format value. If the key is not
114
+ # configured this method will return DEFAULT_KEY and DEFAULT_KEY_FORMAT
115
+ # for the resource hash values.
116
+ #
117
+ # @api private
118
+ #
119
+ # @return [Hash<Symbol, Object>] resource hash attribute
120
+ def parse_global_key
121
+ rsrc_hsh = {}
122
+ (key_format, key) = config.scan(/radius-server key (\d+) (\w+)/).first
123
+ rsrc_hsh[:key_format] = key_format.to_i || DEFAULT_KEY_FORMAT
124
+ rsrc_hsh[:key] = key || DEFAULT_KEY
125
+ rsrc_hsh
126
+ end
127
+ private :parse_global_key
128
+
129
+ ##
130
+ # parse_servers returns an Array of radius server resource hashes. Each
131
+ # hash describes the current state of the radius server and is intended
132
+ # to be merged into the radius resource hash
133
+ #
134
+ # The resource hash returned contains the following information:
135
+ # * hostname: hostname or ip address
136
+ # * vrf: (String) vrf name
137
+ # * key: (String) the key either in plaintext or hashed format
138
+ # * key_format: (Fixnum) e.g. 0 or 7
139
+ # * timeout: (Fixnum) seconds before the timeout period ends
140
+ # * retransmit: (Integer), e.g. 3, attempts after first timeout expiry.
141
+ # * group: (String) Server group associated with this server.
142
+ # * acct_port: (Fixnum) Port number to use for accounting.
143
+ # * accounting_only: (Boolean) Enable this server for accounting only.
144
+ # * auth_port: (Fixnum) Port number to use for authentication
145
+ #
146
+ # @api private
147
+ #
148
+ # @return [Array<Hash<Symbol,Object>>] Array of resource hashes
149
+ def parse_servers
150
+ tuples = config.scan(SERVER_REGEXP)
151
+ tuples.map do |(host, vrf, authp, acctp, tout, tries, keyfm, key)|
152
+ hsh = {}
153
+ hsh[:hostname] = host
154
+ hsh[:vrf] = vrf
155
+ hsh[:auth_port] = authp.to_i
156
+ hsh[:acct_port] = acctp.to_i
157
+ hsh[:timeout] = tout.to_i
158
+ hsh[:retransmit] = tries.to_i
159
+ hsh[:key_format] = keyfm.to_i
160
+ hsh[:key] = key
161
+ hsh
162
+ end
163
+ end
164
+ private :parse_servers
165
+
166
+ ##
167
+ # set_global_key configures the global radius-server key. If the value option
168
+ # is not specified, radius-server key is configured using the no keyword.
169
+ # If the default option is specified, radius-server key is configured
170
+ # using the default keyword. If both options are specified, the default
171
+ # keyword option takes precedence.
172
+ #
173
+ # @eos_version 4.13.7M
174
+ #
175
+ # @commands
176
+ # radius-server key <format> <value>
177
+ # no radius-server key
178
+ # default radius-server key
179
+ #
180
+ # @option [String] :value The value to configure the radius-server key to
181
+ # in the nodes running configuration
182
+ #
183
+ # @option [Fixnum] :key_format The format of the key to be passed to the
184
+ # nodes running configuration. Valid values are 0 (cleartext) or 7
185
+ # (encrypted). The default value is 0 if format is not provided.
186
+ #
187
+ # @option [Boolean] :default Configures the radius-server key using the
188
+ # default keyword argument
189
+ #
190
+ # @return [Boolean] returns true if the commands complete successfully
191
+ def set_global_key(opts = {})
192
+ value = opts[:value]
193
+ key_format = opts[:key_format] || 0
194
+ default = opts[:default] || false
195
+
196
+ case default
197
+ when true
198
+ cmds = 'default radius-server key'
199
+ when false
200
+ cmds = value ? "radius-server key #{key_format} #{value}" :
201
+ 'no radius-server key'
202
+ end
203
+ configure cmds
204
+ end
205
+
206
+ ##
207
+ # set_global_timeout configures the radius-server timeout value. If the value
208
+ # options is not specified, radius-server timeout is configured using the
209
+ # no keyword. If the default option is specified, radius-server timeout
210
+ # is configured using the default keyword. If both options are specified
211
+ # then the default keyword takes precedence.
212
+ #
213
+ # @eos_version 4.13.7M
214
+ #
215
+ # @commands
216
+ # radius-server timeout <value>
217
+ # no radius-server timeout
218
+ # default radius-server timeout
219
+ #
220
+ # @option [String, Fixnum] :value The value to set the global
221
+ # radius-server timeout value to. This value should be in the range of
222
+ # 1 to 1000
223
+ #
224
+ # @option [Boolean] :default Configures the radius-server timeout value
225
+ # using the default keyword.
226
+ #
227
+ # @return [Boolean] returns true if the commands complete successfully
228
+ def set_global_timeout(opts = {})
229
+ value = opts[:value]
230
+ default = opts[:default] || false
231
+
232
+ case default
233
+ when true
234
+ cmds = 'default radius-server timeout'
235
+ when false
236
+ cmds = value ? "radius-server timeout #{value}" :
237
+ 'no radius-server timeout'
238
+ end
239
+ configure cmds
240
+ end
241
+
242
+ ##
243
+ # set_global_retransmit configures the global radius-server restransmit value.
244
+ # If the value is not specified, the radius-server retransmist value is
245
+ # configured using the no keyword. If the default option is specified,
246
+ # the radius-server retransmit value is configured using the default
247
+ # keyword. If both options are specified then the default keyword taks
248
+ # precedence
249
+ #
250
+ # @eos_version 4.13.7M
251
+ #
252
+ # @commands
253
+ # radius-server retransmit <value>
254
+ # no radius-server retransmit
255
+ # default radius-server retrasmit
256
+ #
257
+ # @option [String, Fixnum] :value The valu to set the global
258
+ # radius-server retransmit value to. This value should be in the range
259
+ # of 1 to 100
260
+ #
261
+ # @option [Boolean] :default Configures the radius-server retransmit
262
+ # value using the default keyword
263
+ #
264
+ # @return [Boolean] returns true if the commands complete successfully
265
+ def set_global_retransmit(opts = {})
266
+ value = opts[:value]
267
+ default = opts[:default] || false
268
+
269
+ case default
270
+ when true
271
+ cmds = 'default radius-server retransmit'
272
+ when false
273
+ cmds = value ? "radius-server retransmit #{value}" :
274
+ 'no radius-server retransmit'
275
+ end
276
+ configure cmds
277
+ end
278
+
279
+ ##
280
+ # update_server configures a radius server resource on the target device.
281
+ # This API method maps to the `radius server host` command, e.g.
282
+ # `radius-server host 10.11.12.13 auth-port 1024 acct-port 2048 timeout
283
+ # 30 retransmit 5 key 7 011204070A5955`
284
+ #
285
+ # @api public
286
+ #
287
+ # @return [Boolean] true if there are no errors
288
+ def update_server(opts = {})
289
+ # beware: order of cli keyword options counts
290
+ key_format = opts[:key_format] || 7
291
+ cmd = "radius-server host #{opts[:hostname]}"
292
+ cmd << " vrf #{opts[:vrf]}" if opts[:vrf]
293
+ cmd << " auth-port #{opts[:auth_port]}" if opts[:auth_port]
294
+ cmd << " acct-port #{opts[:acct_port]}" if opts[:acct_port]
295
+ cmd << " timeout #{opts[:timeout]}" if opts[:timeout]
296
+ cmd << " retransmit #{opts[:retransmit]}" if opts[:retransmit]
297
+ cmd << " key #{key_format} #{opts[:key]}" if opts[:key]
298
+ configure cmd
299
+ end
300
+
301
+ ##
302
+ # remove_server removes the SNMP server identified by the hostname,
303
+ # auth_port, and acct_port attributes.
304
+ #
305
+ # @api public
306
+ #
307
+ # @return [Boolean] true if no errors
308
+ def remove_server(opts = {})
309
+ cmd = "no radius-server host #{opts[:hostname]}"
310
+ cmd << " vrf #{opts[:vrf]}" if opts[:vrf]
311
+ cmd << " auth-port #{opts[:auth_port]}" if opts[:auth_port]
312
+ cmd << " acct-port #{opts[:acct_port]}" if opts[:acct_port]
313
+ configure cmd
314
+ end
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,399 @@
1
+ #
2
+ # Copyright (c) 2014, Arista Networks, Inc.
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # Neither the name of Arista Networks nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
24
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+ require 'rbeapi/api'
33
+
34
+
35
+ module Rbeapi
36
+ ##
37
+ # Eos is module namesapce for working with the EOS command API
38
+ module Api
39
+ ##
40
+ # Radius provides instance methods to retrieve and set radius configuration
41
+ # values.
42
+ class Radius < Entity
43
+
44
+ DEFAULT_AUTH_PORT = 1812
45
+ DEFAULT_ACCT_PORT = 1813
46
+
47
+ # Regular expression to extract a radius server's attributes from the
48
+ # running-configuration text. The explicit [ ] spaces enable line
49
+ # wrappping and indentation with the /x flag.
50
+ SERVER_REGEXP = /radius-server[ ]host[ ](.*?)
51
+ (?:[ ]auth-port[ ](\d+))?
52
+ (?:[ ]acct-port[ ](\d+))?
53
+ (?:[ ]timeout[ ](\d+))?
54
+ (?:[ ]deadtime[ ](\d+))?
55
+ (?:[ ]retransmit[ ](\d+))?
56
+ (?:[ ]key[ ](\d+)[ ](\w+))?\s/x
57
+
58
+ GROUP_MEMBER_REGEXP = /server[ ](.*?)
59
+ (?:[ ]auth-port[ ](\d+))?
60
+ (?:[ ]acct-port[ ](\d+))?\s/x
61
+
62
+ # Regular expression to extract a radius server's attributes from the
63
+ # running-configuration text. The explicit [ ] spaces enable line
64
+ # wrappping and indentation with the /x flag.
65
+ SERVER_GROUP_REGEXP = /aaa group server radius (.*)/
66
+
67
+ ##
68
+ # getall Returns an Array with a single resource Hash describing the
69
+ # current state of the global radius configuration on the target device.
70
+ # This method is intended to be used by a provider's instances class
71
+ # method.
72
+ #
73
+ # The resource hash returned contains the following information:
74
+ # * name: ('settings')
75
+ # * enable: (true | false) if radius functionality is enabled. This is
76
+ # always true for EOS.
77
+ # * key: (String) the key either in plaintext or hashed format
78
+ # * key_format: (Integer) e.g. 0 or 7
79
+ # * timeout: (Integer) seconds before the timeout period ends
80
+ # * retransmit_count: (Integer), e.g. 3, attempts after first timeout
81
+ # expiry.
82
+ #
83
+ # @api public
84
+ #
85
+ # @return [Array<Hash>] Single element Array of resource hashes
86
+ def getall
87
+ rsrc_hsh = radius_global_defaults
88
+ rsrc_hsh.merge!(parse_global_key(config))
89
+ rsrc_hsh.merge!(parse_global_timeout(config))
90
+ rsrc_hsh.merge!(parse_global_retransmit(config))
91
+ [rsrc_hsh]
92
+ end
93
+
94
+ ##
95
+ # servers returns an Array of radius server resource hashes. Each hash
96
+ # describes the current state of the radius server and is suitable for
97
+ # use in initializing a radius_server provider.
98
+ #
99
+ # The resource hash returned contains the following information:
100
+ # * hostname: hostname or ip address
101
+ # * key: (String) the key either in plaintext or hashed format
102
+ # * key_format: (Fixnum) e.g. 0 or 7
103
+ # * timeout: (Fixnum) seconds before the timeout period ends
104
+ # * retransmit_count: (Integer), e.g. 3, attempts after first timeout
105
+ # expiry.
106
+ # * group: (String) Server group associated with this server.
107
+ # * deadtime: (Fixnum) number of minutes to ignore an unresponsive
108
+ # server.
109
+ # * acct_port: (Fixnum) Port number to use for accounting.
110
+ # * accounting_only: (Boolean) Enable this server for accounting only.
111
+ # * auth_port: (Fixnum) Port number to use for authentication
112
+ #
113
+ # @api public
114
+ #
115
+ # @return [Array<Hash<Symbol,Object>>] Array of resource hashes
116
+ def servers
117
+ config = running_configuration
118
+ tuples = config.scan(SERVER_REGEXP)
119
+ tuples.map do |(host, authp, acctp, tout, dead, tries, keyfm, key)|
120
+ hsh = { auth_port: DEFAULT_AUTH_PORT, acct_port: DEFAULT_ACCT_PORT }
121
+ hsh[:hostname] = host if host
122
+ hsh[:auth_port] = authp.to_i if authp
123
+ hsh[:acct_port] = acctp.to_i if acctp
124
+ hsh[:timeout] = tout.to_i if tout
125
+ hsh[:retransmit_count] = tries.to_i if tries
126
+ hsh[:deadtime] = dead.to_i if dead
127
+ hsh[:key_format] = keyfm.to_i if keyfm
128
+ hsh[:key] = key if key
129
+ hsh
130
+ end
131
+ end
132
+
133
+ ##
134
+ # server_groups retrieves a list of radius server groups from the target
135
+ # device.
136
+ #
137
+ # @api public
138
+ #
139
+ # @return [Array<Hash<Symbol,Object>>] Array of resource hashes
140
+ def server_groups
141
+ config = running_configuration
142
+ tuples = config.scan(SERVER_GROUP_REGEXP)
143
+ tuples.map do |(name)|
144
+ { name: name, servers: parse_group_servers(config, name) }
145
+ end
146
+ end
147
+
148
+ ##
149
+ # parse_group_servers parses the list of servers associated with a radius
150
+ # server group given a group name and a running configuration text.
151
+ #
152
+ # @param [String] config The running configuration text.
153
+ #
154
+ # @param [String] name The name of the server group to parse.
155
+ #
156
+ # @api private
157
+ #
158
+ # @return [Array<Hash<Symbol,Object>] Array of server attributes
159
+ def parse_group_servers(config, name)
160
+ regexp = /aaa group server radius #{name}(.*?)!/m
161
+ mdata = regexp.match(config)
162
+ if mdata
163
+ tuples = mdata[1].scan(GROUP_MEMBER_REGEXP)
164
+ tuples.collect do |(hostname, auth_port, acct_port)|
165
+ {
166
+ hostname: hostname,
167
+ auth_port: auth_port ? auth_port.to_i : DEFAULT_AUTH_PORT,
168
+ acct_port: acct_port ? acct_port.to_i : DEFAULT_ACCT_PORT
169
+ }
170
+ end
171
+ else
172
+ Array.new
173
+ end
174
+ end
175
+
176
+ ##
177
+ # update_server_group updates a radius server group given an Array of
178
+ # server attributes and the name of the server group. The update happens
179
+ # by first deleting the existing group if it exists then creating it
180
+ # again with all of the specified servers.
181
+ #
182
+ # @param [String] name The name of the server group to update
183
+ #
184
+ # @param [Array<Hash<Symbol,Object>>] servers The array of servers to
185
+ # associate with the server group. This hash should have at least the
186
+ # :hostname key.
187
+ #
188
+ # @api public
189
+ #
190
+ # @return [Boolean] true if no errors
191
+ def update_server_group(opts = {})
192
+ cmd = "aaa group server radius #{opts[:name]}"
193
+ api.config("no #{cmd}")
194
+ cmds = [cmd]
195
+ opts[:servers].each do |hsh|
196
+ server = "server #{hsh[:hostname]}"
197
+ server << " auth-port #{hsh[:auth_port] || DEFAULT_AUTH_PORT}"
198
+ server << " acct-port #{hsh[:acct_port] || DEFAULT_ACCT_PORT}"
199
+ cmds << server
200
+ end
201
+ result = api.config(cmds)
202
+ !result.find { |r| r != {} }
203
+ end
204
+
205
+ ##
206
+ # remove_server_group removes a radius server group by name. This API
207
+ # call maps to the `no aaa group server radius <name>` command.
208
+ #
209
+ # @option opts [String] :name ('RAD-SV2') The name of the radius server
210
+ # group to remove.
211
+ #
212
+ # @api public
213
+ #
214
+ # @return [Boolean] true if no errors
215
+ def remove_server_group(opts = {})
216
+ result = api.config("no aaa group server radius #{opts[:name]}")
217
+ result == [{}]
218
+ end
219
+
220
+ ##
221
+ # update_server configures a radius server resource on the target device.
222
+ # This API method maps to the `radius server host` command, e.g.
223
+ # `radius-server host 10.11.12.13 auth-port 1024 acct-port 2048 timeout
224
+ # 30 retransmit 5 key 7 011204070A5955`
225
+ #
226
+ # @api public
227
+ #
228
+ # @return [Boolean] true if there are no errors
229
+ def update_server(opts = {})
230
+ retransmit = opts[:retransmit_count]
231
+ key_format = opts[:key_format] || 7
232
+ cmd = "radius-server host #{opts[:hostname]}"
233
+ cmd << " auth-port #{opts[:auth_port]}" if opts[:auth_port]
234
+ cmd << " acct-port #{opts[:acct_port]}" if opts[:acct_port]
235
+ cmd << " timeout #{opts[:timeout]}" if opts[:timeout]
236
+ cmd << " deadtime #{opts[:deadtime]}" if opts[:deadtime]
237
+ cmd << " retransmit #{retransmit}" if retransmit
238
+ cmd << " key #{key_format} #{opts[:key]}" if opts[:key]
239
+ result = api.config(cmd)
240
+ result == [{}]
241
+ end
242
+
243
+ ##
244
+ # remove_server removes the SNMP server identified by the hostname,
245
+ # auth_port, and acct_port attributes.
246
+ #
247
+ # @api public
248
+ #
249
+ # @return [Boolean] true if no errors
250
+ def remove_server(opts = {})
251
+ cmd = "no radius-server host #{opts[:hostname]}"
252
+ cmd << " auth-port #{opts[:auth_port]}" if opts[:auth_port]
253
+ cmd << " acct-port #{opts[:acct_port]}" if opts[:acct_port]
254
+ result = api.config(cmd)
255
+ result == [{}]
256
+ end
257
+
258
+ ##
259
+ # radius_global_defaults returns the default values for the radius_global
260
+ # resource. This is in a single method to keep the information in one
261
+ # place. If a value is explicitly configured to be the same as a default
262
+ # value it will not show up in the running configuration and as a result
263
+ # will not be parsed out by the parse instance methods. This method
264
+ # exposes the default values.
265
+ #
266
+ # @return [Array<Hash>] Single element Array of resource hashes
267
+ def radius_global_defaults
268
+ {
269
+ name: 'settings',
270
+ enable: true,
271
+ timeout: 5,
272
+ retransmit_count: 3
273
+ }
274
+ end
275
+ private :radius_global_defaults
276
+
277
+ ##
278
+ # parse_global_key takes a running configuration as a string and
279
+ # parses out the radius global key and global key format if it exists in
280
+ # the configuration. An empty Hash is returned if there is no global key
281
+ # configured. The intent of the Hash is to be merged into a property
282
+ # hash.
283
+ #
284
+ # @param [String] config The running configuration as a single string.
285
+ #
286
+ # @api private
287
+ #
288
+ # @return [Hash<Symbol,Object>] resource hash attributes
289
+ def parse_global_key(config)
290
+ rsrc_hsh = {}
291
+ (key_format, key) = config.scan(/radius-server key (\d+) (\w+)/).first
292
+ rsrc_hsh[:key_format] = key_format.to_i if key_format
293
+ rsrc_hsh[:key] = key if key
294
+ rsrc_hsh
295
+ end
296
+ private :parse_global_key
297
+
298
+ ##
299
+ # parse_global_timeout takes a running configuration as a string
300
+ # and parses out the radius global timeout if it exists in the
301
+ # configuration. An empty Hash is returned if there is no global timeout
302
+ # value configured. The intent of the Hash is to be merged into a
303
+ # property hash.
304
+ #
305
+ # @param [String] config The running configuration as a single string.
306
+ #
307
+ # @api private
308
+ #
309
+ # @return [Hash<Symbol,Object>] resource hash attributes
310
+ def parse_global_timeout(config)
311
+ rsrc_hsh = {}
312
+ timeout = config.scan(/radius-server timeout (\d+)/).first
313
+ # EOS default is 5 (does not show up in the running config)
314
+ rsrc_hsh[:timeout] = timeout.first.to_i if timeout
315
+ rsrc_hsh
316
+ end
317
+ private :parse_global_timeout
318
+
319
+ ##
320
+ # parse_global_retransmit takes a running configuration as a string and
321
+ # parses out the radius global retransmit count value if it exists in the
322
+ # configuration. An empty Hash is returned if there is no global timeout
323
+ # value configured. The intent of the Hash is to be merged into a
324
+ # property hash.
325
+ #
326
+ # @param [String] config The running configuration as a single string.
327
+ #
328
+ # @api private
329
+ #
330
+ # @return [Hash<Symbol,Object>] resource hash attributes
331
+ def parse_global_retransmit(config)
332
+ rsrc_hsh = {}
333
+ count = config.scan(/radius-server retransmit (\d+)/).first
334
+ # EOS default is 3 (does not show up in the running config)
335
+ rsrc_hsh[:retransmit_count] = count.first.to_i if count
336
+ rsrc_hsh
337
+ end
338
+ private :parse_global_retransmit
339
+
340
+ ##
341
+ # set_global_key configures the radius default key. This method maps to
342
+ # the `radius-server key` EOS configuration command, e.g. `radius-server
343
+ # key 7 070E234F1F5B4A`.
344
+ #
345
+ # @option opts [String] :key ('070E234F1F5B4A') The key value
346
+ #
347
+ # @option opts [Fixnum] :key_format (7) The key format, 0 for plaintext
348
+ # and 7 for a hashed value. 7 will be assumed if this option is not
349
+ # provided.
350
+ #
351
+ # @api public
352
+ #
353
+ # @return [Boolean] true if no errors
354
+ def set_global_key(opts = {})
355
+ format = opts[:key_format] || 7
356
+ key = opts[:key]
357
+ fail ArgumentError, 'key option is required' unless key
358
+ result = api.config("radius-server key #{format} #{key}")
359
+ result == [{}]
360
+ end
361
+
362
+ ##
363
+ # set_timeout configures the radius default timeout. This method maps to
364
+ # the `radius-server timeout` setting.
365
+ #
366
+ # @option opts [Fixnum] :timeout (50) The timeout in seconds to
367
+ # configure.
368
+ #
369
+ # @api public
370
+ #
371
+ # @return [Boolean] true if no errors
372
+ def set_timeout(opts = {})
373
+ timeout = opts[:timeout]
374
+ fail ArgumentError, 'timeout option is required' unless timeout
375
+ result = api.config("radius-server timeout #{timeout}")
376
+ result == [{}]
377
+ end
378
+
379
+ ##
380
+ # set_retransmit_count configures the radius default retransmit count.
381
+ # This method maps to the `radius-server retransmit` configuration
382
+ # command.
383
+ #
384
+ # @option opts [Fixnum] :retransmit_count (4) The number of times to
385
+ # retry an unresponsive server after the first timeout period.
386
+ #
387
+ # @api public
388
+ #
389
+ # @return [Boolean] true if no errors
390
+ def set_retransmit_count(opts = {})
391
+ retransmit_count = opts[:retransmit_count]
392
+ fail ArgumentError,
393
+ 'retransmit_count option is required' unless retransmit_count
394
+ result = api.config("radius-server retransmit #{retransmit_count}")
395
+ result == [{}]
396
+ end
397
+ end
398
+ end
399
+ end