rbeapi 0.2.0 → 0.3.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 +1 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +4 -0
- data/README.md +9 -9
- data/Rakefile +20 -0
- data/lib/rbeapi/api/bgp.rb +770 -0
- data/lib/rbeapi/api/dns.rb +32 -31
- data/lib/rbeapi/api/interfaces.rb +106 -87
- data/lib/rbeapi/api/ipinterfaces.rb +27 -42
- data/lib/rbeapi/api/logging.rb +9 -19
- data/lib/rbeapi/api/mlag.rb +60 -90
- data/lib/rbeapi/api/ntp.rb +12 -17
- data/lib/rbeapi/api/ospf.rb +9 -26
- data/lib/rbeapi/api/radius.rb +29 -43
- data/lib/rbeapi/api/snmp.rb +54 -83
- data/lib/rbeapi/api/staticroutes.rb +68 -21
- data/lib/rbeapi/api/stp.rb +41 -49
- data/lib/rbeapi/api/switchports.rb +41 -68
- data/lib/rbeapi/api/system.rb +6 -12
- data/lib/rbeapi/api/tacacs.rb +12 -21
- data/lib/rbeapi/api/varp.rb +25 -26
- data/lib/rbeapi/api/vlans.rb +19 -28
- data/lib/rbeapi/api.rb +30 -21
- data/lib/rbeapi/client.rb +3 -1
- data/lib/rbeapi/version.rb +1 -1
- data/rbeapi.spec.tmpl +4 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/system/api_ospf_interfaces_spec.rb +16 -0
- data/spec/system/api_ospf_spec.rb +14 -0
- data/spec/system/api_varp_interfaces_spec.rb +16 -0
- data/spec/system/rbeapi/api/dns_spec.rb +66 -0
- data/spec/system/rbeapi/api/interfaces_base_spec.rb +4 -4
- data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +6 -6
- data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +6 -6
- data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +4 -4
- data/spec/system/rbeapi/api/ipinterfaces_spec.rb +44 -0
- data/spec/system/rbeapi/api/logging_spec.rb +18 -2
- data/spec/system/rbeapi/api/mlag_spec.rb +94 -2
- data/spec/system/rbeapi/api/ntp_spec.rb +14 -0
- data/spec/system/rbeapi/api/snmp_spec.rb +105 -0
- data/spec/system/rbeapi/api/stp_interfaces_spec.rb +43 -6
- data/spec/system/rbeapi/api/stp_spec.rb +18 -6
- data/spec/system/rbeapi/api/switchports_spec.rb +75 -3
- data/spec/system/rbeapi/api/system_spec.rb +16 -0
- data/spec/system/rbeapi/api/vlans_spec.rb +28 -0
- data/spec/unit/rbeapi/api/bgp/bgp_neighbors_spec.rb +289 -0
- data/spec/unit/rbeapi/api/bgp/bgp_spec.rb +192 -0
- data/spec/unit/rbeapi/api/bgp/fixture_bgp.text +101 -0
- data/spec/unit/rbeapi/api/interfaces/base_spec.rb +7 -13
- data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +3 -3
- data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +11 -16
- data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +15 -21
- data/spec/unit/rbeapi/api/mlag/default_spec.rb +13 -19
- data/spec/unit/rbeapi/api/staticroutes/default_spec.rb +138 -0
- data/spec/unit/rbeapi/api/staticroutes/fixture_staticroutes.text +5 -0
- data/spec/unit/rbeapi/api/vlans/default_spec.rb +4 -4
- metadata +15 -4
@@ -0,0 +1,770 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015, 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
|
+
# Eos is the toplevel namespace for working with Arista EOS nodes
|
36
|
+
module Rbeapi
|
37
|
+
##
|
38
|
+
# Api is module namespace for working with the EOS command API
|
39
|
+
module Api
|
40
|
+
##
|
41
|
+
# The Bgp class implements global BGP router configuration
|
42
|
+
class Bgp < Entity
|
43
|
+
attr_reader :neighbors
|
44
|
+
|
45
|
+
def initialize(node)
|
46
|
+
super(node)
|
47
|
+
@neighbors = BgpNeighbors.new(node)
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# get returns the BGP routing configuration from the nodes current
|
52
|
+
# configuration.
|
53
|
+
#
|
54
|
+
# @return [nil, Hash<Symbol, Object>] Returns the BGP resource as a
|
55
|
+
# Hash.
|
56
|
+
def get
|
57
|
+
config = get_block('^router bgp .*')
|
58
|
+
return {} unless config
|
59
|
+
|
60
|
+
response = Bgp.parse_bgp_as(config)
|
61
|
+
response.merge!(parse_router_id(config))
|
62
|
+
response.merge!(parse_shutdown(config))
|
63
|
+
response.merge!(parse_networks(config))
|
64
|
+
response[:neighbors] = @neighbors.getall
|
65
|
+
response
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# parse_bgp_as scans the BGP routing configuration for the
|
70
|
+
# AS number. Defined as a class method. Used by the BgpNeighbors
|
71
|
+
# class below.
|
72
|
+
#
|
73
|
+
# @param [String] :config The switch config.
|
74
|
+
#
|
75
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
76
|
+
def self.parse_bgp_as(config)
|
77
|
+
value = config.scan(/^router bgp (\d+)/).first
|
78
|
+
{ bgp_as: value[0] }
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# parse_router_id scans the BGP routing configuration for the
|
83
|
+
# router ID.
|
84
|
+
#
|
85
|
+
# @api private
|
86
|
+
#
|
87
|
+
# @param [String] :config The switch config.
|
88
|
+
#
|
89
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
90
|
+
def parse_router_id(config)
|
91
|
+
value = config.scan(/router-id ([^\s]+)/).first
|
92
|
+
value = value ? value[0] : nil
|
93
|
+
{ router_id: value }
|
94
|
+
end
|
95
|
+
private :parse_router_id
|
96
|
+
|
97
|
+
##
|
98
|
+
# parse_shutdown scans the BGP routing configuration for the
|
99
|
+
# shutdown status.
|
100
|
+
#
|
101
|
+
# @api private
|
102
|
+
#
|
103
|
+
# @param [String] :config The switch config.
|
104
|
+
#
|
105
|
+
# @return [Hash<Symbol, Object>] resource hash attribute. Returns
|
106
|
+
# true if shutdown, false otherwise.
|
107
|
+
def parse_shutdown(config)
|
108
|
+
value = config.include?('no shutdown')
|
109
|
+
{ shutdown: !value }
|
110
|
+
end
|
111
|
+
private :parse_shutdown
|
112
|
+
|
113
|
+
##
|
114
|
+
# parse_networks scans the BGP routing configuration for all
|
115
|
+
# the network entries.
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
#
|
119
|
+
# @param [String] :config The switch config.
|
120
|
+
#
|
121
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
122
|
+
# @return [Array<Hash>] Single element hash with Array of network hashes
|
123
|
+
def parse_networks(config)
|
124
|
+
networks = []
|
125
|
+
lines = config.scan(%r{network (.+)/(\d+)(?: route-map (\w+))*})
|
126
|
+
lines.each do |prefix, mask, rmap|
|
127
|
+
rmap = rmap == '' ? nil : rmap
|
128
|
+
networks << { prefix: prefix, masklen: mask.to_i, route_map: rmap }
|
129
|
+
end
|
130
|
+
{ networks: networks }
|
131
|
+
end
|
132
|
+
private :parse_networks
|
133
|
+
|
134
|
+
##
|
135
|
+
# create will create a new instance of BGP routing on the node.
|
136
|
+
#
|
137
|
+
# @commands
|
138
|
+
# router bgp <bgp_as>
|
139
|
+
#
|
140
|
+
# @param [String] :bgp_as The BGP autonomous system number to be
|
141
|
+
# configured for the local BGP routing instance.
|
142
|
+
#
|
143
|
+
# @return [Boolean] returns true if the command completed successfully
|
144
|
+
def create(bgp_as)
|
145
|
+
value = bgp_as
|
146
|
+
configure("router bgp #{value}")
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# delete will delete the BGP routing instance from the node.
|
151
|
+
#
|
152
|
+
# @commands
|
153
|
+
# no router bgp <bgp_as>
|
154
|
+
#
|
155
|
+
# @return [Boolean] returns true if the command completed successfully
|
156
|
+
def delete
|
157
|
+
config = get
|
158
|
+
return true unless config
|
159
|
+
configure("no router bgp #{config[:bgp_as]}")
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# default will configure the BGP routing using the default
|
164
|
+
# keyword. This command has the same effect as deleting the BGP
|
165
|
+
# routine instance from the nodes running configuration.
|
166
|
+
#
|
167
|
+
# @commands
|
168
|
+
# default router bgp <bgp_as>
|
169
|
+
#
|
170
|
+
# @return [Boolean] returns true if the command complete successfully
|
171
|
+
def default
|
172
|
+
config = get
|
173
|
+
return true unless config
|
174
|
+
configure("default router bgp #{config[:bgp_as]}")
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# configure_bgp adds the command to go to BGP config mode.
|
179
|
+
# Then it adds the passed in command. The commands are then
|
180
|
+
# passed on to configure.
|
181
|
+
#
|
182
|
+
# @api private
|
183
|
+
#
|
184
|
+
# @param [String] :cmd Command to run under BGP mode
|
185
|
+
#
|
186
|
+
# @return [Boolean] returns true if the command complete successfully
|
187
|
+
def configure_bgp(cmd)
|
188
|
+
config = get_block('^router bgp .*')
|
189
|
+
fail 'BGP router is not configured' unless config
|
190
|
+
bgp_as = Bgp.parse_bgp_as(config)
|
191
|
+
cmds = ["router bgp #{bgp_as[:bgp_as]}", cmd]
|
192
|
+
configure(cmds)
|
193
|
+
end
|
194
|
+
private :configure_bgp
|
195
|
+
|
196
|
+
##
|
197
|
+
# set_router_id sets the router_id for the BGP routing instance.
|
198
|
+
#
|
199
|
+
# @commands
|
200
|
+
# router bgp <bgp_as>
|
201
|
+
# {no | default} router-id <router_id>
|
202
|
+
#
|
203
|
+
# @param [hash] :opts Optional keyword arguments
|
204
|
+
#
|
205
|
+
# @option :opts [String] :value The BGP routing process router-id
|
206
|
+
# value. When no ID has been specified (i.e. value not set), the
|
207
|
+
# local router ID is set to the following:
|
208
|
+
# * The loopback IP address when a single loopback interface is
|
209
|
+
# configured.
|
210
|
+
# * The loopback with the highest IP address when multiple loopback
|
211
|
+
# interfaces are configured.
|
212
|
+
# * The highest IP address on a physical interface when no loopback
|
213
|
+
# interfaces are configure
|
214
|
+
#
|
215
|
+
# @option :opts [Boolean] :enable If false then the command is
|
216
|
+
# negated. Default is true.
|
217
|
+
#
|
218
|
+
# @option :opts [Boolean] :default Configure the router-id using
|
219
|
+
# the default keyword
|
220
|
+
#
|
221
|
+
# @return [Boolean] returns true if the command complete successfully
|
222
|
+
def set_router_id(opts = {})
|
223
|
+
configure_bgp(command_builder('router-id', opts))
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# set_shutdown configures the administrative state for the global
|
228
|
+
# BGP routing process. The value option is not used by this method.
|
229
|
+
#
|
230
|
+
# @commands
|
231
|
+
# router bgp <bgp_as>
|
232
|
+
# {no | default} shutdown
|
233
|
+
#
|
234
|
+
# @param [hash] :opts Optional keyword arguments
|
235
|
+
#
|
236
|
+
# @option :opts [Boolean] :enable If enable is true then the BGP
|
237
|
+
# routing process is administratively enabled and if enable is
|
238
|
+
# False then the BGP routing process is administratively
|
239
|
+
# disabled.
|
240
|
+
#
|
241
|
+
# @option :opts [Boolean] :default Configure the router-id using
|
242
|
+
# the default keyword
|
243
|
+
#
|
244
|
+
# @return [Boolean] returns true if the command complete successfully
|
245
|
+
def set_shutdown(opts = {})
|
246
|
+
fail 'set_shutdown has the value option set' if opts[:value]
|
247
|
+
# Shutdown semantics are opposite of enable semantics so invert enable
|
248
|
+
value = !opts[:enable]
|
249
|
+
opts.merge!(enable: value)
|
250
|
+
configure_bgp(command_builder('shutdown', opts))
|
251
|
+
end
|
252
|
+
|
253
|
+
##
|
254
|
+
# add_network creates a new instance of a BGP network on the node.
|
255
|
+
#
|
256
|
+
# @commands
|
257
|
+
# router bgp <bgp_as>
|
258
|
+
# network <prefix>/<masklen>
|
259
|
+
# route-map <route_map>
|
260
|
+
#
|
261
|
+
# @param [String] :prefix The IPv4 prefix to configure as part of
|
262
|
+
# the network statement. The value must be a valid IPv4 prefix.
|
263
|
+
# @param [String] :masklen The IPv4 subnet mask length in bits.
|
264
|
+
# The masklen must be in the valid range of 1 to 32.
|
265
|
+
# @param [String] :route_map The route-map name to apply to the
|
266
|
+
# network statement when configured.
|
267
|
+
#
|
268
|
+
# @return [Boolean] returns true if the command complete successfully
|
269
|
+
def add_network(prefix, masklen, route_map = nil)
|
270
|
+
cmd = "network #{prefix}/#{masklen}"
|
271
|
+
cmd << " route-map #{route_map}" if route_map
|
272
|
+
configure_bgp(cmd)
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# remove_network removes the instance of a BGP network on the node.
|
277
|
+
#
|
278
|
+
# @commands
|
279
|
+
# router bgp <bgp_as>
|
280
|
+
# {no} shutdown
|
281
|
+
#
|
282
|
+
# @param [String] :prefix The IPv4 prefix to configure as part of
|
283
|
+
# the network statement. The value must be a valid IPv4 prefix.
|
284
|
+
# @param [String] :masklen The IPv4 subnet mask length in bits.
|
285
|
+
# The masklen must be in the valid range of 1 to 32.
|
286
|
+
# @param [String] :route_map The route-map name to apply to the
|
287
|
+
# network statement when configured.
|
288
|
+
#
|
289
|
+
# @return [Boolean] returns true if the command complete successfully
|
290
|
+
def remove_network(prefix, masklen, route_map = nil)
|
291
|
+
cmd = "no network #{prefix}/#{masklen}"
|
292
|
+
cmd << " route-map #{route_map}" if route_map
|
293
|
+
configure_bgp(cmd)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
##
|
298
|
+
# The BgpNeighbors class implements BGP neighbor configuration
|
299
|
+
class BgpNeighbors < Entity
|
300
|
+
##
|
301
|
+
# get returns a single BGP neighbor entry from the nodes current
|
302
|
+
# configuration.
|
303
|
+
#
|
304
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
305
|
+
# This value can be either an IPv4 address or string (in the
|
306
|
+
# case of managing a peer group).
|
307
|
+
#
|
308
|
+
# @return [nil, Hash<Symbol, Object>] Returns the BGP neighbor
|
309
|
+
# resource as a Hash.
|
310
|
+
def get(name)
|
311
|
+
config = get_block('^router bgp .*')
|
312
|
+
return nil unless config
|
313
|
+
|
314
|
+
response = parse_peer_group(config, name)
|
315
|
+
response.merge!(parse_remote_as(config, name))
|
316
|
+
response.merge!(parse_send_community(config, name))
|
317
|
+
response.merge!(parse_shutdown(config, name))
|
318
|
+
response.merge!(parse_description(config, name))
|
319
|
+
response.merge!(parse_next_hop_self(config, name))
|
320
|
+
response.merge!(parse_route_map_in(config, name))
|
321
|
+
response.merge!(parse_route_map_out(config, name))
|
322
|
+
response
|
323
|
+
end
|
324
|
+
|
325
|
+
##
|
326
|
+
# getall returns the collection of all neighbor entries for the
|
327
|
+
# BGP router instance.
|
328
|
+
#
|
329
|
+
# @return [nil, Hash<Symbol, Object>] Returns a hash that
|
330
|
+
# represents the entire BGP neighbor collection from the nodes
|
331
|
+
# running configuration. If there a BGP router is not configured
|
332
|
+
# or contains no neighbor entries then this method will return
|
333
|
+
# an empty hash.
|
334
|
+
def getall
|
335
|
+
config = get_block('^router bgp .*')
|
336
|
+
return nil unless config
|
337
|
+
|
338
|
+
entries = config.scan(/neighbor ([^\s]+)/)
|
339
|
+
entries.uniq.each_with_object({}) do |name, hsh|
|
340
|
+
resource = get(name[0])
|
341
|
+
hsh[name[0]] = resource if resource
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
##
|
346
|
+
# parse_peer_group scans the BGP neighbor entries for the
|
347
|
+
# peer group.
|
348
|
+
#
|
349
|
+
# @api private
|
350
|
+
#
|
351
|
+
# @param [String] :config The switch config.
|
352
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
353
|
+
# This value can be either an IPv4 address or string (in the
|
354
|
+
# case of managing a peer group).
|
355
|
+
#
|
356
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
357
|
+
def parse_peer_group(config, name)
|
358
|
+
value = config.scan(/neighbor #{name} peer-group ([^\s]+)/)
|
359
|
+
peer_group = value[0] ? value[0][0] : nil
|
360
|
+
{ peer_group: peer_group }
|
361
|
+
end
|
362
|
+
private :parse_peer_group
|
363
|
+
|
364
|
+
##
|
365
|
+
# parse_remote_as scans the BGP neighbor entries for the
|
366
|
+
# remote AS.
|
367
|
+
#
|
368
|
+
# @api private
|
369
|
+
#
|
370
|
+
# @param [String] :config The switch config.
|
371
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
372
|
+
# This value can be either an IPv4 address or string (in the
|
373
|
+
# case of managing a peer group).
|
374
|
+
#
|
375
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
376
|
+
def parse_remote_as(config, name)
|
377
|
+
value = config.scan(/neighbor #{name} remote-as (\d+)/)
|
378
|
+
remote_as = value[0] ? value[0][0] : nil
|
379
|
+
{ remote_as: remote_as }
|
380
|
+
end
|
381
|
+
private :parse_remote_as
|
382
|
+
|
383
|
+
##
|
384
|
+
# parse_send_community scans the BGP neighbor entries for the
|
385
|
+
# remote AS.
|
386
|
+
#
|
387
|
+
# @api private
|
388
|
+
#
|
389
|
+
# @param [String] :config The switch config.
|
390
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
391
|
+
# This value can be either an IPv4 address or string (in the
|
392
|
+
# case of managing a peer group).
|
393
|
+
#
|
394
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
395
|
+
def parse_send_community(config, name)
|
396
|
+
value = config.scan(/no neighbor #{name} send-community/)
|
397
|
+
enabled = value[0] ? false : true
|
398
|
+
{ send_community: enabled }
|
399
|
+
end
|
400
|
+
private :parse_send_community
|
401
|
+
|
402
|
+
##
|
403
|
+
# parse_shutdown scans the BGP neighbor entries for the
|
404
|
+
# remote AS.
|
405
|
+
#
|
406
|
+
# @api private
|
407
|
+
#
|
408
|
+
# @param [String] :config The switch config.
|
409
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
410
|
+
# This value can be either an IPv4 address or string (in the
|
411
|
+
# case of managing a peer group).
|
412
|
+
#
|
413
|
+
# @return [Hash<Symbol, Object>] resource hash attribute. Returns
|
414
|
+
# true if shutdown, false otherwise.
|
415
|
+
def parse_shutdown(config, name)
|
416
|
+
value = config.scan(/no neighbor #{name} shutdown/)
|
417
|
+
shutdown = value[0] ? false : true
|
418
|
+
{ shutdown: shutdown }
|
419
|
+
end
|
420
|
+
private :parse_shutdown
|
421
|
+
|
422
|
+
##
|
423
|
+
# parse_description scans the BGP neighbor entries for the
|
424
|
+
# description.
|
425
|
+
#
|
426
|
+
# @api private
|
427
|
+
#
|
428
|
+
# @param [String] :config The switch config.
|
429
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
430
|
+
# This value can be either an IPv4 address or string (in the
|
431
|
+
# case of managing a peer group).
|
432
|
+
#
|
433
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
434
|
+
def parse_description(config, name)
|
435
|
+
value = config.scan(/neighbor #{name} description (.*)$/)
|
436
|
+
description = value[0] ? value[0][0] : nil
|
437
|
+
{ description: description }
|
438
|
+
end
|
439
|
+
private :parse_description
|
440
|
+
|
441
|
+
##
|
442
|
+
# parse_next_hop_self scans the BGP neighbor entries for the
|
443
|
+
# next hop self.
|
444
|
+
#
|
445
|
+
# @api private
|
446
|
+
#
|
447
|
+
# @param [String] :config The switch config.
|
448
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
449
|
+
# This value can be either an IPv4 address or string (in the
|
450
|
+
# case of managing a peer group).
|
451
|
+
#
|
452
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
453
|
+
def parse_next_hop_self(config, name)
|
454
|
+
value = config.scan(/no neighbor #{name} next-hop-self/)
|
455
|
+
enabled = value[0] ? false : true
|
456
|
+
{ next_hop_self: enabled }
|
457
|
+
end
|
458
|
+
private :parse_next_hop_self
|
459
|
+
|
460
|
+
##
|
461
|
+
# parse_route_map_in scans the BGP neighbor entries for the
|
462
|
+
# route map in.
|
463
|
+
#
|
464
|
+
# @api private
|
465
|
+
#
|
466
|
+
# @param [String] :config The switch config.
|
467
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
468
|
+
# This value can be either an IPv4 address or string (in the
|
469
|
+
# case of managing a peer group).
|
470
|
+
#
|
471
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
472
|
+
def parse_route_map_in(config, name)
|
473
|
+
value = config.scan(/neighbor #{name} route-map ([^\s]+) in/)
|
474
|
+
route_map_in = value[0] ? value[0][0] : nil
|
475
|
+
{ route_map_in: route_map_in }
|
476
|
+
end
|
477
|
+
private :parse_route_map_in
|
478
|
+
|
479
|
+
##
|
480
|
+
# parse_route_map_out scans the BGP neighbor entries for the
|
481
|
+
# route map in.
|
482
|
+
#
|
483
|
+
# @api private
|
484
|
+
#
|
485
|
+
# @param [String] :config The switch config.
|
486
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
487
|
+
# This value can be either an IPv4 address or string (in the
|
488
|
+
# case of managing a peer group).
|
489
|
+
#
|
490
|
+
# @return [Hash<Symbol, Object>] resource hash attribute
|
491
|
+
def parse_route_map_out(config, name)
|
492
|
+
value = config.scan(/neighbor #{name} route-map ([^\s]+) out/)
|
493
|
+
route_map_out = value[0] ? value[0][0] : nil
|
494
|
+
{ route_map_out: route_map_out }
|
495
|
+
end
|
496
|
+
private :parse_route_map_out
|
497
|
+
|
498
|
+
##
|
499
|
+
# configure_bgp adds the command to go to BGP config mode.
|
500
|
+
# Then it adds the passed in command. The commands are then
|
501
|
+
# passed on to configure.
|
502
|
+
#
|
503
|
+
# @api private
|
504
|
+
#
|
505
|
+
# @param [String] :cmd Command to run under BGP mode
|
506
|
+
#
|
507
|
+
# @return [Boolean] returns true if the command complete successfully
|
508
|
+
def configure_bgp(cmd)
|
509
|
+
config = get_block('^router bgp .*')
|
510
|
+
fail 'BGP router is not configured' unless config
|
511
|
+
bgp_as = Bgp.parse_bgp_as(config)
|
512
|
+
cmds = ["router bgp #{bgp_as[:bgp_as]}", cmd]
|
513
|
+
configure(cmds)
|
514
|
+
end
|
515
|
+
private :configure_bgp
|
516
|
+
|
517
|
+
##
|
518
|
+
# create will create a new instance of a BGP neighbor on the node.
|
519
|
+
# The neighbor is created in the shutdown state and then enabled.
|
520
|
+
#
|
521
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
522
|
+
# This value can be either an IPv4 address or string (in the
|
523
|
+
# case of managing a peer group).
|
524
|
+
#
|
525
|
+
# @return [Boolean] returns true if the command completed successfully
|
526
|
+
def create(name)
|
527
|
+
set_shutdown(name, enable: false)
|
528
|
+
end
|
529
|
+
|
530
|
+
##
|
531
|
+
# delete will delete the BGP neighbor from the node.
|
532
|
+
#
|
533
|
+
# @commands
|
534
|
+
# no neighbor <name>
|
535
|
+
# or
|
536
|
+
# no neighbor <name> peer-group
|
537
|
+
#
|
538
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
539
|
+
# This value can be either an IPv4 address or string (in the
|
540
|
+
# case of managing a peer group).
|
541
|
+
#
|
542
|
+
# @return [Boolean] returns true if the command completed successfully
|
543
|
+
def delete(name)
|
544
|
+
cmd = "no neighbor #{name}"
|
545
|
+
response = configure_bgp(cmd)
|
546
|
+
unless response
|
547
|
+
cmd = "no neighbor #{name} peer-group"
|
548
|
+
response = configure_bgp(cmd)
|
549
|
+
end
|
550
|
+
response
|
551
|
+
end
|
552
|
+
|
553
|
+
##
|
554
|
+
# neigh_command_builder for neighbors which calls command_builder
|
555
|
+
#
|
556
|
+
# @param [String] :name The name of the BGP neighbor to manage.
|
557
|
+
# @param [String] :cmd The command portion of the neighbor command.
|
558
|
+
# @param [hash] :opts Optional keyword arguments
|
559
|
+
#
|
560
|
+
# @option :opts [String] :value Value being set.
|
561
|
+
#
|
562
|
+
# @option :opts [Boolean] :enable If false then the command is
|
563
|
+
# negated. Default is true.
|
564
|
+
#
|
565
|
+
# @option :opts [Boolean] :default Configure the command using
|
566
|
+
# the default keyword.
|
567
|
+
#
|
568
|
+
# @return [String] Returns built command string
|
569
|
+
def neigh_command_builder(name, cmd, opts)
|
570
|
+
command_builder("neighbor #{name} #{cmd}", opts)
|
571
|
+
end
|
572
|
+
|
573
|
+
##
|
574
|
+
# set_peer_group creates a BGP static peer group name.
|
575
|
+
#
|
576
|
+
# @commands
|
577
|
+
# router bgp <bgp_as>
|
578
|
+
# {no | default} neighbor <name> peer-group <group-name>
|
579
|
+
#
|
580
|
+
# @param [String] :name The IP address of the neighbor
|
581
|
+
# @param [hash] :opts Optional keyword arguments
|
582
|
+
#
|
583
|
+
# @option :opts [String] :value The group name.
|
584
|
+
#
|
585
|
+
# @option :opts [Boolean] :enable If false then the command is
|
586
|
+
# negated. Default is true.
|
587
|
+
#
|
588
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
589
|
+
# the default keyword
|
590
|
+
#
|
591
|
+
# @return [Boolean] returns true if the command complete successfully
|
592
|
+
def set_peer_group(name, opts = {})
|
593
|
+
configure_bgp(neigh_command_builder(name, 'peer-group', opts))
|
594
|
+
end
|
595
|
+
|
596
|
+
##
|
597
|
+
# set_remote_as configures the expected AS number for a neighbor
|
598
|
+
# (peer).
|
599
|
+
#
|
600
|
+
# @commands
|
601
|
+
# router bgp <bgp_as>
|
602
|
+
# {no | default} neighbor <name> remote-as <as-id>
|
603
|
+
#
|
604
|
+
# @param [String] :name The IP address or name of the peer group.
|
605
|
+
# @param [hash] :opts Optional keyword arguments
|
606
|
+
#
|
607
|
+
# @option :opts [String] :value The remote as-id.
|
608
|
+
#
|
609
|
+
# @option :opts [Boolean] :enable If false then the command is
|
610
|
+
# negated. Default is true.
|
611
|
+
#
|
612
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
613
|
+
# the default keyword
|
614
|
+
#
|
615
|
+
# @return [Boolean] returns true if the command complete successfully
|
616
|
+
def set_remote_as(name, opts = {})
|
617
|
+
configure_bgp(neigh_command_builder(name, 'remote-as', opts))
|
618
|
+
end
|
619
|
+
|
620
|
+
##
|
621
|
+
# set_shutdown disables the specified neighbor. The value option is
|
622
|
+
# not used by this method.
|
623
|
+
#
|
624
|
+
# @commands
|
625
|
+
# router bgp <bgp_as>
|
626
|
+
# {no | default} neighbor <name> shutdown
|
627
|
+
#
|
628
|
+
# @param [String] :name The IP address or name of the peer group.
|
629
|
+
# @param [hash] :opts Optional keyword arguments
|
630
|
+
#
|
631
|
+
# @option :opts [String] :enable True enables the specified neighbor.
|
632
|
+
# False disables the specified neighbor.
|
633
|
+
#
|
634
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
635
|
+
# the default keyword
|
636
|
+
#
|
637
|
+
# @return [Boolean] returns true if the command complete successfully
|
638
|
+
def set_shutdown(name, opts = {})
|
639
|
+
fail 'set_shutdown has value option set' if opts[:value]
|
640
|
+
# Shutdown semantics are opposite of enable semantics so invert enable
|
641
|
+
value = !opts[:enable]
|
642
|
+
opts.merge!(enable: value)
|
643
|
+
configure_bgp(neigh_command_builder(name, 'shutdown', opts))
|
644
|
+
end
|
645
|
+
|
646
|
+
##
|
647
|
+
# set_send_community configures the switch to send community
|
648
|
+
# attributes to the specified BGP neighbor. The value option is
|
649
|
+
# not used by this method.
|
650
|
+
#
|
651
|
+
# @commands
|
652
|
+
# router bgp <bgp_as>
|
653
|
+
# {no | default} neighbor <name> send-community
|
654
|
+
#
|
655
|
+
# @param [String] :name The IP address or name of the peer group.
|
656
|
+
# @param [hash] :opts Optional keyword arguments
|
657
|
+
#
|
658
|
+
# @option :opts [String] :enable True enables the feature. False
|
659
|
+
# disables the feature.
|
660
|
+
#
|
661
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
662
|
+
# the default keyword
|
663
|
+
#
|
664
|
+
# @return [Boolean] returns true if the command complete successfully
|
665
|
+
def set_send_community(name, opts = {})
|
666
|
+
fail 'send_community has the value option set' if opts[:value]
|
667
|
+
configure_bgp(neigh_command_builder(name, 'send-community', opts))
|
668
|
+
end
|
669
|
+
|
670
|
+
##
|
671
|
+
# set_next_hop_self configures the switch to list its address as
|
672
|
+
# the next hop in routes that it advertises to the specified
|
673
|
+
# BGP-speaking neighbor or neighbors in the specified peer group.
|
674
|
+
# The value option is not used by this method.
|
675
|
+
#
|
676
|
+
# @commands
|
677
|
+
# router bgp <bgp_as>
|
678
|
+
# {no | default} neighbor <name> next-hop-self
|
679
|
+
#
|
680
|
+
# @param [String] :name The IP address or name of the peer group.
|
681
|
+
# @param [hash] :opts Optional keyword arguments
|
682
|
+
#
|
683
|
+
# @option :opts [String] :enable True enables the feature. False
|
684
|
+
# disables the feature.
|
685
|
+
#
|
686
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
687
|
+
# the default keyword
|
688
|
+
#
|
689
|
+
# @return [Boolean] returns true if the command complete successfully
|
690
|
+
def set_next_hop_self(name, opts = {})
|
691
|
+
fail 'set_next_hop_self has the value option set' if opts[:value]
|
692
|
+
configure_bgp(neigh_command_builder(name, 'next-hop-self', opts))
|
693
|
+
end
|
694
|
+
|
695
|
+
##
|
696
|
+
# set_route_map_in command applies a route map to inbound BGP
|
697
|
+
# routes.
|
698
|
+
#
|
699
|
+
# @commands
|
700
|
+
# router bgp <bgp_as>
|
701
|
+
# {no | default} neighbor <name> route-map <name> in
|
702
|
+
#
|
703
|
+
# @param [String] :name The IP address or name of the peer group.
|
704
|
+
# @param [hash] :opts Optional keyword arguments
|
705
|
+
#
|
706
|
+
# @option :opts [String] :value Name of a route map.
|
707
|
+
#
|
708
|
+
# @option :opts [Boolean] :enable If false then the command is
|
709
|
+
# negated. Default is true.
|
710
|
+
#
|
711
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
712
|
+
# the default keyword
|
713
|
+
#
|
714
|
+
# @return [Boolean] returns true if the command complete successfully
|
715
|
+
def set_route_map_in(name, opts = {})
|
716
|
+
cmd = neigh_command_builder(name, 'route-map', opts) + ' in'
|
717
|
+
configure_bgp(cmd)
|
718
|
+
end
|
719
|
+
|
720
|
+
##
|
721
|
+
# set_route_map_out command applies a route map to outbound BGP
|
722
|
+
# routes.
|
723
|
+
#
|
724
|
+
# @commands
|
725
|
+
# router bgp <bgp_as>
|
726
|
+
# {no | default} neighbor <name> route-map <name> out
|
727
|
+
#
|
728
|
+
# @param [String] :name The IP address or name of the peer group.
|
729
|
+
# @param [hash] :opts Optional keyword arguments
|
730
|
+
#
|
731
|
+
# @option :opts [String] :value Name of a route map.
|
732
|
+
#
|
733
|
+
# @option :opts [Boolean] :enable If false then the command is
|
734
|
+
# negated. Default is true.
|
735
|
+
#
|
736
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
737
|
+
# the default keyword
|
738
|
+
#
|
739
|
+
# @return [Boolean] returns true if the command complete successfully
|
740
|
+
def set_route_map_out(name, opts = {})
|
741
|
+
cmd = neigh_command_builder(name, 'route-map', opts) + ' out'
|
742
|
+
configure_bgp(cmd)
|
743
|
+
end
|
744
|
+
|
745
|
+
##
|
746
|
+
# set_description associates descriptive text with the specified
|
747
|
+
# peer or peer group.
|
748
|
+
#
|
749
|
+
# @commands
|
750
|
+
# router bgp <bgp_as>
|
751
|
+
# {no | default} neighbor <name> description <string>
|
752
|
+
#
|
753
|
+
# @param [String] :name The IP address or name of the peer group.
|
754
|
+
# @param [hash] :opts Optional keyword arguments
|
755
|
+
#
|
756
|
+
# @option :opts [String] :value The description string.
|
757
|
+
#
|
758
|
+
# @option :opts [Boolean] :enable If false then the command is
|
759
|
+
# negated. Default is true.
|
760
|
+
#
|
761
|
+
# @option :opts [Boolean] :default Configure the peer group using
|
762
|
+
# the default keyword
|
763
|
+
#
|
764
|
+
# @return [Boolean] returns true if the command complete successfully
|
765
|
+
def set_description(name, opts = {})
|
766
|
+
configure_bgp(neigh_command_builder(name, 'description', opts))
|
767
|
+
end
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|