Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
4c83215
Structured output needs to handle nil value cases
mikewiebe Apr 17, 2018
3efa684
Update changelog with Unreleased Tag
mikewiebe Apr 19, 2018
d6790be
New dev version 1.10.0
mikewiebe Apr 19, 2018
be6fd86
Merge pull request #580 from cisco/rel190/hdev_fixes
rahushen Apr 20, 2018
d0dbb94
Set host_reachability correctly when setting ingress_replication
mikewiebe May 7, 2018
e3a4ca2
Review comments
mikewiebe May 7, 2018
4543f46
Merge pull request #581 from cisco/rel200/fix_vxlan_vtep_vni
rahushen May 7, 2018
a8ac59a
Add 9.2 version check for additional_paths_send
mikewiebe Jun 1, 2018
26e29a8
Add 7_0_3_I7_4 support
mikewiebe Jun 15, 2018
8e1c022
Address default behavior change
mikewiebe Jun 18, 2018
74af32f
Make robocop happy
mikewiebe Jun 18, 2018
0e5e727
Merge pull request #582 from cisco/rel_1_10_0/fix_multicast
mikewiebe Jun 18, 2018
f949139
Skip legacy defect
mikewiebe Jun 19, 2018
64e90f3
(NETDEV-39) add facility to syslog_server
shermdog Jun 26, 2018
cf96d74
Merge pull request #583 from shermdog/NETDEV-39
mikewiebe Jun 28, 2018
98e6d7c
(FM-7136) exclude add_quotes from entire 7.3 series
shermdog Jun 28, 2018
eb34186
Merge pull request #584 from shermdog/FM-7136
mikewiebe Jul 5, 2018
aead973
Set http port explicitly in setup and cleanup methods
mikewiebe Jul 6, 2018
973fa37
fix cust issues
Jul 10, 2018
1ad7b99
Merge pull request #585 from cisco/cust
shermdog Jul 12, 2018
7acbbb8
(CISCO-71) Add support for banner/motd
shermdog Aug 3, 2018
1d8a29a
(NETDEV-43) add syslog_facility
shermdog Aug 10, 2018
987b847
Merge pull request #586 from shermdog/CISCO-71
mikewiebe Aug 20, 2018
64427ae
(CISCO-75/76) Fix interface_hsrp_group
shermdog Aug 23, 2018
d5de465
Merge pull request #587 from shermdog/NETDEV-43
mikewiebe Aug 23, 2018
c819444
(NETDEV-46) Add logfile to syslog_settings
Aug 22, 2018
468a26f
fix cisco-72
Aug 24, 2018
9c35935
fix cisco-77
Aug 24, 2018
a6c4c62
doc
Aug 24, 2018
d3a3e81
copyright
Aug 24, 2018
81c9db2
copyright
Aug 24, 2018
7cc9dd5
Merge pull request #591 from cisco/cisco-72
mikewiebe Aug 29, 2018
3f83873
Merge pull request #592 from cisco/cisco-77
mikewiebe Aug 29, 2018
37e4624
(FM-7109) Bump gRPC gem version
shermdog Aug 24, 2018
d532432
(FM-7109) Add ability to dynamically specify environment
shermdog Jun 21, 2018
93e31c2
Merge pull request #589 from shermdog/CISCO-75
mikewiebe Sep 4, 2018
a393fb7
Merge pull request #593 from shermdog/FM-7109
mikewiebe Sep 4, 2018
105d537
Merge pull request #590 from willmeek/NETDEV-44
mikewiebe Sep 6, 2018
7e9e06d
Fix for Cisco-73 (#596)
Sep 11, 2018
1c09c7f
CISCO-74 Fix puppet resource interface defaults (#595)
mikewiebe Sep 13, 2018
7de6a04
(NETDEV-37) Add support for hostname
Sep 6, 2018
71f100a
Merge pull request #594 from willmeek/NETDEV-37
shermdog Sep 13, 2018
2d3bd07
version
Sep 13, 2018
976b201
fixes for n7k failures
Sep 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
Changelog
=========

## [v1.10.0]

### New Cisco Resources

### Added
* Added syslog_facility with attribute:
* `level`
* Extend syslog_server with attribute:
* `facility`
* Extend interface with attributes:
* `ipv6_redirects`
* Extend ace with attributes:
* `proto_option`
* `vlan`
* `set_erspan_dscp`
* `set_erspan_gre_proto`
* Extend network_dns with attributes:
* `hostname`
* Added ability to specify environment at run time

Example:
```ruby
env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
Cisco::Environment.add_env('default', env)
```

### Changed

### Removed

### Issues Addressed
* Removed default values for authentication in `interface_hsrp_group`

## [v1.9.0]

### New Cisco Resources
Expand Down Expand Up @@ -554,6 +587,7 @@ Changelog
[git-flow]: https://github.com/petervanderdoes/gitflow-avh
[SimpleCov]: https://github.com/colszowka/simplecov

[v1.10.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.9.0...v1.10.0
[v1.9.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.8.0...v1.9.0
[v1.8.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.7.0...v1.8.0
[v1.7.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.6.0...v1.7.0
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ An example configuration file (illustrating each of the above scenarios) is prov

*For security purposes, it is highly recommended that access to this file be restricted to only the owning user (`chmod 0600`).*

Configuration may also be specified at runtime and can be used in the absence of configuration files or to override them.

Example:
```ruby
env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
Cisco::Environment.add_env('default', env)
```

## <a name="documentation">Documentation</a>

### Client
Expand Down Expand Up @@ -151,12 +159,18 @@ client2 = Cisco::Client.create('n9k')
# Warning: Make sure to exclude devices using the 'no_proxy' environment variable
# to ensure successful remote connections.

# Add runtime configuration for remote device and connect
env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
Cisco::Environment.add_env('remote', env)
client3 = Cisco::Client.create('remote')

# Use connections to get and set device state.
client1.set(values: 'feature vtp')
client1.set(values: 'vtp domain mycompany.com')
puts client1.get(command: 'show vtp status | inc Domain')

puts client2.get(command: 'show version')
puts client3.get(command: 'show version')
```

#### High-level Node API
Expand Down
2 changes: 1 addition & 1 deletion ext/mkrf_conf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
os == 'ios_xr' || deps << Gem::Dependency.new('net_http_unix',
'~> 0.2', '>= 0.2.1')
# NX-OS doesn't need gRPC
os == 'nexus' || deps << Gem::Dependency.new('grpc', '~> 0.12')
os == 'nexus' || deps << Gem::Dependency.new('grpc', '~> 1.14.1')

deps.each do |dep|
installed = dep.matching_specs
Expand Down
149 changes: 142 additions & 7 deletions lib/cisco_node_utils/ace.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
# Copyright (c) 2015-2018 Cisco and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

require 'ipaddr'
require_relative 'node_util'

module Cisco
Expand Down Expand Up @@ -73,6 +74,9 @@ def ace_get
remark = Regexp.new('(?<seqno>\d+) remark (?<remark>.*)').match(str)
return remark unless remark.nil?

# specialized icmp protocol handling
return icmp_ace_get(str) if str.include?('icmp')

# rubocop:disable Metrics/LineLength
regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
' *(?<proto>\d+|\S+)'\
Expand All @@ -95,6 +99,60 @@ def ace_get
regexp.match(str)
end

# icmp ace getter
def icmp_ace_get(str)
# rubocop:disable Metrics/LineLength
# fragments is nvgen at a different location than all other
# proto_option so get rid of it so as not to mess up other fields
str.sub!('fragments ', '')
regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
' *(?<proto>\d+|\S+)'\
' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
' *(?<proto_option>\S+)?'\
' *(?<precedence>precedence \S+)?'\
' *(?<dscp>dscp \S+)?'\
' *(?<time_range>time-range \S+)?'\
' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
' *(?<ttl>ttl \d+)?'\
' *(?<vlan>vlan \d+)?'\
' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
' *(?<redirect>redirect \S+)?')
regexp_no_proto_option = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
' *(?<proto>\d+|\S+)'\
' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
' *(?<precedence>precedence \S+)?'\
' *(?<dscp>dscp \S+)?'\
' *(?<time_range>time-range \S+)?'\
' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
' *(?<ttl>ttl \d+)?'\
' *(?<vlan>vlan \d+)?'\
' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
' *(?<redirect>redirect \S+)?')
temp = regexp.match(str)
po = temp[:proto_option]
if po.nil?
return temp
# redirect can be proto_option or an actual redirect to interface
elsif po.strip.match(/redirect$/)
if str.match(/Ethernet|port-channel/)
# if proto_option is given as redirect and also redirect to intf
# we need to do extra processing
return temp if check_redirect_repeat(str)
return regexp_no_proto_option.match(str)
end
# the reserved keywords check
elsif po.strip.match(/precedence$|dscp$|time-range$|packet-length$|ttl$|vlan$|set-erspan-gre-proto$|set-erspan-dscp$|log$/)
return regexp_no_proto_option.match(str)
else
return temp
end
# rubocop:enable Metrics/LineLength
end

# common ace setter. Put the values you need in a hash and pass it in.
# attrs = {:action=>'permit', :proto=>'tcp', :src =>'host 1.1.1.1'}
def ace_set(attrs)
Expand Down Expand Up @@ -130,6 +188,10 @@ def ace_set(attrs)
:tcp_option_length,
:redirect,
:log,
:proto_option,
:set_erspan_dscp,
:set_erspan_gre_proto,
:vlan,
].each do |p|
attrs[p] = '' if attrs[p].nil?
send(p.to_s + '=', attrs[p])
Expand All @@ -139,6 +201,21 @@ def ace_set(attrs)
config_set('acl', cmd, @set_args)
end

def valid_ipv6?(addr)
begin
ret = IPAddr.new(addr.split[0]).ipv6?
rescue
ret = false
end
ret
end

def check_redirect_repeat(str)
return false unless str.include?('redirect')
nstr = str.sub('redirect', '').strip
nstr.include?('redirect') ? true : false
end

# PROPERTIES
# ----------
def seqno
Expand Down Expand Up @@ -182,7 +259,7 @@ def src_addr
return nil if match.nil? || !match.names.include?('src_addr')
addr = match[:src_addr]
# Normalize addr. Some platforms zero_pad ipv6 addrs.
addr.gsub!(/^0*/, '').gsub!(/:0*/, ':')
addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
addr
end

Expand All @@ -205,7 +282,7 @@ def dst_addr
return nil if match.nil? || !match.names.include?('dst_addr')
addr = match[:dst_addr]
# Normalize addr. Some platforms zero_pad ipv6 addrs.
addr.gsub!(/^0*/, '').gsub!(/:0*/, ':')
addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
addr
end

Expand Down Expand Up @@ -261,6 +338,49 @@ def dscp=(dscp)
@set_args[:dscp] = Utils.attach_prefix(dscp, :dscp)
end

def vlan
Utils.extract_value(ace_get, 'vlan')
end

def vlan=(vlan)
@set_args[:vlan] = Utils.attach_prefix(vlan, :vlan)
end

def set_erspan_dscp
ret = Utils.extract_value(ace_get, 'set_erspan_dscp', 'set-erspan-dscp')
return ret if ret
# position of set_erspan_dscp is different in older release so check again
str = config_get('acl', 'ace', @get_args)
sstr = str.split
return sstr[sstr.index('set-erspan-dscp') + 1] if
sstr.include?('set-erspan-dscp')
end

def set_erspan_dscp=(set_erspan_dscp)
@set_args[:set_erspan_dscp] = Utils.attach_prefix(set_erspan_dscp,
:set_erspan_dscp,
'set-erspan-dscp')
end

def set_erspan_gre_proto
ret = Utils.extract_value(ace_get, 'set_erspan_gre_proto',
'set-erspan-gre-proto')
return ret if ret
# position of set_erspan_gre_proto is different in older release
# so check again
str = config_get('acl', 'ace', @get_args)
sstr = str.split
return sstr[sstr.index('set-erspan-gre-proto') + 1] if
sstr.include?('set-erspan-gre-proto')
end

def set_erspan_gre_proto=(set_erspan_gre_proto)
@set_args[:set_erspan_gre_proto] =
Utils.attach_prefix(set_erspan_gre_proto,
:set_erspan_gre_proto,
'set-erspan-gre-proto')
end

def time_range
Utils.extract_value(ace_get, 'time_range', 'time-range')
end
Expand Down Expand Up @@ -317,12 +437,27 @@ def redirect=(redirect)
@set_args[:redirect] = Utils.attach_prefix(redirect, :redirect)
end

def log
def proto_option
match = ace_get
return nil if match.nil? || proto != 'icmp' || !remark.nil?
# fragments is nvgen at a different location than all other
# proto_option
if config_get('acl', 'ace', @get_args).include?('fragments')
return 'fragments'
end
# log is special case
return nil if !match.names.include?('proto_option') ||
match[:proto_option] == 'log'
match[:proto_option]
end

def proto_option=(proto_option)
@set_args[:proto_option] = proto_option
end

def log
return nil unless remark.nil?
return false if match.nil?
return false unless match.names.include?('log')
match[:log] == 'log' ? true : false
config_get('acl', 'ace', @get_args).include?('log') ? true : false
end

def log=(log)
Expand Down
63 changes: 63 additions & 0 deletions lib/cisco_node_utils/banner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Banner provider class
#
# Rick Sherman et al., August 2018
#
# Copyright (c) 2014-2018 Cisco and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require_relative 'node_util'

module Cisco
# Banner - node utility class for Banner configuration management
class Banner < NodeUtil
attr_reader :name

def initialize(name)
fail TypeError unless name.is_a?(String)
fail ArgumentError,
"This provider only accepts an id of 'default'" \
unless name.eql?('default')
@name = name
end

def self.banners
hash = {}
hash['default'] = Banner.new('default')
hash
end

def ==(other)
name == other.name
end

def motd
config_get('banner', 'motd')
end

def motd=(val)
if val.nil? && (motd != default_motd)
config_set('banner', 'motd', state: 'no', motd: '')
elsif !val.nil?
config_set('banner',
'motd',
state: '',
motd: "^#{val.gsub(/\n/, '\\n')}^")
end
end

def default_motd
config_get_default('banner', 'motd')
end
end # class
end # module
2 changes: 1 addition & 1 deletion lib/cisco_node_utils/bridge_domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def default_bd_name
# This type property can be defined only for one bd
def fabric_control
match = config_get('bridge_domain', 'fabric_control', bd: @bd_ids)
match == @bd_ids ? true : false
match.to_s == @bd_ids ? true : false
end

def fabric_control=(val)
Expand Down
2 changes: 1 addition & 1 deletion lib/cisco_node_utils/cisco_cmn_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def self.merge_range(range)
end # merge_range

def self.add_quotes(value)
return value if image_version?(/7.3.0/)
return value if image_version?(/7.3/)
value = "\"#{value}\"" unless
value.start_with?('"') && value.end_with?('"')
value
Expand Down
Loading