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,272 @@
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
+ module Rbeapi
35
+ ##
36
+ # Eos is module namesapce for working with the EOS command API
37
+ module Api
38
+ ##
39
+ # The Switchport class provides a base class instance for working with
40
+ # logical layer-2 interfaces.
41
+ #
42
+ class Switchports < Entity
43
+
44
+ ##
45
+ # Retrieves the properies for a logical switchport from the
46
+ # running-config using eAPI
47
+ #
48
+ # Example
49
+ # {
50
+ # "name": <String>,
51
+ # "mode": [access, trunk],
52
+ # "trunk_allowed_vlans": array<strings>
53
+ # "trunk_native_vlan": <Integer>,
54
+ # "access_vlan": <Integer>
55
+ # }
56
+ #
57
+ # @param [String] name The full name of the interface to get. The
58
+ # interface name must be the full interface (ie Ethernet, not Et)
59
+ #
60
+ # @return [Hash] a hash that includes the switchport properties
61
+ def get(name)
62
+ config = get_block("interface #{name}")
63
+ return nil unless config
64
+ return nil if /no\sswitchport$/ =~ config
65
+
66
+ response = {}
67
+ response.merge!(parse_mode(config))
68
+ response.merge!(parse_access_vlan(config))
69
+ response.merge!(parse_trunk_native_vlan(config))
70
+ response.merge!(parse_trunk_allowed_vlans(config))
71
+ response
72
+ end
73
+
74
+ def parse_mode(config)
75
+ mdata = /(?<=\s{3}switchport\smode\s)(.+)$/.match(config)
76
+ { mode: mdata[1] }
77
+ end
78
+
79
+ def parse_access_vlan(config)
80
+ mdata = /(?<=access\svlan\s)(.+)$/.match(config)
81
+ { access_vlan: mdata[1] }
82
+ end
83
+
84
+ def parse_trunk_native_vlan(config)
85
+ mdata = /(?<=trunk\snative\svlan\s)(.+)$/.match(config)
86
+ { trunk_native_vlan: mdata[1] }
87
+ end
88
+
89
+ def parse_trunk_allowed_vlans(config)
90
+ mdata = /(?<=trunk\sallowed\svlan\s)(.+)$/.match(config)
91
+ return { trunk_allowed_vlans: [] } unless mdata[1] != 'none'
92
+ vlans = mdata[1].split(',')
93
+ values = vlans.each_with_object([]) do |vlan, arry|
94
+ if /-/ !~ vlan
95
+ arry << vlan.to_i
96
+ else
97
+ range_start, range_end = vlan.split('-')
98
+ arry.push(*Array(range_start.to_i..range_end.to_i))
99
+ end
100
+ end
101
+ { trunk_allowed_vlans: values }
102
+ end
103
+
104
+ ##
105
+ # Retrieves all switchport interfaces from the running-config
106
+ #
107
+ # @return [Array] an array of switchport hashes
108
+ def getall
109
+ interfaces = config.scan(/(?<=^interface\s)([Et|Po].+)$/)
110
+ interfaces.each_with_object({}) do |port, hsh|
111
+ cfg = get port.first
112
+ hsh[port.first] = cfg if cfg
113
+ end
114
+ end
115
+
116
+ ##
117
+ # Creates a new logical switchport interface in EOS
118
+ #
119
+ # @param [String] name The name of the logical interface
120
+ #
121
+ # @return [Boolean] True if it succeeds otherwise False
122
+ def create(name)
123
+ configure ["interface #{name}", 'no ip address', 'switchport']
124
+ end
125
+
126
+ ##
127
+ # Deletes a logical switchport interface from the running-config
128
+ #
129
+ # @param [String] name The name of the logical interface
130
+ #
131
+ # @return [Boolean] True if it succeeds otherwise False
132
+ def delete(name)
133
+ configure ["interface #{name}", 'no switchport']
134
+ end
135
+
136
+ ##
137
+ # Defaults a logical switchport interface in the running-config
138
+ #
139
+ # @param [String] name The name of the logical interface
140
+ #
141
+ # @return [Boolean] True if it succeeds otherwise False
142
+ def default(name)
143
+ configure ["interface #{name}", 'default switchport']
144
+ end
145
+
146
+ ##
147
+ # Configures the switchport mode for the specified interafce. Valid
148
+ # modes are access (default) or trunk
149
+ #
150
+ # @param [String] name The name of the interface to configure
151
+ # @param [Hash] opts The configuration parameters for the interface
152
+ # @option opts [string] :value The value to set the mode to
153
+ # @option opts [Boolean] :default The value should be set to default
154
+ #
155
+ # @return [Boolean] True if the commands succeed otherwise False
156
+ def set_mode(name, opts = {})
157
+ value = opts[:value]
158
+ default = opts[:default] || false
159
+
160
+ cmds = ["interface #{name}"]
161
+ case default
162
+ when true
163
+ cmds << 'default switchport mode'
164
+ when false
165
+ cmds << (value.nil? ? 'no switchport mode' : \
166
+ "switchport mode #{value}")
167
+ end
168
+ configure(cmds)
169
+ end
170
+
171
+ ##
172
+ # set_trunk_allowed_vlans configures the list of vlan ids that are
173
+ # allowed on the specified trunk port. If the value option is not
174
+ # provided, then the allowed trunks is configured using the no keyword.
175
+ # If the default keyword is provied then the allowed trunks is configured
176
+ # using the default keywork The default optio takes precedence over the
177
+ # value option if both are specified
178
+ #
179
+ # @eos_version 4.13.7M
180
+ #
181
+ # @commands
182
+ # switchport trunk allowed vlan add <value>
183
+ # no switchport trunk allowed vlan
184
+ # default switchport trunk allowed vlan
185
+ #
186
+ # @option [Array] :value The list of vlan ids to configure on the
187
+ # switchport to be allowed. This value must be an array of valid vlan
188
+ # ids
189
+ #
190
+ # @option [Boolean] :default Configures the switchport trunk allowed
191
+ # vlans command using the default keyword
192
+ #
193
+ # @return [Boolean] returns true if the commands complete successfully
194
+ def set_trunk_allowed_vlans(name, opts = {})
195
+ value = opts[:value]
196
+ default = opts[:default] || false
197
+
198
+ unless value.is_a?(Array)
199
+ raise ArgumentError, 'value must be an Array'
200
+ end
201
+
202
+ value = value.map(&:inspect).join(',') if value
203
+
204
+ cmds = ["interface #{name}"]
205
+ case default
206
+ when true
207
+ cmds << 'default switchport trunk allowed vlan'
208
+ when false
209
+ if value.nil?
210
+ cmds << 'no switchport trunk allowed vlan'
211
+ else
212
+ cmds << 'switchport trunk allowed vlan none'
213
+ cmds << "switchport trunk allowed vlan add #{value}"
214
+ end
215
+ end
216
+ configure(cmds)
217
+ end
218
+
219
+ ##
220
+ # Configures the trunk port native vlan for the specified interface.
221
+ # This value is only valid if the switchport mode is configure as
222
+ # trunk.
223
+ #
224
+ # @param [String] name The name of the interface to configure
225
+ # @param [Hash] opts The configuration parameters for the interface
226
+ # @option opts [string] :value The value of the trunk native vlan
227
+ # @option opts [Boolean] :default The value should be set to default
228
+ #
229
+ # @return [Boolean] True if the commands succeed otherwise False
230
+ def set_trunk_native_vlan(name, opts = {})
231
+ value = opts[:value]
232
+ default = opts[:default] || false
233
+
234
+ cmds = ["interface #{name}"]
235
+ case default
236
+ when true
237
+ cmds << 'default switchport trunk native vlan'
238
+ when false
239
+ cmds << (value.nil? ? 'no switchport trunk native vlan' : \
240
+ "switchport trunk native vlan #{value}")
241
+ end
242
+ configure(cmds)
243
+ end
244
+
245
+ ##
246
+ # Configures the access port vlan for the specified interface.
247
+ # This value is only valid if the switchport mode is configure
248
+ # in access mode.
249
+ #
250
+ # @param [String] name The name of the interface to configure
251
+ # @param [Hash] opts The configuration parameters for the interface
252
+ # @option opts [string] :value The value of the access vlan
253
+ # @option opts [Boolean] :default The value should be set to default
254
+ #
255
+ # @return [Boolean] True if the commands succeed otherwise False
256
+ def set_access_vlan(name, opts = {})
257
+ value = opts[:value]
258
+ default = opts[:default] || false
259
+
260
+ cmds = ["interface #{name}"]
261
+ case default
262
+ when true
263
+ cmds << 'default switchport access vlan'
264
+ when false
265
+ cmds << (value.nil? ? 'no switchport access vlan' : \
266
+ "switchport access vlan #{value}")
267
+ end
268
+ configure(cmds)
269
+ end
270
+ end
271
+ end
272
+ end
@@ -0,0 +1,87 @@
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
+ module Rbeapi
35
+
36
+ module Api
37
+
38
+ ##
39
+ # The System class configures the node system services such as
40
+ # hostname and domain name
41
+ class System < Entity
42
+
43
+ ##
44
+ # Returns the system settings
45
+ #
46
+ # @example
47
+ # {
48
+ # hostname: <string>
49
+ # }
50
+ #
51
+ # @return [Hash] A Ruby hash objec that provides the system settings as
52
+ # key/value pairs.
53
+ def get()
54
+ response = {}
55
+ response.merge!(parse_hostname(config))
56
+ response
57
+ end
58
+
59
+ def parse_hostname(config)
60
+ mdata = /(?<=^hostname\s)(.+)$/.match(config)
61
+ { hostname: mdata.nil? ? '' : mdata[1] }
62
+ end
63
+
64
+ ##
65
+ # Configures the system hostname value in the running-config
66
+ #
67
+ # @param [Hash] opts The configuration parameters
68
+ # @option opts [string] :value The value to set the hostname to
69
+ # @option opts [Boolean] :default The value should be set to default
70
+ #
71
+ # @return [Boolean] returns true if the command completed successfully
72
+ def set_hostname(opts = {})
73
+ value = opts[:value]
74
+ default = opts[:default] || false
75
+
76
+ case default
77
+ when true
78
+ cmds = ['default hostname']
79
+ when false
80
+ cmds = (value.nil? ? 'no hostname' : \
81
+ "hostname #{value}")
82
+ end
83
+ configure(cmds)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,236 @@
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
+ module Rbeapi
35
+ ##
36
+ # Eos is module namesapce for working with the EOS command API
37
+ module Api
38
+
39
+ ##
40
+ # Tacacs provides instance methods to retrieve and set tacacs configuration
41
+ # values.
42
+ class Tacacs < Entity
43
+
44
+ DEFAULT_KEY_FORMAT = 0
45
+ DEFAULT_KEY = nil
46
+
47
+ # Regular expression to extract a tacacs 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 = /tacacs-server[ ]host[ ]([^\s]+)
51
+ (?:[ ](single-connection))?
52
+ (?:[ ]vrf[ ]([^\s]+))?
53
+ (?:[ ]port[ ](\d+))?
54
+ (?:[ ]timeout[ ](\d+))?
55
+ (?:[ ]key[ ](\d+)[ ](\w+))?\s/x
56
+
57
+ # Default Tacacs TCP port
58
+ DEFAULT_PORT = 49
59
+
60
+ ##
61
+ # getall Returns an Array with a single resource Hash describing the
62
+ # current state of the global tacacs configuration on the target device.
63
+ # This method is intended to be used by a provider's instances class
64
+ # method.
65
+ #
66
+ # The resource hash returned contains the following information:
67
+ # * name: ('settings')
68
+ # * enable: (true | false) if tacacs functionality is enabled. This is
69
+ # always true for EOS.
70
+ # * key: (String) the key either in plaintext or hashed format
71
+ # * key_format: (Integer) e.g. 0 or 7
72
+ # * timeout: (Integer) seconds before the timeout period ends
73
+ #
74
+ # @api public
75
+ #
76
+ # @return [Array<Hash>] Single element Array of resource hashes
77
+ def get
78
+ global = {}
79
+ global.merge!(parse_global_timeout)
80
+ global.merge!(parse_global_key)
81
+ resource = { global: global, servers: servers }
82
+ resource
83
+ end
84
+
85
+ ##
86
+ # parse_global_key takes a running configuration as a string and
87
+ # parses out the radius global key and global key format if it exists in
88
+ # the configuration. An empty Hash is returned if there is no global key
89
+ # configured. The intent of the Hash is to be merged into a property
90
+ # hash.
91
+ #
92
+ # @param [String] config The running configuration as a single string.
93
+ #
94
+ # @api private
95
+ #
96
+ # @return [Hash<Symbol,Object>] resource hash attributes
97
+ def parse_global_key
98
+ rsrc_hsh = {}
99
+ (key_format, key) = config.scan(/tacacs-server key (\d+) (\w+)/).first
100
+ rsrc_hsh[:key_format] = key_format.to_i || DEFAULT_KEY_FORMAT
101
+ rsrc_hsh[:key] = key || DEFAULT_KEY
102
+ { key: key, key_format: key_format }
103
+ end
104
+ private :parse_global_key
105
+
106
+ ##
107
+ # parse_global_timeout takes a running configuration as a string
108
+ # and parses out the tacacs global timeout if it exists in the
109
+ # configuration. An empty Hash is returned if there is no global timeout
110
+ # value configured. The intent of the Hash is to be merged into a
111
+ # property hash.
112
+ #
113
+ # @param [String] config The running configuration as a single string.
114
+ #
115
+ # @api private
116
+ #
117
+ # @return [Hash<Symbol,Object>] resource hash attributes
118
+ def parse_global_timeout
119
+ timeout = config.scan(/tacacs-server timeout (\d+)/).first
120
+ { timeout: timeout.first.to_i }
121
+ end
122
+ private :parse_global_timeout
123
+
124
+ ##
125
+ # servers returns an Array of tacacs server resource hashes. Each hash
126
+ # describes the current state of the tacacs server and is suitable for
127
+ # use in initializing a tacacs_server provider.
128
+ #
129
+ # The resource hash returned contains the following information:
130
+ #
131
+ # * hostname: hostname or ip address, part of the identifier
132
+ # * port: (Fixnum) TCP port of the server, part of the identifier
133
+ # * key: (String) the key either in plaintext or hashed format
134
+ # * key_format: (Fixnum) e.g. 0 or 7
135
+ # * timeout: (Fixnum) seconds before the timeout period ends
136
+ # * multiplex: (Boolean) true when configured to make requests through a
137
+ # single connection
138
+ #
139
+ # @api public
140
+ #
141
+ # @return [Array<Hash<Symbol,Object>>] Array of resource hashes
142
+ def servers
143
+ tuples = config.scan(SERVER_REGEXP)
144
+ tuples.map do |(host, mplex, vrf, port, tout, keyfm, key)|
145
+ hsh = {}
146
+ hsh[:hostname] = host
147
+ hsh[:vrf] = vrf
148
+ hsh[:port] = port.to_i
149
+ hsh[:timeout] = tout.to_i
150
+ hsh[:key_format] = keyfm.to_i
151
+ hsh[:key] = key
152
+ hsh[:multiplex] = mplex ? true : false
153
+ hsh
154
+ end
155
+ end
156
+
157
+ ##
158
+ # set_global_key configures the tacacs default key. This method maps to
159
+ # the `tacacs-server key` EOS configuration command, e.g. `tacacs-server
160
+ # key 7 070E234F1F5B4A`.
161
+ #
162
+ # @option opts [String] :key ('070E234F1F5B4A') The key value
163
+ #
164
+ # @option opts [Fixnum] :key_format (7) The key format, 0 for plaintext
165
+ # and 7 for a hashed value. 7 will be assumed if this option is not
166
+ # provided.
167
+ #
168
+ # @api public
169
+ #
170
+ # @return [Boolean] true if no errors
171
+ def set_global_key(opts = {})
172
+ format = opts[:key_format]
173
+ key = opts[:key]
174
+ fail ArgumentError, 'key option is required' unless key
175
+ result = api.config("tacacs-server key #{format} #{key}")
176
+ result == [{}]
177
+ end
178
+
179
+ ##
180
+ # set_timeout configures the tacacs default timeout. This method maps to
181
+ # the `tacacs-server timeout` setting.
182
+ #
183
+ # @option opts [Fixnum] :timeout (50) The timeout in seconds to
184
+ # configure.
185
+ #
186
+ # @api public
187
+ #
188
+ # @return [Boolean] true if no errors
189
+ def set_global_timeout(opts = {})
190
+ value = opts[:value]
191
+ default = opts[:default] || false
192
+
193
+ case default
194
+ when true
195
+ cmds = 'default tacacs-server timeout'
196
+ when false
197
+ cmds = value ? "tacacs-server timeout #{value}" :
198
+ 'no tacacs-server timeout'
199
+ end
200
+ configure cmds
201
+ end
202
+
203
+ ##
204
+ # update_server configures a tacacs server resource on the target device.
205
+ # This API method maps to the `tacacs server host` command, e.g.
206
+ # `tacacs-server host 1.2.3.4 single-connection port 4949 timeout 6 key 7
207
+ # 06070D221D1C5A`
208
+ #
209
+ # @api public
210
+ #
211
+ # @return [Boolean] true if there are no errors
212
+ def update_server(opts = {})
213
+ key_format = opts[:key_format] || 7
214
+ cmd = "tacacs-server host #{opts[:hostname]}"
215
+ cmd << ' single-connection' if opts[:multiplex]
216
+ cmd << " port #{opts[:port]}" if opts[:port]
217
+ cmd << " timeout #{opts[:timeout]}" if opts[:timeout]
218
+ cmd << " key #{key_format} #{opts[:key]}" if opts[:key]
219
+ configure cmd
220
+ end
221
+
222
+ ##
223
+ # remove_server removes the tacacs server identified by the hostname,
224
+ # and port attributes.
225
+ #
226
+ # @api public
227
+ #
228
+ # @return [Boolean] true if no errors
229
+ def remove_server(opts = {})
230
+ cmd = "no tacacs-server host #{opts[:hostname]}"
231
+ cmd << " port #{opts[:port]}" if opts[:port]
232
+ configure cmd
233
+ end
234
+ end
235
+ end
236
+ end