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.
- data/.gitignore +35 -0
- data/Gemfile +25 -0
- data/Guardfile +15 -0
- data/LICENSE +28 -0
- data/README.md +218 -0
- data/Rakefile +12 -0
- data/lib/rbeapi.rb +32 -0
- data/lib/rbeapi/api.rb +135 -0
- data/lib/rbeapi/api/aaa.rb +410 -0
- data/lib/rbeapi/api/dns.rb +198 -0
- data/lib/rbeapi/api/interfaces.rb +1193 -0
- data/lib/rbeapi/api/ipinterfaces.rb +328 -0
- data/lib/rbeapi/api/logging.rb +157 -0
- data/lib/rbeapi/api/mlag.rb +519 -0
- data/lib/rbeapi/api/ntp.rb +201 -0
- data/lib/rbeapi/api/ospf.rb +214 -0
- data/lib/rbeapi/api/prefixlists.rb +98 -0
- data/lib/rbeapi/api/radius.rb +317 -0
- data/lib/rbeapi/api/radius.rb.old +399 -0
- data/lib/rbeapi/api/routemaps.rb +100 -0
- data/lib/rbeapi/api/snmp.rb +427 -0
- data/lib/rbeapi/api/staticroutes.rb +88 -0
- data/lib/rbeapi/api/stp.rb +381 -0
- data/lib/rbeapi/api/switchports.rb +272 -0
- data/lib/rbeapi/api/system.rb +87 -0
- data/lib/rbeapi/api/tacacs.rb +236 -0
- data/lib/rbeapi/api/varp.rb +181 -0
- data/lib/rbeapi/api/vlans.rb +338 -0
- data/lib/rbeapi/client.rb +454 -0
- data/lib/rbeapi/eapilib.rb +334 -0
- data/lib/rbeapi/netdev/snmp.rb +370 -0
- data/lib/rbeapi/utils.rb +70 -0
- data/lib/rbeapi/version.rb +37 -0
- data/rbeapi.gemspec +32 -0
- data/spec/fixtures/dut.conf +5 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/fixtures.rb +114 -0
- data/spec/support/shared_examples_for_api_modules.rb +124 -0
- data/spec/system/api_ospf_interfaces_spec.rb +58 -0
- data/spec/system/api_ospf_spec.rb +111 -0
- data/spec/system/api_varp_interfaces_spec.rb +60 -0
- data/spec/system/api_varp_spec.rb +44 -0
- data/spec/system/rbeapi/api/dns_spec.rb +77 -0
- data/spec/system/rbeapi/api/interfaces_base_spec.rb +94 -0
- data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +135 -0
- data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +188 -0
- data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +115 -0
- data/spec/system/rbeapi/api/ipinterfaces_spec.rb +97 -0
- data/spec/system/rbeapi/api/logging_spec.rb +65 -0
- data/spec/system/rbeapi/api/mlag_interfaces_spec.rb +80 -0
- data/spec/system/rbeapi/api/mlag_spec.rb +94 -0
- data/spec/system/rbeapi/api/ntp_spec.rb +76 -0
- data/spec/system/rbeapi/api/snmp_spec.rb +68 -0
- data/spec/system/rbeapi/api/stp_instances_spec.rb +61 -0
- data/spec/system/rbeapi/api/stp_interfaces_spec.rb +71 -0
- data/spec/system/rbeapi/api/stp_spec.rb +57 -0
- data/spec/system/rbeapi/api/switchports_spec.rb +135 -0
- data/spec/system/rbeapi/api/system_spec.rb +38 -0
- data/spec/system/rbeapi/api/vlans_spec.rb +121 -0
- 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
|