From 835dc0781cbbeada03fcb7d633734f1a00f1516b Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Mon, 13 Mar 2017 19:10:11 -0400 Subject: [PATCH 01/13] Add destroy = default for physical ints --- lib/cisco_node_utils/cmd_ref/interface.yaml | 7 +++++++ lib/cisco_node_utils/interface.rb | 11 ++++++++++- tests/test_interface.rb | 12 ++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/cisco_node_utils/cmd_ref/interface.yaml b/lib/cisco_node_utils/cmd_ref/interface.yaml index c1e57e8f..12127668 100644 --- a/lib/cisco_node_utils/cmd_ref/interface.yaml +++ b/lib/cisco_node_utils/cmd_ref/interface.yaml @@ -40,6 +40,13 @@ create: set_context: ~ set_value: "interface " +default: + multiple: + set_context: ~ + set_value: "default interface " + get_command: "show running interface " + get_value: '/(.*)/' + description: kind: string get_value: '/^description (.*)/' diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 16563bd1..04b36ff6 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -141,7 +141,16 @@ def create end def destroy - config_set('interface', 'destroy', name: @name) + if @name[/ethernet/] + config_set('interface', 'default', name: @name) + else + config_set('interface', 'destroy', name: @name) + end + end + + def default? + state = config_get('interface', 'default', name: @name) + state.nil? ? true : false end def pvlan_enable diff --git a/tests/test_interface.rb b/tests/test_interface.rb index 991cfc43..747aa045 100755 --- a/tests/test_interface.rb +++ b/tests/test_interface.rb @@ -1833,4 +1833,16 @@ def test_load_interval_counter_3_delay subif.destroy lb.destroy end + + def test_destroy_physical + name = interfaces[0] + int = Interface.new(name) + + int.description = 'destroy_pysical' + int.ipv4_addr_mask_set('192.168.0.1', '24') + refute(int.default?) + + int.destroy + assert(int.default?) + end end From 092e65f00086e4a35608cbc853cce7c071cfa219 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 3 Oct 2017 16:58:05 -0400 Subject: [PATCH 02/13] Extend test_default_physical int test --- tests/test_interface.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/test_interface.rb b/tests/test_interface.rb index eac0d0d4..a3d428ba 100755 --- a/tests/test_interface.rb +++ b/tests/test_interface.rb @@ -1837,17 +1837,28 @@ def test_load_interval_counter_3_delay lb.destroy end - def test_destroy_physical + def test_default_physical name = interfaces[0] int = Interface.new(name) + int.switchport_mode = :disabled - int.description = 'destroy_pysical' + # Verify l3 -> default + int.description = 'default_pysical' int.ipv4_addr_mask_set('192.168.0.1', '24') refute(int.default?) int.destroy assert(int.default?) + # Verify l2 trunk -> default + int.switchport_mode = :access + int.switchport_autostate_exclude = true + refute(int.default?) + + int.destroy + assert(int.default?) + end + def test_purge_config name = interfaces[0] int = Interface.new(name) From 6023a1ba06011f347a5d72230832e5846ea9c7cc Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Wed, 4 Oct 2017 12:29:51 -0400 Subject: [PATCH 03/13] Keep track of interface default state --- lib/cisco_node_utils/interface.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 96d7febe..bee76d9c 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -51,7 +51,7 @@ class Interface < Cisco::InterfaceDeprecated # Regexp to match various link bundle interface variants PORTCHANNEL = Regexp.new('(port-channel|Bundle-Ether)', Regexp::IGNORECASE) - attr_reader :name + attr_reader :name, :state_default def initialize(name, instantiate=true) fail TypeError unless name.is_a?(String) @@ -60,6 +60,13 @@ def initialize(name, instantiate=true) @smr = config_get('interface', 'stp_mst_range') @svr = config_get('interface', 'stp_vlan_range') @match_found = false + # Keep track of default vs non-default state for + # interfaces that cannot be created/destroyed. + @state_default = nil + # Track ethernet but not sub-interfaces + if @name[/ethernet/] && !@name[/ethernet.*\.\d+/] + @state_default = default? + end create if instantiate end From 7666f63e2ce900fbf9a7bdef2fce319afbbd88e7 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Wed, 4 Oct 2017 16:27:15 -0400 Subject: [PATCH 04/13] Sub-interfaces should be destroyed --- lib/cisco_node_utils/interface.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index bee76d9c..b8babb57 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -148,7 +148,7 @@ def create end def destroy - if @name[/ethernet/] + if @name[/ethernet/] && !@name[/ethernet.*\.\d+/] config_set('interface', 'default', name: @name) else config_set('interface', 'destroy', name: @name) From 40b524b69132ba36fb9499f26dab0496d95ea05f Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Mon, 9 Oct 2017 09:45:43 -0400 Subject: [PATCH 05/13] Add 8.2 version to test_bgp_af.rb --- tests/test_bgp_af.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_bgp_af.rb b/tests/test_bgp_af.rb index daa78cc1..1b2f649c 100644 --- a/tests/test_bgp_af.rb +++ b/tests/test_bgp_af.rb @@ -170,7 +170,7 @@ def check_test_exceptions(test_, os_, vrf_, af_) # triggers a version check below. if expect == :runtime case Platform.image_version - when /8.0|8.1/ + when /8.0|8.1|8.2/ expect = :success when /I5.2|I5.3|I6/ expect = :success if test == :maximum_paths || test == :maximum_paths_ibgp From a6d3e5c5e54f5a3fa7757b564e593d89a700c4e4 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Mon, 9 Oct 2017 15:43:15 -0400 Subject: [PATCH 06/13] Fix interface dhcp and vtp properties --- lib/cisco_node_utils/interface.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index b8babb57..1ea34951 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -595,6 +595,7 @@ def ipv4_dhcp_relay_info_trust end def ipv4_dhcp_relay_info_trust=(state) + return false if !state && !Feature.dhcp_enabled? Feature.dhcp_enable if state config_set('interface', 'ipv4_dhcp_relay_info_trust', name: @name, state: state ? '' : 'no') @@ -609,6 +610,7 @@ def ipv4_dhcp_relay_src_addr_hsrp end def ipv4_dhcp_relay_src_addr_hsrp=(state) + return false if !state && !Feature.dhcp_enabled? Feature.dhcp_enable if state config_set('interface', 'ipv4_dhcp_relay_src_addr_hsrp', name: @name, state: state ? '' : 'no') @@ -627,8 +629,9 @@ def ipv4_dhcp_relay_src_intf def ipv4_dhcp_relay_src_intf=(val) state = val == default_ipv4_dhcp_relay_src_intf ? 'no' : '' - intf = val == default_ipv4_dhcp_relay_src_intf ? '' : val + return false if state == 'no' && !Feature.dhcp_enabled? Feature.dhcp_enable if state.empty? + intf = val == default_ipv4_dhcp_relay_src_intf ? '' : val config_set('interface', 'ipv4_dhcp_relay_src_intf', name: @name, state: state, intf: intf) end @@ -642,6 +645,7 @@ def ipv4_dhcp_relay_subnet_broadcast end def ipv4_dhcp_relay_subnet_broadcast=(state) + return false if !state && !Feature.dhcp_enabled? Feature.dhcp_enable if state config_set('interface', 'ipv4_dhcp_relay_subnet_broadcast', name: @name, state: state ? '' : 'no') @@ -656,6 +660,7 @@ def ipv4_dhcp_smart_relay end def ipv4_dhcp_smart_relay=(state) + return false if !state && !Feature.dhcp_enabled? Feature.dhcp_enable if state config_set('interface', 'ipv4_dhcp_smart_relay', name: @name, state: state ? '' : 'no') @@ -804,8 +809,9 @@ def ipv6_dhcp_relay_src_intf def ipv6_dhcp_relay_src_intf=(val) state = val == default_ipv6_dhcp_relay_src_intf ? 'no' : '' - intf = val == default_ipv6_dhcp_relay_src_intf ? '' : val + return false if state == 'no' && !Feature.dhcp_enabled? Feature.dhcp_enable if state.empty? + intf = val == default_ipv6_dhcp_relay_src_intf ? '' : val config_set('interface', 'ipv6_dhcp_relay_src_intf', name: @name, state: state, intf: intf) end @@ -1848,6 +1854,7 @@ def switchport_vtp=(vtp_set) # TODO: throw UnsupportedError instead of returning false? return false unless switchport_vtp_mode_capable? no_cmd = (vtp_set) ? '' : 'no' + return false unless Feature.vtp_enabled? && no_cmd == '' config_set('interface', 'vtp', name: @name, state: no_cmd) end From 10ba5cc90703a5b7905e15f33fc9b8cf8dd05e47 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Mon, 9 Oct 2017 18:55:41 -0400 Subject: [PATCH 07/13] Improve int collection performance --- lib/cisco_node_utils/cmd_ref/interface.yaml | 5 ++++- lib/cisco_node_utils/interface.rb | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/cisco_node_utils/cmd_ref/interface.yaml b/lib/cisco_node_utils/cmd_ref/interface.yaml index 88c994e8..7f55f8bd 100644 --- a/lib/cisco_node_utils/cmd_ref/interface.yaml +++ b/lib/cisco_node_utils/cmd_ref/interface.yaml @@ -18,8 +18,11 @@ all_interfaces: multiple: ios_xr: get_command: 'show running all-interfaces' + get_value: '/^interface (.*)/' + nexus: + get_command: "show running-config interface | section '^interface'" + get_value: '/(.*)/' get_context: ~ - get_value: '/^interface (.*)/' bfd_echo: _exclude: [ios_xr] diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 1ea34951..74bfe048 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -53,7 +53,7 @@ class Interface < Cisco::InterfaceDeprecated attr_reader :name, :state_default - def initialize(name, instantiate=true) + def initialize(name, instantiate=true, default_state=false) fail TypeError unless name.is_a?(String) fail ArgumentError unless name.length > 0 @name = name.downcase @@ -65,7 +65,7 @@ def initialize(name, instantiate=true) @state_default = nil # Track ethernet but not sub-interfaces if @name[/ethernet/] && !@name[/ethernet.*\.\d+/] - @state_default = default? + @state_default = default_state end create if instantiate end @@ -79,10 +79,14 @@ def self.interfaces(opt=nil) intf_list = config_get('interface', 'all_interfaces') return hash if intf_list.nil? + intf_list = intf_list.to_s.split('interface') intf_list.each do |id| - id = id.downcase + int_data = id.delete('"').split(',').select { |f| /\S+/.match(f) } + id = int_data[0].strip.downcase + next if id[/\[/] next if opt && filter(opt, id) - hash[id] = Interface.new(id, false) + default_state = int_data.size > 1 ? false : true + hash[id] = Interface.new(id, false, default_state) end hash end From 7b1520cce530bc448c1b88d87a60e4a6fcac48a4 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 10 Oct 2017 12:48:36 -0400 Subject: [PATCH 08/13] switchport_vtp and interface_ospf collection fixes --- lib/cisco_node_utils/cmd_ref/interface_ospf.yaml | 5 +++++ lib/cisco_node_utils/interface.rb | 3 ++- lib/cisco_node_utils/interface_ospf.rb | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml b/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml index 2a5a83a1..7fcf8843 100644 --- a/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +++ b/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml @@ -6,6 +6,11 @@ _template: get_command: 'show running interface all' context: ["interface %s"] +all_interfaces: + multiple: + get_context: ~ + get_value: '/^interface (.*)/' + area: get_value: '/^\s*ip router ospf (\S+) area (\S+)/' set_value: "%s ip router ospf %s area %s" diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 74bfe048..31cf9c89 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -1857,8 +1857,9 @@ def switchport_vtp def switchport_vtp=(vtp_set) # TODO: throw UnsupportedError instead of returning false? return false unless switchport_vtp_mode_capable? + return false if !vtp_set && !Feature.vtp_enabled? + Feature.vtp_enable if vtp_set no_cmd = (vtp_set) ? '' : 'no' - return false unless Feature.vtp_enabled? && no_cmd == '' config_set('interface', 'vtp', name: @name, state: no_cmd) end diff --git a/lib/cisco_node_utils/interface_ospf.rb b/lib/cisco_node_utils/interface_ospf.rb index 8f7f48ce..aec02a1b 100644 --- a/lib/cisco_node_utils/interface_ospf.rb +++ b/lib/cisco_node_utils/interface_ospf.rb @@ -53,7 +53,7 @@ def self.interfaces(ospf_name=nil) fail TypeError unless ospf_name.is_a?(String) || ospf_name.nil? ints = {} - intf_list = config_get('interface', 'all_interfaces') + intf_list = config_get('interface_ospf', 'all_interfaces') return ints if intf_list.nil? intf_list.each do |name| match = config_get('interface_ospf', 'area', name) From d1964337cf10d961e2a7ac5f276c048fd84566a9 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 10 Oct 2017 14:04:46 -0400 Subject: [PATCH 09/13] interface_portchannel fixes --- lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml | 5 +++++ lib/cisco_node_utils/interface_portchannel.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml b/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml index 79b864a3..c445f4ac 100644 --- a/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +++ b/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml @@ -7,6 +7,11 @@ _template: get_context: ['/^interface %s$/i'] set_context: ["interface %s"] +all_interfaces: + multiple: + get_context: ~ + get_value: '/^interface (.*)/' + bfd_per_link: kind: boolean get_value: '/^bfd per-link$/' diff --git a/lib/cisco_node_utils/interface_portchannel.rb b/lib/cisco_node_utils/interface_portchannel.rb index 16f803f5..a4fc568e 100644 --- a/lib/cisco_node_utils/interface_portchannel.rb +++ b/lib/cisco_node_utils/interface_portchannel.rb @@ -38,7 +38,7 @@ def to_s def self.interfaces hash = {} - intf_list = config_get('interface', 'all_interfaces') + intf_list = config_get('interface_portchannel', 'all_interfaces') return hash if intf_list.nil? intf_list.each do |id| From e3e9f93dfe92698ab589f6e19b9325746c2f63a2 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 10 Oct 2017 16:50:18 -0400 Subject: [PATCH 10/13] Fix bug in self.interfaces method --- lib/cisco_node_utils/interface.rb | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 31cf9c89..4978e090 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -79,12 +79,21 @@ def self.interfaces(opt=nil) intf_list = config_get('interface', 'all_interfaces') return hash if intf_list.nil? - intf_list = intf_list.to_s.split('interface') + # Massage intf_list data into an array that is easy + # to work with. + intf_list.collect! { |x| x.strip || x } + intf_list.delete('') + intf_list = intf_list.join(' ').split('interface') + intf_list.delete('') + intf_list.each do |id| - int_data = id.delete('"').split(',').select { |f| /\S+/.match(f) } - id = int_data[0].strip.downcase - next if id[/\[/] + int_data = id.strip.split(' ') + next if int_data[0].nil? + id = int_data[0].downcase next if opt && filter(opt, id) + # If there are any additional options associated + # with this interface then it's in a non-default + # state. default_state = int_data.size > 1 ? false : true hash[id] = Interface.new(id, false, default_state) end From d3a4b4daf8782a21bf03dc892445706e4dfd1425 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Wed, 11 Oct 2017 10:33:32 -0400 Subject: [PATCH 11/13] Set description on ethernet create --- lib/cisco_node_utils/interface.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 4978e090..753a2d82 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -152,6 +152,9 @@ def self.capabilities(intf, mode=:hash) def create feature_vlan_set(true) if @name[/(vlan|bdi)/i] config_set('interface', 'create', name: @name) + if @name[/ethernet/] && !@name[/ethernet.*\.\d+/] + self.description = 'Managed by Puppet' + end rescue Cisco::CliError # Some XR platforms do not support channel-group configuration # on some OS versions. Since this is an OS version difference and not From 0eae2946814e5c1ae5bd5827ea5e98dd90cfe224 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Wed, 11 Oct 2017 12:41:31 -0400 Subject: [PATCH 12/13] Update copyrights --- lib/cisco_node_utils/interface.rb | 2 +- lib/cisco_node_utils/interface_ospf.rb | 2 +- lib/cisco_node_utils/interface_portchannel.rb | 2 +- tests/test_bgp_af.rb | 2 +- tests/test_interface.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 753a2d82..96dc4c0d 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -1,6 +1,6 @@ # November 2015, Chris Van Heuveln # -# Copyright (c) 2015-2016 Cisco and/or its affiliates. +# Copyright (c) 2015-2017 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. diff --git a/lib/cisco_node_utils/interface_ospf.rb b/lib/cisco_node_utils/interface_ospf.rb index aec02a1b..c7568c3d 100644 --- a/lib/cisco_node_utils/interface_ospf.rb +++ b/lib/cisco_node_utils/interface_ospf.rb @@ -1,6 +1,6 @@ # March 2015, Alex Hunsberger # -# Copyright (c) 2015-2016 Cisco and/or its affiliates. +# Copyright (c) 2015-2017 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. diff --git a/lib/cisco_node_utils/interface_portchannel.rb b/lib/cisco_node_utils/interface_portchannel.rb index a4fc568e..5496cf88 100644 --- a/lib/cisco_node_utils/interface_portchannel.rb +++ b/lib/cisco_node_utils/interface_portchannel.rb @@ -1,6 +1,6 @@ # December 2015, Sai Chintalapudi # -# Copyright (c) 2015-2016 Cisco and/or its affiliates. +# Copyright (c) 2015-2017 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. diff --git a/tests/test_bgp_af.rb b/tests/test_bgp_af.rb index 1b2f649c..fc95f2bf 100644 --- a/tests/test_bgp_af.rb +++ b/tests/test_bgp_af.rb @@ -4,7 +4,7 @@ # # Richard Wellum, August, 2015 # -# Copyright (c) 2015-2016 Cisco and/or its affiliates. +# Copyright (c) 2015-2017 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. diff --git a/tests/test_interface.rb b/tests/test_interface.rb index a3d428ba..f5c6d5b0 100755 --- a/tests/test_interface.rb +++ b/tests/test_interface.rb @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2016 Cisco and/or its affiliates. +# Copyright (c) 2013-2017 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. From 7cc35353b0681519a10c642b0201bfd4ebc9cf4e Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 13 Oct 2017 11:47:47 -0400 Subject: [PATCH 13/13] Remove set description in create method --- lib/cisco_node_utils/interface.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/cisco_node_utils/interface.rb b/lib/cisco_node_utils/interface.rb index 96dc4c0d..5db9eaa9 100644 --- a/lib/cisco_node_utils/interface.rb +++ b/lib/cisco_node_utils/interface.rb @@ -152,9 +152,6 @@ def self.capabilities(intf, mode=:hash) def create feature_vlan_set(true) if @name[/(vlan|bdi)/i] config_set('interface', 'create', name: @name) - if @name[/ethernet/] && !@name[/ethernet.*\.\d+/] - self.description = 'Managed by Puppet' - end rescue Cisco::CliError # Some XR platforms do not support channel-group configuration # on some OS versions. Since this is an OS version difference and not