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