diff --git a/CHANGELOG.md b/CHANGELOG.md
index 763ad39d7..4d716070b 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,23 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
+## [1.6.0] - 2017-03-13
+
+### New feature support
+#### Cisco Resources
+- `cisco_route_map` type and provider.
+- `cisco_upgrade` type and provider.
+
+### Added
+- Extend cisco_interface with attributes:
+ - `load_interval_counter_1_delay`
+ - `load_interval_counter_2_delay`
+ - `load_interval_counter_3_delay`
+
+### Changed
+
+### Removed
+
## [1.5.0] - 2017-01-11
### New feature support
@@ -337,6 +354,7 @@ This version was never released.
- Initial release of puppetlabs-ciscopuppet module, supporting Cisco NX-OS software release 7.0(3)I2(1) on Cisco Nexus switch platforms: N95xx, N93xx, N30xx and N31xx.
- Please note: 0.9.0 is an EFT pre-release for a limited audience with access to NX-OS 7.0(3)I2(1). Additional code changes may occur in 0.9.x prior to the final 1.0.0 release.
+[1.6.0]: https://github.com/cisco/cisco-network-puppet-module/compare/v1.5.0...v1.6.0
[1.5.0]: https://github.com/cisco/cisco-network-puppet-module/compare/v1.4.1...v1.5.0
[1.4.1]: https://github.com/cisco/cisco-network-puppet-module/compare/v1.4.0...v1.4.1
[1.4.0]: https://github.com/cisco/cisco-network-puppet-module/compare/v1.3.2...v1.4.0
diff --git a/README.md b/README.md
index d2d193d0f..fbcd83341 100644
--- a/README.md
+++ b/README.md
@@ -147,6 +147,7 @@ The following resources include cisco types and providers along with cisco provi
* Miscellaneous Types
* [`cisco_command_config`](#type-cisco_command_config)
* [`cisco_vdc`](#type-cisco_vdc)
+ * [`cisco_upgrade`](#type-cisco_upgrade)
* AAA Types
* [`cisco_aaa_authentication_login`](#type-cisco_aaa_authentication_login)
@@ -232,6 +233,9 @@ The following resources include cisco types and providers along with cisco provi
* [`radius_server (netdev_stdlib)`](#type-radius_server)
* [`radius_server_group (netdev_stdlib)`](#type-radius_server_group)
+* RouteMap Types
+ * [`cisco_route_map`](#type-cisco_route_map)
+
* STP Types
* [`cisco_stp_global`](#type-cisco_stp_global)
@@ -323,6 +327,7 @@ The following resources include cisco types and providers along with cisco provi
* [`cisco_pim_grouplist`](#type-cisco_pim_grouplist)
* [`cisco_pim_rp_address`](#type-cisco_pim_rp_address)
* [`cisco_portchannel_global`](#type-cisco_portchannel_global)
+* [`cisco_route_map`](#type-cisco_route_map)
* [`cisco_stp_global`](#type-cisco_stp_global)
* [`cisco_snmp_community`](#type-cisco_snmp_community)
* [`cisco_snmp_group`](#type-cisco_snmp_group)
@@ -330,6 +335,7 @@ The following resources include cisco types and providers along with cisco provi
* [`cisco_snmp_user`](#type-cisco_snmp_user)
* [`cisco_tacacs_server`](#type-cisco_tacacs_server)
* [`cisco_tacacs_server_host`](#type-cisco_tacacs_server_host)
+* [`cisco_upgrade`](#type-cisco_upgrade)
* [`cisco_vdc`](#type-cisco_vdc)
* [`cisco_vlan`](#type-cisco_vlan)
* [`cisco_vpc_domain`](#type-cisco_vpc_domain)
@@ -433,6 +439,7 @@ Symbol | Meaning | Description
| [cisco_pim_rp_address](#type-cisco_pim_rp_address) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [cisco_pim_grouplist](#type-cisco_pim_grouplist) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [cisco_portchannel_global](#type-cisco_portchannel_global) | ✅* | ✅* | ✅* | ✅* | ✅* | ✅* | \*[caveats](#cisco_portchannel_global-caveats) |
+| [cisco_route_map](#type-cisco_route_map) | ✅* | ✅* | ✅* | ✅* | ✅* | ✅* | \*[caveats](#cisco_route_map-caveats) |
| [cisco_stp_global](#type-cisco_stp_global) | ✅* | ✅* | ✅* | ✅* | ✅ | ✅ | \*[caveats](#cisco_stp_global-caveats) |
| [cisco_snmp_community](#type-cisco_snmp_community) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [cisco_snmp_group](#type-cisco_snmp_group) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
@@ -440,6 +447,7 @@ Symbol | Meaning | Description
| [cisco_snmp_user](#type-cisco_snmp_user) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [cisco_tacacs_server](#type-cisco_tacacs_server) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [cisco_tacacs_server_host](#type-cisco_tacacs_server_host) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| [cisco_upgrade](type-cisco_upgrade) | ✅* | ✅* | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign:| \*[caveats](#cisco_upgrade-caveats) |
| [cisco_vdc](#type-cisco_vdc) | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | ✅ | :heavy_minus_sign: |
| [cisco_vlan](#type-cisco_vlan) | ✅* | ✅* | ✅ | ✅ | ✅ | ✅ | \*[caveats](#cisco_vlan-caveats) |
| [cisco_vpc_domain](#type-cisco_vpc_domain) | ✅* | ✅* | ✅* | ✅* | ✅* | :heavy_minus_sign: | \*[caveats](#cisco_vpc_domain-caveats) |
@@ -1985,6 +1993,9 @@ Manages a Cisco Network Interface. Any resource dependency should be run before
| `hsrp_use_bia` | Not supported on N5k,N6k
Minimum puppet module version 1.5.0
Supported in OS Version 8.0 and later on N7k |
| `hsrp_version` | Not supported on N5k,N6k
Minimum puppet module version 1.5.0
Supported in OS Version 8.0 and later on N7k |
| `pim_bfd` | Minimum puppet module version 1.5.0 |
+| `load_interval_counter_1_delay` | Minimum puppet module version 1.6.0 |
+| `load_interval_counter_2_delay` | Minimum puppet module version 1.6.0 |
+| `load_interval_counter_3_delay` | Minimum puppet module version 1.6.0 |
#### Parameters
@@ -2289,6 +2300,17 @@ HSRP uses this interface's burned in address. Valid values are 'use_bia', 'use_b
##### `hsrp_version`
HSRP version for this interface. Valid values are integer, keyword 'default'.
+##### load-interval config attributes
+
+##### `load_interval_counter_1_delay`
+Load interval delay for counter 1 in seconds. Valid values are integer, keyword 'default'
+
+##### `load_interval_counter_2_delay`
+Load interval delay for counter 2 in seconds. Valid values are integer, keyword 'default'
+
+##### `load_interval_counter_3_delay`
+Load interval delay for counter 3 in seconds. Valid values are integer, keyword 'default'
+
--
### Type: cisco_interface_channel_group
@@ -3223,6 +3245,430 @@ port-channel hash input offset. Valid values are integer or 'default'.
##### `symmetry`
port-channel symmetry hash. Valid values are true, false or 'default'.
+--
+### Type: cisco_route_map
+
+Manages a Cisco Route Map.
+
+| Platform | OS Minimum Version | Module Minimum Version |
+|----------|:------------------:|:----------------------:|
+| N9k | 7.0(3)I2(1) | 1.6.0 |
+| N3k | 7.0(3)I2(1) | 1.6.0 |
+| N5k | 7.3(0)N1(1) | 1.6.0 |
+| N6k | 7.3(0)N1(1) | 1.6.0 |
+| N7k | 7.3(0)D1(1) | 1.6.0 |
+| N9k-F | 7.0(3)F1(1) | 1.6.0 |
+
+#### Caveats
+
+| Property | Caveat Description |
+|:---------|:-------------|
+| `match_evpn_route_type_1` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_2_all` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_2_mac_ip` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_2_mac_only` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_3` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_4` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_5` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_6` | Not supported on N3k,N9k-F,N9k |
+| `match_evpn_route_type_all` | Not supported on N3k,N9k-F,N9k |
+| `match_length` | Not supported on N3k,N9k-F,N9k |
+| `match_mac_list` | Not supported on N3k,N9k-F,N9k |
+| `match_metric` | Not supported on N9k-F |
+| `match_ospf_area` | Not supported on N5k,N6k,N7k,N9k-F
Supported in OS version 7.0(3)I5.1 and later on N3k, N9k |
+| `match_vlan` | Not supported on N3k,N9k-F,N9k |
+| `set_extcommunity_4bytes_additive` | Not supported on N9k-F |
+| `set_extcommunity_4bytes_non_transitive` | Not supported on N9k-F |
+| `set_extcommunity_4bytes_transitive` | Not supported on N9k-F |
+| `set_extcommunity_cost_igp` | Not supported on N9k-F |
+| `set_extcommunity_cost_pre_bestpath` | Not supported on N9k-F |
+| `set_extcommunity_rt_additive` | Not supported on N9k-F |
+| `set_extcommunity_rt_asn` | Not supported on N9k-F,N9k |
+| `set_forwarding_addr` | Not supported on N9k-F |
+| `set_ipv4_default_next_hop` | Not supported on N5k,N6k,N9k-F,N9k |
+| `set_ipv4_default_next_hop_load_share` | Not supported on N5k,N6k,N9k-F,N9k |
+| `set_ipv4_next_hop` | Not supported on N9k-F |
+| `set_ipv4_next_hop_load_share` | Not supported on N5k,N6k,N9k-F
Supported in OS Version 7.0(3)I5.1 and later on N9k |
+| `set_ipv4_next_hop_redist` | Supported on N5k,N6k,N7k,N9k-F
Supported in OS Version 7.0(3)I5.1 and later on N3k,N9k |
+| `set_ipv4_precedence` | Not supported on N9k-F |
+| `set_ipv4_prefix` | Not supported on N5k,N6k,N9k-F |
+OS Version 7.0(3)I5.1 and later on N3k,N9k |
+| `set_ipv6_default_next_hop` | Not supported on N5k,N6k,N9k-F,N9k |
+| `set_ipv6_default_next_hop_load_share` | Not supported on N5k,N6k,N9k-F,N9k |
+| `set_ipv6_next_hop` | Not supported on N9k-F |
+| `set_ipv6_next_hop_load_share` | Not supported on N5k,N6k,N9k-F
Supported in OS Version 7.0(3)I5.1 and later on N9k |
+| `set_ipv6_next_hop_redist` | Supported on N5k,N6k,N7k,N9k-F
Supported in OS Version 7.0(3)I5.1 and later on N3k,N9k |
+| `set_ipv6_prefix` | Not supported on N5k,N6k,N9k-F |
+| `set_vrf` | Supported on N7k |
+
+
+| Example Parameter Usage |
+|:--
+|`match_as_number { ', -, ..':`
+|`match_as_number { '['3', '22-34', '38', '101-110', '120']':`
+
+##### Basic interface config attributes
+
+###### `ensure`
+Determine whether the route map config should be present or not. Valid values
+are 'present' and 'absent'.
+
+
+##### `description`
+Description of the route-map. Valid values are string, or keyword 'default'
+
+##### `match_as_number`
+Match BGP peer AS number. Valid values are an array of ranges or keyword 'default'
+
+
+##### `match_as_number_as_path_list`
+Match BGP AS path list. Valid values are an array of list names or keyword 'default'
+
+##### `match_community`
+Match BGP community list. Valid values are an array of communities or keyword 'default'
+
+##### `match_community_exact_match`
+Enable exact matching of communities. Valid values 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_1`
+Enable match BGP EVPN route type-1. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_2_all`
+Enable match all BGP EVPN route in type-2. Valid values are 'true', false or keyword 'default'
+
+##### `match_evpn_route_type_2_mac_ip`
+Enable match mac-ip BGP EVPN route in type-2. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_2_mac_only`
+Enable match mac-only BGP EVPN route in type-2. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_3`
+Enable match BGP EVPN route type-3. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_4`
+Enable match BGP EVPN route type-4. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_5`
+Enable match BGP EVPN route type-5. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_6`
+Enable match BGP EVPN route type-6. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_evpn_route_type_all`
+Enable match BGP EVPN route type 1-6. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_ext_community`
+Match BGP extended community list. Valid values are an array of extended communities or keyword 'default'
+
+##### `match_ext_community_exact_match`
+Enable exact matching of extended communities. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_interface`
+Match first hop interface of route. Valid values are array of interfaces or keyword 'default'
+
+##### `match_ipv4_addr_access_list`
+Match IPv4 access-list name. Valid values are String or keyword 'default'
+
+##### `match_ipv4_addr_prefix_list`
+Match entries of prefix-lists for IPv4. Valid values are array of prefixes or keyword 'default'
+
+##### `match_ipv4_multicast_enable`
+Enable match IPv4 multicast. This property should be set to 'true' before setting any IPv4 multicast properties. Valid values are are 'true', 'false' or keyword 'default'
+
+##### `match_ipv4_multicast_group_addr`
+Match IPv4 multicast group prefix. Valid values are string, or keyword 'default'
+
+##### `match_ipv4_multicast_group_range_begin_addr`
+Match IPv4 multicast group address begin range. Valid values are string, or keyword 'default'
+
+##### `match_ipv4_multicast_group_range_end_addr`
+Match IPv4 multicast group address end range. Valid values are string, or keyword 'default'
+
+##### `match_ipv4_multicast_rp_addr`
+Match IPv4 multicast rendezvous prefix. Valid values are string, or keyword 'default'
+
+##### `match_ipv4_multicast_rp_type`
+Match IPv4 multicast rendezvous point type. Valid values are 'ASM', 'Bidir' or keyword 'default'
+
+##### `match_ipv4_multicast_src_addr`
+Match IPv4 multicast source prefix. Valid values are string or keyword 'default'
+
+##### `match_ipv4_next_hop_prefix_list`
+Match entries of prefix-lists for next-hop address of route for IPv4. Valid values are an array of prefixes or keyword 'default'
+
+##### `match_ipv4_route_src_prefix_list`
+Match entries of prefix-lists for advertising source address of route for IPv4. Valid values are an array of prefixes or keyword 'default'
+
+##### `match_ipv6_addr_access_list`
+Match IPv6 access-list name. Valid values are string or keyword 'default'
+
+##### `match_ipv6_addr_prefix_list`
+Match entries of prefix-lists for IPv6. Valid values are array of prefixes or keyword 'default'
+
+##### `match_ipv6_multicast_enable`
+Enable match IPv6 multicast. This property should be set to 'true' before setting any IPv6 multicast properties. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_ipv6_multicast_group_addr`
+Match IPv6 multicast group prefix. Valid values are string, or keyword 'default'
+
+##### `match_ipv6_multicast_group_range_begin_addr`
+Match IPv6 multicast group address begin range. Valid values are string, or keyword 'default'
+
+##### `match_ipv6_multicast_group_range_end_addr`
+Match IPv6 multicast group address end range. Valid values are string, or keyword 'default'
+
+##### `match_ipv6_multicast_rp_addr`
+Match IPv6 multicast rendezvous prefix. Valid values are string, or keyword 'default'
+
+##### `match_ipv6_multicast_rp_type`
+Match IPv6 multicast rendezvous point type. Valid values are 'ASM', 'Bidir' or keyword 'default'
+
+##### `match_ipv6_multicast_src_addr`
+Match IPv6 multicast source prefix. Valid values are string or keyword 'default'
+
+##### `match_ipv6_next_hop_prefix_list`
+Match entries of prefix-lists for next-hop address of route for IPv6. Valid values are array of prefixes or keyword 'default'
+
+##### `match_ipv6_route_src_prefix_list`
+Match entries of prefix-lists for advertising source address of route for IPv6. Valid values are array of prefixes or keyword 'default'
+
+##### `match_length`
+Match packet length. Valid values are array of minimum and maximum lengths or keyword 'default'
+
+##### `match_mac_list`
+Match entries of mac-lists. Valid values are array of mac list names or keyword 'default'
+
+##### `match_metric`
+Match metric of route. Valid values are array of [metric, deviation] pairs or keyword 'default'
+
+##### `match_ospf_area`
+Match entries of ospf area IDs. Valid values are array of ids or keyword 'default'
+
+##### `match_route_type_external`
+Enable match external route type (BGP, EIGRP and OSPF type 1/2). Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_inter_area`
+Enable match OSPF inter area type. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_internal`
+Enable match OSPF inter area type (OSPF intra/inter area). Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_intra_area`
+Enable match OSPF intra area route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_level_1`
+Enable match IS-IS level-1 route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_level_2`
+Enable match IS-IS level-2 route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_local`
+Enable match locally generated route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_nssa_external`
+Enable match nssa-external route (OSPF type 1/2). Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_type_1`
+Enable match OSPF external type 1 route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_route_type_type_2`
+Enable match OSPF external type 2 route. Valid values are 'true', 'false' or keyword 'default'
+
+##### `match_src_proto`
+Match source protocol. Valid values are array of protocols or keyword 'default'
+
+##### `match_tag`
+Match tag of route. Valid values are array of tags or keyword 'default'
+
+##### `match_vlan`
+Match VLAN Id. Valid values are array of string of VLAN ranges or keyword 'default'
+
+##### `set_as_path_prepend`
+Prepend string for a BGP AS-path attribute. Valid values are array of AS numbers or keyword 'default'
+
+##### `set_as_path_prepend_last_as`
+Number of last-AS prepends. Valid values are integer or keyword 'default'
+
+##### `set_as_path_tag`
+Set the tag as an AS-path attribute. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_comm_list`
+Set BGP community list (for deletion). Valid values are String or keyword 'default'
+
+##### `set_community_additive`
+Add to existing BGP community. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_community_asn`
+Set community number. Valid values are array of AS numbers or keyword 'default'
+
+##### `set_community_internet`
+Set Internet community. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_community_local_as`
+Do not send outside local AS. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_community_no_advtertise`
+Do not advertise to any peer. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_community_no_export`
+Do not export to next AS. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_community_none`
+Set no community attribute. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_dampening_half_life`
+Set half-life time for the penalty of BGP route flap dampening. Valid values are integer or keyword 'default'
+
+##### `set_dampening_max_duation`
+Set maximum duration to suppress a stable route of BGP route flap dampening. Valid values are integer or keyword 'default'
+
+##### `set_dampening_reuse`
+Set penalty to start reusing a route of BGP route flap dampening. Valid values are integer or keyword 'default'
+
+##### `set_dampening_suppress`
+Set penalty to start suppressing a route of BGP route flap dampening. Valid values are integer or keyword 'default'
+
+##### `set_distance_igp_ebgp`
+Set administrative distance for IGP or EBGP routes. Valid values are integer or keyword 'default'
+
+##### `set_distance_internal`
+Set administrative distance for internal routes. Valid values are integer or keyword 'default'
+
+##### `set_distance_local`
+Set administrative distance for local routes. Valid values are integer or keyword 'default'
+
+##### `set_extcomm_list`
+Set BGP extended community list (for deletion). Valid values are string or keyword 'default'
+
+##### `set_extcommunity_4bytes_additive`
+Add to existing generic extcommunity. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_extcommunity_4bytes_non_transitive`
+Set non-transitive extended community. Valid values are array of communities, or keyword 'default'
+
+##### `set_extcommunity_4bytes_none`
+Set no extcommunity generic attribute. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_extcommunity_4bytes_transitive`
+Set transitive extended community. Valid values are array of communities, or keyword 'default'
+
+##### `set_extcommunity_cost_igp`
+Compare following IGP cost comparison. Valid values are array of [communityId, cost] pairs or keyword 'default'
+
+##### `set_extcommunity_cost_pre_bestpath`
+Compare before all other steps in bestpath calculation. Valid values are array of [communityId, cost] pairs or keyword 'default'
+
+##### `set_extcommunity_rt_additive`
+Set add to existing route target extcommunity. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_extcommunity_rt_asn`
+Set community number. Valid values are array of AS numbers or keyword 'default'
+
+##### `set_forwarding_addr`
+Set the forwarding address. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_interface`
+Set output interface. Valid values are 'Null0' or keyword 'default'
+
+##### `set_ipv4_default_next_hop`
+Set default next-hop IPv4 address. Valid values are array of next hops or keyword 'default'
+
+##### `set_ipv4_default_next_hop_load_share`
+Enable default IPv4 next-hop load-sharing. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv4_next_hop`
+Set next-hop IPv4 address. Valid values are array of next hops or keyword 'default'
+
+##### `set_ipv4_next_hop_load_share`
+Enable IPv4 next-hop load-sharing. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv4_next_hop_peer_addr`
+Enable IPv4 next-hop peer address. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv4_next_hop_redist`
+Enable IPv4 next-hop unchanged address during redistribution. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv4_next_hop_unchanged`
+Enable IPv4 next-hop unchanged address. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv4_precedence`
+Set IPv4 precedence field. Valid values are 'critical', 'flash', 'flash-override', 'immediate', 'internet', 'network', 'priority', 'routine' or keyword 'default'
+
+##### `set_ipv4_prefix`
+Set IPv4 prefix-list. Valid values are string or keyword 'default'
+
+##### `set_ipv6_default_next_hop`
+Set default next-hop IPv6 address. Valid values are array of next hops or keyword 'default'
+
+##### `set_ipv6_default_next_hop_load_share`
+Enable default IPv6 next-hop load-sharing. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv6_next_hop`
+Set next-hop IPv6 address. Valid values are array of next hops or keyword 'default'
+
+##### `set_ipv6_next_hop_load_share`
+Enable IPv6 next-hop load-sharing. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv6_next_hop_peer_addr`
+Enable IPv6 next-hop peer address. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv6_next_hop_redist`
+Enable IPv6 next-hop unchanged address during redistribution. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv6_next_hop_unchanged`
+Enable IPv6 next-hop unchanged address. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_ipv6_precedence`
+Set IPv6 precedence field. Valid values are 'critical', 'flash', 'flash-override', 'immediate', 'internet', 'network', 'priority', 'routine' or keyword 'default'
+
+##### `set_ipv6_prefix`
+Set IPv6 prefix-list. Valid values are string or keyword 'default'
+
+##### `set_level`
+Set where to import route. Valid values are 'level-1', 'level-1-2', 'level-2' or keyword 'default'
+
+##### `set_local_preference`
+Set BGP local preference path attribute. Valid values are integer or keyword 'default'
+
+##### `set_metric_additive`
+Set add to metric. Valid values are 'true', 'false' or keyword 'default'
+
+##### `set_metric_bandwidth`
+Set metric value or Bandwidth in kbps. Valid values are integer or keyword 'default'
+
+##### `set_metric_delay`
+Set IGRP delay metric. Valid values are integer or keyword 'default'
+
+##### `set_metric_effective_bandwidth`
+Set IGRP Effective bandwidth metric. Valid values are integer or keyword 'default'
+
+##### `set_metric_mtu`
+Set IGRP MTU of the path. Valid values are integer or keyword 'default'
+
+##### `set_metric_reliability`
+Set IGRP reliability metric. Valid values are integer or keyword 'default'
+
+##### `set_metric_type`
+Set type of metric for destination routing protocol. Valid values are 'external, 'internal', 'type-1, 'type-2, or keyword 'default'
+
+##### `set_nssa_only`
+Set OSPF NSSA Areas. Valid values are 'true, 'false' or keyword 'default'
+
+##### `set_origin`
+Set BGP origin code. Valid values are 'egp, 'igp', 'incomplete', or keyword 'default'
+
+##### `set_path_selection`
+Set path selection criteria for BGP. Valid values are 'true, 'false' or keyword 'default'
+
+##### `set_tag`
+Set tag value for destination routing protocol. Valid values are integer or keyword 'default'
+
+##### `set_vrf`
+Set the VRF for next-hop resolution. Valid values are string or keyword 'default'
+
+##### `set_weight`
+Set BGP weight for routing table. Valid values are integer or keyword 'default'
+
--
### Type: cisco_stp_global
Manages spanning tree global parameters
@@ -3567,6 +4013,50 @@ Specifies a preshared key for the host. Valid values are 'clear', 'encrypted',
##### `encryption_password`
"Specifies the preshared key password for the host. Valid value is a string.
+--
+### Type: cisco_upgrade
+
+Manages the upgrade of a Cisco device.
+
+| Platform | OS Minimum Version | Module Minimum Version |
+|----------|:------------------:|:----------------------:|
+| N9k | 7.0(3)I2(2e) | 1.6.0 |
+| N3k | 7.0(3)I2(2e) | 1.6.0 |
+| N5k | not applicable | not applicable |
+| N6k | not applicable | not applicable |
+| N7k | not applicable | not applicable |
+| N9k-F | 7.0(3)F1(1) | 1.6.0 |
+
+#### Caveats
+
+The `cisco_upgrade` is only supported on *simplex* N3k, N9k and N9k-F devices. HA devices are currently not supported.
+
+| Property | Caveat Description |
+|:--------|:-------------|
+| `source_uri` | Only images on `bootflash:` are supported. The puppet file provider can be used to copy the image file to `bootflash`. Refer to Demo Upgrade for an example. |
+
+#### Parameters
+
+##### `name`
+Name of cisco_upgrade instance. Valid values are string.
+*Only 'image' is a valid name for the cisco_upgrade resource.*
+
+##### `source_uri`
+Image upgrade URI. Format `:`. Valid values are string.
+*Example --> bootflash:nxos.7.0.3.I5.2.bin*
+*NOTE: Only images on `bootflash:` are supported.*
+
+##### `delete_boot_image`
+Delete the booted image. Valid values are `true`, `false`.
+
+##### `force_upgrade`
+Force upgrade the device.Valid values are `true`, `false`.
+
+#### Properties
+
+##### `version`
+Version of the Cisco image to install on the device. Valid values are strings.
+
--
### Type: cisco_vdc
diff --git a/docs/README-agent-install.md b/docs/README-agent-install.md
index 87a2f28c9..d58184bb4 100644
--- a/docs/README-agent-install.md
+++ b/docs/README-agent-install.md
@@ -493,7 +493,7 @@ The `guestshell` environment uses **systemd** for service management. The Puppet
EnvironmentFile=-/etc/sysconfig/puppet
EnvironmentFile=-/etc/default/puppet
-ExecStart=/opt/puppetlabs/puppet/bin/puppet agent $PUPPET_EXTRA_OPTS --no-daemonize
-+ExecStart=/bin/nsenter --net=/var/run/netns/management /opt/puppetlabs/puppet/bin/puppet agent $PUPPET_EXTRA_OPTS --no-daemonize
++ExecStart=/bin/nsenter --net=/var/run/netns/management -- /opt/puppetlabs/puppet/bin/puppet agent $PUPPET_EXTRA_OPTS --no-daemonize
KillMode=process
[Install]
@@ -535,7 +535,7 @@ A virtual Nexus N9k may be helpful for development and testing. To obtain a virt
## License
~~~
-Copyright (c) 2014-2016 Cisco and/or its affiliates.
+Copyright (c) 2014-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/examples/cisco/demo_interface.pp b/examples/cisco/demo_interface.pp
index f78c79e22..495ebf8b2 100755
--- a/examples/cisco/demo_interface.pp
+++ b/examples/cisco/demo_interface.pp
@@ -78,10 +78,13 @@
}
cisco_interface { 'Ethernet1/3':
- description => 'default',
- shutdown => 'default',
- access_vlan => 'default',
- switchport_mode => access,
+ description => 'default',
+ shutdown => 'default',
+ access_vlan => 'default',
+ load_interval_counter_1_delay => 150,
+ load_interval_counter_2_delay => 250,
+ load_interval_counter_3_delay => 90,
+ switchport_mode => access,
}
cisco_interface { 'Ethernet1/4':
diff --git a/examples/cisco/demo_route_map.pp b/examples/cisco/demo_route_map.pp
new file mode 100644
index 000000000..bb2773761
--- /dev/null
+++ b/examples/cisco/demo_route_map.pp
@@ -0,0 +1,401 @@
+# Manifest to demo cisco_interface provider
+#
+# Copyright (c) 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.
+# 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.
+
+class ciscopuppet::cisco::demo_route_map {
+
+ $match_evpn_route_type_1 = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_2_all = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_2_mac_ip = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_2_mac_only = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_3 = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_4 = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_5 = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_6 = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_evpn_route_type_all = platform_get() ? {
+ /(n5k|n6k|n7k)/ => true,
+ default => undef
+ }
+
+ $match_length = platform_get() ? {
+ /(n5k|n6k|n7k)/ => ['45', '345'],
+ default => undef
+ }
+
+ $match_mac_list = platform_get() ? {
+ /(n5k|n6k|n7k)/ => ['mac1', 'listmac'],
+ default => undef
+ }
+
+ $match_ospf_area = platform_get() ? {
+ /(n3k|n9k$)/ => $facts['cisco']['images']['system_image'] ? {
+ /(I2|I3|I4)/ => undef,
+ default => ['10', '7', '222']
+ },
+ default => undef
+ }
+
+ $match_vlan = platform_get() ? {
+ /(n5k|n6k|n7k)/ => '32, 45-200, 300-350, 400-453',
+ default => undef
+ }
+
+ $set_ipv4_default_next_hop = platform_get() ? {
+ /(n3k|n7k)/ => ['1.1.1.1', '2.2.2.2'],
+ default => undef
+ }
+
+ $set_ipv4_default_next_hop_load_share = platform_get() ? {
+ /(n3k|n7k)/ => true,
+ default => undef
+ }
+
+ $set_ipv4_next_hop_load_share = platform_get() ? {
+ /(n3k|n9k$)/ => $facts['cisco']['images']['system_image'] ? {
+ /(I2|I3|I4)/ => undef,
+ default => true
+ },
+ 'n7k' => true,
+ default => undef
+ }
+
+ $set_ipv4_prefix = platform_get() ? {
+ /(n3k|n7k|n9k)/ => 'abcdef',
+ default => undef
+ }
+
+ $set_ipv6_default_next_hop = platform_get() ? {
+ /(n3k|n7k)/ => ['2000::1', '2000::11', '2000::22'],
+ default => undef
+ }
+
+ $set_ipv6_default_next_hop_load_share = platform_get() ? {
+ /(n3k|n7k)/ => true,
+ default => undef
+ }
+
+ $set_ipv4_next_hop_redist = platform_get() ? {
+ /(n3k|n9k$)/ => $facts['cisco']['images']['system_image'] ? {
+ /(I2|I3|I4)/ => undef,
+ default => true
+ },
+ default => true
+ }
+
+ $set_ipv6_next_hop_redist = platform_get() ? {
+ /(n3k|n9k$)/ => $facts['cisco']['images']['system_image'] ? {
+ /(I2|I3|I4)/ => undef,
+ default => true
+ },
+ default => true
+ }
+
+ $set_ipv6_next_hop_load_share = platform_get() ? {
+ /(n3k|n9k$)/ => $facts['cisco']['images']['system_image'] ? {
+ /(I2|I3|I4)/ => undef,
+ default => true
+ },
+ 'n7k' => true,
+ default => undef
+ }
+
+ $set_ipv6_prefix = platform_get() ? {
+ /(n3k|n7k|n9k)/ => 'wxyz',
+ default => undef
+ }
+
+ $set_extcommunity_rt_asn = platform_get() ? {
+ /(n3k|n5k|n6k|n7k)/ => ['11:22', '33:44', '12.22.22.22:12', '123.256:543'],
+ default => undef
+ }
+
+ $set_vrf = platform_get() ? {
+ 'n7k' => 'igp',
+ default => undef
+ }
+
+ if platform_get() =~ /n(3|5|6|7|9)k$/ {
+ cisco_route_map {'MyRouteMap1 123 permit':
+ ensure => 'present',
+ description => 'Testing',
+ match_as_number => ['3', '22-34', '38', '101-110'],
+ match_as_number_as_path_list => ['abc', 'xyz', 'pqr'],
+ match_community => ['public', 'private'],
+ match_community_exact_match => true,
+ match_evpn_route_type_1 => $match_evpn_route_type_1,
+ match_evpn_route_type_2_all => $match_evpn_route_type_2_all,
+ match_evpn_route_type_2_mac_ip => $match_evpn_route_type_2_mac_ip,
+ match_evpn_route_type_2_mac_only => $match_evpn_route_type_2_mac_only,
+ match_evpn_route_type_3 => $match_evpn_route_type_3,
+ match_evpn_route_type_4 => $match_evpn_route_type_4,
+ match_evpn_route_type_5 => $match_evpn_route_type_5,
+ match_evpn_route_type_6 => $match_evpn_route_type_6,
+ match_evpn_route_type_all => $match_evpn_route_type_all,
+ match_ext_community => ['epublic', 'eprivate'],
+ match_ext_community_exact_match => true,
+ match_interface => ['ethernet1/1', 'loopback2', 'mgmt0', 'null0', 'port-channel10'],
+ match_ipv4_addr_access_list => 'access',
+ match_ipv4_addr_prefix_list => ['p1', 'p7', 'pre5'],
+ match_ipv4_multicast_enable => true,
+ match_ipv4_multicast_src_addr => '242.1.1.1/32',
+ match_ipv4_multicast_group_addr => '239.2.2.2/32',
+ match_ipv4_multicast_rp_addr => '242.1.1.1/32',
+ match_ipv4_multicast_rp_type => 'ASM',
+ match_ipv4_next_hop_prefix_list => ['nh5', 'nh1', 'nh42'],
+ match_ipv4_route_src_prefix_list => ['rs2', 'rs22', 'pre15'],
+ match_ipv6_multicast_enable => true,
+ match_ipv6_multicast_src_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_group_addr => 'ff0e::2:101:0:0/96',
+ match_ipv6_multicast_rp_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type => 'ASM',
+ match_ipv6_next_hop_prefix_list => ['nhv6', 'v6nh1', 'nhv42'],
+ match_ipv6_route_src_prefix_list => ['rsv6', 'rs22v6', 'prev6'],
+ match_mac_list => $match_mac_list,
+ match_metric => [['1', '0'], ['8', '0'], ['224', '9'], ['23', '0'], ['5', '8'], ['6', '0']],
+ match_ospf_area => $match_ospf_area,
+ match_route_type_external => true,
+ match_route_type_inter_area => true,
+ match_route_type_internal => true,
+ match_route_type_intra_area => true,
+ match_route_type_level_1 => true,
+ match_route_type_level_2 => true,
+ match_route_type_local => true,
+ match_route_type_nssa_external => true,
+ match_route_type_type_1 => true,
+ match_route_type_type_2 => true,
+ match_src_proto => ['tcp', 'udp', 'igmp'],
+ match_tag => ['5', '342', '28', '3221'],
+ match_vlan => $match_vlan,
+ set_as_path_prepend => ['55.77', '12', '45.3'],
+ set_as_path_prepend_last_as => 1,
+ set_as_path_tag => true,
+ set_comm_list => 'abc',
+ set_community_additive => true,
+ set_community_asn => ['11:22', '33:44', '123:11'],
+ set_community_internet => true,
+ set_community_local_as => true,
+ set_community_no_advtertise => true,
+ set_community_no_export => true,
+ set_community_none => false,
+ set_dampening_half_life => 6,
+ set_dampening_max_duation => 55,
+ set_dampening_reuse => 22,
+ set_dampening_suppress => 44,
+ set_distance_igp_ebgp => 1,
+ set_distance_internal => 2,
+ set_distance_local => 3,
+ set_extcomm_list => 'xyz',
+ set_extcommunity_4bytes_additive => true,
+ set_extcommunity_4bytes_non_transitive => ['21:42', '43:22', '59:17'],
+ set_extcommunity_4bytes_transitive => ['11:22', '33:44', '66:77'],
+ set_extcommunity_cost_igp => [['0', '23'], ['3', '33'], ['100', '10954']],
+ set_extcommunity_cost_pre_bestpath => [['23', '999'], ['88', '482'], ['120', '2323']],
+ set_extcommunity_rt_additive => true,
+ set_extcommunity_rt_asn => $set_extcommunity_rt_asn,
+ set_forwarding_addr => true,
+ set_ipv4_next_hop => ['3.3.3.3', '4.4.4.4'],
+ set_ipv4_next_hop_load_share => $set_ipv4_next_hop_load_share,
+ set_ipv4_precedence => 'critical',
+ set_ipv4_prefix => $set_ipv4_prefix,
+ set_ipv6_next_hop => ['2000::1', '2000::11', '2000::22'],
+ set_ipv6_next_hop_load_share => $set_ipv6_next_hop_load_share,
+ set_ipv6_prefix => $set_ipv6_prefix,
+ set_level => 'level-1',
+ set_local_preference => 100,
+ set_metric_additive => false,
+ set_metric_bandwidth => 44,
+ set_metric_delay => 55,
+ set_metric_reliability => 66,
+ set_metric_effective_bandwidth => 77,
+ set_metric_mtu => 88,
+ set_metric_type => 'external',
+ set_nssa_only => true,
+ set_origin => 'egp',
+ set_path_selection => true,
+ set_tag => 101,
+ set_weight => 222,
+ }
+ }
+
+ if platform_get() =~ /n9k-f/ {
+ cisco_route_map {'MyRouteMap1 123 permit':
+ ensure => 'present',
+ description => 'Testing',
+ match_as_number => ['3', '22-34', '38', '101-110'],
+ match_as_number_as_path_list => ['abc', 'xyz', 'pqr'],
+ match_community => ['public', 'private'],
+ match_community_exact_match => true,
+ match_evpn_route_type_1 => $match_evpn_route_type_1,
+ match_evpn_route_type_2_all => $match_evpn_route_type_2_all,
+ match_evpn_route_type_2_mac_ip => $match_evpn_route_type_2_mac_ip,
+ match_evpn_route_type_2_mac_only => $match_evpn_route_type_2_mac_only,
+ match_evpn_route_type_3 => $match_evpn_route_type_3,
+ match_evpn_route_type_4 => $match_evpn_route_type_4,
+ match_evpn_route_type_5 => $match_evpn_route_type_5,
+ match_evpn_route_type_6 => $match_evpn_route_type_6,
+ match_evpn_route_type_all => $match_evpn_route_type_all,
+ match_ext_community => ['epublic', 'eprivate'],
+ match_ext_community_exact_match => true,
+ match_interface => ['ethernet1/1', 'loopback2', 'mgmt0', 'null0', 'port-channel10'],
+ match_ipv4_addr_access_list => 'access',
+ match_ipv4_addr_prefix_list => ['p1', 'p7', 'pre5'],
+ match_ipv4_multicast_enable => true,
+ match_ipv4_multicast_src_addr => '242.1.1.1/32',
+ match_ipv4_multicast_group_addr => '239.2.2.2/32',
+ match_ipv4_multicast_rp_addr => '242.1.1.1/32',
+ match_ipv4_multicast_rp_type => 'ASM',
+ match_ipv4_next_hop_prefix_list => ['nh5', 'nh1', 'nh42'],
+ match_ipv4_route_src_prefix_list => ['rs2', 'rs22', 'pre15'],
+ match_ipv6_multicast_enable => true,
+ match_ipv6_multicast_src_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_group_addr => 'ff0e::2:101:0:0/96',
+ match_ipv6_multicast_rp_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type => 'ASM',
+ match_ipv6_next_hop_prefix_list => ['nhv6', 'v6nh1', 'nhv42'],
+ match_ipv6_route_src_prefix_list => ['rsv6', 'rs22v6', 'prev6'],
+ match_mac_list => $match_mac_list,
+ match_ospf_area => $match_ospf_area,
+ match_route_type_external => true,
+ match_route_type_inter_area => true,
+ match_route_type_internal => true,
+ match_route_type_intra_area => true,
+ match_route_type_level_1 => true,
+ match_route_type_level_2 => true,
+ match_route_type_local => true,
+ match_route_type_nssa_external => true,
+ match_route_type_type_1 => true,
+ match_route_type_type_2 => true,
+ match_src_proto => ['tcp', 'udp', 'igmp'],
+ match_tag => ['5', '342', '28', '3221'],
+ match_vlan => $match_vlan,
+ set_as_path_prepend => ['55.77', '12', '45.3'],
+ set_as_path_prepend_last_as => 1,
+ set_as_path_tag => true,
+ set_comm_list => 'abc',
+ set_community_additive => true,
+ set_community_asn => ['11:22', '33:44', '123:11'],
+ set_community_internet => true,
+ set_community_local_as => true,
+ set_community_no_advtertise => true,
+ set_community_no_export => true,
+ set_community_none => false,
+ set_dampening_half_life => 6,
+ set_dampening_max_duation => 55,
+ set_dampening_reuse => 22,
+ set_dampening_suppress => 44,
+ set_distance_igp_ebgp => 1,
+ set_distance_internal => 2,
+ set_distance_local => 3,
+ set_extcomm_list => 'xyz',
+ set_level => 'level-1',
+ set_local_preference => 100,
+ set_metric_additive => false,
+ set_metric_bandwidth => 44,
+ set_metric_delay => 55,
+ set_metric_reliability => 66,
+ set_metric_effective_bandwidth => 77,
+ set_metric_mtu => 88,
+ set_metric_type => 'external',
+ set_nssa_only => true,
+ set_origin => 'egp',
+ set_path_selection => true,
+ set_tag => 101,
+ set_weight => 222,
+ }
+ }
+
+ cisco_route_map {'MyRouteMap2 149 deny':
+ ensure => 'present',
+ match_ipv6_addr_prefix_list => ['pv6', 'pv67', 'prev6'],
+ match_ipv4_multicast_enable => true,
+ match_ipv4_multicast_src_addr => '242.1.1.1/32',
+ match_ipv4_multicast_group_range_begin_addr => '239.1.1.1',
+ match_ipv4_multicast_group_range_end_addr => '239.2.2.2',
+ match_ipv4_multicast_rp_addr => '242.1.1.1/32',
+ match_ipv4_multicast_rp_type => 'Bidir',
+ match_ipv6_addr_access_list => 'v6access',
+ match_ipv6_multicast_enable => true,
+ match_ipv6_multicast_src_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_group_range_begin_addr => 'ff01::',
+ match_ipv6_multicast_group_range_end_addr => 'ff02::',
+ match_ipv6_multicast_rp_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type => 'Bidir',
+ set_community_none => true,
+ set_extcommunity_4bytes_none => true,
+ set_ipv4_default_next_hop => $set_ipv4_default_next_hop,
+ set_ipv4_default_next_hop_load_share => $set_ipv4_default_next_hop_load_share,
+ set_ipv4_next_hop_peer_addr => true,
+ set_ipv6_precedence => 'flash',
+ set_level => 'level-1-2',
+ set_metric_additive => true,
+ set_metric_bandwidth => 33,
+ set_metric_type => 'type-2',
+ set_origin => 'incomplete',
+ }
+
+ cisco_route_map {'MyRouteMap3 159 deny':
+ ensure => 'present',
+ set_ipv6_default_next_hop => $set_ipv6_default_next_hop,
+ set_ipv6_default_next_hop_load_share => $set_ipv6_default_next_hop_load_share,
+ set_ipv6_next_hop_peer_addr => true,
+ }
+
+ cisco_route_map {'MyRouteMap4 200 permit':
+ ensure => 'present',
+ set_interface => 'Null0',
+ set_ipv4_next_hop_redist => $set_ipv4_next_hop_redist,
+ set_ipv6_next_hop_redist => $set_ipv6_next_hop_redist,
+ set_ipv6_next_hop_unchanged => true,
+ set_ipv4_next_hop_unchanged => true,
+ }
+
+ cisco_route_map {'MyRouteMap5 199 deny':
+ ensure => 'present',
+ match_length => $match_length,
+ set_vrf => $set_vrf,
+ }
+}
diff --git a/examples/cisco/demo_upgrade.pp b/examples/cisco/demo_upgrade.pp
new file mode 100644
index 000000000..7a1876044
--- /dev/null
+++ b/examples/cisco/demo_upgrade.pp
@@ -0,0 +1,78 @@
+# Manifest to demo cisco_upgrade
+#
+# Copyright (c) 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.
+# 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.
+
+class ciscopuppet::cisco::demo_upgrade {
+
+ # To use this manifest, make sure the gem and bin file are in the files directory under your
+ # puppet module on the puppet master.
+
+ # agent-lab9-pm:files:2009> cd /etc/puppetlabs/code/environments/production/modules/ciscopuppet/files/
+ # agent-lab9-pm:files:2010> ls -lh
+ # total 1.3G
+ # -rw-r--r-- 1 root root 431K Mar 2 14:19 cisco_node_utils-1.5.0.gem
+ # -rwxr-xr-- 1 root root 530M Mar 2 15:46 nxos.7.0.3.I2.5.bin
+ # -rwxr-xr-- 1 root root 723M Mar 2 15:25 nxos.7.0.3.I5.1.bin
+ # agent-lab9-pm:files:2011>
+
+ node default {
+ $gem = 'cisco_node_utils-1.5.0.gem'
+ $uri = 'bootflash'
+ $image = 'nxos.7.0.3.I2.5.bin'
+ $version = '7.0(3)I2(5)'
+
+ # If you are behind proxy, please set the proxy variable.
+ # $proxy = 'http://.:'
+ $proxy = ''
+
+ if $proxy == '' {
+ $opts = {}
+ }
+ else {
+ $opts = { '--http-proxy' => $proxy }
+ }
+
+ # If installing cisco_node_utils from local source
+ # file { "/${uri}/${gem}" :
+ # ensure => file,
+ # source => "puppet:///modules/ciscopuppet/${gem}",
+ # owner => 'root',
+ # group => 'root',
+ # mode => 'ug+rwx',
+ # }
+
+ package { 'cisco_node_utils' :
+ ensure => present,
+ provider => 'gem',
+ # source => "/${uri}/${gem}",
+ install_options => $opts,
+ }
+
+ file { "/${uri}/${image}" :
+ ensure => file,
+ source => "puppet:///modules/ciscopuppet/${image}",
+ owner => 'root',
+ group => 'root',
+ mode => 'ug+rwx',
+ }
+
+ cisco_upgrade { 'image' :
+ version => "${version}",
+ source_uri => "${uri}:///${image}",
+ force_upgrade => false,
+ delete_boot_image => false,
+ }
+ }
+}
diff --git a/examples/demo_all_cisco.pp b/examples/demo_all_cisco.pp
index a152f91bf..7948b6304 100644
--- a/examples/demo_all_cisco.pp
+++ b/examples/demo_all_cisco.pp
@@ -42,12 +42,14 @@
include ciscopuppet::cisco::demo_patching
include ciscopuppet::cisco::demo_pim
include ciscopuppet::cisco::demo_portchannel
+ include ciscopuppet::cisco::demo_route_map
include ciscopuppet::cisco::demo_snmp
#stp_bd and stp_vlan are exclusive, so comment one of them
#include ciscopuppet::cisco::demo_stp_bd
include ciscopuppet::cisco::demo_stp_vlan
include ciscopuppet::cisco::demo_tacacs_server
include ciscopuppet::cisco::demo_tacacs_server_host
+ # include ciscopuppet::cisco::demo_upgrade
include ciscopuppet::cisco::demo_vlan
include ciscopuppet::cisco::demo_vpc_domain
include ciscopuppet::cisco::demo_vrf
diff --git a/lib/puppet/feature/cisco_node_utils.rb b/lib/puppet/feature/cisco_node_utils.rb
index 5110412cb..6173654bb 100644
--- a/lib/puppet/feature/cisco_node_utils.rb
+++ b/lib/puppet/feature/cisco_node_utils.rb
@@ -37,7 +37,7 @@ def cisco_node_utils?
@results['cisco_node_utils'] = test('cisco_node_utils',
libs: ['cisco_node_utils'])
if @results['cisco_node_utils']
- rec_version = Gem::Version.new('1.5.0')
+ rec_version = Gem::Version.new('1.6.0')
gem_version = Gem::Version.new(CiscoNodeUtils::VERSION)
if gem_version < rec_version
warn "This module works best with version #{rec_version} of gem "\
diff --git a/lib/puppet/provider/cisco_command_config/cisco.rb b/lib/puppet/provider/cisco_command_config/cisco.rb
index 780af6ca3..6dda8cb1b 100644
--- a/lib/puppet/provider/cisco_command_config/cisco.rb
+++ b/lib/puppet/provider/cisco_command_config/cisco.rb
@@ -42,15 +42,16 @@ def command
manifest_hash = Cisco::ConfigParser::Configuration.new(@resource[:command])
# Compare full manifest config to running-config.
- existing_str = manifest_hash.compare_with(running_hash)
- debug "Existing:\n>#{existing_str}<"
+ strip_pattern = Regexp.new('^ *| *$|\s')
+ existing_str = manifest_hash.compare_with(running_hash).gsub(strip_pattern, '')
+ debug "Existing:\n>#{existing_str.inspect}<"
manifest_config_str =
Cisco::ConfigParser::Configuration.config_hash_to_str(
- manifest_hash.configuration)
- debug "Manifest:\n>#{manifest_config_str}<"
+ manifest_hash.configuration).gsub(strip_pattern, '')
+ debug "Manifest:\n>#{manifest_config_str.inspect}<"
- if existing_str.gsub(/^ *| *$/, '').include?(manifest_config_str)
+ if existing_str.include?(manifest_config_str)
debug 'Current running-config already satisfies manifest'
@property_hash[:command] = @resource[:command]
else
diff --git a/lib/puppet/provider/cisco_interface/cisco.rb b/lib/puppet/provider/cisco_interface/cisco.rb
index 553ebbfaf..8f2ab8181 100644
--- a/lib/puppet/provider/cisco_interface/cisco.rb
+++ b/lib/puppet/provider/cisco_interface/cisco.rb
@@ -61,6 +61,9 @@
:ipv6_acl_in,
:ipv6_acl_out,
:ipv6_dhcp_relay_src_intf,
+ :load_interval_counter_1_delay,
+ :load_interval_counter_2_delay,
+ :load_interval_counter_3_delay,
:mtu,
:speed,
:duplex,
diff --git a/lib/puppet/provider/cisco_route_map/cisco.rb b/lib/puppet/provider/cisco_route_map/cisco.rb
new file mode 100644
index 000000000..bcfd06f31
--- /dev/null
+++ b/lib/puppet/provider/cisco_route_map/cisco.rb
@@ -0,0 +1,557 @@
+# January, 2017
+#
+# Copyright (c) 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.
+# 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 'cisco_node_utils' if Puppet.features.cisco_node_utils?
+begin
+ require 'puppet_x/cisco/autogen'
+rescue LoadError # seen on master, not on agent
+ # See longstanding Puppet issues #4248, #7316, #14073, #14149, etc. Ugh.
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..',
+ 'puppet_x', 'cisco', 'autogen.rb'))
+end
+
+begin
+ require 'puppet_x/cisco/cmnutils'
+rescue LoadError # seen on master, not on agent
+ # See longstanding Puppet issues #4248, #7316, #14073, #14149, etc. Ugh.
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..',
+ 'puppet_x', 'cisco', 'cmnutils.rb'))
+end
+Puppet::Type.type(:cisco_route_map).provide(:cisco) do
+ desc 'The Cisco route map provider.'
+
+ confine feature: :cisco_node_utils
+ defaultfor operatingsystem: :nexus
+
+ mk_resource_methods
+
+ ROUTE_MAP_NON_BOOL_PROPS = [
+ :description,
+ :match_ipv4_addr_access_list,
+ :match_ipv4_multicast_group_addr,
+ :match_ipv4_multicast_group_range_begin_addr,
+ :match_ipv4_multicast_group_range_end_addr,
+ :match_ipv4_multicast_rp_addr,
+ :match_ipv4_multicast_rp_type,
+ :match_ipv4_multicast_src_addr,
+ :match_ipv6_addr_access_list,
+ :match_ipv6_multicast_group_addr,
+ :match_ipv6_multicast_group_range_begin_addr,
+ :match_ipv6_multicast_group_range_end_addr,
+ :match_ipv6_multicast_rp_addr,
+ :match_ipv6_multicast_rp_type,
+ :match_ipv6_multicast_src_addr,
+ :match_vlan,
+ :set_as_path_prepend_last_as,
+ :set_comm_list,
+ :set_dampening_half_life,
+ :set_dampening_max_duation,
+ :set_dampening_reuse,
+ :set_dampening_suppress,
+ :set_distance_igp_ebgp,
+ :set_distance_internal,
+ :set_distance_local,
+ :set_extcomm_list,
+ :set_interface,
+ :set_ipv4_precedence,
+ :set_ipv4_prefix,
+ :set_ipv6_precedence,
+ :set_ipv6_prefix,
+ :set_level,
+ :set_local_preference,
+ :set_metric_bandwidth,
+ :set_metric_delay,
+ :set_metric_reliability,
+ :set_metric_effective_bandwidth,
+ :set_metric_mtu,
+ :set_metric_type,
+ :set_origin,
+ :set_tag,
+ :set_vrf,
+ :set_weight,
+ ]
+
+ ROUTE_MAP_BOOL_PROPS = [
+ :match_community_exact_match,
+ :match_evpn_route_type_1,
+ :match_evpn_route_type_2_all,
+ :match_evpn_route_type_2_mac_ip,
+ :match_evpn_route_type_2_mac_only,
+ :match_evpn_route_type_3,
+ :match_evpn_route_type_4,
+ :match_evpn_route_type_5,
+ :match_evpn_route_type_6,
+ :match_evpn_route_type_all,
+ :match_ext_community_exact_match,
+ :match_ipv4_multicast_enable,
+ :match_ipv6_multicast_enable,
+ :match_route_type_external,
+ :match_route_type_inter_area,
+ :match_route_type_internal,
+ :match_route_type_intra_area,
+ :match_route_type_level_1,
+ :match_route_type_level_2,
+ :match_route_type_local,
+ :match_route_type_nssa_external,
+ :match_route_type_type_1,
+ :match_route_type_type_2,
+ :set_as_path_tag,
+ :set_community_additive,
+ :set_community_internet,
+ :set_community_local_as,
+ :set_community_no_advtertise,
+ :set_community_no_export,
+ :set_community_none,
+ :set_extcommunity_4bytes_additive,
+ :set_extcommunity_4bytes_none,
+ :set_extcommunity_rt_additive,
+ :set_forwarding_addr,
+ :set_ipv4_default_next_hop_load_share,
+ :set_ipv4_next_hop_load_share,
+ :set_ipv4_next_hop_peer_addr,
+ :set_ipv4_next_hop_redist,
+ :set_ipv4_next_hop_unchanged,
+ :set_ipv6_default_next_hop_load_share,
+ :set_ipv6_next_hop_load_share,
+ :set_ipv6_next_hop_peer_addr,
+ :set_ipv6_next_hop_redist,
+ :set_ipv6_next_hop_unchanged,
+ :set_metric_additive,
+ :set_nssa_only,
+ :set_path_selection,
+ ]
+
+ ROUTE_MAP_ARRAY_FLAT_PROPS = [
+ :match_as_number,
+ :match_as_number_as_path_list,
+ :match_community,
+ :match_ext_community,
+ :match_interface,
+ :match_ipv4_addr_prefix_list,
+ :match_ipv4_next_hop_prefix_list,
+ :match_ipv4_route_src_prefix_list,
+ :match_ipv6_addr_prefix_list,
+ :match_ipv6_next_hop_prefix_list,
+ :match_ipv6_route_src_prefix_list,
+ :match_length,
+ :match_mac_list,
+ :match_ospf_area,
+ :match_src_proto,
+ :match_tag,
+ :set_as_path_prepend,
+ :set_community_asn,
+ :set_extcommunity_4bytes_non_transitive,
+ :set_extcommunity_4bytes_transitive,
+ :set_extcommunity_rt_asn,
+ :set_ipv4_default_next_hop,
+ :set_ipv4_next_hop,
+ :set_ipv6_default_next_hop,
+ :set_ipv6_next_hop,
+ ]
+
+ ROUTE_MAP_ARRAY_NESTED_PROPS = [
+ :match_metric,
+ :set_extcommunity_cost_igp,
+ :set_extcommunity_cost_pre_bestpath,
+ ]
+
+ ROUTE_MAP_ALL_PROPS = ROUTE_MAP_NON_BOOL_PROPS +
+ ROUTE_MAP_ARRAY_FLAT_PROPS +
+ ROUTE_MAP_ARRAY_NESTED_PROPS +
+ ROUTE_MAP_BOOL_PROPS
+
+ PuppetX::Cisco::AutoGen.mk_puppet_methods(:bool, self, '@nu',
+ ROUTE_MAP_BOOL_PROPS)
+ PuppetX::Cisco::AutoGen.mk_puppet_methods(:non_bool, self, '@nu',
+ ROUTE_MAP_NON_BOOL_PROPS)
+ PuppetX::Cisco::AutoGen.mk_puppet_methods(:array_flat, self, '@nu',
+ ROUTE_MAP_ARRAY_FLAT_PROPS)
+ PuppetX::Cisco::AutoGen.mk_puppet_methods(:array_nested, self, '@nu',
+ ROUTE_MAP_ARRAY_NESTED_PROPS)
+
+ def initialize(value={})
+ super(value)
+ rmname = @property_hash[:rmname]
+ sequence = @property_hash[:sequence]
+ action = @property_hash[:action]
+ @nu = Cisco::RouteMap.maps[rmname][sequence][action] unless
+ rmname.nil? || sequence.nil? || action.nil?
+ @property_flush = {}
+ end
+
+ def self.properties_get(rmname, sequence, action, nu_obj)
+ debug "Checking route map instance, #{rmname} #{sequence} #{action}"
+ current_state = {
+ name: "#{rmname} #{sequence} #{action}",
+ rmname: rmname,
+ sequence: sequence,
+ action: action,
+ ensure: :present,
+ }
+
+ # Call node_utils getter for each property
+ (ROUTE_MAP_NON_BOOL_PROPS).each do |prop|
+ current_state[prop] = nu_obj.send(prop)
+ end
+ ROUTE_MAP_ARRAY_FLAT_PROPS.each do |prop|
+ current_state[prop] = nu_obj.send(prop)
+ end
+ ROUTE_MAP_ARRAY_NESTED_PROPS.each do |prop|
+ current_state[prop] = nu_obj.send(prop)
+ end
+ ROUTE_MAP_BOOL_PROPS.each do |prop|
+ val = nu_obj.send(prop)
+ if val.nil?
+ current_state[prop] = nil
+ else
+ current_state[prop] = val ? :true : :false
+ end
+ end
+ new(current_state)
+ end # self.properties_get
+
+ def self.instances
+ rm_instances = []
+ Cisco::RouteMap.maps.each do |rmname, sequences|
+ sequences.each do |sequence, actions|
+ actions.each do |action, nu_obj|
+ rm_instances << properties_get(rmname, sequence, action, nu_obj)
+ end
+ end
+ end
+ rm_instances
+ end # self.instances
+
+ def self.prefetch(resources)
+ rm_instances = instances
+ resources.keys.each do |id|
+ provider = rm_instances.find do |rmi|
+ rmi.rmname.to_s == resources[id][:rmname].to_s &&
+ rmi.sequence.to_s == resources[id][:sequence].to_s &&
+ rmi.action.to_s == resources[id][:action].to_s
+ end
+ resources[id].provider = provider unless provider.nil?
+ end
+ end
+
+ def exists?
+ @property_hash[:ensure] == :present
+ end
+
+ def create
+ @property_flush[:ensure] = :present
+ end
+
+ def destroy
+ @property_flush[:ensure] = :absent
+ end
+
+ def properties_set(new_rm=false)
+ ROUTE_MAP_ALL_PROPS.each do |prop|
+ next unless @resource[prop]
+ send("#{prop}=", @resource[prop]) if new_rm
+ unless @property_flush[prop].nil?
+ @nu.send("#{prop}=", @property_flush[prop]) if
+ @nu.respond_to?("#{prop}=")
+ end
+ end
+ # custom setters which require one-shot multi-param setters
+ match_community_set
+ match_ext_community_set
+ match_ipv4_multicast_set
+ match_ipv6_multicast_set
+ match_ip_addr_access_list_set
+ match_ip_addr_prefix_list_set
+ match_route_type_set
+ set_dampening_set
+ set_distance_set
+ set_community_set
+ set_extcommunity_4bytes_set
+ set_extcommunity_rt_set
+ set_extcommunity_cost_set
+ set_ip_next_hop_set
+ set_ip_precedence_set
+ set_metric_set
+ end
+
+ def match_ip_addr_access_list_set
+ pf = @property_flush[:match_ipv4_addr_access_list]
+ v4 = pf.nil? ? @nu.match_ipv4_addr_access_list : pf
+ pf = @property_flush[:match_ipv6_addr_access_list]
+ v6 = pf.nil? ? @nu.match_ipv6_addr_access_list : pf
+ @nu.match_ip_addr_access_list(v4, v6)
+ end
+
+ def match_ip_addr_prefix_list_set
+ pf = @property_flush[:match_ipv4_addr_prefix_list]
+ v4 = pf.nil? ? @nu.match_ipv4_addr_prefix_list : pf
+ pf = @property_flush[:match_ipv6_addr_prefix_list]
+ v6 = pf.nil? ? @nu.match_ipv6_addr_prefix_list : pf
+ @nu.match_ip_addr_prefix_list(v4, v6)
+ end
+
+ def match_community_set
+ comm = @property_flush[:match_community] ? @property_flush[:match_community] : @nu.match_community
+ pf = @property_flush[:match_community_exact_match]
+ exact = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.match_community_exact_match
+ @nu.match_community_set(comm, exact)
+ end
+
+ def match_ext_community_set
+ comm = @property_flush[:match_ext_community] ? @property_flush[:match_ext_community] : @nu.match_ext_community
+ pf = @property_flush[:match_ext_community_exact_match]
+ exact = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.match_ext_community_exact_match
+ @nu.match_ext_community_set(comm, exact)
+ end
+
+ def match_set_helper(properties, setter)
+ return unless properties.any? { |p| @property_flush.key?(p) }
+ attrs = {}
+ # At least one var has changed, get all vals from manifest
+ properties.each do |p|
+ if @resource[p] == :default
+ attrs[p] = @nu.send("default_#{p}")
+ else
+ attrs[p] = @resource[p]
+ attrs[p] = PuppetX::Cisco::Utils.bool_sym_to_s(attrs[p])
+ end
+ end
+ @nu.send(setter, *[attrs])
+ end
+
+ def match_ipv4_multicast_set
+ properties = [
+ :match_ipv4_multicast_src_addr,
+ :match_ipv4_multicast_group_addr,
+ :match_ipv4_multicast_group_range_begin_addr,
+ :match_ipv4_multicast_group_range_end_addr,
+ :match_ipv4_multicast_rp_addr,
+ :match_ipv4_multicast_rp_type,
+ :match_ipv4_multicast_enable,
+ ]
+ match_set_helper(properties, 'match_ipv4_multicast_set')
+ end
+
+ def match_ipv6_multicast_set
+ properties = [
+ :match_ipv6_multicast_src_addr,
+ :match_ipv6_multicast_group_addr,
+ :match_ipv6_multicast_group_range_begin_addr,
+ :match_ipv6_multicast_group_range_end_addr,
+ :match_ipv6_multicast_rp_addr,
+ :match_ipv6_multicast_rp_type,
+ :match_ipv6_multicast_enable,
+ ]
+ match_set_helper(properties, 'match_ipv6_multicast_set')
+ end
+
+ def match_route_type_set
+ properties = [
+ :match_route_type_external,
+ :match_route_type_inter_area,
+ :match_route_type_internal,
+ :match_route_type_intra_area,
+ :match_route_type_level_1,
+ :match_route_type_level_2,
+ :match_route_type_local,
+ :match_route_type_nssa_external,
+ :match_route_type_type_1,
+ :match_route_type_type_2,
+ ]
+ match_set_helper(properties, 'match_route_type_set')
+ end
+
+ def set_ip_precedence_set
+ pf = @property_flush[:set_ipv4_precedence]
+ v4 = pf.nil? ? @nu.set_ipv4_precedence : pf
+ pf = @property_flush[:set_ipv6_precedence]
+ v6 = pf.nil? ? @nu.set_ipv6_precedence : pf
+ @nu.set_ip_precedence(v4, v6)
+ end
+
+ def set_metric_set
+ pf = @property_flush[:set_metric_additive]
+ plus = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_metric_additive
+ bw = @property_flush[:set_metric_bandwidth].nil? ? @nu.set_metric_bandwidth : @property_flush[:set_metric_bandwidth]
+ del = @property_flush[:set_metric_delay].nil? ? @nu.set_metric_delay : @property_flush[:set_metric_delay]
+ rel = @property_flush[:set_metric_reliability].nil? ? @nu.set_metric_reliability : @property_flush[:set_metric_reliability]
+ pf = @property_flush[:set_metric_effective_bandwidth]
+ ebw = pf.nil? ? @nu.set_metric_effective_bandwidth : pf
+ mtu = @property_flush[:set_metric_mtu].nil? ? @nu.set_metric_mtu : @property_flush[:set_metric_mtu]
+ @nu.set_metric_set(plus, bw, del, rel, ebw, mtu)
+ end
+
+ def set_dampening_set
+ hl = @property_flush[:set_dampening_half_life].nil? ? @nu.set_dampening_half_life : @property_flush[:set_dampening_half_life]
+ md = @property_flush[:set_dampening_max_duation].nil? ? @nu.set_dampening_max_duation : @property_flush[:set_dampening_max_duation]
+ re = @property_flush[:set_dampening_reuse].nil? ? @nu.set_dampening_reuse : @property_flush[:set_dampening_reuse]
+ sup = @property_flush[:set_dampening_suppress].nil? ? @nu.set_dampening_suppress : @property_flush[:set_dampening_suppress]
+ @nu.set_dampening_set(hl, re, sup, md)
+ end
+
+ def set_distance_set
+ igp = @property_flush[:set_distance_igp_ebgp].nil? ? @nu.set_distance_igp_ebgp : @property_flush[:set_distance_igp_ebgp]
+ int = @property_flush[:set_distance_internal].nil? ? @nu.set_distance_internal : @property_flush[:set_distance_internal]
+ loc = @property_flush[:set_distance_local].nil? ? @nu.set_distance_local : @property_flush[:set_distance_local]
+ @nu.set_distance_set(igp, int, loc)
+ end
+
+ def set_ipv4_default_next_hop_set
+ nh = @property_flush[:set_ipv4_default_next_hop] ? @property_flush[:set_ipv4_default_next_hop] : @nu.set_ipv4_default_next_hop
+ pf = @property_flush[:set_ipv4_default_next_hop_load_share]
+ ls = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_default_next_hop_load_share
+ @nu.set_ipv4_default_next_hop_set(nh, ls)
+ end
+
+ def set_ipv4_next_hop_set
+ nh = @property_flush[:set_ipv4_next_hop] ? @property_flush[:set_ipv4_next_hop] : @nu.set_ipv4_next_hop
+ pf = @property_flush[:set_ipv4_next_hop_load_share]
+ ls = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_next_hop_load_share
+ @nu.set_ipv4_next_hop_set(nh, ls)
+ end
+
+ def set_ipv6_default_next_hop_set
+ nh = @property_flush[:set_ipv6_default_next_hop] ? @property_flush[:set_ipv6_default_next_hop] : @nu.set_ipv6_default_next_hop
+ pf = @property_flush[:set_ipv6_default_next_hop_load_share]
+ ls = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_default_next_hop_load_share
+ @nu.set_ipv6_default_next_hop_set(nh, ls)
+ end
+
+ def set_ipv6_next_hop_set
+ nh = @property_flush[:set_ipv6_next_hop] ? @property_flush[:set_ipv6_next_hop] : @nu.set_ipv6_next_hop
+ pf = @property_flush[:set_ipv6_next_hop_load_share]
+ ls = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_next_hop_load_share
+ @nu.set_ipv6_next_hop_set(nh, ls)
+ end
+
+ def set_community_set
+ pf = @property_flush[:set_community_none]
+ none = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_none
+ pf = @property_flush[:set_community_no_advtertise]
+ noadv = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_no_advtertise
+ pf = @property_flush[:set_community_no_export]
+ noexp = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_no_export
+ pf = @property_flush[:set_community_additive]
+ add = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_additive
+ pf = @property_flush[:set_community_local_as]
+ local = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_local_as
+ pf = @property_flush[:set_community_internet]
+ inter = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_community_internet
+ asn = @property_flush[:set_community_asn] ? @property_flush[:set_community_asn] : @nu.set_community_asn
+ @nu.set_community_set(none, noadv, noexp, add, local, inter, asn)
+ end
+
+ def set_extcommunity_4bytes_set
+ pf = @property_flush[:set_extcommunity_4bytes_none]
+ none = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_extcommunity_4bytes_none
+ pf = @property_flush[:set_extcommunity_4bytes_transitive]
+ tr = pf ? pf : @nu.set_extcommunity_4bytes_transitive
+ pf = @property_flush[:set_extcommunity_4bytes_non_transitive]
+ ntr = pf ? pf : @nu.set_extcommunity_4bytes_non_transitive
+ pf = @property_flush[:set_extcommunity_4bytes_additive]
+ add = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_extcommunity_4bytes_additive
+ @nu.set_extcommunity_4bytes_set(none, tr, ntr, add)
+ end
+
+ def set_extcommunity_rt_set
+ pf = @property_flush[:set_extcommunity_rt_asn]
+ asn = pf ? pf : @nu.set_extcommunity_rt_asn
+ pf = @property_flush[:set_extcommunity_rt_additive]
+ add = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_extcommunity_rt_additive
+ @nu.set_extcommunity_rt_set(asn, add)
+ end
+
+ def set_extcommunity_cost_set
+ pf = @property_flush[:set_extcommunity_cost_igp]
+ igp = pf ? pf : @nu.set_extcommunity_cost_igp
+ pf = @property_flush[:set_extcommunity_cost_pre_bestpath]
+ pre = pf ? pf : @nu.set_extcommunity_cost_pre_bestpath
+ @nu.set_extcommunity_cost_set(igp, pre)
+ end
+
+ def legacy_image?
+ fd = Facter.value('cisco')
+ image = fd['images']['system_image']
+ image[/7.0.3.I2|I3|I4/]
+ end
+
+ def v4_ip_next_hop(attrs)
+ pf = @property_flush[:set_ipv4_default_next_hop]
+ attrs[:v4dnh] = pf ? pf : @nu.set_ipv4_default_next_hop
+ pf = @property_flush[:set_ipv4_default_next_hop_load_share]
+ attrs[:v4dls] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_default_next_hop_load_share
+ pf = @property_flush[:set_ipv4_next_hop]
+ attrs[:v4nh] = pf ? pf : @nu.set_ipv4_next_hop
+ pf = @property_flush[:set_ipv4_next_hop_load_share]
+ attrs[:v4ls] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_next_hop_load_share
+ pf = @property_flush[:set_ipv4_next_hop_peer_addr]
+ attrs[:v4peer] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_next_hop_peer_addr
+ pf = @property_flush[:set_ipv4_next_hop_redist]
+ if legacy_image?
+ attrs[:v4red] = nil
+ else
+ attrs[:v4red] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_next_hop_redist
+ end
+ pf = @property_flush[:set_ipv4_next_hop_unchanged]
+ attrs[:v4unc] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv4_next_hop_unchanged
+ end
+
+ def v6_ip_next_hop(attrs)
+ pf = @property_flush[:set_ipv6_default_next_hop]
+ attrs[:v6dnh] = pf ? pf : @nu.set_ipv6_default_next_hop
+ pf = @property_flush[:set_ipv6_default_next_hop_load_share]
+ attrs[:v6dls] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_default_next_hop_load_share
+ pf = @property_flush[:set_ipv6_next_hop]
+ attrs[:v6nh] = pf ? pf : @nu.set_ipv6_next_hop
+ pf = @property_flush[:set_ipv6_next_hop_load_share]
+ attrs[:v6ls] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_next_hop_load_share
+ pf = @property_flush[:set_ipv6_next_hop_peer_addr]
+ attrs[:v6peer] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_next_hop_peer_addr
+ pf = @property_flush[:set_ipv6_next_hop_redist]
+ if legacy_image?
+ attrs[:v4red] = nil
+ else
+ attrs[:v6red] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_next_hop_redist
+ end
+ pf = @property_flush[:set_ipv6_next_hop_unchanged]
+ attrs[:v6unc] = PuppetX::Cisco::Utils.flush_boolean?(pf) ? pf : @nu.set_ipv6_next_hop_unchanged
+ end
+
+ def set_ip_next_hop_set
+ attrs = {}
+ attrs[:intf] = @property_flush[:set_interface] ? @property_flush[:set_interface] : @nu.set_interface
+ v4_ip_next_hop(attrs)
+ v6_ip_next_hop(attrs)
+ @nu.set_ip_next_hop_set(attrs)
+ end
+
+ def flush
+ if @property_flush[:ensure] == :absent
+ @nu.destroy
+ @nu = nil
+ else
+ # Create/Update
+ new_rm = false
+ if @nu.nil?
+ new_rm = true
+ @nu = Cisco::RouteMap.new(@resource[:rmname],
+ @resource[:sequence],
+ @resource[:action])
+ end
+ properties_set(new_rm)
+ end
+ end
+end
diff --git a/lib/puppet/provider/cisco_tacacs_server/cisco.rb b/lib/puppet/provider/cisco_tacacs_server/cisco.rb
index 0d79c5ae2..c8ea17ec6 100644
--- a/lib/puppet/provider/cisco_tacacs_server/cisco.rb
+++ b/lib/puppet/provider/cisco_tacacs_server/cisco.rb
@@ -114,6 +114,21 @@ def destroy
@tacacs_server = nil
end # destroy
+ # this method is put here instead of type file due to older
+ # releases of platform code is not taking care of quotes in
+ # the manifest properly
+ def encryption_password
+ res = @resource[:encryption_password]
+ ph = @property_hash[:encryption_password]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @tacacs_server.default_encryption_password
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def timeout
debug 'Getting timeout.'
if @resource[:timeout] == :default &&
diff --git a/lib/puppet/provider/cisco_tacacs_server_host/cisco.rb b/lib/puppet/provider/cisco_tacacs_server_host/cisco.rb
index 2813eec29..2746483a1 100644
--- a/lib/puppet/provider/cisco_tacacs_server_host/cisco.rb
+++ b/lib/puppet/provider/cisco_tacacs_server_host/cisco.rb
@@ -69,6 +69,21 @@ def destroy
@property_flush[:ensure] = :absent
end
+ # this method is put here instead of type file due to older
+ # releases of platform code is not taking care of quotes in
+ # the manifest properly
+ def encryption_password
+ res = @resource[:encryption_password]
+ ph = @property_hash[:encryption_password]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @tacacs_server_host.default_encryption_password
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def port
if @resource[:port] == :default &&
@property_hash[:port] == Cisco::TacacsServerHost.default_port
diff --git a/lib/puppet/provider/cisco_upgrade/cisco.rb b/lib/puppet/provider/cisco_upgrade/cisco.rb
new file mode 100644
index 000000000..c6c187e4d
--- /dev/null
+++ b/lib/puppet/provider/cisco_upgrade/cisco.rb
@@ -0,0 +1,82 @@
+#
+# Puppet provider to manage upgrade of Cisco devices
+#
+# Copyright (c) 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.
+# 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 'cisco_node_utils' if Puppet.features.cisco_node_utils?
+begin
+ require 'puppet_x/cisco/autogen'
+rescue LoadError # seen on master, not on agent
+ # See longstanding Puppet issues #4248, #7316, #14073, #14149, etc. Ugh.
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..',
+ 'puppet_x', 'cisco', 'autogen.rb'))
+end
+
+begin
+ require 'puppet_x/cisco/cmnutils'
+rescue LoadError # seen on master, not on agent
+ # See longstanding Puppet issues #4248, #7316, #14073, #14149, etc. Ugh.
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..',
+ 'puppet_x', 'cisco', 'cmnutils.rb'))
+end
+Puppet::Type.type(:cisco_upgrade).provide(:cisco) do
+ desc 'The Cisco Upgrade provider to upgrade Cisco devices.'
+
+ confine feature: :cisco_node_utils
+ defaultfor operatingsystem: :nexus
+
+ mk_resource_methods
+
+ UPGRADE_NON_BOOL_PROPS = [
+ :version
+ ]
+
+ UPGRADE_ALL_PROPS = UPGRADE_NON_BOOL_PROPS
+
+ PuppetX::Cisco::AutoGen.mk_puppet_methods(:non_bool, self, '@nu',
+ UPGRADE_NON_BOOL_PROPS)
+
+ def initialize(value={})
+ super(value)
+ @nu = Cisco::Upgrade
+ @property_flush = {}
+ end
+
+ def self.instances
+ inst = []
+ upgrade = Cisco::Upgrade
+
+ inst << new(
+ name: 'image',
+ version: upgrade.image_version)
+ end
+
+ def self.prefetch(resources)
+ resources.values.first.provider = instances.first
+ end
+
+ def version=(new_version)
+ return if new_version.nil?
+ # Convert del_boot_image and force_upgrade from symbols
+ # to Boolean Class
+ fail 'The source_uri parameter must be set in the manifest' if
+ @resource[:source_uri].nil?
+ del_boot_image = (@resource[:delete_boot_image] == :true)
+ force_upgrade = (@resource[:force_upgrade] == :true)
+ @nu.upgrade(new_version, @resource[:source_uri][:image_name], @resource[:source_uri][:uri],
+ del_boot_image, force_upgrade)
+ @property_hash[:version] = new_version
+ end
+end
diff --git a/lib/puppet/provider/radius_global/cisco.rb b/lib/puppet/provider/radius_global/cisco.rb
index 203fcef2d..8a12e96a3 100644
--- a/lib/puppet/provider/radius_global/cisco.rb
+++ b/lib/puppet/provider/radius_global/cisco.rb
@@ -76,6 +76,18 @@ def self.prefetch(resources)
end
end # self.prefetch
+ def key
+ res = @resource[:key]
+ ph = @property_hash[:key]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @radius_global.default_key
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def munge_flush(val)
if val.is_a?(String) && val.eql?('unset')
nil
diff --git a/lib/puppet/provider/radius_server/cisco.rb b/lib/puppet/provider/radius_server/cisco.rb
index cada4b15b..dc975cb7d 100644
--- a/lib/puppet/provider/radius_server/cisco.rb
+++ b/lib/puppet/provider/radius_server/cisco.rb
@@ -89,6 +89,18 @@ def self.prefetch(resources)
end
end # self.prefetch
+ def key
+ res = @resource[:key]
+ ph = @property_hash[:key]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @radius_server.default_key
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def munge_flush(val)
if val.is_a?(String) && val.eql?('unset')
nil
diff --git a/lib/puppet/provider/tacacs_global/cisco.rb b/lib/puppet/provider/tacacs_global/cisco.rb
index 0d2e7471c..96d7d92e4 100644
--- a/lib/puppet/provider/tacacs_global/cisco.rb
+++ b/lib/puppet/provider/tacacs_global/cisco.rb
@@ -74,6 +74,18 @@ def self.prefetch(resources)
end
end # self.prefetch
+ def key
+ res = @resource[:key]
+ ph = @property_hash[:key]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @tacacs_global.default_key
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def munge_flush(val)
if val.is_a?(String) && val.eql?('unset')
nil
diff --git a/lib/puppet/provider/tacacs_server/cisco.rb b/lib/puppet/provider/tacacs_server/cisco.rb
index d1edca277..2d44b6afe 100644
--- a/lib/puppet/provider/tacacs_server/cisco.rb
+++ b/lib/puppet/provider/tacacs_server/cisco.rb
@@ -117,6 +117,18 @@ def destroy
@property_flush[:ensure] = :absent
end
+ def key
+ res = @resource[:key]
+ ph = @property_hash[:key]
+ return ph if res.nil?
+ return :default if res == :default &&
+ ph == @tacacs_server.encryption_password
+ unless res.start_with?('"') && res.end_with?('"')
+ ph = ph.gsub(/\A"|"\Z/, '')
+ end
+ ph
+ end
+
def munge_flush(val)
if val.is_a?(String) && val.eql?('unset')
nil
diff --git a/lib/puppet/type/cisco_dhcp_relay_global.rb b/lib/puppet/type/cisco_dhcp_relay_global.rb
index 6ec90b0b8..8accbc9b0 100644
--- a/lib/puppet/type/cisco_dhcp_relay_global.rb
+++ b/lib/puppet/type/cisco_dhcp_relay_global.rb
@@ -124,7 +124,11 @@
munge do |value|
value = value.strip
- value = :default if value == 'default'
+ if value == 'default'
+ value = :default
+ else
+ value = "\"#{value}\"" unless value.start_with?('"') && value.end_with?('"')
+ end
value
end
end # property ipv4_sub_option_circuit_id_string
diff --git a/lib/puppet/type/cisco_interface.rb b/lib/puppet/type/cisco_interface.rb
index 375ea1d18..5b24e7c5c 100755
--- a/lib/puppet/type/cisco_interface.rb
+++ b/lib/puppet/type/cisco_interface.rb
@@ -110,6 +110,9 @@
ipv4_arp_timeout => 300,
svi_autostate => true,
svi_management => true,
+ load_interval_counter_1_delay => 150,
+ load_interval_counter_2_delay => 250,
+ load_interval_counter_3_delay => 90,
}
cisco_interface { 'ethernet8/1' :
description => 'Private-vlan host',
@@ -1251,4 +1254,29 @@ def is_to_s(value)
munge { |value| value == 'default' ? :default : Integer(value) }
end # property hsrp_version
+
+ ############################
+ # load-interval attributes #
+ ############################
+
+ newproperty(:load_interval_counter_1_delay) do
+ desc "Load interval delay for counter 1 in seconds. Valid values
+ are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property load_interval_counter_1_delay
+
+ newproperty(:load_interval_counter_2_delay) do
+ desc "Load interval delay for counter 2 in seconds. Valid values
+ are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property load_interval_counter_2_delay
+
+ newproperty(:load_interval_counter_3_delay) do
+ desc "Load interval delay for counter 3 in seconds. Valid values
+ are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property load_interval_counter_3_delay
end # Puppet::Type.newtype
diff --git a/lib/puppet/type/cisco_interface_hsrp_group.rb b/lib/puppet/type/cisco_interface_hsrp_group.rb
index 31bcbdc44..17733787a 100644
--- a/lib/puppet/type/cisco_interface_hsrp_group.rb
+++ b/lib/puppet/type/cisco_interface_hsrp_group.rb
@@ -103,6 +103,7 @@ def name
newparam(:interface, namevar: true) do
desc 'Name of the interface instance. Valid values are string.'
+ munge(&:downcase)
end # param interface
##############
diff --git a/lib/puppet/type/cisco_route_map.rb b/lib/puppet/type/cisco_route_map.rb
new file mode 100644
index 000000000..7122180d0
--- /dev/null
+++ b/lib/puppet/type/cisco_route_map.rb
@@ -0,0 +1,1659 @@
+# Manages the Cisco route map configuration resource.
+#
+# January 2017
+#
+# Copyright (c) 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.
+# 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.
+
+Puppet::Type.newtype(:cisco_route_map) do
+ @doc = "Manages a route map.
+
+ cisco_route_map {\" \":
+ ..attributes..
+ }
+
+ is the name of the route map.
+ is sequence to insert/delete existing route-map entry
+ is permit or deny.
+
+ Examples:
+ cisco_route_map {'MyRouteMap1 123 permit':
+ ensure => 'present',
+ description => 'Testing',
+ match_as_number => ['3', '22-34', '38'],
+ match_as_number_as_path_list => ['abc', 'xyz', 'pqr'],
+ match_community => ['public', 'private'],
+ match_community_exact_match => true,
+ match_evpn_route_type_1 => true,
+ match_evpn_route_type_2_all => true,
+ match_evpn_route_type_2_mac_ip => true,
+ match_evpn_route_type_2_mac_only => true,
+ match_evpn_route_type_3 => true,
+ match_evpn_route_type_4 => true,
+ match_evpn_route_type_5 => true,
+ match_evpn_route_type_6 => true,
+ match_evpn_route_type_all => true,
+ match_ext_community => ['epublic', 'eprivate'],
+ match_ext_community_exact_match => true,
+ match_interface => ['loopback2', 'mgmt0'],
+ match_ipv4_addr_access_list => 'access1',
+ match_ipv4_addr_prefix_list => ['p1', 'p7', 'pre5'],
+ match_ipv4_multicast_enable => true,
+ match_ipv4_multicast_src_addr => '242.1.1.1/32',
+ match_ipv4_multicast_group_addr => '239.2.2.2/32',
+ match_ipv4_multicast_group_range_begin_addr => default,
+ match_ipv4_multicast_group_range_end_addr => default,
+ match_ipv4_multicast_rp_addr => '242.1.1.1/32',
+ match_ipv4_multicast_rp_type => 'ASM',
+ match_ipv4_next_hop_prefix_list => ['nh5', 'nh1', 'nh42'],
+ match_ipv4_route_src_prefix_list => ['rs2', 'rs22', 'pre15'],
+ match_ipv6_addr_access_list => 'v6access',
+ match_ipv6_addr_prefix_list => ['pv6', 'pv67', 'prev6'],
+ match_ipv6_multicast_enable => true,
+ match_ipv6_multicast_src_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_group_addr => 'ff0e::2:101:0:0/96',
+ match_ipv6_multicast_group_range_begin_addr => default,
+ match_ipv6_multicast_group_range_end_addr => default,
+ match_ipv6_multicast_rp_addr => '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type => 'ASM',
+ match_ipv6_next_hop_prefix_list => ['nhv6', 'v6nh1', 'nhv42'],
+ match_ipv6_route_src_prefix_list => ['rsv6', 'rs22v6', 'prev6'],
+ match_length => ['45', '345'],
+ match_mac_list => ['mac1', 'listmac'],
+ match_metric => [['8', '0'], ['224', '9']]
+ match_ospf_area => ['10', '7', '222'],
+ match_route_type_external => true,
+ match_route_type_inter_area => true,
+ match_route_type_internal => true,
+ match_route_type_intra_area => true,
+ match_route_type_level_1 => true,
+ match_route_type_level_2 => true,
+ match_route_type_local => true,
+ match_route_type_nssa_external => true,
+ match_route_type_type_1 => true,
+ match_route_type_type_2 => true,
+ match_src_proto => ['tcp', 'udp', 'igmp'],
+ match_tag => ['5', '342', '28', '3221'],
+ match_vlan => '32, 45-200, 300-399, 402',
+ set_as_path_prepend => ['55.77', '12', '45.3'],
+ set_as_path_prepend_last_as => 1,
+ set_as_path_tag => true,
+ set_comm_list => 'abc',
+ set_community_additive => true,
+ set_community_asn => ['11:22', '33:44', '123:11'],
+ set_community_internet => true,
+ set_community_local_as => true,
+ set_community_no_advtertise => true,
+ set_community_no_export => true,
+ set_community_none => false,
+ set_dampening_half_life => 6,
+ set_dampening_max_duation => 55,
+ set_dampening_reuse => 22,
+ set_dampening_suppress => 44,
+ set_distance_igp_ebgp => 44,
+ set_dampening_suppress => 44,
+ set_dampening_suppress => 1,
+ set_distance_internal => 2,
+ set_distance_local => 3,
+ set_extcomm_list => 'xyz',
+ set_extcommunity_4bytes_additive => true,
+ set_extcommunity_4bytes_non_transitive => ['21:42', '43:22', '59:17'],
+ set_extcommunity_4bytes_transitive => ['11:22', '33:44', '66:77'],
+ set_extcommunity_cost_igp => [[0, 23], [3, 33]],
+ set_extcommunity_cost_pre_bestpath => [[23, 999], [88, 482]],
+ set_extcommunity_rt_additive => true,
+ set_extcommunity_rt_asn => ['11:22', '123.256:543'],
+ set_forwarding_addr => true,
+ set_interface => 'Null0',
+ set_ipv4_default_next_hop => ['1.1.1.1', '2.2.2.2'],
+ set_ipv4_default_next_hop_load_share => true,
+ set_ipv4_next_hop => ['3.3.3.3', '4.4.4.4'],
+ set_ipv4_next_hop_load_share => true,
+ set_ipv4_next_hop_peer_addr => true,
+ set_ipv4_next_hop_redist => true,
+ set_ipv4_next_hop_unchanged => true,
+ set_ipv4_precedence => 'critical',
+ set_ipv4_prefix => 'abcdef',
+ set_ipv6_default_next_hop => ['2000::1', '2000::11'],
+ set_ipv6_default_next_hop_load_share => true,
+ set_ipv6_next_hop => ['2000::1', '2000::11'],
+ set_ipv6_next_hop_load_share => true,
+ set_ipv6_next_hop_peer_addr => true,
+ set_ipv6_next_hop_redist => true,
+ set_ipv6_next_hop_unchanged => true,
+ set_ipv6_precedence => 'network',
+ set_ipv6_prefix => 'wxyz',
+ set_level => 'level-1',
+ set_local_preference => 100,
+ set_metric_additive => false,
+ set_metric_bandwidth => 44,
+ set_metric_delay => 55,
+ set_metric_reliability => 66,
+ set_metric_effective_bandwidth => 77,
+ set_metric_mtu => 88,
+ set_metric_type => 'external',
+ set_nssa_only => true,
+ set_origin => 'egp',
+ set_path_selection => true,
+ set_tag => 101,
+ set_vrf => 'igp',
+ set_weight => 222,
+ }
+ "
+
+ ensurable
+
+ ###################
+ # Resource Naming #
+ ###################
+
+ # Parse out the title to fill in the attributes in these
+ # patterns. These attributes can be overwritten later.
+ def self.title_patterns
+ identity = ->(x) { x }
+ patterns = []
+
+ # Below pattern matches both parts of the full composite name.
+ patterns << [
+ /^(\S+) (\d+) (\S+)$/,
+ [
+ [:rmname, identity],
+ [:sequence, identity],
+ [:action, identity],
+ ],
+ ]
+ patterns
+ end
+
+ # Overwrites name method. Original method simply returns self[:name],
+ # which is no longer valid or complete.
+ # Would not have failed, but just return nothing useful.
+ def name
+ "#{self[:rmname]} #{self[:sequence]} #{self[:action]}"
+ end
+
+ newparam(:name) do
+ desc 'Name of cisco_route_map, not used, but needed for puppet'
+ end
+
+ newparam(:rmname, namevar: true) do
+ desc 'Name of the route map instance. Valid values are string.'
+ end # param rmname
+
+ newparam(:sequence, namevar: true) do
+ desc "Sequence to insert/delete existing route-map entry.
+ Valid values are integer."
+ end # param sequence
+
+ newparam(:action, namevar: true) do
+ desc 'Action for set oprtations. Valid values are permit or deny.'
+ munge(&:to_s)
+ newvalues(:permit, :deny)
+ end # param action
+
+ ##############
+ # Attributes #
+ ##############
+
+ newproperty(:description) do
+ desc "Description of the route-map. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property description
+
+ newproperty(:match_as_number, array_matching: :all) do
+ format = '[range1, range2]'
+ desc 'Match BGP peer AS number. An array of [range1, range2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_as_number
+
+ newproperty(:match_as_number_as_path_list, array_matching: :all) do
+ format = '[list1, list2]'
+ desc 'Match BGP AS path list. An array of [list1, list2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_as_number_as_path_list
+
+ newproperty(:match_community, array_matching: :all) do
+ format = '[comm1, comm2]'
+ desc 'Match BGP community list. An array of [comm1, comm2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_community
+
+ newproperty(:match_community_exact_match) do
+ desc 'Enable exact matching of communities'
+
+ newvalues(:true, :false, :default)
+ end # property match_community_exact_match
+
+ newproperty(:match_evpn_route_type_1) do
+ desc 'Enable match BGP EVPN route type-1'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_1
+
+ newproperty(:match_evpn_route_type_2_all) do
+ desc 'Enable match all BGP EVPN route in type-2'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_2_all
+
+ newproperty(:match_evpn_route_type_2_mac_ip) do
+ desc 'Enable match mac-ip BGP EVPN route in type-2'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_2_mac_ip
+
+ newproperty(:match_evpn_route_type_2_mac_only) do
+ desc 'Enable match mac-only BGP EVPN route in type-2'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_2_mac_only
+
+ newproperty(:match_evpn_route_type_3) do
+ desc 'Enable match BGP EVPN route type-3'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_3
+
+ newproperty(:match_evpn_route_type_4) do
+ desc 'Enable match BGP EVPN route type-4'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_4
+
+ newproperty(:match_evpn_route_type_5) do
+ desc 'Enable match BGP EVPN route type-5'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_5
+
+ newproperty(:match_evpn_route_type_6) do
+ desc 'Enable match BGP EVPN route type-6'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_6
+
+ newproperty(:match_evpn_route_type_all) do
+ desc 'Enable match BGP EVPN route type 1-6'
+
+ newvalues(:true, :false, :default)
+ end # property match_evpn_route_type_all
+
+ newproperty(:match_ext_community, array_matching: :all) do
+ format = '[ecomm1, ecomm2]'
+ desc 'Match BGP extended community list. An array of [ecomm1, ecomm2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ext_community
+
+ newproperty(:match_ext_community_exact_match) do
+ desc 'Enable exact matching of extended communities'
+
+ newvalues(:true, :false, :default)
+ end # property match_ext_community_exact_match
+
+ newproperty(:match_interface, array_matching: :all) do
+ format = '[int1, int2]'
+ desc 'Match first hop interface of route. An array of [int1, int2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_interface
+
+ newproperty(:match_ipv4_addr_access_list) do
+ desc "IPv4 access-list name. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_addr_access_list
+
+ newproperty(:match_ipv4_addr_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for IPv4. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv4_addr_prefix_list
+
+ newproperty(:match_ipv4_multicast_enable) do
+ desc 'Enable match IPv4 multicast'
+
+ newvalues(:true, :false, :default)
+ end # property match_ipv4_multicast_enable
+
+ newproperty(:match_ipv4_multicast_group_addr) do
+ desc "Match IPv4 multicast group prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_multicast_group_addr
+
+ newproperty(:match_ipv4_multicast_group_range_begin_addr) do
+ desc "Match IPv4 multicast group address begin range.
+ Valid values are string, keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_multicast_group_range_begin_addr
+
+ newproperty(:match_ipv4_multicast_group_range_end_addr) do
+ desc "Match IPv4 multicast group address end range.
+ Valid values are string, keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_multicast_group_range_end_addr
+
+ newproperty(:match_ipv4_multicast_rp_addr) do
+ desc "Match IPv4 multicast rendezvous prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_multicast_rp_addr
+
+ newproperty(:match_ipv4_multicast_rp_type) do
+ desc 'Match IPv4 multicast rendezvous point type'
+
+ newvalues(:ASM, :Bidir, :default)
+ end # property match_ipv4_multicast_rp_type
+
+ newproperty(:match_ipv4_multicast_src_addr) do
+ desc "Match IPv4 multicast source prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv4_multicast_src_addr
+
+ newproperty(:match_ipv4_next_hop_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for next-hop address of route for IPv4. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv4_next_hop_prefix_list
+
+ newproperty(:match_ipv4_route_src_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for advertising source address of route for IPv4. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv4_route_src_prefix_list
+
+ newproperty(:match_ipv6_addr_access_list) do
+ desc "IPv6 access-list name. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_addr_access_list
+
+ newproperty(:match_ipv6_addr_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for IPv6. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv6_addr_prefix_list
+
+ newproperty(:match_ipv6_multicast_enable) do
+ desc 'Enable match IPv6 multicast'
+
+ newvalues(:true, :false, :default)
+ end # property match_ipv6_multicast_enable
+
+ newproperty(:match_ipv6_multicast_group_addr) do
+ desc "Match IPv6 multicast group prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_multicast_group_addr
+
+ newproperty(:match_ipv6_multicast_group_range_begin_addr) do
+ desc "Match IPv6 multicast group address begin range.
+ Valid values are string, keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_multicast_group_range_begin_addr
+
+ newproperty(:match_ipv6_multicast_group_range_end_addr) do
+ desc "Match IPv6 multicast group address end range.
+ Valid values are string, keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_multicast_group_range_end_addr
+
+ newproperty(:match_ipv6_multicast_rp_addr) do
+ desc "Match IPv6 multicast rendezvous prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_multicast_rp_addr
+
+ newproperty(:match_ipv6_multicast_rp_type) do
+ desc 'Match IPv6 multicast rendezvous point type'
+
+ newvalues(:ASM, :Bidir, :default)
+ end # property match_ipv6_multicast_rp_type
+
+ newproperty(:match_ipv6_multicast_src_addr) do
+ desc "Match IPv6 multicast source prefix. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property match_ipv6_multicast_src_addr
+
+ newproperty(:match_ipv6_next_hop_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for next-hop address of route for IPv6. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv6_next_hop_prefix_list
+
+ newproperty(:match_ipv6_route_src_prefix_list, array_matching: :all) do
+ format = '[pf1, pf2]'
+ desc 'Match entries of prefix-lists for advertising source address of route for IPv6. An array of [pf1, pf2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ipv6_route_src_prefix_list
+
+ newproperty(:match_length, array_matching: :all) do
+ format = '[minlen, maxlen]'
+ desc 'Match packet length. An array of [minlen, maxlen]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_length
+
+ newproperty(:match_mac_list, array_matching: :all) do
+ format = '[list1, list2]'
+ desc 'Match entries of mac-lists. An array of [list1, list2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_mac_list
+
+ newproperty(:match_metric, array_matching: :all) do
+ format = '[[metric, deviation], [met, dev]]'
+ desc 'An array of [metric, deviation] pairs. '\
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ fail("Value must match format #{format}") unless value.is_a?(Array)
+ value
+ end
+ end
+ end # property match_metric
+
+ newproperty(:match_ospf_area, array_matching: :all) do
+ format = '[area1, area2]'
+ desc 'Match entries of ospf area IDs. An array of [area1, area2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_ospf_area
+
+ newproperty(:match_route_type_external) do
+ desc 'Enable match external route type (BGP, EIGRP and OSPF type 1/2)'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_external
+
+ newproperty(:match_route_type_inter_area) do
+ desc 'Enable match OSPF inter area type'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_inter_area
+
+ newproperty(:match_route_type_internal) do
+ desc 'Enable match OSPF inter area type (OSPF intra/inter area)'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_internal
+
+ newproperty(:match_route_type_intra_area) do
+ desc 'Enable match OSPF intra area route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_intra_area
+
+ newproperty(:match_route_type_level_1) do
+ desc 'Enable match IS-IS level-1 route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_level_1
+
+ newproperty(:match_route_type_level_2) do
+ desc 'Enable match IS-IS level-2 route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_level_2
+
+ newproperty(:match_route_type_local) do
+ desc 'Enable match locally generated route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_local
+
+ newproperty(:match_route_type_nssa_external) do
+ desc 'Enable match nssa-external route (OSPF type 1/2)'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_nssa_external
+
+ newproperty(:match_route_type_type_1) do
+ desc 'Enable match OSPF external type 1 route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_type_1
+
+ newproperty(:match_route_type_type_2) do
+ desc 'Enable match OSPF external type 2 route'
+
+ newvalues(:true, :false, :default)
+ end # property match_route_type_type_2
+
+ newproperty(:match_src_proto, array_matching: :all) do
+ format = '[pr1, pr2]'
+ desc 'Match source protocol. An array of [pr1, pr2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_src_proto
+
+ newproperty(:match_tag, array_matching: :all) do
+ format = '[tag1, tag2]'
+ desc 'Match tag of route. An array of [tag1, tag2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property match_tag
+
+ newproperty(:match_vlan) do
+ desc "Match Vlan ID. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = value == 'default' ? :default : PuppetX::Cisco::Utils.range_summarize(value)
+ value = value.gsub(',', ', ') unless value == :default
+ value
+ end
+ end # property match_vlan
+
+ newproperty(:set_as_path_prepend, array_matching: :all) do
+ format = '[asn1, asn2]'
+ desc 'Prepend string for a BGP AS-path attribute. An array of [asn1, asn2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_as_path_prepend
+
+ newproperty(:set_as_path_prepend_last_as) do
+ desc "Number of last-AS prepends. Valid values are
+ integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_as_path_prepend_last_as
+
+ newproperty(:set_as_path_tag) do
+ desc 'Set the tag as an AS-path attribute'
+
+ newvalues(:true, :false, :default)
+ end # property set_as_path_tag
+
+ newproperty(:set_comm_list) do
+ desc "Set BGP community list (for deletion). Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property set_comm_list
+
+ newproperty(:set_community_additive) do
+ desc 'Add to existing BGP community'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_additive
+
+ newproperty(:set_community_asn, array_matching: :all) do
+ format = '[asn1, asn2]'
+ desc 'Set community number. An array of [asn1, asn2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_community_asn
+
+ newproperty(:set_community_internet) do
+ desc 'Set Internet community'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_internet
+
+ newproperty(:set_community_local_as) do
+ desc 'Do not send outside local AS'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_local_as
+
+ newproperty(:set_community_no_advtertise) do
+ desc 'Do not advertise to any peer'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_no_advtertise
+
+ newproperty(:set_community_no_export) do
+ desc 'Do not export to next AS'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_no_export
+
+ newproperty(:set_community_none) do
+ desc 'Set no community attribute'
+
+ newvalues(:true, :false, :default)
+ end # property set_community_none
+
+ newproperty(:set_dampening_half_life) do
+ desc "Set half-life time for the penalty of BGP route flap dampening.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_dampening_half_life
+
+ newproperty(:set_dampening_max_duation) do
+ desc "Set maximum duration to suppress a stable route of BGP route
+ flap dampening. Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_dampening_max_duation
+
+ newproperty(:set_dampening_reuse) do
+ desc "Set penalty to start reusing a route of BGP route flap dampening.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_dampening_reuse
+
+ newproperty(:set_dampening_suppress) do
+ desc "Set penalty to start suppressing a route of BGP route
+ flap dampening. Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_dampening_suppress
+
+ newproperty(:set_distance_igp_ebgp) do
+ desc "Set administrative distance for IGP or EBGP routes.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_distance_igp_ebgp
+
+ newproperty(:set_distance_internal) do
+ desc "Set administrative distance for internal routes.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_distance_internal
+
+ newproperty(:set_distance_local) do
+ desc "Set administrative distance for local routes.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_distance_local
+
+ newproperty(:set_extcomm_list) do
+ desc "Set BGP extended community list (for deletion). Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property set_extcomm_list
+
+ newproperty(:set_extcommunity_4bytes_additive) do
+ desc 'Add to existing generic extcommunity'
+
+ newvalues(:true, :false, :default)
+ end # property set_extcommunity_4bytes_additive
+
+ newproperty(:set_extcommunity_4bytes_non_transitive, array_matching: :all) do
+ format = '[nt1, nt2]'
+ desc 'Set non-transitive extended community. An array of [nt1, nt2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_extcommunity_4bytes_non_transitive
+
+ newproperty(:set_extcommunity_4bytes_none) do
+ desc 'Set no extcommunity generic attribute'
+
+ newvalues(:true, :false, :default)
+ end # property set_extcommunity_4bytes_none
+
+ newproperty(:set_extcommunity_4bytes_transitive, array_matching: :all) do
+ format = '[tr1, tr2]'
+ desc 'Set transitive extended community. An array of [tr1, tr2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_extcommunity_4bytes_transitive
+
+ newproperty(:set_extcommunity_cost_igp, array_matching: :all) do
+ format = '[[communityId, cost], [cid, co]]'
+ desc 'An array of [communityId, cost] pairs. '\
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ fail("Value must match format #{format}") unless value.is_a?(Array)
+ value
+ end
+ end
+ end # property set_extcommunity_cost_igp
+
+ newproperty(:set_extcommunity_cost_pre_bestpath, array_matching: :all) do
+ format = '[[communityId, cost], [cid, co]]'
+ desc 'An array of [communityId, cost] pairs. '\
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ fail("Value must match format #{format}") unless value.is_a?(Array)
+ value
+ end
+ end
+ end # property set_extcommunity_cost_pre_bestpath
+
+ newproperty(:set_extcommunity_rt_additive) do
+ desc 'Set add to existing route target extcommunity'
+
+ newvalues(:true, :false, :default)
+ end # property set_extcommunity_rt_additive
+
+ newproperty(:set_extcommunity_rt_asn, array_matching: :all) do
+ format = '[asn1, asn2]'
+ desc 'Set community number. An array of [asn1, asn2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_extcommunity_rt_asn
+
+ newproperty(:set_forwarding_addr) do
+ desc 'Set the forwarding address'
+
+ newvalues(:true, :false, :default)
+ end # property set_forwarding_addr
+
+ newproperty(:set_interface) do
+ desc 'Set output interface'
+
+ newvalues(:Null0, :default)
+ end # property set_interface
+
+ newproperty(:set_ipv4_default_next_hop, array_matching: :all) do
+ format = '[dnh1, dnh2]'
+ desc 'Set default next-hop IPv4 address. An array of [dnh1, dnh2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_ipv4_default_next_hop
+
+ newproperty(:set_ipv4_default_next_hop_load_share) do
+ desc 'Enable default IPv4 next-hop load-sharing'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv4_default_next_hop_load_share
+
+ newproperty(:set_ipv4_next_hop, array_matching: :all) do
+ format = '[nh1, nh2]'
+ desc 'Set default next-hop ip address. An array of [nh1, nh2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_ipv4_next_hop
+
+ newproperty(:set_ipv4_next_hop_load_share) do
+ desc 'Enable IPv4 next-hop load-sharing'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv4_next_hop_load_share
+
+ newproperty(:set_ipv4_next_hop_peer_addr) do
+ desc 'Enable IPv4 next-hop peer address'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv4_next_hop_peer_addr
+
+ newproperty(:set_ipv4_next_hop_redist) do
+ desc 'Enable IPv4 next-hop unchanged address during redistribution'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv4_next_hop_redist
+
+ newproperty(:set_ipv4_next_hop_unchanged) do
+ desc 'Enable IPv4 next-hop unchanged address'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv4_next_hop_unchanged
+
+ newproperty(:set_ipv4_precedence) do
+ desc 'Set precedence field'
+
+ newvalues(:critical, :flash, :'flash-override', :immediate,
+ :internet, :network, :priority, :routine, :default)
+ end # property set_ipv4_precedence
+
+ newproperty(:set_ipv4_prefix) do
+ desc "Set IPv4 prefix-list. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property set_ipv4_prefix
+
+ newproperty(:set_ipv6_default_next_hop, array_matching: :all) do
+ format = '[nh1, nh2]'
+ desc 'Set default next-hop IPv6 address. An array of [nh1, nh2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_ipv6_default_next_hop
+
+ newproperty(:set_ipv6_default_next_hop_load_share) do
+ desc 'Enable default IPv6 next-hop load-sharing'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv6_default_next_hop_load_share
+
+ newproperty(:set_ipv6_next_hop, array_matching: :all) do
+ format = '[dnh1, dnh2]'
+ desc 'Set default next-hop ip address. An array of [dnh1, dnh2 and so on]' \
+ "Valid values match format #{format}."
+
+ # Override puppet's insync method, which checks whether current value is
+ # equal to value specified in manifest. Make sure puppet considers
+ # 2 arrays with same elements but in different order as equal.
+ def insync?(is)
+ (is.size == should.size && is.sort == should.sort)
+ end
+
+ def should_to_s(value)
+ value.inspect
+ end
+
+ def is_to_s(value)
+ value.inspect
+ end
+
+ munge do |value|
+ begin
+ return value = :default if value == 'default'
+ value
+ end
+ end
+ end # property set_ipv6_next_hop
+
+ newproperty(:set_ipv6_next_hop_load_share) do
+ desc 'Enable IPv6 next-hop load-sharing'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv6_next_hop_load_share
+
+ newproperty(:set_ipv6_next_hop_peer_addr) do
+ desc 'Enable IPv6 next-hop peer address'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv6_next_hop_peer_addr
+
+ newproperty(:set_ipv6_next_hop_redist) do
+ desc 'Enable IPv6 next-hop unchanged address during redistribution'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv6_next_hop_redist
+
+ newproperty(:set_ipv6_next_hop_unchanged) do
+ desc 'Enable IPv6 next-hop unchanged address'
+
+ newvalues(:true, :false, :default)
+ end # property set_ipv6_next_hop_unchanged
+
+ newproperty(:set_ipv6_precedence) do
+ desc 'Set precedence field'
+
+ newvalues(:critical, :flash, :'flash-override', :immediate,
+ :internet, :network, :priority, :routine, :default)
+ end # property set_ipv6_precedence
+
+ newproperty(:set_ipv6_prefix) do
+ desc "Set IPv6 prefix-list. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property set_ipv6_prefix
+
+ newproperty(:set_level) do
+ desc 'Set where to import route'
+
+ newvalues(:'level-1', :'level-1-2', :'level-2', :default)
+ end # property set_level
+
+ newproperty(:set_local_preference) do
+ desc "Set BGP local preference path attribute.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_local_preference
+
+ newproperty(:set_metric_additive) do
+ desc 'Set add to metric'
+
+ newvalues(:true, :false, :default)
+ end # property set_metric_additive
+
+ newproperty(:set_metric_bandwidth) do
+ desc "Set metric value or Bandwidth in kbps.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_metric_bandwidth
+
+ newproperty(:set_metric_delay) do
+ desc "Set IGRP delay metric.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_metric_delay
+
+ newproperty(:set_metric_effective_bandwidth) do
+ desc "Set IGRP Effective bandwidth metric.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_metric_effective_bandwidth
+
+ newproperty(:set_metric_mtu) do
+ desc "Set IGRP MTU of the path.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_metric_mtu
+
+ newproperty(:set_metric_reliability) do
+ desc "Set IGRP reliability metric.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_metric_reliability
+
+ newproperty(:set_metric_type) do
+ desc 'Set type of metric for destination routing protocol'
+
+ newvalues(:external, :internal, :'type-1', :'type-2', :default)
+ end # property set_metric_type
+
+ newproperty(:set_nssa_only) do
+ desc 'Set OSPF NSSA Areas'
+
+ newvalues(:true, :false, :default)
+ end # property set_nssa_only
+
+ newproperty(:set_origin) do
+ desc 'Set BGP origin code'
+
+ newvalues(:egp, :igp, :incomplete, :default)
+ end # property set_origin
+
+ newproperty(:set_path_selection) do
+ desc 'Set path selection criteria for BGP'
+
+ newvalues(:true, :false, :default)
+ end # property set_path_selection
+
+ newproperty(:set_tag) do
+ desc "Set tag value for destination routing protocol.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_tag
+
+ newproperty(:set_vrf) do
+ desc "Set the VRF for next-hop resolution. Valid values are string,
+ keyword 'default'"
+
+ munge do |value|
+ value = :default if value == 'default'
+ value
+ end
+ end # property set_vrf
+
+ newproperty(:set_weight) do
+ desc "Set BGP weight for routing table.
+ Valid values are integer, keyword 'default'."
+
+ munge { |value| value == 'default' ? :default : Integer(value) }
+ end # property set_weight
+
+ def cmprop(prop)
+ self[prop].nil? || self[prop].empty? || self[prop] == :default
+ end
+
+ def check_match_ipv4_multicast
+ return if cmprop(:match_ipv4_multicast_enable)
+ fail ArgumentError, 'At least one of the ipv4 multicast properties MUST be non default' if
+ cmprop(:match_ipv4_multicast_src_addr) &&
+ cmprop(:match_ipv4_multicast_group_addr) &&
+ cmprop(:match_ipv4_multicast_rp_addr) &&
+ cmprop(:match_ipv4_multicast_group_range_begin_addr) &&
+ cmprop(:match_ipv4_multicast_group_range_end_addr)
+ end
+
+ def check_match_ipv6_multicast
+ return if cmprop(:match_ipv6_multicast_enable)
+ fail ArgumentError, 'At least one of the ipv6 multicast properties MUST be non default' if
+ cmprop(:match_ipv6_multicast_src_addr) &&
+ cmprop(:match_ipv6_multicast_group_addr) &&
+ cmprop(:match_ipv6_multicast_rp_addr) &&
+ cmprop(:match_ipv6_multicast_group_range_begin_addr) &&
+ cmprop(:match_ipv6_multicast_group_range_end_addr)
+ end
+
+ validate do
+ check_match_ipv4_multicast
+ check_match_ipv6_multicast
+ end
+end
diff --git a/lib/puppet/type/cisco_upgrade.rb b/lib/puppet/type/cisco_upgrade.rb
new file mode 100644
index 000000000..3bf9cc55a
--- /dev/null
+++ b/lib/puppet/type/cisco_upgrade.rb
@@ -0,0 +1,116 @@
+#
+# Manages the version of Cisco Image running on a device.
+#
+# Copyright (c) 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.
+# 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.
+
+Puppet::Type.newtype(:cisco_upgrade) do
+ @doc = "Manages the version of Cisco Image running on a device.
+
+ ```
+ cisco_upgrade {\"\":
+ ..attributes..
+ }
+ ```
+
+ There can only be one instance of cisco_upgrade i.e. 'image'
+
+ Example:
+ ```
+ cisco_upgrade {'image' :
+ version => '7.0(3)I5(1)',
+ source_uri => 'bootflash:///nxos.7.0.3.I5.1.bin',
+ force_upgrade => false,
+ delete_boot_image => false,
+ }
+ ```
+ "
+
+ # Parse out the title to fill in the attributes in these
+ # patterns. These attributes can be overwritten later.
+ def self.title_patterns
+ identity = ->(x) { x }
+ patterns = []
+
+ patterns << [
+ /^(\S+)$/,
+ [
+ [:name, identity]
+ ],
+ ]
+ patterns
+ end
+
+ newparam(:name, namevar: :true) do
+ # Parameter used only to satisfy namevar
+ desc 'Name of cisco_upgrade instance. Valid values are string'
+ validate do |name|
+ warning "only 'image' is accepted as a valid name" if name != 'image'
+ end
+ end
+
+ newparam(:source_uri) do
+ examples = "\nExample:\nbootflash:nxos.7.0.3.I5.2.bin"
+ supported = "\nNOTE: Only bootflash: is supported."
+ desc "URI to the image to install on the device. Format :.
+ Valid values are string.#{examples}#{supported}"
+
+ validate do |uri|
+ fail 'source_uri must match format :' unless uri[/\S+:\S+/]
+ end
+ munge do |uri|
+ image = {}
+ # Convert : to a hash.
+ # The Node-utils API expects uri and image_name as two
+ # separate arguments. Pre-processing the arguments here.
+ if uri.include?('/')
+ image[:uri] = uri.split('/')[0]
+ image[:image_name] = uri.split('/')[-1]
+ else
+ image[:uri] = uri.split(':')[0] + ':'
+ image[:image_name] = uri.split(':')[-1]
+ end
+ image
+ end
+ end # param source_uri
+
+ newparam(:force_upgrade) do
+ desc 'Force upgrade the device.'
+ defaultto :false
+ newvalues(:true, :false)
+ end # param force_upgrade
+
+ newparam(:delete_boot_image) do
+ desc 'Delete the booted image(s).'
+ defaultto :false
+ newvalues(:true, :false)
+ end # param delete_boot_image
+
+ ##############
+ # Attributes #
+ ##############
+
+ newproperty(:version) do
+ desc 'Version of the Cisco image to install on the device.
+ Valid values are strings'
+ validate do |ver|
+ fail "Version can't be nil or an empty string" if
+ ver == '' || ver.nil? == :true
+ valid_chars = 'Version can only have the following
+ characters: 0-9, a-z, A-Z, (, ) and .'
+ fail "Invalid version string. #{valid_chars}" unless
+ (/([0-9a-zA-Z().]*)/.match(ver))[0] == ver
+ end
+ end # property version
+end
diff --git a/metadata.json b/metadata.json
index a5fb7d30d..9e55de5b1 100644
--- a/metadata.json
+++ b/metadata.json
@@ -1,6 +1,6 @@
{
"name": "puppetlabs-ciscopuppet",
- "version": "1.5.0",
+ "version": "1.6.0",
"author": "cisco",
"summary": "Cisco Puppet providers and types for NX-OS devices",
"license": "Apache-2.0",
@@ -34,9 +34,9 @@
"7.0(3)I3",
"7.0(3)I4",
"7.0(3)I5",
- "7.3(0)N1(1)",
- "7.3(0)D1(1)",
- "7.0(3)F1(1)",
+ "7.3(0)N1",
+ "7.3(0)D1",
+ "7.0(3)F1",
"8.0(1)"
]
}
diff --git a/tests/beaker_tests/cisco_command_config/test_command_config.rb b/tests/beaker_tests/cisco_command_config/test_command_config.rb
index 49933c313..7847c149a 100644
--- a/tests/beaker_tests/cisco_command_config/test_command_config.rb
+++ b/tests/beaker_tests/cisco_command_config/test_command_config.rb
@@ -163,6 +163,25 @@
},
}
+tests[:control_characters] = {
+ desc: '1.6 CTRL_CHARS',
+ # Command indentation is very important!
+ # Make sure config appears exactly how it nvgens on the switch.
+ manifest_props: {
+ command: "
+feature bgp\r\n
+router bgp 55\r\n
+ neighbor 1.1.1.1\r\n
+ address-family ipv6 unicast\r\n
+ capability additional-paths send\t\r\n
+ "
+ },
+ resource: {
+ 'ensure' => 'present',
+ 'additional_paths_send' => 'enable',
+ },
+}
+
def test_set_get
stepinfo = 'Test test_get/test_set properties'
logger.info("\n#{'-' * 60}\n#{stepinfo}")
@@ -211,6 +230,10 @@ def test_harness_run_cc(tests, id, res_cmd)
test_harness_run_cc(tests, :bgp_neighbor_af, 'cisco_bgp_neighbor_af')
test_harness_run_cc(tests, :loopback, 'cisco_interface')
+ # Cleanup before next test.
+ cleanup(agent)
+ test_harness_run_cc(tests, :control_characters, 'cisco_bgp_neighbor_af')
+
# -------------------------------------------------------------------
logger.info("\n#{'-' * 60}\nSection 2. test_set / test_get")
cleanup(agent)
diff --git a/tests/beaker_tests/cisco_dhcp_relay_global/test_dhcp_relay_global.rb b/tests/beaker_tests/cisco_dhcp_relay_global/test_dhcp_relay_global.rb
index aac0514bf..0d6953e1d 100644
--- a/tests/beaker_tests/cisco_dhcp_relay_global/test_dhcp_relay_global.rb
+++ b/tests/beaker_tests/cisco_dhcp_relay_global/test_dhcp_relay_global.rb
@@ -99,7 +99,7 @@
ipv4_src_addr_hsrp: 'true',
ipv4_src_intf: 'port-channel200',
ipv4_sub_option_circuit_id_custom: 'true',
- ipv4_sub_option_circuit_id_string: 'WORD',
+ ipv4_sub_option_circuit_id_string: add_quotes('WORD'),
ipv4_sub_option_cisco: 'true',
ipv6_option_cisco: 'true',
ipv6_option_vpn: 'true',
diff --git a/tests/beaker_tests/cisco_interface/test_interface_L2.rb b/tests/beaker_tests/cisco_interface/test_interface_L2.rb
index db385aaa0..56391d4fe 100755
--- a/tests/beaker_tests/cisco_interface/test_interface_L2.rb
+++ b/tests/beaker_tests/cisco_interface/test_interface_L2.rb
@@ -86,6 +86,9 @@
sys_def_sw_shut: true,
manifest_props: {
shutdown: 'default',
+ load_interval_counter_1_delay: 'default',
+ load_interval_counter_2_delay: 'default',
+ load_interval_counter_3_delay: 'default',
storm_control_broadcast: 'default',
storm_control_multicast: 'default',
storm_control_unicast: 'default',
@@ -97,6 +100,9 @@
},
resource: {
shutdown: 'true',
+ load_interval_counter_1_delay: '30',
+ load_interval_counter_2_delay: '300',
+ load_interval_counter_3_delay: 'false',
storm_control_broadcast: '100.00',
storm_control_multicast: '100.00',
storm_control_unicast: '100.00',
@@ -115,6 +121,9 @@
sys_def_sw_shut: true,
manifest_props: {
shutdown: 'false',
+ load_interval_counter_1_delay: '200',
+ load_interval_counter_2_delay: '100',
+ load_interval_counter_3_delay: '150',
storm_control_broadcast: '22.22',
storm_control_multicast: '44.44',
storm_control_unicast: '66.66',
diff --git a/tests/beaker_tests/cisco_route_map/test_route_map.rb b/tests/beaker_tests/cisco_route_map/test_route_map.rb
new file mode 100644
index 000000000..7ff8abdbb
--- /dev/null
+++ b/tests/beaker_tests/cisco_route_map/test_route_map.rb
@@ -0,0 +1,571 @@
+###############################################################################
+# Copyright (c) 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.
+# 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.
+###############################################################################
+#
+# See README-develop-beaker-scripts.md (Section: Test Script Variable Reference)
+# for information regarding:
+# - test script general prequisites
+# - command return codes
+# - A description of the 'tests' hash and its usage
+#
+###############################################################################
+
+require File.expand_path('../../lib/utilitylib.rb', __FILE__)
+
+# Test hash top-level keys
+tests = {
+ master: master,
+ agent: agent,
+ operating_system: 'nexus',
+ resource_name: 'cisco_route_map',
+}
+
+skip_unless_supported(tests)
+
+# Test hash test cases
+tests[:default] = {
+ desc: '1.1 Defaults',
+ title_pattern: 'rm1 123 permit',
+ manifest_props: {
+ description: 'default',
+ match_as_number: 'default',
+ match_as_number_as_path_list: 'default',
+ match_community: 'default',
+ match_community_exact_match: 'default',
+ match_evpn_route_type_1: 'default',
+ match_evpn_route_type_2_all: 'default',
+ match_evpn_route_type_2_mac_ip: 'default',
+ match_evpn_route_type_2_mac_only: 'default',
+ match_evpn_route_type_3: 'default',
+ match_evpn_route_type_4: 'default',
+ match_evpn_route_type_5: 'default',
+ match_evpn_route_type_6: 'default',
+ match_evpn_route_type_all: 'default',
+ match_ext_community: 'default',
+ match_ext_community_exact_match: 'default',
+ match_interface: 'default',
+ match_ipv4_addr_access_list: 'default',
+ match_ipv4_addr_prefix_list: 'default',
+ match_ipv4_multicast_enable: 'default',
+ match_ipv4_multicast_group_addr: 'default',
+ match_ipv4_multicast_group_range_begin_addr: 'default',
+ match_ipv4_multicast_group_range_end_addr: 'default',
+ match_ipv4_multicast_rp_addr: 'default',
+ match_ipv4_multicast_rp_type: 'default',
+ match_ipv4_multicast_src_addr: 'default',
+ match_ipv4_next_hop_prefix_list: 'default',
+ match_ipv4_route_src_prefix_list: 'default',
+ match_ipv6_addr_access_list: 'default',
+ match_ipv6_addr_prefix_list: 'default',
+ match_ipv6_multicast_enable: 'default',
+ match_ipv6_multicast_group_addr: 'default',
+ match_ipv6_multicast_group_range_begin_addr: 'default',
+ match_ipv6_multicast_group_range_end_addr: 'default',
+ match_ipv6_multicast_rp_addr: 'default',
+ match_ipv6_multicast_rp_type: 'default',
+ match_ipv6_multicast_src_addr: 'default',
+ match_ipv6_next_hop_prefix_list: 'default',
+ match_ipv6_route_src_prefix_list: 'default',
+ match_length: 'default',
+ match_mac_list: 'default',
+ match_metric: 'default',
+ match_ospf_area: 'default',
+ match_route_type_external: 'default',
+ match_route_type_inter_area: 'default',
+ match_route_type_internal: 'default',
+ match_route_type_intra_area: 'default',
+ match_route_type_level_1: 'default',
+ match_route_type_level_2: 'default',
+ match_route_type_local: 'default',
+ match_route_type_nssa_external: 'default',
+ match_route_type_type_1: 'default',
+ match_route_type_type_2: 'default',
+ match_src_proto: 'default',
+ match_tag: 'default',
+ match_vlan: 'default',
+ set_as_path_prepend: 'default',
+ set_as_path_prepend_last_as: 'default',
+ set_as_path_tag: 'default',
+ set_comm_list: 'default',
+ set_community_additive: 'default',
+ set_community_asn: 'default',
+ set_community_internet: 'default',
+ set_community_local_as: 'default',
+ set_community_no_advtertise: 'default',
+ set_community_no_export: 'default',
+ set_community_none: 'default',
+ set_dampening_half_life: 'default',
+ set_dampening_max_duation: 'default',
+ set_dampening_reuse: 'default',
+ set_dampening_suppress: 'default',
+ set_distance_igp_ebgp: 'default',
+ set_distance_internal: 'default',
+ set_distance_local: 'default',
+ set_extcomm_list: 'default',
+ set_extcommunity_4bytes_additive: 'default',
+ set_extcommunity_4bytes_non_transitive: 'default',
+ set_extcommunity_4bytes_none: 'default',
+ set_extcommunity_4bytes_transitive: 'default',
+ set_extcommunity_cost_igp: 'default',
+ set_extcommunity_cost_pre_bestpath: 'default',
+ set_extcommunity_rt_additive: 'default',
+ set_extcommunity_rt_asn: 'default',
+ set_forwarding_addr: 'default',
+ set_interface: 'default',
+ set_ipv4_default_next_hop: 'default',
+ set_ipv4_default_next_hop_load_share: 'default',
+ set_ipv4_next_hop: 'default',
+ set_ipv4_next_hop_load_share: 'default',
+ set_ipv4_next_hop_peer_addr: 'default',
+ set_ipv4_next_hop_redist: 'default',
+ set_ipv4_next_hop_unchanged: 'default',
+ set_ipv4_precedence: 'default',
+ set_ipv4_prefix: 'default',
+ set_ipv6_default_next_hop: 'default',
+ set_ipv6_default_next_hop_load_share: 'default',
+ set_ipv6_next_hop: 'default',
+ set_ipv6_next_hop_load_share: 'default',
+ set_ipv6_next_hop_peer_addr: 'default',
+ set_ipv6_next_hop_redist: 'default',
+ set_ipv6_next_hop_unchanged: 'default',
+ set_ipv6_precedence: 'default',
+ set_ipv6_prefix: 'default',
+ set_level: 'default',
+ set_local_preference: 'default',
+ set_metric_additive: 'default',
+ set_metric_bandwidth: 'default',
+ set_metric_delay: 'default',
+ set_metric_effective_bandwidth: 'default',
+ set_metric_mtu: 'default',
+ set_metric_reliability: 'default',
+ set_metric_type: 'default',
+ set_nssa_only: 'default',
+ set_origin: 'default',
+ set_path_selection: 'default',
+ set_tag: 'default',
+ set_vrf: 'default',
+ set_weight: 'default',
+ },
+ code: [0, 2],
+ resource: {
+ description: 'false',
+ match_community_exact_match: 'false',
+ match_evpn_route_type_1: 'false',
+ match_evpn_route_type_2_all: 'false',
+ match_evpn_route_type_2_mac_ip: 'false',
+ match_evpn_route_type_2_mac_only: 'false',
+ match_evpn_route_type_3: 'false',
+ match_evpn_route_type_4: 'false',
+ match_evpn_route_type_5: 'false',
+ match_evpn_route_type_6: 'false',
+ match_evpn_route_type_all: 'false',
+ match_ext_community_exact_match: 'false',
+ match_ipv4_addr_access_list: 'false',
+ match_ipv4_multicast_enable: 'false',
+ match_ipv6_addr_access_list: 'false',
+ match_ipv6_multicast_enable: 'false',
+ match_route_type_external: 'false',
+ match_route_type_inter_area: 'false',
+ match_route_type_internal: 'false',
+ match_route_type_intra_area: 'false',
+ match_route_type_level_1: 'false',
+ match_route_type_level_2: 'false',
+ match_route_type_local: 'false',
+ match_route_type_nssa_external: 'false',
+ match_route_type_type_1: 'false',
+ match_route_type_type_2: 'false',
+ set_as_path_prepend_last_as: 'false',
+ set_as_path_tag: 'false',
+ set_comm_list: 'false',
+ set_community_additive: 'false',
+ set_community_internet: 'false',
+ set_community_local_as: 'false',
+ set_community_no_advtertise: 'false',
+ set_community_no_export: 'false',
+ set_community_none: 'false',
+ set_dampening_half_life: 'false',
+ set_dampening_max_duation: 'false',
+ set_dampening_reuse: 'false',
+ set_dampening_suppress: 'false',
+ set_distance_igp_ebgp: 'false',
+ set_distance_internal: 'false',
+ set_distance_local: 'false',
+ set_extcomm_list: 'false',
+ set_extcommunity_4bytes_additive: 'false',
+ set_extcommunity_4bytes_none: 'false',
+ set_extcommunity_rt_additive: 'false',
+ set_forwarding_addr: 'false',
+ set_interface: 'false',
+ set_ipv4_default_next_hop_load_share: 'false',
+ set_ipv4_next_hop_load_share: 'false',
+ set_ipv4_next_hop_peer_addr: 'false',
+ set_ipv4_next_hop_redist: 'false',
+ set_ipv4_next_hop_unchanged: 'false',
+ set_ipv4_precedence: 'false',
+ set_ipv4_prefix: 'false',
+ set_ipv6_default_next_hop_load_share: 'false',
+ set_ipv6_next_hop_load_share: 'false',
+ set_ipv6_next_hop_peer_addr: 'false',
+ set_ipv6_next_hop_redist: 'false',
+ set_ipv6_next_hop_unchanged: 'false',
+ set_ipv6_precedence: 'false',
+ set_ipv6_prefix: 'false',
+ set_level: 'false',
+ set_local_preference: 'false',
+ set_metric_additive: 'false',
+ set_metric_bandwidth: 'false',
+ set_metric_delay: 'false',
+ set_metric_effective_bandwidth: 'false',
+ set_metric_mtu: 'false',
+ set_metric_reliability: 'false',
+ set_metric_type: 'false',
+ set_nssa_only: 'false',
+ set_origin: 'false',
+ set_path_selection: 'false',
+ set_tag: 'false',
+ set_vrf: 'false',
+ set_weight: 'false',
+ },
+}
+
+tests[:non_default_1] = {
+ desc: '2.1 Non Defaults 1',
+ title_pattern: 'rm1 123 permit',
+ manifest_props: {
+ description: 'map1',
+ match_as_number: ['3', '22-34', '38', '101-110'],
+ match_as_number_as_path_list: %w(abc xyz pqr),
+ match_community: %w(public private),
+ match_community_exact_match: 'true',
+ match_evpn_route_type_1: 'true',
+ match_evpn_route_type_2_all: 'true',
+ match_evpn_route_type_2_mac_ip: 'true',
+ match_evpn_route_type_2_mac_only: 'true',
+ match_evpn_route_type_3: 'true',
+ match_evpn_route_type_4: 'true',
+ match_evpn_route_type_5: 'true',
+ match_evpn_route_type_6: 'true',
+ match_evpn_route_type_all: 'true',
+ match_ext_community: %w(epublic eprivate),
+ match_ext_community_exact_match: 'true',
+ match_interface: %w(loopback2 mgmt0 null0),
+ match_ipv4_addr_access_list: 'access',
+ match_ipv4_addr_prefix_list: %w(p1 p7 pre5),
+ match_ipv4_multicast_enable: 'true',
+ match_ipv4_multicast_group_addr: '239.2.2.2/32',
+ match_ipv4_multicast_rp_addr: '242.1.1.1/32',
+ match_ipv4_multicast_rp_type: 'ASM',
+ match_ipv4_multicast_src_addr: '242.1.1.1/32',
+ match_ipv4_next_hop_prefix_list: %w(nh5 nh1 nh42),
+ match_ipv4_route_src_prefix_list: %w(rs2 rs22 pre15),
+ match_ipv6_multicast_enable: 'true',
+ match_ipv6_multicast_group_addr: 'ff0e::2:101:0:0/96',
+ match_ipv6_multicast_rp_addr: '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type: 'ASM',
+ match_ipv6_multicast_src_addr: '2001::348:0:0/96',
+ match_ipv6_next_hop_prefix_list: %w(nhv6 v6nh1 nhv42),
+ match_ipv6_route_src_prefix_list: %w(rsv6 rs22v6 prev6),
+ match_mac_list: %w(mac1 listmac),
+ match_metric: [%w(1 0), %w(8 0), %w(224 9), %w(23 0), %w(5 8), %w(6 0)],
+ match_ospf_area: %w(10 7 222),
+ match_route_type_external: 'true',
+ match_route_type_inter_area: 'true',
+ match_route_type_internal: 'true',
+ match_route_type_intra_area: 'true',
+ match_route_type_level_1: 'true',
+ match_route_type_level_2: 'true',
+ match_route_type_local: 'true',
+ match_route_type_nssa_external: 'true',
+ match_route_type_type_1: 'true',
+ match_route_type_type_2: 'true',
+ match_src_proto: %w(tcp udp igmp),
+ match_tag: %w(5 342 28 3221),
+ match_vlan: '32, 45-200, 300-399, 402',
+ set_as_path_prepend: ['55.77', '12', '45.3'],
+ set_as_path_prepend_last_as: 1,
+ set_as_path_tag: 'true',
+ set_comm_list: 'abc',
+ set_community_additive: 'true',
+ set_community_asn: ['11:22', '33:44', '123:11'],
+ set_community_internet: 'true',
+ set_community_local_as: 'true',
+ set_community_no_advtertise: 'true',
+ set_community_no_export: 'true',
+ set_dampening_half_life: 6,
+ set_dampening_max_duation: 55,
+ set_dampening_reuse: 22,
+ set_dampening_suppress: 44,
+ set_distance_igp_ebgp: 1,
+ set_distance_internal: 2,
+ set_distance_local: 3,
+ set_extcomm_list: 'xyz',
+ set_extcommunity_4bytes_additive: 'true',
+ set_extcommunity_4bytes_non_transitive: ['21:42', '43:22', '59:17'],
+ set_extcommunity_4bytes_transitive: ['11:22', '33:44', '66:77'],
+ set_extcommunity_cost_igp: [%w(0 23), %w(3 33), %w(100 10954)],
+ set_extcommunity_cost_pre_bestpath: [%w(23 999), %w(88 482), %w(120 2323)],
+ set_extcommunity_rt_additive: 'true',
+ set_extcommunity_rt_asn: ['11:22', '33:44', '12.22.22.22:12', '123.256:543'],
+ set_forwarding_addr: 'true',
+ set_ipv4_next_hop: ['3.3.3.3', '4.4.4.4'],
+ set_ipv4_next_hop_load_share: 'true',
+ set_ipv4_precedence: 'critical',
+ set_ipv4_prefix: 'abcdef',
+ set_ipv6_next_hop: ['2000::1', '2000::11', '2000::22'],
+ set_ipv6_next_hop_load_share: 'true',
+ set_ipv6_prefix: 'wxyz',
+ set_level: 'level-1',
+ set_local_preference: 100,
+ set_metric_additive: 'false',
+ set_metric_bandwidth: 44,
+ set_metric_delay: 55,
+ set_metric_effective_bandwidth: 77,
+ set_metric_mtu: 88,
+ set_metric_reliability: 66,
+ set_metric_type: 'external',
+ set_nssa_only: 'true',
+ set_origin: 'egp',
+ set_path_selection: 'true',
+ set_tag: 101,
+ set_weight: 222,
+ },
+}
+
+tests[:non_default_2] = {
+ desc: '2.2 Non Defaults 2',
+ title_pattern: 'rm2 149 deny',
+ manifest_props: {
+ match_ipv6_addr_prefix_list: %w(pv6 pv67 prev6),
+ match_ipv4_multicast_enable: 'true',
+ match_ipv4_multicast_src_addr: '242.1.1.1/32',
+ match_ipv4_multicast_group_range_begin_addr: '239.1.1.1',
+ match_ipv4_multicast_group_range_end_addr: '239.2.2.2',
+ match_ipv4_multicast_rp_addr: '242.1.1.1/32',
+ match_ipv4_multicast_rp_type: 'Bidir',
+ match_ipv6_addr_access_list: 'v6access',
+ match_ipv6_multicast_enable: 'true',
+ match_ipv6_multicast_src_addr: '2001::348:0:0/96',
+ match_ipv6_multicast_group_range_begin_addr: 'ff01::',
+ match_ipv6_multicast_group_range_end_addr: 'ff02::',
+ match_ipv6_multicast_rp_addr: '2001::348:0:0/96',
+ match_ipv6_multicast_rp_type: 'Bidir',
+ set_community_none: 'true',
+ set_extcommunity_4bytes_none: 'true',
+ set_ipv4_default_next_hop: ['1.1.1.1', '2.2.2.2'],
+ set_ipv4_default_next_hop_load_share: 'true',
+ set_ipv4_next_hop_peer_addr: 'true',
+ set_ipv6_precedence: 'flash',
+ set_level: 'level-1-2',
+ set_metric_additive: 'true',
+ set_metric_bandwidth: 33,
+ set_metric_type: 'type-2',
+ set_origin: 'incomplete',
+ },
+}
+
+tests[:non_default_3] = {
+ desc: '2.3 Non Defaults 3',
+ title_pattern: 'rm3 159 deny',
+ manifest_props: {
+ set_ipv6_default_next_hop: ['2000::1', '2000::11', '2000::22'],
+ set_ipv6_default_next_hop_load_share: 'true',
+ set_ipv6_next_hop_peer_addr: 'true',
+ },
+}
+
+tests[:non_default_4] = {
+ desc: '2.4 Non Defaults 4',
+ title_pattern: 'rm4 200 permit',
+ manifest_props: {
+ set_interface: 'Null0',
+ set_ipv4_next_hop_redist: 'true',
+ set_ipv6_next_hop_redist: 'true',
+ set_ipv4_next_hop_unchanged: 'true',
+ set_ipv6_next_hop_unchanged: 'true',
+ },
+}
+
+tests[:non_default_5] = {
+ desc: '2.5 Non Defaults 5',
+ title_pattern: 'rm5 199 deny',
+ manifest_props: {
+ match_length: %w(45 345),
+ set_vrf: 'igp',
+ },
+}
+
+def unsupp_n3k
+ im = nexus_image
+ unprops = []
+ unprops <<
+ :match_evpn_route_type_1 <<
+ :match_evpn_route_type_2_all <<
+ :match_evpn_route_type_2_mac_ip <<
+ :match_evpn_route_type_2_mac_only <<
+ :match_evpn_route_type_3 <<
+ :match_evpn_route_type_4 <<
+ :match_evpn_route_type_5 <<
+ :match_evpn_route_type_6 <<
+ :match_evpn_route_type_all <<
+ :match_length <<
+ :match_mac_list <<
+ :match_vlan <<
+ :set_vrf
+ unprops <<
+ :match_ospf_area <<
+ :set_ipv4_next_hop_redist <<
+ :set_ipv6_next_hop_redist if im[/(I2|I3|I4)/]
+ unprops
+end
+
+def unsupp_n56k
+ unprops = []
+ unprops <<
+ :match_ospf_area <<
+ :set_ipv4_default_next_hop <<
+ :set_ipv4_default_next_hop_load_share <<
+ :set_ipv4_next_hop_load_share <<
+ :set_ipv4_prefix <<
+ :set_ipv6_default_next_hop <<
+ :set_ipv6_default_next_hop_load_share <<
+ :set_ipv6_next_hop_load_share <<
+ :set_ipv6_prefix <<
+ :set_vrf
+ unprops
+end
+
+def unsupp_n7k
+ unprops = []
+ unprops <<
+ :match_ospf_area
+ unprops
+end
+
+def unsupp_n9k
+ im = nexus_image
+ unprops = []
+ unprops <<
+ :match_evpn_route_type_1 <<
+ :match_evpn_route_type_2_all <<
+ :match_evpn_route_type_2_mac_ip <<
+ :match_evpn_route_type_2_mac_only <<
+ :match_evpn_route_type_3 <<
+ :match_evpn_route_type_4 <<
+ :match_evpn_route_type_5 <<
+ :match_evpn_route_type_6 <<
+ :match_evpn_route_type_all <<
+ :match_length <<
+ :match_mac_list <<
+ :match_vlan <<
+ :set_ipv4_default_next_hop <<
+ :set_ipv4_default_next_hop_load_share <<
+ :set_ipv6_default_next_hop <<
+ :set_ipv6_default_next_hop_load_share <<
+ :set_extcommunity_rt_asn <<
+ :set_vrf
+ unprops <<
+ :set_ipv4_next_hop_load_share <<
+ :set_ipv6_next_hop_load_share <<
+ :match_ospf_area <<
+ :set_ipv4_next_hop_redist <<
+ :set_ipv6_next_hop_redist if im[/(I2|I3|I4)/]
+ unprops << :match_metric if im['I4']
+ unprops
+end
+
+def unsupp_n9kf
+ unprops = []
+ unprops <<
+ :match_evpn_route_type_1 <<
+ :match_evpn_route_type_2_all <<
+ :match_evpn_route_type_2_mac_ip <<
+ :match_evpn_route_type_2_mac_only <<
+ :match_evpn_route_type_3 <<
+ :match_evpn_route_type_4 <<
+ :match_evpn_route_type_5 <<
+ :match_evpn_route_type_6 <<
+ :match_evpn_route_type_all <<
+ :match_length <<
+ :match_mac_list <<
+ :match_metric <<
+ :match_ospf_area <<
+ :match_vlan <<
+ :set_extcommunity_4bytes_additive <<
+ :set_extcommunity_4bytes_non_transitive <<
+ :set_extcommunity_4bytes_transitive <<
+ :set_extcommunity_cost_igp <<
+ :set_extcommunity_cost_pre_bestpath <<
+ :set_extcommunity_rt_additive <<
+ :set_extcommunity_rt_asn <<
+ :set_forwarding_addr <<
+ :set_ipv4_default_next_hop <<
+ :set_ipv4_default_next_hop_load_share <<
+ :set_ipv6_default_next_hop <<
+ :set_ipv6_default_next_hop_load_share <<
+ :set_ipv4_next_hop <<
+ :set_ipv4_next_hop_load_share <<
+ :set_ipv4_precedence <<
+ :set_ipv4_prefix <<
+ :set_ipv6_next_hop <<
+ :set_ipv6_next_hop_load_share <<
+ :set_ipv6_prefix <<
+ :set_vrf
+ unprops
+end
+
+def unsupported_properties(_tests, _id)
+ if platform[/n3k/]
+ unsupp_n3k
+ elsif platform[/n(5|6)k/]
+ unsupp_n56k
+ elsif platform[/n7k/]
+ unsupp_n7k
+ elsif platform[/n9k$/]
+ unsupp_n9k
+ elsif platform[/n9k-f/]
+ unsupp_n9kf
+ end
+end
+
+def cleanup(agent)
+ resource_absent_cleanup(agent, 'cisco_route_map')
+end
+
+#################################################################
+# TEST CASE EXECUTION
+#################################################################
+test_name "TestCase :: #{tests[:resource_name]}" do
+ teardown { cleanup(agent) }
+ cleanup(agent)
+
+ # -------------------------------------------------------------------
+ logger.info("\n#{'-' * 60}\nSection 1. Default Property Testing")
+ test_harness_run(tests, :default)
+
+ id = :default
+ tests[id][:ensure] = :absent
+ test_harness_run(tests, id)
+
+ # -------------------------------------------------------------------
+ logger.info("\n#{'-' * 60}\nSection 2. Non Default Property Testing")
+
+ test_harness_run(tests, :non_default_1)
+ test_harness_run(tests, :non_default_2)
+ test_harness_run(tests, :non_default_3)
+ test_harness_run(tests, :non_default_4)
+ test_harness_run(tests, :non_default_5)
+end
+
+logger.info("TestCase :: #{tests[:resource_name]} :: End")
diff --git a/tests/beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb b/tests/beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb
new file mode 100644
index 000000000..f6bb498a7
--- /dev/null
+++ b/tests/beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb
@@ -0,0 +1,60 @@
+###############################################################################
+# Copyright (c) 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.
+# 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.
+###############################################################################
+#
+# See README-develop-beaker-scripts.md (Section: Test Script Variable Reference)
+# for information regarding:
+# - test script general prequisites
+# - command return codes
+# - A description of the 'tests' hash and its usage
+#
+###############################################################################
+require File.expand_path('../../lib/utilitylib.rb', __FILE__)
+@version = image_version.to_s.strip
+# Test hash top-level keys
+tests = {
+ master: master,
+ agent: agent,
+ operating_system: 'nexus',
+ ensurable: false,
+ resource_name: 'cisco_upgrade',
+}
+
+# Non-default Tests. NOTE: [:resource] = [:manifest_props] for all non-default
+tests[:non_default] = {
+ desc: '1.1 Non_Defaults',
+ code: [0],
+ title_pattern: 'image',
+ platform: 'n(3|9)k',
+ manifest_props: {
+ version: @version,
+ source_uri: on(agent, facter_cmd('-p cisco.images.system_image')).output,
+ force_upgrade: false,
+ delete_boot_image: false,
+ },
+ resource: {
+ version: @version
+ },
+}
+
+#################################################################
+# TEST CASE EXECUTION
+#################################################################
+test_name "TestCase :: #{tests[:resource_name]}" do
+ # -------------------------------------------------------------------
+ logger.info("\n#{'-' * 60}\nSection Non Default Property Testing")
+ test_harness_run(tests, :non_default)
+end
+logger.info("TestCase :: #{tests[:resource_name]} :: End")
diff --git a/tests/beaker_tests/lib/utilitylib.rb b/tests/beaker_tests/lib/utilitylib.rb
index 8b3480155..74fc7e3e2 100644
--- a/tests/beaker_tests/lib/utilitylib.rb
+++ b/tests/beaker_tests/lib/utilitylib.rb
@@ -75,6 +75,7 @@ def hash_to_patterns(hash)
if /^\[.*\]$/.match(value)
value.gsub!(/[\[\]]/) { |s| '\\' + "#{s}" }.gsub!(/\"/) { |_s| '\'' }
end
+ value.gsub!(/[\(\)]/) { |s| '\\' + "#{s}" } if /\(.*\)/.match(value)
regexparr << Regexp.new("#{key}\s+=>\s+'?#{value}'?")
end
regexparr
@@ -1110,6 +1111,14 @@ def nexus_image
@image ||= image_regexp.match(data)[1]
end
+# Gets the version of the image running on a device
+@version = nil
+def image_version
+ facter_opt = '-p os.release.full'
+ data = on(agent, facter_cmd(facter_opt)).stdout.chomp
+ @version ||= data
+end
+
# On match will skip all testcases
# Do not use this for skipping individual properties.
def skip_nexus_image(image, tests)
@@ -1450,6 +1459,7 @@ def test_patch_version(tests, id, name, ver)
# Returns: String with double quotes: (Example: '"foo"'
#
def add_quotes(string)
- string = "\"#{string}\"" if image?[/8.0/]
+ return string if image?[/7.3.0/]
+ string = "\"#{string}\""
string
end
diff --git a/tests/beaker_tests/radius_global/radius_global_provider_defaults.rb b/tests/beaker_tests/radius_global/radius_global_provider_defaults.rb
index 5dbc0ab18..d02f5c109 100644
--- a/tests/beaker_tests/radius_global/radius_global_provider_defaults.rb
+++ b/tests/beaker_tests/radius_global/radius_global_provider_defaults.rb
@@ -72,7 +72,7 @@
# Expected exit_code is 2 since this is a puppet agent cmd with change.
cmd_str = PUPPET_BINPATH + 'agent -t'
- on(agent, cmd_str, acceptable_exit_codes: [2])
+ on(agent, cmd_str, acceptable_exit_codes: [0, 2])
logger.info("Get resource present manifest from master :: #{result}")
end