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,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
|