rbeapi 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +25 -2
- data/Gemfile +13 -7
- data/Rakefile +8 -7
- data/lib/rbeapi/api/alias.rb +160 -0
- data/lib/rbeapi/api/bgp.rb +9 -9
- data/lib/rbeapi/api/dns.rb +3 -1
- data/lib/rbeapi/api/interfaces.rb +194 -32
- data/lib/rbeapi/api/ipinterfaces.rb +5 -3
- data/lib/rbeapi/api/managementdefaults.rb +119 -0
- data/lib/rbeapi/api/mlag.rb +6 -6
- data/lib/rbeapi/api/ntp.rb +1 -1
- data/lib/rbeapi/api/ospf.rb +171 -12
- data/lib/rbeapi/api/prefixlists.rb +19 -9
- data/lib/rbeapi/api/radius.rb +5 -5
- data/lib/rbeapi/api/routemaps.rb +12 -12
- data/lib/rbeapi/api/snmp.rb +6 -4
- data/lib/rbeapi/api/stp.rb +24 -24
- data/lib/rbeapi/api/switchports.rb +15 -9
- data/lib/rbeapi/api/tacacs.rb +1 -1
- data/lib/rbeapi/api/users.rb +4 -4
- data/lib/rbeapi/api/varp.rb +7 -3
- data/lib/rbeapi/api/vlans.rb +2 -2
- data/lib/rbeapi/api/vrrp.rb +61 -61
- data/lib/rbeapi/client.rb +9 -6
- data/lib/rbeapi/eapilib.rb +3 -3
- data/lib/rbeapi/netdev/snmp.rb +8 -6
- data/lib/rbeapi/switchconfig.rb +9 -10
- data/lib/rbeapi/version.rb +1 -1
- data/spec/support/fixtures.rb +4 -4
- data/spec/support/matchers/switch_config_sections.rb +2 -2
- data/spec/system/rbeapi/api/acl_spec.rb +2 -4
- data/spec/system/rbeapi/api/alias_spec.rb +168 -0
- data/spec/system/rbeapi/api/bgp_spec.rb +1 -2
- data/spec/system/rbeapi/api/interfaces_base_spec.rb +7 -8
- data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +36 -3
- data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +35 -3
- data/spec/system/rbeapi/api/interfaces_vlan_spec.rb +90 -0
- data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +3 -4
- data/spec/system/rbeapi/api/managementdefaults_spec.rb +31 -0
- data/spec/system/rbeapi/api/ospf_interfaces_spec.rb +36 -11
- data/spec/system/rbeapi/api/ospf_spec.rb +240 -17
- data/spec/system/rbeapi/api/prefixlists_spec.rb +105 -89
- data/spec/system/rbeapi/api/routemaps_spec.rb +15 -10
- data/spec/system/rbeapi/api/users_spec.rb +4 -5
- data/spec/system/rbeapi/api/vrrp_spec.rb +2 -5
- data/spec/system/rbeapi/client_spec.rb +1 -2
- data/spec/unit/rbeapi/api/acl/default_spec.rb +1 -2
- data/spec/unit/rbeapi/api/alias/default_spec.rb +119 -0
- data/spec/unit/rbeapi/api/alias/fixture_alias.text +3 -0
- data/spec/unit/rbeapi/api/bgp/bgp_neighbors_spec.rb +1 -2
- data/spec/unit/rbeapi/api/bgp/bgp_spec.rb +1 -2
- data/spec/unit/rbeapi/api/interfaces/base_spec.rb +1 -1
- data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +35 -1
- data/spec/unit/rbeapi/api/interfaces/fixture_interfaces.text +68 -0
- data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +41 -4
- data/spec/unit/rbeapi/api/interfaces/vlan_spec.rb +72 -0
- data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +2 -2
- data/spec/unit/rbeapi/api/managementdefaults/default_spec.rb +50 -0
- data/spec/unit/rbeapi/api/managementdefaults/fixture_managementdefaults.yaml +1 -0
- data/spec/unit/rbeapi/api/prefixlists/default_spec.rb +98 -80
- data/spec/unit/rbeapi/api/prefixlists/fixture_prefixlists.text +9 -4
- data/spec/unit/rbeapi/api/users/default_spec.rb +2 -4
- data/spec/unit/rbeapi/api/vrrp/default_spec.rb +2 -5
- data/spec/unit/rbeapi/client_spec.rb +21 -14
- data/spec/unit/rbeapi/switchconfig_spec.rb +10 -3
- metadata +49 -59
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1dc55f02164a2136033dc85beedb95892b9c4123
|
4
|
+
data.tar.gz: 834b6277842521fb9fbfd47a00364dd1ac30457b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6af640792253a287f6fc05cb940e1783c06c767d1bb592a61497e35a2c0b6db59ce5d11b0d26178219797d33554c5626e68506a0173ce1f9a43ee4fc73325442
|
7
|
+
data.tar.gz: 7571e8a5ebe5cb10b0f0c77f5c2011958d3f5cfeea568d5542a13d3cc56edb1ae30309dba4053bffe5ecc83b49bb252168554ae0ba3c60cbd5f06f8fef7e1d8a
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,28 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [1.
|
4
|
-
[Full Changelog](https://github.com/arista-eosplus/rbeapi/compare/
|
3
|
+
## [1.1](https://github.com/arista-eosplus/rbeapi/tree/1.1) (2016-12-06)
|
4
|
+
[Full Changelog](https://github.com/arista-eosplus/rbeapi/compare/v1.0...1.1)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- add subinterface functionality [\#161](https://github.com/arista-eosplus/rbeapi/pull/161) ([mmailand](https://github.com/mmailand))
|
9
|
+
- add support to set aliases [\#160](https://github.com/arista-eosplus/rbeapi/pull/160) ([mmailand](https://github.com/mmailand))
|
10
|
+
- added support for setting the crypto in managementdefaults [\#159](https://github.com/arista-eosplus/rbeapi/pull/159) ([mmailand](https://github.com/mmailand))
|
11
|
+
- added support for autostate [\#158](https://github.com/arista-eosplus/rbeapi/pull/158) ([mmailand](https://github.com/mmailand))
|
12
|
+
- add support for multi/single-line prefix list output [\#155](https://github.com/arista-eosplus/rbeapi/pull/155) ([mrvinti](https://github.com/mrvinti))
|
13
|
+
|
14
|
+
**Fixed bugs:**
|
15
|
+
|
16
|
+
- Fix multiline alias support [\#165](https://github.com/arista-eosplus/rbeapi/pull/165) ([jerearista](https://github.com/jerearista))
|
17
|
+
- extend and fix ospf features [\#156](https://github.com/arista-eosplus/rbeapi/pull/156) ([rknaus](https://github.com/rknaus))
|
18
|
+
|
19
|
+
**Merged pull requests:**
|
20
|
+
|
21
|
+
- Style updates for Rubocop 0.45 [\#163](https://github.com/arista-eosplus/rbeapi/pull/163) ([jerearista](https://github.com/jerearista))
|
22
|
+
- fix for rspec failure on current develop [\#162](https://github.com/arista-eosplus/rbeapi/pull/162) ([mmailand](https://github.com/mmailand))
|
23
|
+
|
24
|
+
## [v1.0](https://github.com/arista-eosplus/rbeapi/tree/v1.0) (2016-09-26)
|
25
|
+
[Full Changelog](https://github.com/arista-eosplus/rbeapi/compare/v0.5.1...v1.0)
|
5
26
|
|
6
27
|
**Implemented enhancements:**
|
7
28
|
|
@@ -24,6 +45,8 @@
|
|
24
45
|
|
25
46
|
**Merged pull requests:**
|
26
47
|
|
48
|
+
- Release 1.0 [\#153](https://github.com/arista-eosplus/rbeapi/pull/153) ([jerearista](https://github.com/jerearista))
|
49
|
+
- Release 1.0 [\#152](https://github.com/arista-eosplus/rbeapi/pull/152) ([jerearista](https://github.com/jerearista))
|
27
50
|
- Add json option to get\_config [\#151](https://github.com/arista-eosplus/rbeapi/pull/151) ([jerearista](https://github.com/jerearista))
|
28
51
|
- Handle more multiline config commands [\#150](https://github.com/arista-eosplus/rbeapi/pull/150) ([jerearista](https://github.com/jerearista))
|
29
52
|
- Ensure get\_config, running\_config, and startup\_config return sane output [\#149](https://github.com/arista-eosplus/rbeapi/pull/149) ([jerearista](https://github.com/jerearista))
|
data/Gemfile
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
|
2
2
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rbeapi/version'
|
6
|
+
|
3
7
|
gem 'inifile'
|
4
8
|
gem 'net_http_unix'
|
5
9
|
gem 'netaddr'
|
@@ -12,20 +16,20 @@ group :development do
|
|
12
16
|
end
|
13
17
|
|
14
18
|
group :development, :test do
|
19
|
+
gem 'ci_reporter_rspec', require: false
|
15
20
|
gem 'listen', '<=3.0.3'
|
21
|
+
gem 'pry', require: false
|
22
|
+
gem 'pry-doc', require: false
|
23
|
+
gem 'pry-stack_explorer', require: false
|
16
24
|
gem 'rake', '~> 10.1.0'
|
25
|
+
gem 'rbeapi', Rbeapi::VERSION, path: '.'
|
26
|
+
gem 'redcarpet', '~> 3.1.2'
|
17
27
|
gem 'rspec', '~> 3.0.0'
|
18
28
|
gem 'rspec-mocks', '~> 3.0.0'
|
19
29
|
gem 'simplecov'
|
20
|
-
gem 'yard'
|
21
|
-
gem 'redcarpet', '~> 3.1.2'
|
22
|
-
gem 'pry', require: false
|
23
|
-
gem 'pry-doc', require: false
|
24
|
-
gem 'pry-stack_explorer', require: false
|
25
|
-
gem 'rbeapi', '1.0', path: '.'
|
26
|
-
gem 'ci_reporter_rspec', require: false
|
27
30
|
gem 'simplecov-json', require: false
|
28
31
|
gem 'simplecov-rcov', require: false
|
32
|
+
gem 'yard'
|
29
33
|
end
|
30
34
|
|
31
35
|
# Rubocop > 0.37 requires a gem that only works with ruby 2.x
|
@@ -35,6 +39,8 @@ if RUBY_VERSION.to_f < 2.0
|
|
35
39
|
gem 'rubocop', '>=0.35.1', '< 0.38'
|
36
40
|
end
|
37
41
|
else
|
42
|
+
# Rubocop thinks these are duplicates.
|
43
|
+
# rubocop:disable Bundler/DuplicatedGem
|
38
44
|
gem 'json'
|
39
45
|
group :development, :test do
|
40
46
|
gem 'rubocop', '>=0.35.1'
|
data/Rakefile
CHANGED
@@ -9,13 +9,14 @@ end
|
|
9
9
|
|
10
10
|
RPM_OPTS = '--define "_topdir %(pwd)/rpmbuild" --define "_builddir ' \
|
11
11
|
'%{_topdir}" --define "_rpmdir %(pwd)/rpms" --define "_srcrpmdir ' \
|
12
|
-
'%{_rpmdir}" --define "_sourcedir %(pwd)" --define "_specdir %(pwd)"
|
12
|
+
'%{_rpmdir}" --define "_sourcedir %(pwd)" --define "_specdir %(pwd)" '\
|
13
|
+
'-bb'.freeze
|
13
14
|
desc 'Generate regular and puppet-enterprise rbeapi RPMs for EOS'
|
14
15
|
task rpm: :build do
|
15
16
|
system "sed -e 's/^Version:.*/Version: #{Rbeapi::VERSION}/g' " \
|
16
17
|
'rbeapi.spec.tmpl > rbeapi.spec'
|
17
18
|
system "rpmbuild #{RPM_OPTS} rbeapi.spec"
|
18
|
-
RPMS = `find rpms/noarch -name "*rbeapi*rpm"
|
19
|
+
RPMS = `find rpms/noarch -name "*rbeapi*rpm"`.freeze
|
19
20
|
puts "\n################################################\n#"
|
20
21
|
puts "Created the following in rpms/noarch/\n#{RPMS}"
|
21
22
|
puts "#\n################################################\n\n"
|
@@ -32,7 +33,7 @@ task :inifile do
|
|
32
33
|
system "sed -e 's/^Version:.*/Version: #{INIFILE_VERSION}/g' " \
|
33
34
|
'gems/inifile/inifile.spec.tmpl > gems/inifile/inifile.spec'
|
34
35
|
system "rpmbuild #{RPM_OPTS} gems/inifile/inifile.spec"
|
35
|
-
RPMS = `find rpms/noarch -name "*inifile*rpm"
|
36
|
+
RPMS = `find rpms/noarch -name "*inifile*rpm"`.freeze
|
36
37
|
puts "\n################################################\n#"
|
37
38
|
puts "Created the following in rpms/noarch/\n#{RPMS}"
|
38
39
|
puts "#\n################################################\n\n"
|
@@ -50,7 +51,7 @@ task :net_http_unix do
|
|
50
51
|
'gems/net_http_unix/net_http_unix.spec.tmpl > ' \
|
51
52
|
'gems/net_http_unix/net_http_unix.spec'
|
52
53
|
system "rpmbuild #{RPM_OPTS} gems/net_http_unix/net_http_unix.spec"
|
53
|
-
RPMS = `find rpms/noarch -name "*net_http_unix*rpm"
|
54
|
+
RPMS = `find rpms/noarch -name "*net_http_unix*rpm"`.freeze
|
54
55
|
puts "\n################################################\n#"
|
55
56
|
puts "Created the following in rpms/noarch/\n#{RPMS}"
|
56
57
|
puts "#\n################################################\n\n"
|
@@ -67,7 +68,7 @@ task :netaddr do
|
|
67
68
|
system "sed -e 's/^Version:.*/Version: #{NETADDR_VERSION}/g' " \
|
68
69
|
'gems/netaddr/netaddr.spec.tmpl > gems/netaddr/netaddr.spec'
|
69
70
|
system "rpmbuild #{RPM_OPTS} gems/netaddr/netaddr.spec"
|
70
|
-
RPMS = `find rpms/noarch -name "*netaddr*rpm"
|
71
|
+
RPMS = `find rpms/noarch -name "*netaddr*rpm"`.freeze
|
71
72
|
puts "\n################################################\n#"
|
72
73
|
puts "Created the following in rpms/noarch/\n#{RPMS}"
|
73
74
|
puts "#\n################################################\n\n"
|
@@ -114,7 +115,7 @@ end
|
|
114
115
|
desc 'Generate SWIX files from RPMs'
|
115
116
|
task swix: :all_rpms do
|
116
117
|
SWIX = 'PYTHONPATH=${PYTHONPATH}:/nfs/misc/tools/swix \
|
117
|
-
/nfs/misc/tools/swix/swix'
|
118
|
+
/nfs/misc/tools/swix/swix'.freeze
|
118
119
|
system "(cd rpms/noarch;
|
119
120
|
rm -f rbeapi-#{Rbeapi::VERSION}-1.swix;
|
120
121
|
#{SWIX} create rbeapi-#{Rbeapi::VERSION}-1.swix \
|
@@ -141,7 +142,7 @@ task swix: :all_rpms do
|
|
141
142
|
rubygem-inifile-puppet-aio-3.0.0-5.eos4.noarch.rpm \
|
142
143
|
rubygem-netaddr-puppet-aio-1.5.1-4.eos4.noarch.rpm \
|
143
144
|
rubygem-net_http_unix-puppet-aio-0.2.2-5.eos4.noarch.rpm)"
|
144
|
-
SWIXS = `find rpms/noarch -name "rbeapi*swix" -ls
|
145
|
+
SWIXS = `find rpms/noarch -name "rbeapi*swix" -ls`.freeze
|
145
146
|
puts "\n################################################\n#"
|
146
147
|
puts "The following artifacts are in rpms/noarch/\n#{SWIXS}"
|
147
148
|
puts "#\n################################################\n\n"
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#
|
2
|
+
## Copyright (c) 2016, 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
|
+
# Rbeapi toplevel namespace.
|
36
|
+
module Rbeapi
|
37
|
+
##
|
38
|
+
# Api is module namespace for working with the EOS command API.
|
39
|
+
module Api
|
40
|
+
##
|
41
|
+
# The Alias class manages aliass entries on an EOS node.
|
42
|
+
class Alias < Entity
|
43
|
+
##
|
44
|
+
# get returns the current alias configuration hash extracted from the
|
45
|
+
# nodes running configuration.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# {
|
49
|
+
# alias: array<strings>
|
50
|
+
# }
|
51
|
+
#
|
52
|
+
# @return [Hash<Symbol, Object>] Returns the alias resource as a hash
|
53
|
+
# object from the nodes current configuration.
|
54
|
+
def get(name)
|
55
|
+
# Complex regex handles the following cases:
|
56
|
+
# All aliases start with 'alian <name>' followed by
|
57
|
+
# <space><single-line command>
|
58
|
+
# <carriage return><multiple lines of commands>
|
59
|
+
pattern = /^alias #{name}((?:(?= )(?:.+?)(?=\n)|\n(?:.+?)(?=\n\!)))/m
|
60
|
+
aliases = config.scan(pattern)
|
61
|
+
return nil unless aliases[0]
|
62
|
+
parse_alias_entry(name, aliases[0])
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# getall returns a collection of alias resource hashes from the nodes
|
67
|
+
# running configuration. The alias resource collection hash is keyed
|
68
|
+
# by the unique alias name.
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# [
|
72
|
+
# <alias>: {
|
73
|
+
# command: <string>
|
74
|
+
# },
|
75
|
+
# <alias>: {
|
76
|
+
# command: <string>
|
77
|
+
# },
|
78
|
+
# ...
|
79
|
+
# ]
|
80
|
+
#
|
81
|
+
# @return [Hash<Symbol, Object>] Returns a hash that represents the
|
82
|
+
# entire alias collection from the nodes running configuration. If
|
83
|
+
# there are no aliass configured, this method will return an empty
|
84
|
+
# hash.
|
85
|
+
def getall
|
86
|
+
entries = config.scan(/^alias (\w+)(.+)?/)
|
87
|
+
entries.inspect
|
88
|
+
response = {}
|
89
|
+
entries.each do |aliases|
|
90
|
+
response[aliases[0]] = get aliases[0]
|
91
|
+
end
|
92
|
+
response
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# parse_alias_entry maps the tokens found to the hash entries.
|
97
|
+
#
|
98
|
+
# @api private
|
99
|
+
#
|
100
|
+
# @param alias [Array] An array of values returned from the regular
|
101
|
+
# expression scan of the aliass configuration.
|
102
|
+
#
|
103
|
+
# @return [Hash<Symbol, Object>] Returns the resource hash attribute.
|
104
|
+
def parse_alias_entry(name, command)
|
105
|
+
hsh = {}
|
106
|
+
hsh[:name] = name
|
107
|
+
com = command[0]
|
108
|
+
hsh[:command] = com.strip
|
109
|
+
hsh
|
110
|
+
end
|
111
|
+
private :parse_alias_entry
|
112
|
+
|
113
|
+
##
|
114
|
+
# create will create a alias entry in the nodes current
|
115
|
+
# configuration with the specified address.
|
116
|
+
#
|
117
|
+
# @since eos_version 4.13.7M
|
118
|
+
#
|
119
|
+
# ===Commands
|
120
|
+
# alias <name> <address>
|
121
|
+
#
|
122
|
+
# @param name [String] The name of the alias.
|
123
|
+
#
|
124
|
+
# @param opts [hash] Optional keyword arguments.
|
125
|
+
#
|
126
|
+
# @option opts command [String] Configures the alias ip address
|
127
|
+
#
|
128
|
+
# @return [Boolean] Returns true if the command completed successfully.
|
129
|
+
def create(name, opts = {})
|
130
|
+
raise ArgumentError, 'a command must be provided' unless \
|
131
|
+
opts[:command] =~ /.+/
|
132
|
+
command = opts.fetch(:command)
|
133
|
+
cmd = ["alias #{name} "]
|
134
|
+
if command =~ /\\n/
|
135
|
+
command.split('\\n').each { |a| cmd << a }
|
136
|
+
else
|
137
|
+
cmd[0] << command
|
138
|
+
end
|
139
|
+
configure(cmd)
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# delete will delete an existing alias entry from the nodes current
|
144
|
+
# running configuration. If the delete method is called and the alias
|
145
|
+
# entry does not exist, this method will succeed.
|
146
|
+
#
|
147
|
+
# @since eos_version 4.13.7M
|
148
|
+
#
|
149
|
+
# ===Commands
|
150
|
+
# no alias <name>
|
151
|
+
#
|
152
|
+
# @param name [String] The alias name entry to delete from the node.
|
153
|
+
#
|
154
|
+
# @return [Boolean] Returns true if the command completed successfully.
|
155
|
+
def delete(name)
|
156
|
+
configure("no alias #{name}")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/rbeapi/api/bgp.rb
CHANGED
@@ -227,7 +227,7 @@ module Rbeapi
|
|
227
227
|
def create(bgp_as, opts = {})
|
228
228
|
if opts[:maximum_ecmp_paths] && !opts[:maximum_paths]
|
229
229
|
message = 'maximum_paths must be set if maximum_ecmp_paths is set'
|
230
|
-
|
230
|
+
raise ArgumentError, message
|
231
231
|
end
|
232
232
|
cmds = ["router bgp #{bgp_as}"]
|
233
233
|
if opts.key?(:enable)
|
@@ -284,7 +284,7 @@ module Rbeapi
|
|
284
284
|
# @return [Boolean] Returns true if the command complete successfully.
|
285
285
|
def configure_bgp(cmd)
|
286
286
|
config = get_block('^router bgp .*')
|
287
|
-
|
287
|
+
raise 'BGP router is not configured' unless config
|
288
288
|
bgp_as = Bgp.parse_bgp_as(config)
|
289
289
|
cmds = ["router bgp #{bgp_as[:bgp_as]}", cmd]
|
290
290
|
configure(cmds)
|
@@ -341,10 +341,10 @@ module Rbeapi
|
|
341
341
|
#
|
342
342
|
# @return [Boolean] Returns true if the command complete successfully.
|
343
343
|
def set_shutdown(opts = {})
|
344
|
-
|
344
|
+
raise 'set_shutdown has the value option set' if opts[:value]
|
345
345
|
# Shutdown semantics are opposite of enable semantics so invert enable
|
346
346
|
value = !opts[:enable]
|
347
|
-
opts
|
347
|
+
opts[:enable] = value
|
348
348
|
configure_bgp(command_builder('shutdown', opts))
|
349
349
|
end
|
350
350
|
|
@@ -697,7 +697,7 @@ module Rbeapi
|
|
697
697
|
# @return [Boolean] Returns true if the command complete successfully.
|
698
698
|
def configure_bgp(cmd)
|
699
699
|
config = get_block('^router bgp .*')
|
700
|
-
|
700
|
+
raise 'BGP router is not configured' unless config
|
701
701
|
bgp_as = Bgp.parse_bgp_as(config)
|
702
702
|
cmds = ["router bgp #{bgp_as[:bgp_as]}", cmd]
|
703
703
|
configure(cmds)
|
@@ -831,10 +831,10 @@ module Rbeapi
|
|
831
831
|
#
|
832
832
|
# @return [Boolean] Returns true if the command complete successfully.
|
833
833
|
def set_shutdown(name, opts = {})
|
834
|
-
|
834
|
+
raise 'set_shutdown has value option set' if opts[:value]
|
835
835
|
# Shutdown semantics are opposite of enable semantics so invert enable.
|
836
836
|
value = !opts[:enable]
|
837
|
-
opts
|
837
|
+
opts[:enable] = value
|
838
838
|
configure_bgp(neigh_command_builder(name, 'shutdown', opts))
|
839
839
|
end
|
840
840
|
|
@@ -859,7 +859,7 @@ module Rbeapi
|
|
859
859
|
#
|
860
860
|
# @return [Boolean] Returns true if the command complete successfully.
|
861
861
|
def set_send_community(name, opts = {})
|
862
|
-
|
862
|
+
raise 'send_community has the value option set' if opts[:value]
|
863
863
|
configure_bgp(neigh_command_builder(name, 'send-community', opts))
|
864
864
|
end
|
865
865
|
|
@@ -885,7 +885,7 @@ module Rbeapi
|
|
885
885
|
#
|
886
886
|
# @return [Boolean] Returns true if the command complete successfully.
|
887
887
|
def set_next_hop_self(name, opts = {})
|
888
|
-
|
888
|
+
raise 'set_next_hop_self has the value option set' if opts[:value]
|
889
889
|
configure_bgp(neigh_command_builder(name, 'next-hop-self', opts))
|
890
890
|
end
|
891
891
|
|
data/lib/rbeapi/api/dns.rb
CHANGED
@@ -213,7 +213,9 @@ module Rbeapi
|
|
213
213
|
default = opts[:default] || false
|
214
214
|
|
215
215
|
if value
|
216
|
-
|
216
|
+
unless value.is_a?(Array)
|
217
|
+
raise ArgumentError, 'value must be an Array'
|
218
|
+
end
|
217
219
|
end
|
218
220
|
|
219
221
|
cmds = []
|
@@ -55,6 +55,7 @@ module Rbeapi
|
|
55
55
|
# name: <string>,
|
56
56
|
# type: <string>,
|
57
57
|
# description: <string>,
|
58
|
+
# encapsulation: <integer>,
|
58
59
|
# shutdown: <boolean>
|
59
60
|
# }
|
60
61
|
#
|
@@ -77,6 +78,7 @@ module Rbeapi
|
|
77
78
|
# name: <string>,
|
78
79
|
# type: <string>,
|
79
80
|
# description: <string>,
|
81
|
+
# encapsulation: <integer>,
|
80
82
|
# shutdown: <boolean>,
|
81
83
|
# ...
|
82
84
|
# },
|
@@ -84,6 +86,7 @@ module Rbeapi
|
|
84
86
|
# name: <string>,
|
85
87
|
# type: <string>,
|
86
88
|
# description: <string>,
|
89
|
+
# encapsulation: <integer>,
|
87
90
|
# shutdown: <boolean>,
|
88
91
|
# ...
|
89
92
|
# },
|
@@ -110,16 +113,18 @@ module Rbeapi
|
|
110
113
|
# @return [Object] Returns the interface instance as an Object.
|
111
114
|
def get_instance(name)
|
112
115
|
name = name[0, 2].upcase
|
113
|
-
case name
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
116
|
+
cls = case name
|
117
|
+
when 'ET'
|
118
|
+
'Rbeapi::Api::EthernetInterface'
|
119
|
+
when 'PO'
|
120
|
+
'Rbeapi::Api::PortchannelInterface'
|
121
|
+
when 'VX'
|
122
|
+
'Rbeapi::Api::VxlanInterface'
|
123
|
+
when 'VL'
|
124
|
+
'Rbeapi::Api::VlanInterface'
|
125
|
+
else
|
126
|
+
'Rbeapi::Api::BaseInterface'
|
127
|
+
end
|
123
128
|
|
124
129
|
return @instances[name] if @instances.include?(cls)
|
125
130
|
instance = Rbeapi::Utils.class_from_string(cls).new(@node)
|
@@ -127,10 +132,12 @@ module Rbeapi
|
|
127
132
|
instance
|
128
133
|
end
|
129
134
|
|
135
|
+
# rubocop:disable Style/MethodMissing
|
130
136
|
def method_missing(method_name, *args, &block)
|
131
137
|
instance = get_instance(args[0])
|
132
138
|
instance.send(method_name.to_sym, *args, &block)
|
133
139
|
end
|
140
|
+
# rubocop:enable Style/MethodMissing
|
134
141
|
|
135
142
|
def respond_to?(method_name, name = nil)
|
136
143
|
return super unless name
|
@@ -143,8 +150,9 @@ module Rbeapi
|
|
143
150
|
# The BaseInterface class extends Entity and provides an implementation
|
144
151
|
# that is common to all interfaces configured in EOS.
|
145
152
|
class BaseInterface < Entity
|
146
|
-
DEFAULT_INTF_DESCRIPTION = ''
|
147
|
-
|
153
|
+
DEFAULT_INTF_DESCRIPTION = ''.freeze
|
154
|
+
DEFAULT_INTF_ENCAPSULATION = ''.freeze
|
155
|
+
DEFAULT_LOAD_INTERVAL = ''.freeze
|
148
156
|
|
149
157
|
##
|
150
158
|
# get returns the specified interface resource hash that represents the
|
@@ -157,6 +165,7 @@ module Rbeapi
|
|
157
165
|
# name: <string>
|
158
166
|
# type: 'generic'
|
159
167
|
# description: <string>
|
168
|
+
# encapsulation: <integer>
|
160
169
|
# shutdown: [true, false]
|
161
170
|
# load_interval: <string>
|
162
171
|
# }
|
@@ -173,6 +182,7 @@ module Rbeapi
|
|
173
182
|
|
174
183
|
response = { name: name, type: 'generic' }
|
175
184
|
response.merge!(parse_description(config))
|
185
|
+
response.merge!(parse_encapsulation(config))
|
176
186
|
response.merge!(parse_shutdown(config))
|
177
187
|
response.merge!(parse_load_interval(config))
|
178
188
|
response
|
@@ -197,6 +207,26 @@ module Rbeapi
|
|
197
207
|
end
|
198
208
|
private :parse_description
|
199
209
|
|
210
|
+
##
|
211
|
+
# parse_encapsulation scans the provided configuration block and parses
|
212
|
+
# the encapsulation value if it exists in the configuration. If the
|
213
|
+
# encapsulation value is not configured, then the
|
214
|
+
# DEFALT_INTF_ENCAPSULATION value is returned. The hash returned by this
|
215
|
+
# method is intended to be merged into the interface resource hash
|
216
|
+
# returned by the get method.
|
217
|
+
#
|
218
|
+
# @api private
|
219
|
+
#
|
220
|
+
# @param config [String] The configuration block retrieved from the
|
221
|
+
# nodes current running configuration.
|
222
|
+
#
|
223
|
+
# @return [Hash<Symbol, Object>] Returns the resource hash attribute.
|
224
|
+
def parse_encapsulation(config)
|
225
|
+
mdata = /^\s{3}encapsulation dot1q vlan\s(.+)$/.match(config)
|
226
|
+
{ encapsulation: mdata.nil? ? DEFAULT_INTF_ENCAPSULATION : mdata[1] }
|
227
|
+
end
|
228
|
+
private :parse_encapsulation
|
229
|
+
|
200
230
|
##
|
201
231
|
# parse_shutdown scans the provided configuration block and parses
|
202
232
|
# the shutdown value. If the shutdown value is configured then true
|
@@ -315,6 +345,44 @@ module Rbeapi
|
|
315
345
|
configure_interface(name, commands)
|
316
346
|
end
|
317
347
|
|
348
|
+
##
|
349
|
+
# set_encapsulation configures the VLAN ID value for the specified
|
350
|
+
# interface name in the nodes running configuration. If the enable
|
351
|
+
# keyword is false then the encapsulation value is negated using the no
|
352
|
+
# keyword. If the default keyword is set to true, then the encapsulation
|
353
|
+
# value is defaulted using the default keyword. The default keyword takes
|
354
|
+
# precedence over the enable keyword if both are provided.
|
355
|
+
#
|
356
|
+
# @since eos_version X.XX.XM
|
357
|
+
#
|
358
|
+
# @param name [String] The interface name to apply the configuration
|
359
|
+
# to. The name value must be the full interface identifier.
|
360
|
+
#
|
361
|
+
# @param opts [hash] Optional keyword arguments.
|
362
|
+
#
|
363
|
+
# @option opts value [String] The value to configure the VLAN ID to be
|
364
|
+
# used in the encapsulation dot1q vlan setting for a subinterface.
|
365
|
+
#
|
366
|
+
# @option opts enable [Boolean] If false then the command is
|
367
|
+
# negated. Default is true.
|
368
|
+
#
|
369
|
+
# @option opts default [Boolean] Configure the interface encapsulation
|
370
|
+
# using the default keyword.
|
371
|
+
#
|
372
|
+
# @return [Boolean] Returns true if the command completed successfully.
|
373
|
+
def set_encapsulation(name, opts = {})
|
374
|
+
unless name =~ /\./
|
375
|
+
raise ArgumentError, 'Parameter encapsulation can be set only on '\
|
376
|
+
'subinterfaces'
|
377
|
+
end
|
378
|
+
unless name.downcase =~ /et|po/
|
379
|
+
raise ArgumentError, 'Parameter encapsulation can be set only on '\
|
380
|
+
'Ethernet and PostChannel interfaces'
|
381
|
+
end
|
382
|
+
commands = command_builder('encapsulation dot1q vlan', opts)
|
383
|
+
configure_interface(name, commands)
|
384
|
+
end
|
385
|
+
|
318
386
|
##
|
319
387
|
# set_shutdown configures the administrative state of the specified
|
320
388
|
# interface in the node. If the enable keyword is false, then the
|
@@ -340,10 +408,10 @@ module Rbeapi
|
|
340
408
|
#
|
341
409
|
# @return [Boolean] Returns true if the command completed successfully.
|
342
410
|
def set_shutdown(name, opts = {})
|
343
|
-
|
411
|
+
raise 'set_shutdown has the value option set' if opts[:value]
|
344
412
|
# Shutdown semantics are opposite of enable semantics so invert enable.
|
345
413
|
value = !opts[:enable]
|
346
|
-
opts
|
414
|
+
opts[:enable] = value
|
347
415
|
commands = command_builder('shutdown', opts)
|
348
416
|
configure_interface(name, commands)
|
349
417
|
end
|
@@ -374,9 +442,9 @@ module Rbeapi
|
|
374
442
|
# The EthernetInterface class manages all Ethernet interfaces on an
|
375
443
|
# EOS node.
|
376
444
|
class EthernetInterface < BaseInterface
|
377
|
-
DEFAULT_ETH_FLOWC_TX = 'off'
|
378
|
-
DEFAULT_ETH_FLOWC_RX = 'off'
|
379
|
-
DEFAULT_SPEED = 'default'
|
445
|
+
DEFAULT_ETH_FLOWC_TX = 'off'.freeze
|
446
|
+
DEFAULT_ETH_FLOWC_RX = 'off'.freeze
|
447
|
+
DEFAULT_SPEED = 'default'.freeze
|
380
448
|
DEFAULT_LACP_PRIORITY = 32_768
|
381
449
|
|
382
450
|
##
|
@@ -388,6 +456,7 @@ module Rbeapi
|
|
388
456
|
# name: <string>,
|
389
457
|
# type: <string>,
|
390
458
|
# description: <string>,
|
459
|
+
# encapsulation: <integer>,
|
391
460
|
# shutdown: <boolean>,
|
392
461
|
# load_interval: <string>
|
393
462
|
# speed: <string>,
|
@@ -509,14 +578,19 @@ module Rbeapi
|
|
509
578
|
##
|
510
579
|
# create overrides the create method from the BaseInterface and raises
|
511
580
|
# an exception because Ethernet interface creation is not supported.
|
581
|
+
# This doesn't happen for Ethernet subinterfaces
|
512
582
|
#
|
513
|
-
# @param
|
583
|
+
# @param name [String] The name of the interface.
|
514
584
|
#
|
515
585
|
# @raise [NotImplementedError] Creation of physical Ethernet interfaces
|
516
|
-
# is not supported.
|
517
|
-
def create(
|
518
|
-
|
519
|
-
|
586
|
+
# is not supported. Only subinterfaces are allowed.
|
587
|
+
def create(name)
|
588
|
+
if name !~ /\./
|
589
|
+
raise NotImplementedError, 'creating Ethernet interfaces is '\
|
590
|
+
'not supported'
|
591
|
+
else
|
592
|
+
configure("interface #{name}")
|
593
|
+
end
|
520
594
|
end
|
521
595
|
|
522
596
|
##
|
@@ -524,13 +598,17 @@ module Rbeapi
|
|
524
598
|
# raises an exception because Ethernet interface deletion is not
|
525
599
|
# supported.
|
526
600
|
#
|
527
|
-
# @param
|
601
|
+
# @param name [String] The name of the interface.
|
528
602
|
#
|
529
603
|
# @raise [NotImplementedError] Deletion of physical Ethernet interfaces
|
530
604
|
# is not supported.
|
531
|
-
def delete(
|
532
|
-
|
533
|
-
|
605
|
+
def delete(name)
|
606
|
+
if name !~ /\./
|
607
|
+
raise NotImplementedError, 'deleting Ethernet interfaces is '\
|
608
|
+
'not supported'
|
609
|
+
else
|
610
|
+
configure("no interface #{name}")
|
611
|
+
end
|
534
612
|
end
|
535
613
|
|
536
614
|
##
|
@@ -720,9 +798,9 @@ module Rbeapi
|
|
720
798
|
# The PortchannelInterface class manages all port channel interfaces on an
|
721
799
|
# EOS node.
|
722
800
|
class PortchannelInterface < BaseInterface
|
723
|
-
DEFAULT_LACP_FALLBACK = 'disabled'
|
724
|
-
DEFAULT_LACP_MODE = 'on'
|
725
|
-
DEFAULT_MIN_LINKS = '0'
|
801
|
+
DEFAULT_LACP_FALLBACK = 'disabled'.freeze
|
802
|
+
DEFAULT_LACP_MODE = 'on'.freeze
|
803
|
+
DEFAULT_MIN_LINKS = '0'.freeze
|
726
804
|
|
727
805
|
##
|
728
806
|
# get returns the specified port-channel interface configuration from
|
@@ -734,6 +812,7 @@ module Rbeapi
|
|
734
812
|
# {
|
735
813
|
# type: 'portchannel'
|
736
814
|
# description: <string>
|
815
|
+
# encapsulation: <integer>
|
737
816
|
# shutdown: [true, false]
|
738
817
|
# load_interval: <string>
|
739
818
|
# members: array[<strings>]
|
@@ -861,6 +940,7 @@ module Rbeapi
|
|
861
940
|
# @return [Hash<Symbol, Object>] Returns the resource hash attribute.
|
862
941
|
def parse_lacp_timeout(config)
|
863
942
|
mdata = /lacp fallback timeout (\d+)$/.match(config)
|
943
|
+
return { lacp_timeout: [] } unless defined? mdata[1]
|
864
944
|
{ lacp_timeout: mdata[1] }
|
865
945
|
end
|
866
946
|
private :parse_lacp_timeout
|
@@ -925,7 +1005,7 @@ module Rbeapi
|
|
925
1005
|
#
|
926
1006
|
# @return [Boolean] Returns true if the command completed successfully.
|
927
1007
|
def set_members(name, members, mode = nil)
|
928
|
-
|
1008
|
+
raise ArgumentError, 'members must be an Array' unless
|
929
1009
|
members.is_a?(Array)
|
930
1010
|
|
931
1011
|
current_members = Set.new parse_members(name)[:members]
|
@@ -1091,8 +1171,8 @@ module Rbeapi
|
|
1091
1171
|
##
|
1092
1172
|
# The VxlanInterface class manages all Vxlan interfaces on an EOS node.
|
1093
1173
|
class VxlanInterface < BaseInterface
|
1094
|
-
DEFAULT_SRC_INTF = ''
|
1095
|
-
DEFAULT_MCAST_GRP = ''
|
1174
|
+
DEFAULT_SRC_INTF = ''.freeze
|
1175
|
+
DEFAULT_MCAST_GRP = ''.freeze
|
1096
1176
|
|
1097
1177
|
##
|
1098
1178
|
# Returns the Vxlan interface configuration as a Ruby hash of key/value
|
@@ -1105,6 +1185,7 @@ module Rbeapi
|
|
1105
1185
|
# name: <string>,
|
1106
1186
|
# type: <string>,
|
1107
1187
|
# description: <string>,
|
1188
|
+
# encapsulation: <string>,
|
1108
1189
|
# shutdown: <boolean>,
|
1109
1190
|
# load_interval: <string>
|
1110
1191
|
# source_interface: <string>,
|
@@ -1374,5 +1455,86 @@ module Rbeapi
|
|
1374
1455
|
configure_interface(name, "no vxlan vlan #{vlan} vni")
|
1375
1456
|
end
|
1376
1457
|
end
|
1458
|
+
|
1459
|
+
##
|
1460
|
+
# The VlanInterface class manages all Vlan interfaces on an EOS node.
|
1461
|
+
class VlanInterface < BaseInterface
|
1462
|
+
##
|
1463
|
+
# Returns the Vlan interface configuration as a Ruby hash of key/value
|
1464
|
+
# pairs from the nodes running configuration. This method extends the
|
1465
|
+
# BaseInterface get method and adds the Vlan specific attributes to
|
1466
|
+
# the hash.
|
1467
|
+
#
|
1468
|
+
# @example
|
1469
|
+
# {
|
1470
|
+
# name: <string>,
|
1471
|
+
# type: <string>,
|
1472
|
+
# description: <string>,
|
1473
|
+
# shutdown: <boolean>,
|
1474
|
+
# autostate: <boolean>
|
1475
|
+
# }
|
1476
|
+
#
|
1477
|
+
# @param name [String] The interface name to return from the nodes
|
1478
|
+
# configuration.
|
1479
|
+
#
|
1480
|
+
# @return [nil, Hash<String, String>] Returns the interface configuration
|
1481
|
+
# as a Ruby hash object. If the provided interface name is not found
|
1482
|
+
# then this method will return nil.
|
1483
|
+
def get(name)
|
1484
|
+
config = get_block("interface #{name}")
|
1485
|
+
return nil unless config
|
1486
|
+
|
1487
|
+
response = super(name)
|
1488
|
+
response[:type] = 'vlan'
|
1489
|
+
response.merge!(parse_autostate(config))
|
1490
|
+
response
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
##
|
1494
|
+
# parse_autostate scans the interface config block and returns the
|
1495
|
+
# value of the vlan autostate. If the autostate is not
|
1496
|
+
# configured then it's enabled, as by default. The hash
|
1497
|
+
# returned is intended to be merged into the interface resource hash
|
1498
|
+
#
|
1499
|
+
# @api private
|
1500
|
+
#
|
1501
|
+
# @param config [String] The interface configuration block to extract
|
1502
|
+
# the vlan autostate value from.
|
1503
|
+
#
|
1504
|
+
# @return [Hash<Symbol, Object>]
|
1505
|
+
def parse_autostate(config)
|
1506
|
+
mdata = /^\s{3}no\sautostate$/.match(config)
|
1507
|
+
{ autostate: mdata.nil? ? :true : :false }
|
1508
|
+
end
|
1509
|
+
private :parse_autostate
|
1510
|
+
|
1511
|
+
##
|
1512
|
+
# set_autostate configures the autostate on a vlan interface.
|
1513
|
+
# Default value is true, if set to false 'no autostate' is
|
1514
|
+
# configured on the interface.
|
1515
|
+
#
|
1516
|
+
# @since eos_version 4.13.7M
|
1517
|
+
#
|
1518
|
+
# @param name [String] The interface name to apply the configuration
|
1519
|
+
# values to. The name must be the full interface identifier.
|
1520
|
+
#
|
1521
|
+
# @param opts [Hash] Optional keyword arguments.
|
1522
|
+
#
|
1523
|
+
# @option opts value [Boolean] Enables or disables autotate for vlan
|
1524
|
+
# interfaces. Default is true.
|
1525
|
+
#
|
1526
|
+
# @option opts default [Boolean] Configures the autostate value
|
1527
|
+
# on the interface using the default value (true).
|
1528
|
+
#
|
1529
|
+
# @return [Boolean] Returns true if the command completed successfully.
|
1530
|
+
def set_autostate(name, opts = {})
|
1531
|
+
commands = if opts[:value] == :false
|
1532
|
+
command_builder('no autostate')
|
1533
|
+
else
|
1534
|
+
command_builder('autostate')
|
1535
|
+
end
|
1536
|
+
configure_interface(name, commands)
|
1537
|
+
end
|
1538
|
+
end
|
1377
1539
|
end
|
1378
1540
|
end
|